diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index 7fb889809..91f359a8b 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -3,12 +3,7 @@ name: CD - production on: push: branches: [ main ] -env: - NEXT_PUBLIC_BASE_PATH: '' - NEXT_PUBLIC_DOCSEARCH_APP_ID: ${{ secrets.NEXT_PUBLIC_DOCSEARCH_APP_ID }} - NEXT_PUBLIC_DOCSEARCH_API_KEY: ${{ secrets.NEXT_PUBLIC_DOCSEARCH_API_KEY }} - NEXT_PUBLIC_DOCSEARCH_INDEX_NAME: ${{ secrets.NEXT_PUBLIC_DOCSEARCH_INDEX_NAME }} - + jobs: build: runs-on: ubuntu-latest @@ -24,5 +19,5 @@ jobs: aws-access-key-id: ${{ secrets.AWS_S3_PRODUCTION_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_S3_PRODUCTION_SECRET }} aws-region: eu-west-1 - - run: aws s3 sync ./out ${{ secrets.AWS_S3_PRODUCTION_PATH }} + - run: aws s3 sync ./build ${{ secrets.AWS_S3_PRODUCTION_PATH }} - run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_DISTRIBUTION_PRODUCTION }} --paths '/*' diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index 0e8ec5281..eec8052d5 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -3,11 +3,6 @@ name: CD on: push: branches: [ staging ] -env: - NEXT_PUBLIC_BASE_PATH: '' - NEXT_PUBLIC_DOCSEARCH_APP_ID: ${{ secrets.NEXT_PUBLIC_DOCSEARCH_APP_ID }} - NEXT_PUBLIC_DOCSEARCH_API_KEY: ${{ secrets.NEXT_PUBLIC_DOCSEARCH_API_KEY }} - NEXT_PUBLIC_DOCSEARCH_INDEX_NAME: ${{ secrets.NEXT_PUBLIC_DOCSEARCH_INDEX_NAME }} jobs: build: @@ -24,5 +19,5 @@ jobs: aws-access-key-id: ${{ secrets.AWS_S3_STAGE_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_S3_STAGE_SECRET }} aws-region: eu-west-1 - - run: aws s3 sync ./out ${{ secrets.AWS_S3_STAGE_PATH }} + - run: aws s3 sync ./build ${{ secrets.AWS_S3_STAGE_PATH }} - run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_DISTRIBUTION_STAGE }} --paths '/*' diff --git a/.gitignore b/.gitignore index 02dbd0405..85643fb34 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ node_modules .next .env.local .DS_Store -out \ No newline at end of file +.docusaurus/* +out +build + diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 2e1fa2d52..000000000 --- a/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -*.md \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..2e5a68f8e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Trilitech + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 95380447e..47c57b38c 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ cp .env.example .env.local Next, run the development server: ```bash -npm run dev +npm run start ``` Finally, open [http://localhost:3000](http://localhost:3000) in your browser to view the website. diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 000000000..e00595dae --- /dev/null +++ b/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 000000000..4db8cb23c --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,24 @@ +# Architecture + +- Who created it and who is in charge of it +- What entities participate in it +- How it is built (architecture, with diagrams) + +## Decentralization +## p2p network (introducting nodes, baking) +## smart contracts and dapps +## governance and roadmap for scaling + +## goals/inspiration, tiny bit of history +need for decentralization, smart contracts, then for Tezos, need for blockchains to evolve, be environmental friendly, secure +## p2p network, DOS protection, etc. +Idea: to make it more active, create an interactive experience where people simulate playing different roles, through the path of a transaction +## accounts, cryptocurrency, transactions +Here the animation would let people play with transactions ana d simulated wallet +## chain of blocks +idea that for people to agree on a sequence of transactions, they need to be grouped in block, and we create an append-only structure +## baking, consensus mechanism +"someone needs to propose a new block, so we have a system involving bakers, then a mechanism to pick the baker, confirm the block through attestations, and finality +you could have a small interface where you try to create the best block" +## recap: path of a transaction +wallet, simulation, propagation through the nodes, mempool, accepted by a baker, block is propagated and validated, then becomes final, shown as validated on the wallet, and visible by everyone \ No newline at end of file diff --git a/docs/architecture/accounts.md b/docs/architecture/accounts.md new file mode 100644 index 000000000..85955e198 --- /dev/null +++ b/docs/architecture/accounts.md @@ -0,0 +1,15 @@ +--- +title: Accounts +authors: "Tim McMackin" +lastUpdated: 18th October 2023 +--- + +Tezos uses two types of accounts: + +- Classic accounts (also known as _implicit accounts_) with an address, storing tez (ꜩ). +These accounts have addresses that start with "tz1", "tz2", "tz3" or "tz4." +Any wallet application or the Octez command-line tool can create implicit accounts. + +- Smart contract accounts (also known as _originated accounts_) with an address, storing code and tez (ꜩ). +Originated accounts have addresses that start with "KT1." +Creating an originated account is part of the process of deploying a smart contract; see [Smart contracts](../smart-contracts). diff --git a/docs/architecture/baking.md b/docs/architecture/baking.md new file mode 100644 index 000000000..13cb06db3 --- /dev/null +++ b/docs/architecture/baking.md @@ -0,0 +1,9 @@ +# Baking + +- What is baking? +- Why would I want to do it? +- What's involved in baking + +Should this link to tezos.gitlab.io instead of being here? There are no topics on Baking there, but octez is how you bake. + +We write an overview, based on what is on opentezos, to give a good understanding of what running nodes involve, without diving into details \ No newline at end of file diff --git a/docs/architecture/baking/running-nodes.md b/docs/architecture/baking/running-nodes.md new file mode 100644 index 000000000..9032b8f6b --- /dev/null +++ b/docs/architecture/baking/running-nodes.md @@ -0,0 +1,3 @@ +# Hosting a baking node + +We write an overview, based on what is on opentezos, to give a good understanding of what running nodes involve, without diving into details \ No newline at end of file diff --git a/src/pages/tezos-basics/governance/index.md b/docs/architecture/governance.md similarity index 98% rename from src/pages/tezos-basics/governance/index.md rename to docs/architecture/governance.md index c854bec29..7f3d822b9 100644 --- a/src/pages/tezos-basics/governance/index.md +++ b/docs/architecture/governance.md @@ -1,12 +1,13 @@ --- -title: Tezos Governance +title: Governance lastUpdated: 3rd July 2023 --- + ## What is Self Amendment? Tezos is a self-amending blockchain network that incorporates an on-chain mechanism for proposing, selecting, testing, and activating protocol upgrades without the need to hard fork. -## How Does It Work? +## How Does It Work? The self-amendment process is split into 5 periods: Proposal Period, Exploration Vote Period, Cooldown Period, Promotion Vote Period, and Adoption Period. Each of these periods lasts five baking cycles (i.e. 40,960 blocks at 30-second intervals or roughly 14 days, 5 hours), comprising roughly 2 months and 10 days. diff --git a/src/pages/tezos-basics/governance/history-of-amendments/index.md b/docs/architecture/governance/amendment-history.md similarity index 98% rename from src/pages/tezos-basics/governance/history-of-amendments/index.md rename to docs/architecture/governance/amendment-history.md index 83566e3ea..28e20c5dd 100644 --- a/src/pages/tezos-basics/governance/history-of-amendments/index.md +++ b/docs/architecture/governance/amendment-history.md @@ -1,11 +1,10 @@ --- -id: history-of-amendments title: History of amendments authors: 'Thomas Zoughebi, Aymeric Bethencourt, and Maxime Fernandez' lastUpdated: 30th June 2023 --- -As presented in the [Governance on-chain chapter](/tezos-basics/governance-on-chain), the Tezos blockchain is constantly evolving, through new amendments. In this chapter, we will present an overview of past proposals and the reasons for their approval or disapproval. +As presented in [Governance](../governance), the Tezos blockchain is constantly evolving, through new amendments. In this chapter, we will present an overview of past proposals and the reasons for their approval or disapproval. ## [Athens](https://tezos.gitlab.io/protocols/004_Pt24m4xi.html) (Pt24m4xiP) @@ -82,7 +81,7 @@ Florence's notable bug fixes and improvements are the: * Changing inter-contract calls to a [depth-first search](https://en.wikipedia.org/wiki/Depth-first_search) ordering, as opposed to [breadth-first search](https://en.wikipedia.org/wiki/Breadth-first_search) ordering * The elimination of the test chain activation - + [*Bakings Accounts*](https://midl-dev.medium.com/tezos-in-favor-of-baking-accounts-3886effa370c) was also included in the feature set. However, ongoing testing uncovered some important and previously undocumented breaking changes in the proposal with *Baking Accounts*. Hence, the feature was postponed until a thorough audit of the functionality was completed or an alternative implementation was produced. The version of *Florence* without *Baking Accounts* was considered a [safer choice](https://research-development.nomadic-labs.com/baking-accounts-proposal-contains-unexpected-breaking-changes.html). For more information, see the blog post from [Nomadic Labs](https://research-development.nomadic-labs.com/florence-our-next-protocol-upgrade-proposal.html) and [Tarides](https://tarides.com/blog/2021-03-04-florence-and-beyond-the-future-of-tezos-storage), as well as the [reference documentation](https://tezos.gitlab.io/protocols/009_florence.html). diff --git a/src/pages/tezos-basics/governance/improvement-process-tzip/index.md b/docs/architecture/governance/improvement-process.md similarity index 97% rename from src/pages/tezos-basics/governance/improvement-process-tzip/index.md rename to docs/architecture/governance/improvement-process.md index 9a03405b2..803e0005b 100644 --- a/src/pages/tezos-basics/governance/improvement-process-tzip/index.md +++ b/docs/architecture/governance/improvement-process.md @@ -2,14 +2,14 @@ title: Tezos Improvement Process (TZIP) lastUpdated: 10th July 2023 --- -As Tezos is a large decentralized project that is constantly evolving, its members need to have a mechanism for proposing improvements to the ecosystem. +As Tezos is a large decentralized project that is constantly evolving, its members need to have a mechanism for proposing improvements to the ecosystem. A Tezos Improvement Proposal (or TZIP, pronounced "tee-zip") is a document that offers ways to improve Tezos via new features, tools, or standards (e.g. smart contract specifications). Specifically, a TZIP is a design document providing information to the Tezos community, describing a feature for Tezos or its processes or environment, and supporting the formal protocol governance process. The TZIP process complements (but is subsidiary to) Tezos' formal on-chain governance process. -The TZIP document should contain a concise technical specification and rationale that clearly articulates what the proposal is, how it may be implemented, and why the proposal is an improvement. It should also include an FAQ that documents, compares, and answers alternative options, opinions, and objections. - +The TZIP document should contain a concise technical specification and rationale that clearly articulates what the proposal is, how it may be implemented, and why the proposal is an improvement. It should also include an FAQ that documents, compares, and answers alternative options, opinions, and objections. + An explorer for all of the TZIPs, both past and present, can be found [here](https://tzip.tezosagora.org/). ## Key TZIP Standards @@ -18,7 +18,7 @@ An explorer for all of the TZIPs, both past and present, can be found [here](htt TZIP-7, more commonly referred to as FA1.2, introduced an [ERC20](https://eips.ethereum.org/EIPS/eip-20)-like fungible token standard for Tezos. At its core, FA1.2 contains a ledger that maps identities to token balances, provides a standard API for token transfer operations, as well as providing approval to external contracts (e.g. an auction) or accounts to transfer a user's tokens. -For those coming from [ERC20](https://eips.ethereum.org/EIPS/eip-20), the FA1.2 interface differs from ERC-20 in that it does not contain `transferfrom`, which has instead been merged into a single transfer entrypoint. +For those coming from [ERC20](https://eips.ethereum.org/EIPS/eip-20), the FA1.2 interface differs from ERC-20 in that it does not contain `transferfrom`, which has instead been merged into a single transfer entrypoint. The FA1.2 specification is described in detail in [TZIP-7](https://gitlab.com/tzip/tzip/blob/master/proposals/tzip-7/tzip-7.md), and several implementations of FA1.2 can be found [here](https://packages.ligolang.org/package/ligo-fa1.2). @@ -47,8 +47,8 @@ TZIP-16 defines: * A basic structure to find some metadata in a contract's storage. * A URI scheme to find data: on-chain (contract storage) or off-chain (web services or IPFS). -* An extensible JSON format (JSON-Schema) to describe the metadata -* Optional entrypoints to validate metadata information +* An extensible JSON format (JSON-Schema) to describe the metadata +* Optional entrypoints to validate metadata information ### [**TZIP-17**](https://tzip.tezosagora.org/proposal/tzip-17/): Permit & Meta-transactions @@ -60,7 +60,7 @@ For instance, a “relayer” can submit a user’s pre-signed (meta) transactio TZIP-17 enables developers to provide more native experiences for user onboarding and allows users to pay fees using the token (e.g. a stablecoin) used in the transaction. The relayer still pays transaction fees in tez at the protocol level and, because Tezos is Proof-of-Stake, these [transaction fees accrue to stakeholders](http://ex.rs/protocol-level-fees/) rather than just a small group of miners. -Ultimately, this brings the experience of using digital assets on Tezos more in line with that of traditional financial transactions and supports the use of Tezos as a settlement layer. +Ultimately, this brings the experience of using digital assets on Tezos more in line with that of traditional financial transactions and supports the use of Tezos as a settlement layer. **** ### [**TZIP-20**](https://tzip.tezosagora.org/proposal/tzip-20/): Off-chain Events @@ -69,7 +69,7 @@ Off-chain events can be used for various purposes, but one of the most obvious u However, the indexer can't determine which particular balances have changed if the invoked method is not standardized (e.g. FA2/FA1.2 transfer), or if there was an initial token distribution at the origination. -The current approach is using custom handlers for known contracts. +The current approach is using custom handlers for known contracts. This approach is tied to a specific indexer implementation and is not scalable. Therefore we need a better alternative that is flexible enough to cover the majority of cases, simple enough to implement/integrate with the existing codebase, and not tied to any specific entity or implementation. diff --git a/src/pages/tezos-basics/tezos-protocol-and-shell/index.md b/docs/architecture/protocol.md similarity index 95% rename from src/pages/tezos-basics/tezos-protocol-and-shell/index.md rename to docs/architecture/protocol.md index e251f99da..a2fac7e61 100644 --- a/src/pages/tezos-basics/tezos-protocol-and-shell/index.md +++ b/docs/architecture/protocol.md @@ -1,5 +1,4 @@ --- -id: tezos-protocol-and-shell title: Tezos Protocol and Shell lastUpdated: 29th June 2023 --- @@ -18,7 +17,7 @@ The rest of the shell includes the peer-to-peer layer, the disk storage of block Protocols are compiled using a tweaked OCaml compiler that does two things. First, it checks that the protocol’s main module has the right type. A good analogy is to see protocol as plug-ins, and in this case, it means that it respects the common plugin interface. Then, it restricts the typing environment of the protocol’s code so that it only calls authorized modules and functions. Seeing protocols as plug-ins, it means that the code only called primitives from the plug-in API. It is a form of statically enforced sandboxing. -Note that the economic protocol on the chain is subject to an amendment procedure. On-chain operations can be used to switch from one protocol to another. +Note that the economic protocol on the chain is subject to an amendment procedure. On-chain operations can be used to switch from one protocol to another. Finally, the RPC layer is an important part of the node. It is how the client, third-party applications, and daemons can interact with the node and introspect its state. This component uses the mainstream JSON format and HTTP protocol. It uses the library resto. It is fully interoperable, and auto-descriptive, using JSON schema. @@ -45,29 +44,28 @@ As previously stated, Tezos is a self-amending blockchain. In large part of Tezo The economic protocol provides the rules for checking the validity of the blocks and operations, and for updating the blockchain state accordingly, by applying new valid blocks and operations on the current blockchain state. It defines under which conditions a block is a valid extension of the current blockchain, and defines an ordering on blocks to arbitrate between concurrent extensions. -The rules it uses for recognizing and applying valid blocks can be changed through voting. Thus, the economic protocol represents the amendable part of Tezos. To learn about the voting and amendment process see [Tezos Agora's overview](https://www.tezosagora.org/learn) of Tezos Governance. +The rules it uses for recognizing and applying valid blocks can be changed through voting. Thus, the economic protocol represents the amendable part of Tezos. To learn about the voting and amendment process see [Tezos Agora's overview](https://www.tezosagora.org/learn) of Tezos Governance. -Each Tezos protocol is named after a (usually ancient) city, with the first one named Athens. Each successive name follows the previous alphabetically, continuing to Babylon, Carthage, Delphi, and so on. At the time of writing this article, the network is on the Mumbai protocol, with Nairobi planned for June 2023. There is a protocol upgrade roughly every 3 months. +Each Tezos protocol is named after a (usually ancient) city, with the first one named Athens. Each successive name follows the previous alphabetically, continuing to Babylon, Carthage, Delphi, and so on. At the time of writing this article, the network is on the Mumbai protocol, with Nairobi planned for June 2023. There is a protocol upgrade roughly every 3 months. -## Shell-protocol interaction +## Shell-protocol interaction -The economic protocol and the shell interact in order to ensure that the blocks being appended to the blockchain are valid. The shell does not accept a branch whose fork point is some number of cycles in the past--anything before is deemed immutable. Also, when receiving a new block the shell determines if the block is valid and its fitness is higher than the current head. +The economic protocol and the shell interact in order to ensure that the blocks being appended to the blockchain are valid. The shell does not accept a branch whose fork point is some number of cycles in the past--anything before is deemed immutable. Also, when receiving a new block the shell determines if the block is valid and its fitness is higher than the current head. The protocol provides support for validating blocks which can be modulated by different "validation modes". -## The Shell +## The Shell -The shell contains everything that is not part of the economic protocol. It includes: +The shell contains everything that is not part of the economic protocol. It includes: - The Validator: the component responsible for checking that blocks coming from the network or a baker are valid, w.r.t. the rules defined by the economic protocol. - The Prevalidator: responsible for determining which operations to propagate for this chain over the peer-to-peer network. - The Storage Layer: responsible for aggregating blocks (along with their respective ledger state) and operations within blocks (along with their associated metadata). -- Synchronization heuristic: Process to bootstrap a node when first joining the network, and knowing when it's synced with the network. +- Synchronization heuristic: Process to bootstrap a node when first joining the network, and knowing when it's synced with the network. - The peer-to-peer layer: this part is in charge of establishing and maintaining network connections with other nodes (via a gossip protocol). - Protocol Environment: a restricted API that may be used by the Octez code to interact with the protocol, and vice versa. -{% callout type="note" %} -In-depth documentation on the [shell](https://tezos.gitlab.io/shell/the_big_picture.html) and [protocol](https://tezos.gitlab.io/active/protocol.html) and the semantics of [operations and blocks](https://tezos.gitlab.io/active/blocks_ops.html) can be found in Tezos' [technical documentation](https://tezos.gitlab.io/index.html). -{% /callout %} +:::note +In-depth documentation on the [shell](https://tezos.gitlab.io/shell/the_big_picture.html) and [protocol](https://tezos.gitlab.io/active/protocol.html) and the semantics of [operations and blocks](https://tezos.gitlab.io/active/blocks_ops.html) can be found in Tezos' [technical documentation](https://tezos.gitlab.io/index.html). diff --git a/src/pages/advanced-topics/smart-rollups/index.md b/docs/architecture/smart-rollups.md similarity index 94% rename from src/pages/advanced-topics/smart-rollups/index.md rename to docs/architecture/smart-rollups.md index 0d1e3acbc..0138e2660 100644 --- a/src/pages/advanced-topics/smart-rollups/index.md +++ b/docs/architecture/smart-rollups.md @@ -1,5 +1,4 @@ --- -id: smart-rollups title: Smart Optimistic Rollups authors: 'Nomadic Labs, TriliTech' lastUpdated: 30th June 2023 @@ -9,7 +8,11 @@ Rollups play a crucial part in providing next-generation scaling on Tezos. This ## Prerequisites -This page covers an advanced topic at the bleeding edge of Tezos core development. If you are interested in more fundamental reading, a great place to start is [Tezos Protocol and Shell](/tezos-basics/tezos-protocol-and-shell/) and [Smart Contracts](/smart-contracts/smart-contract-languages/). +This page covers an advanced topic at the bleeding edge of Tezos core development. If you are interested in more fundamental reading, a great place to start is [Tezos Protocol and Shell](./protocol) and [Smart Contracts](../smart-contracts/languages). + +## Examples + +For examples of smart rollups, see this repository: https://gitlab.com/tezos/kernel-gallery. ## What is a rollup? @@ -111,7 +114,7 @@ Contrary to external messages, which are submitted by the end users, internal messages are constructed by layer 1. At the beginning of every Tezos block, layer 1 pushes two internal -messages: +messages: - `"Start of level"` - no associated payload - `"Info per level"` - provides @@ -282,7 +285,7 @@ indirectly using the Octez rollup client. An Octez rollup node needs an Octez node to run. We assume that an Octez node has been launched locally: -``` sh +```sh octez-node config init --data-dir "${ONODE_DIR}" --network "${NETWORK}" octez-node run --data-dir "${ONODE_DIR}" --network "${NETWORK}" --rpc-addr 127.0.0.1 ``` @@ -291,7 +294,7 @@ Finally, you need to check that your balance is greater than 10,000 tez to make sure that staking is possible. If your balance is not sufficient, you can get test tokens from a faucet. -``` sh +```sh octez-client get balance for "${OPERATOR_ADDR}" ``` @@ -299,7 +302,7 @@ octez-client get balance for "${OPERATOR_ADDR}" Anyone can originate a smart rollup with the following invocation of the Octez client: -``` sh +```sh octez-client originate smart rollup "${SOR_ALIAS}" \ from "${OPERATOR_ADDR}" \ of kind wasm_2_0_0 \ @@ -308,23 +311,23 @@ octez-client originate smart rollup "${SOR_ALIAS}" \ --burn-cap 999 ``` -where `${SOR_ALIAS}` is an alias to memorize the smart rollup address in the client. This alias can be used in any command where a smart rollup address is expected. `${KERNEL}` is a hex representation of a WebAssembly bytecode serving as an initial program to boot on. +where `${SOR_ALIAS}` is an alias to memorize the smart rollup address in the client. This alias can be used in any command where a smart rollup address is expected. `${KERNEL}` is a hex representation of a WebAssembly bytecode serving as an initial program to boot on. You can obtain this representation through the WASM bytecode file named `kernel.wasm`: -``` sh +```sh xxd -ps -c 0 | tr -d '\n' ``` To experiment, we propose that you use the value `${KERNEL}` defined in the file `sr_boot_kernel.sh`. -``` sh -source sr_boot_kernel.sh +```sh +source sr_boot_kernel.sh ``` If everything went well, the origination command results in: -``` sh +```sh This sequence of operations was run: Manager signed operations: From: tz1fp5ncDmqYwYC568fREYz9iwQTgGQuKZqX @@ -375,7 +378,7 @@ First, we need to decide on a directory where the rollup node stores its data. L The rollup node can be run with: -``` sh +```sh octez-smart-rollup-node-alpha --base-dir "${OCLIENT_DIR}" \ run operator for "${SOR_ALIAS_OR_ADDR}" \ with operators "${OPERATOR_ADDR}" \ @@ -384,10 +387,10 @@ octez-smart-rollup-node-alpha --base-dir "${OCLIENT_DIR}" \ The log should show that the rollup node follows layer 1 chain and is processing the inbox of each level. -{% callout type="note" title="Distinct layer 1 Addresses" %} +:::note Distinct layer 1 Addresses Distinct layer 1 addresses could be used for layer 1 operations issued by the rollup node simply by editing the configuration file to set different addresses for `publish` `add_messages` `cement` `refute`. -{% /callout %} +::: In addition, a rollup node can run under different modes: @@ -418,55 +421,24 @@ The following table summarizes the operation modes, focusing on the L1 operations which are injected by the rollup node in each mode. -{% table %} -* -* Add Messages -* Publish -* Cement -* Refute ---- -* Operator -* Yes -* Yes -* Yes -* Yes ---- -* Batcher -* Yes -* No -* No -* No ---- -* Observer -* No -* No -* No -* No ---- -* Maintenance -* No -* Yes -* Yes -* Yes ---- -* Accuser -* No -* Yes* -* No -* Yes +  | Add Messages | Publish | Cement | Refute +---|---|---|---|--- +Operator | Yes | Yes | Yes | Yes +Batcher | Yes | No | No | No +Observer | No | No | No | No +Maintenance | No | Yes | Yes | Yes +Accuser | No | Yes* | No | Yes -{% /table %} - -{% callout type="note" title="When does an accuser publish commitments?" %} +:::note When does an accuser publish commitments? An accuser node will publish commitments only when it detects conflicts. In this case, it must deposit 10,000 tez. -{% /callout %} +::: ### Configuration file The rollup node can also be configured with the following command that uses the same arguments as the `run` command: -``` sh +```sh octez-smart-rollup-node-alpha --base-dir "${OCLIENT_DIR}" \ init operator config for "${SOR_ALIAS_OR_ADDR}" \ with operators "${OPERATOR_ADDR}" \ @@ -475,7 +447,7 @@ octez-smart-rollup-node-alpha --base-dir "${OCLIENT_DIR}" \ This creates a configuration file at `${ROLLUP_NODE_DIR}/config.json`: -``` sh +```sh { "data-dir": "${ROLLUP_NODE_DIR}", "smart-rollup-address": "${SOR_ADDR}", @@ -492,7 +464,7 @@ This creates a configuration file at `${ROLLUP_NODE_DIR}/config.json`: The rollup node can now be run with: -``` sh +```sh octez-smart-rollup-node-alpha -d "${OCLIENT_DIR}" run --data-dir ${ROLLUP_NODE_DIR} ``` @@ -504,13 +476,13 @@ The node can also be tested locally with a sandbox environment. Once you initialized the **sandboxed** client data with: -``` sh +```sh ./src/bin_client/octez-init-sandboxed-client.sh -``` +``` You can run a sandboxed rollup node with: -``` sh +```sh `octez-smart-rollup-node-Pt${CURRENT_PROTOCOL} run`. ``` @@ -521,19 +493,19 @@ used. However, a specific data directory can be set with the environment variabl ## Sending an External Inbox Message -The Octez client can be used to send an external message into the rollup inbox. Assuming that `${EMESSAGE}` is the hexadecimal representation of the message payload, to inject an external message, run: +The Octez client can be used to send an external message into the rollup inbox. Assuming that `${EMESSAGE}` is the hexadecimal representation of the message payload, to inject an external message, run: -``` sh +```sh octez-client" -d "${OCLIENT_DIR}" -p Pt${CURRENT_PROTOCOL} \ send smart rollup message "hex:[ \"${EMESSAGE}\" ]" \ from "${OPERATOR_ADDR}" ``` -Let's now produce some viable contents for `${EMESSAGE}`. The kernel used previously in our running example is a simple "echo" kernel that copies its input as a new message to its outbox. Therefore, the input must be a valid binary encoding of an outbox message to make this work. +Let's now produce some viable contents for `${EMESSAGE}`. The kernel used previously in our running example is a simple "echo" kernel that copies its input as a new message to its outbox. Therefore, the input must be a valid binary encoding of an outbox message to make this work. Specifically, assuming that we have originated a layer 1 smart contract as follows: -``` sh +```sh octez-client -d "${OCLIENT_DIR}" -p Pt${CURRENT_PROTOCOL} \ originate contract go transferring 1 from "${OPERATOR_ADDR}" \ running 'parameter string; storage string; code {CAR; NIL operation; PAIR};' \ @@ -544,7 +516,7 @@ and that this contract is identified by a address `${CONTRACT}`, then one can encode an outbox transaction using the Octez rollup client as follows: -``` sh +```sh MESSAGE='[ { \ "destination" : "${CONTRACT}", \ "parameters" : "\"Hello world\"", \ @@ -563,14 +535,14 @@ weeks long. When the commitment is cemented, one can observe that the outbox is populated as follows: -``` sh +```sh octez-smart-rollup-client-Pt${CURRENT_PROTOCOL} rpc get \ /global/block/cemented/outbox/${L}/messages ``` Here is the output for this command: -``` +``` [ { "outbox_level": ${L}, "message_index": "0", "message": { "transactions": @@ -584,7 +556,7 @@ triggered. This requires precomputing a proof that this outbox message is indeed in the outbox. In the case of our running example, this proof is retrieved as follows: -``` sh +```sh PROOF=$(octez-smart-rollup-client-Pt${CURRENT_PROTOCOL} get proof for message 0 \ of outbox at level "${L}" \ transferring "${MESSAGE}") @@ -592,19 +564,18 @@ PROOF=$(octez-smart-rollup-client-Pt${CURRENT_PROTOCOL} get proof for message 0 Finally, the execution of the outbox message is done as follows: -``` sh +```sh "${TEZOS_PATH}/octez-client" -d "${OCLIENT_DIR}" -p Pt${CURRENT_PROTOCOL} \ execute outbox message of smart rollup "${SOR_ALIAS_OR_ADDR}" \ from "${OPERATOR_ADDR}" for commitment hash "${LCC}" \ and output proof "${PROOF}" ``` -where `${LCC}` is the hash of the latest cemented commitment. +where `${LCC}` is the hash of the latest cemented commitment. -{% callout type="note" title="Who can trigger the execution of an outbox message?" %} +:::note Who can trigger the execution of an outbox message? Anyone can trigger the execution of an outbox message (not only an operator). -{% /callout %} To check the contract has indeed been called with the parameter `Hello World` through an internal operation, we can check the receipt. More complex parameters, typically assets represented as tickets, can be used as long as they match the type of the entrypoint of the @@ -618,7 +589,7 @@ address. The parameter of this transfer must be a value of the Michelson type de Remember that our running example rollup has been originated with: -``` sh +```sh octez-client originate smart rollup "${SOR_ALIAS}" \ from "${OPERATOR_ADDR}" \ of kind wasm_2_0_0 \ @@ -634,7 +605,7 @@ Here is an example of a Michelson script that sends an internal message to the rollup of our running example. The payload of the internal message is the value passed as parameter of type `bytes` to the rollup. -``` sh +```sh parameter bytes; storage unit; code @@ -677,19 +648,10 @@ The performance of the WebAssembly execution is affected primarily by the choice Here are some compiler options: -{% table %} -* Compiler -* `OCTEZ_WASMER_COMPILER` -* Description ---- -* Singlepass -* `singlepass` -* [When to use Singlepass](https://github.com/wasmerio/wasmer/tree/master/lib/compiler-singlepass#when-to-use-singlepass) ---- -* Cranelift -* `cranelift` -* [When to use Cranelift](https://github.com/wasmerio/wasmer/tree/master/lib/compiler-cranelift#when-to-use-cranelift) -{% /table %} +Compiler | `OCTEZ_WASMER_COMPILER` | Description +--- | --- | --- +Singlepass | `singlepass` | [When to use Singlepass](https://github.com/wasmerio/wasmer/tree/master/lib/compiler-singlepass#when-to-use-singlepass) | +Cranelift | `cranelift` | [When to use Cranelift](https://github.com/wasmerio/wasmer/tree/master/lib/compiler-cranelift#when-to-use-cranelift) ## Developing WASM Kernels @@ -697,7 +659,7 @@ A rollup is primarily characterized by the semantics given to the input messages it processes. These semantics are provided at origination time as a WASM program (i.e. `wasm_2_0_0`) called a **kernel**. The kernel is a WASM module encoded in the binary format as defined by the WASM standard. -A key requirement for any web3 technology is determinism. To ensure determinism, the following restrictions are in place: +A key requirement for any web3 technology is determinism. To ensure determinism, the following restrictions are in place: 1. Instructions and types related to floating-point arithmetic are not supported. This is because IEEE floats are not deterministic, as the @@ -716,7 +678,7 @@ Otherwise, we support the full WASM language. A valid kernel is a WASM module th For instance, an example of a simple `Hello World` kernel is the following WASM program in text format. -``` sh +```sh (module (import "smart_rollup_core" "write_debug" (func $write_debug (param i32 i32) (result i32))) @@ -735,7 +697,7 @@ following WASM program in text format. This program can be compiled to the WASM binary format with general-purpose tool like [WABT](https://github.com/WebAssembly/wabt). -``` sh +```sh wat2wasm hello.wat -o hello.wasm ``` @@ -759,27 +721,27 @@ of fetching inputs from layer 1, and executing the `kernel_run` function exposed The smart rollup carries two states: 1. A transient state, that is reset after each call to the `kernel_run` function, similar to RAM. -2. A persistent state, that is preserved across `kernel_run` calls. +2. A persistent state, that is preserved across `kernel_run` calls. - The **inbox** possesses this persistent state which is regularly populated with the inputs coming from layer 1. - The **outbox** which the kernel can populate with contract calls targeting smart contracts in layer 1. This can be thought of as durable storage similar to a file system. -The durable storage is a persistent tree, whose contents is addressed by path-like keys. +The durable storage is a persistent tree, whose contents is addressed by path-like keys. -A path in the storage may contain: +A path in the storage may contain: - a value (also called file) consisting of a sequence of raw bytes -- and/or any number of subtrees (also called directories) i.e. the paths in the storage prefixed by the current path. +- and/or any number of subtrees (also called directories) i.e. the paths in the storage prefixed by the current path. Thus, unlike most file systems, a path in the durable storage may be at the same time a file and a directory (a set of sub-paths). The WASM kernel can write and read the raw bytes stored under a given path (the file), but can also interact (delete, copy, move, etc.) with -subtrees (directories). +subtrees (directories). -{% callout type="note" title="Read-only values and subtrees" %} +:::note Read-only values and subtrees The values and subtrees under the key `/readonly` are not writable by a kernel, but can be used by the PVM to give information to the kernel. -{% /callout %} +::: ### Control Flow @@ -792,13 +754,13 @@ the `kernel_run` function is called, from a clean `transient` state. More precisely, the WASM kernel is re-initialized, then `kernel_run` is called. -By default, the WASM kernel yields when `kernel_run` returns. In this case: +By default, the WASM kernel yields when `kernel_run` returns. In this case: -- The WASM kernel execution is put on hold while the inputs of the next inbox are loaded. +- The WASM kernel execution is put on hold while the inputs of the next inbox are loaded. - The inputs that were not consumed by `kernel_run` are dropped - `kernel_run` can prevent the WASM kernel from yielding by writing arbitrary data under the path `/kernel/env/reboot` in its durable storage. -- In such a case (known as `reboot`), `kernel_run` is called again, without dropping unread inputs. +- In such a case (known as `reboot`), `kernel_run` is called again, without dropping unread inputs. - The value at `/kernel/env/reboot` is removed between each call of `kernel_run`, and the `kernel_run` function can maximally postpone yielding 1,000 reboots for each Tezos level. A call to `kernel_run` cannot take an arbitrary amount of time to @@ -807,7 +769,7 @@ optimistic rollup infrastructure of Tezos. To dodge the halting problem, the ref The current bound is set to 11,000,000,000 ticks. `octez-smart-rollup-wasm-debugger` is the best tool available -to verify the `kernel_run` function does not go over this tick limit. +to verify the `kernel_run` function does not go over this tick limit. The direct consequence of this setup is that it might be necessary for a WASM kernel to span a long computation across several calls to `kernel_run`, requiring serialization of any data it needs in the @@ -842,11 +804,11 @@ it to interact with the components of persistent state: - `store_read` - loads at most 2048 bytes from a file in the durable storage to a buffer in the memory of the WASM kernel. -- `store_write` - writes at most 2048 bytes from a buffer in the memory of the WASM kernel to a file of the durable storage, increasing its size if necessary. Note that files in the durable storage cannot exceed {% math inline=true %} 2^{31} - 1 {% /math %} bytes, (i.e. 2GB - 1). +- `store_write` - writes at most 2048 bytes from a buffer in the memory of the WASM kernel to a file of the durable storage, increasing its size if necessary. Note that files in the durable storage cannot exceed $$2^{31} - 1$$ bytes, (i.e. 2GB - 1). - `store_value_size` - returns the size (in bytes) of a file under a given key in the durable storage. -- `store_list_size` - returns the number of child objects (either directories or files) under a given key. +- `store_list_size` - returns the number of child objects (either directories or files) under a given key. `reveal_preimage` - loads in memory the preimage of a hash. The size of the hash in bytes must be specified as an input to the function. @@ -856,51 +818,28 @@ These host functions use a "C-like" API. In particular, most of them return a signed 32bit integer, where negative values are reserved for conveying errors, as shown in the next table. -{% table %} -* Code -* Description ---- -* ` > -1` -* Input is too large to be a valid key of the durable storage ---- -* ` > -2` -* Input cannot be parsed as a valid key of the durable storage ---- -* ` > -3` -* There is no file under the requested key ---- -* ` > -4` -* The host functions tried to read or write an invalid section (determined by an offset and a length) of the value stored under a given key ---- -* ` > -5` -* Cannot write a value beyond the 2GB size limit ---- -* ` > -6` -* Invalid memory access (segmentation fault) ---- -* ` > -7` -* Tried to read from the inbox or write to the outbox more than 4,096 bytes ---- -* ` > -8` -* Unknown error due to an invalid access ---- -* ` > -9` -* Attempt to modify a readonly value ---- -* ` > -10` -* Key has no tree in the storage ---- -* ` > -11` -* Outbox is full, no new message can be appended ---- -{% /table %} + +Code | Description +--- | --- +` > -1` | Input is too large to be a valid key of the durable storage +` > -2` | Input cannot be parsed as a valid key of the durable storage +` > -3` | There is no file under the requested key +` > -4` | The host functions tried to read or write an invalid section (determined by an offset and a length) of the value stored under a given key +` > -5` | Cannot write a value beyond the 2GB size limit +` > -6` | Invalid memory access (segmentation fault) +` > -7` | Tried to read from the inbox or write to the outbox more than 4,096 bytes +` > -8` | Unknown error due to an invalid access +` > -9` | Attempt to modify a readonly value +` > -10` | Key has no tree in the storage +` > -11` | Outbox is full, no new message can be appended + ## Implementing a WASM Kernel in Rust -{% callout type="note" title="Rust Familiarity" %} +:::note Rust Familiarity This document is not a tutorial about Rust. Familiarity with the language and its ecosystem (in particular, how Rust crates are structured) is assumed. -{% /callout %} +::: Though WASM is a good fit for efficiently executing computation-intensive, arbitrary programs, it is a low-level, stack-based, memory unsafe language. Fortunately, it was designed to be @@ -917,7 +856,7 @@ vulnerabilities that arbitrary WASM programs may suffer from. `rustup` is installed, enabling WASM as a compilation target is as simple as running the following command. -``` sh +```sh rustup target add wasm32-unknown-unknown ``` @@ -926,7 +865,7 @@ provides a 32bit address space. The simplest kernel one can implement in Rust (the one that returns directly after being called, without specification) is the following Rust file (by convention named `lib.rs` in Rust). -``` rust +```rust #[no_mangle] pub extern "C" fn kernel_run() { } @@ -935,7 +874,7 @@ pub extern "C" fn kernel_run() { This code can be easily computed with `cargo` with the following `Cargo.toml`. -``` toml +```toml [package] name = 'noop' version = '0.1.0' @@ -947,21 +886,21 @@ crate-type = ["cdylib"] The key line to spot is the `crate-type` definition to `cdylib`. When writing a library that will eventually be consumed by a Kernel WASM crate, this line must be modified to: -``` toml +```toml crate-type = ["cdylib", "rlib"] ``` Compiling our "noop" kernel is done by calling `cargo` with the correct argument: -``` sh +```sh cargo build --target wasm32-unknown-unknown ``` It is also possible to use the `--release` CLI flag to tell `cargo` to optimize the kernel. To make the use of the `target` optional, it is possible to create a `.cargo/config.toml` file, containing the following line. -``` toml +```toml [build] target = "wasm32-unknown-unknown" @@ -971,7 +910,7 @@ lld = true% The resulting project looks as follows. -``` sh +```sh . ├── .cargo │   └── config.toml @@ -993,7 +932,7 @@ The host functions exported by the WASM runtime to Rust programs are exposed by the API below. The `link` pragma is used to specify the module that exports them (in our case, `smart_rollup_core`). -``` rust +```rust #[repr(C)] pub struct ReadInputMessageInfo { pub level: i32, @@ -1087,7 +1026,7 @@ provide a safe API on top of them. For instance, the `read_input` host function can be used to declare a safe function which allocates a fresh Rust Vector to receive the input. -``` rust +```rust // Assuming the host functions are defined in a module `host`. pub const MAX_MESSAGE_SIZE: u32 = 4096u32; @@ -1130,15 +1069,15 @@ is a good approach to avoid initializing the 4,096 bytes of memory every time yo ### Testing your Kernel -{% callout type="note" title="Smart Rollup WASM Debugger" %} +:::note Smart Rollup WASM Debugger `octez-smart-rollup-wasm-debugger` is available in the Octez distribution starting with `/releases/version-16`. -{% /callout %} +::: Testing a kernel without having to start a rollup node on a test network is very convenient. We provide a debugger as a means to evaluate the WASM PVM without relying on any node and network: -``` sh +```sh octez-smart-rollup-wasm-debugger "${WASM_FILE}" --inputs "${JSON_INPUTS}" --rollup "${SOR_ADDR}" ``` @@ -1148,7 +1087,7 @@ Beside the kernel file, the debugger can optionally take an input file containing inboxes and a rollup address. The expected contents of the inboxes is a JSON value, with the following schema: -``` json +```json [ [ { "payload" : , "sender" : , @@ -1164,11 +1103,11 @@ inboxes is a JSON value, with the following schema: The contents of the input file is a JSON array of arrays of inputs, which encodes a sequence of inboxes, where an inbox is a set of -messages. These inboxes are read in the same order as they appear in the JSON file. +messages. These inboxes are read in the same order as they appear in the JSON file. For example, here is a valid input file that defines two inboxes: the first array encodes an inbox containing only an external message, while the second array encodes an inbox containing two messages: -``` json +```json [ [ { @@ -1191,8 +1130,8 @@ For example, here is a valid input file that defines two inboxes: the first arra Note that the `sender`, `source` and `destination` fields are optional and will be given default values by the debugger, respectively: -- `KT18amZmM5W7qDWVt2pH6uj7sCEd3kbzLrHT` -- `tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU` +- `KT18amZmM5W7qDWVt2pH6uj7sCEd3kbzLrHT` +- `tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU` - `sr163Lv22CdE8QagCwf48PWDTquk6isQwv57` If no input file is given, the inbox will be assumed empty. If the option `--rollup` is given, it replaces the default value for the rollup address. @@ -1202,7 +1141,7 @@ user inputs to continue its execution. Its initial state is exactly the same as right after its origination. Its current state can be inspected with the command `show status`: -``` sh +```sh > show status Status: Waiting for inputs Internal state: Collect @@ -1213,7 +1152,7 @@ that it is not executing any WASM code, and is waiting for inputs in order to proceed. The command `load inputs` will load the first inbox from the file given with the option `--inputs`, putting `Start_of_level` and `Info_per_level` before these inputs and `End_of_level` after the inputs. -``` sh +```sh > load inputs Loaded 3 inputs at level 0 @@ -1224,7 +1163,7 @@ Internal state: Snapshot The internal input buffer can be inspected with `show inbox`: -``` sh +```sh > show inbox Inbox has 3 messages: { raw_level: 0; @@ -1242,7 +1181,7 @@ The first input of an inbox at the beginning of a level is `Start_of_level`, and is represented by the message `\000\001` on the kernel side. We can now start a `kernel_run` evaluation: -``` sh +```sh > step kernel_run Evaluation took 11000000000 ticks so far Status: Waiting for inputs @@ -1254,7 +1193,7 @@ The memory of the interpreter is flushed between two `kernel_run` calls storage can be used as a persistent memory. Let's assume this kernel wrote data at key `/store/key`: -``` sh +```sh > show key /store/key `` ``` @@ -1264,7 +1203,7 @@ debugger can only return its raw value. Please note that the command `show keys ` will return the keys for the given path. This can help you navigate in the durable storage. -``` sh +```sh > show keys /store /key /another_key @@ -1273,7 +1212,7 @@ help you navigate in the durable storage. It is also possible to inspect the memory by stopping the PVM before its snapshot internal state, with `step result`, and inspect the memory at pointer `n` and length `l`, and finally evaluate until the next `kernel_run`: -``` sh +```sh > step result Evaluation took 2500 ticks so far Status: Evaluating @@ -1295,7 +1234,7 @@ It will take care of the possible reboots asked by the kernel (through the usage of the `/kernel/env/reboot_flag` flag) and stop at the next collection phase: -``` sh +```sh > step inbox Evaluation took 44000000000 ticks Status: Waiting for inputs @@ -1304,7 +1243,7 @@ Internal state: Collect It is also possible to show the outbox for any given level: -``` sh +```sh > show outbox at level 0 Outbox has N messages: { unparsed_parameters: ..; @@ -1314,11 +1253,11 @@ Outbox has N messages: ``` The reveal channel described previously is available in the debugger, -either automatically or through specific commands. The debugger can automatically fill preimages from files in a specific directory on the disk, by default in the `preimage` subdirectory of the working directory. It can be configured with the option `--preimage-dir `. +either automatically or through specific commands. The debugger can automatically fill preimages from files in a specific directory on the disk, by default in the `preimage` subdirectory of the working directory. It can be configured with the option `--preimage-dir `. In case there is no corresponding file found for the requested preimage, the debugger will ask for the hexadecimal value of the preimage: -``` sh +```sh > step inbox Preimage for hash 0000[..] not found. > 48656c6c6f207468657265210a diff --git a/docs/dApps.md b/docs/dApps.md new file mode 100644 index 000000000..3e4f61ad1 --- /dev/null +++ b/docs/dApps.md @@ -0,0 +1,12 @@ +# Decentralized applications (dApps) + +One of the main features of blockchains is the _decentralization_: each transaction sent is verified by multiple nodes and its validation process does not rely on a single trusted third party. +Decentralized applications (dApps or Dapps) take advantage of these features to create applications that are independent, transparent, and trustless. + +In general, dApps have two parts: + +- An on-chain component that consists of one or more smart contracts +- An off-chain component that can act as a user interface to simplify interaction with the on-chain component, run off-chain processing, and get information from the outside world + +The off-chain component can be nearly any kind of program, including a web application, mobile or desktop app, or command-line interface. +It relies on wallets to interact with the smart contract on behalf of a user's Tezos account. diff --git a/src/pages/app-development/framework-best-practices/index.md b/docs/dApps/best-practices.md similarity index 98% rename from src/pages/app-development/framework-best-practices/index.md rename to docs/dApps/best-practices.md index 4f3f96eb2..409de3dfd 100644 --- a/src/pages/app-development/framework-best-practices/index.md +++ b/docs/dApps/best-practices.md @@ -1,6 +1,5 @@ --- -id: framework-best-practices -title: Framework Best Practices +title: Best practices and avoiding flaws authors: Claude Barde lastUpdated: 10th July 2023 --- diff --git a/docs/dApps/quickstart.md b/docs/dApps/quickstart.md new file mode 100644 index 000000000..42fbdadff --- /dev/null +++ b/docs/dApps/quickstart.md @@ -0,0 +1,5 @@ +# dApp quickstart + +Here we insert the tutorial that shows how to build a react dapp on top of the contract we built in the "first smart contract" guide + +Mention Beacon, diagram about key custody, dapp is never concerned about keys \ No newline at end of file diff --git a/docs/dApps/samples.md b/docs/dApps/samples.md new file mode 100644 index 000000000..dbd747c50 --- /dev/null +++ b/docs/dApps/samples.md @@ -0,0 +1,11 @@ +--- +title: Sample dApps +author: "Tim McMackin" +lastUpdated: 19 October 2023 +--- + +Here are some sample web applications that access Tezos: + +- Completed applications from the tutorials are in the repository https://github.com/trilitech/tutorial-applications +- For a collection of example applications that use Taquito, see https://tezostaquito.io/docs/contracts_collection/ +- For a sample application that uses Taqueria, see https://taqueria.io/docs/scaffolds/taco-shop/ diff --git a/src/pages/app-development/taquito/index.md b/docs/dApps/taquito.md similarity index 98% rename from src/pages/app-development/taquito/index.md rename to docs/dApps/taquito.md index 7c4e57845..5281da496 100644 --- a/src/pages/app-development/taquito/index.md +++ b/docs/dApps/taquito.md @@ -1,6 +1,5 @@ --- -id: taquito -title: Taquito +title: Taquito dApp SDK for TypeScript authors: Claude Barde lastUpdated: 10th July 2023 --- @@ -66,7 +65,7 @@ First, download the `@taquito/beacon-wallet` package from NPM: npm install @taquito/beacon-wallet ``` -Next, import the `BeaconWallet` class and create a new instance by passing an object with the different options required by the Beacon SDK. +Next, import the `BeaconWallet` class and create a new instance by passing an object with the different options required by the Beacon SDK. After creating the instance of the wallet, you can request permission from the user to connect their wallet before passing the wallet instance to the wallet provider in the TezosToolkit provided by Taquito: ```typescript @@ -137,7 +136,7 @@ const storage = await contract.storage() ### Getting token metadata -Taquito also provides a library to get token metadata, which can be very useful when you build a dapp that handles NFTs. +Taquito also provides a library to get token metadata, which can be very useful when you build a dapp that handles NFTs. Without Taquito, you would have to fetch the location of the metadata from the contract, understand where the metadata is stored, fetch it and parse it. Taquito does all of that for you: ```typescript @@ -239,23 +238,22 @@ try { ### One single TezosToolkit instance -You should make sure that you only have one instance of the `TezosToolkit` at all times in your app to avoid using the wrong one, which can have negative financial consequences for your users. +You should make sure that you only have one instance of the `TezosToolkit` at all times in your app to avoid using the wrong one, which can have negative financial consequences for your users. Even if your app requires a change in the network or Tezos node, it is better to create a new instance of the `TezosToolkit` and stop using the previous one to prevent unexpected behaviours. ### Contract API vs Wallet API -The Contract API is better suited for backend applications that don't require the manual signing of transactions, while the Wallet API is better suited for frontend applications that will interact with the users' wallets. +The Contract API is better suited for backend applications that don't require the manual signing of transactions, while the Wallet API is better suited for frontend applications that will interact with the users' wallets. The use of one or the other should be consistent within the same app to prevent unexpected behaviours. ### `methods` vs `methodsObject` -The `methodsObject` property is better used in cases when the parameter for a contract call is a complex pair. +The `methodsObject` property is better used in cases when the parameter for a contract call is a complex pair. You can use `methods` to pass single parameters or simple pairs. ### Catching transaction errors It is important to wrap contract calls and other transactions sent from the app inside a `try... catch` in order to handle transaction failures. Transactions fail more often than you think and you must handle it to provide visual feedback to your users and prevent unwanted behaviours like users clicking a button again even if the transaction already failed before. -{% callout title="More information" %} +:::note More information You can find more information about Taquito on the official website: [Taquito](https://tezostaquito.io/docs/quick_start) -{% /callout%} diff --git a/src/pages/gaming/tezos-sdk-for-unity/index.md b/docs/dApps/unity.md similarity index 90% rename from src/pages/gaming/tezos-sdk-for-unity/index.md rename to docs/dApps/unity.md index 9579cd8c3..92e7e28d2 100644 --- a/src/pages/gaming/tezos-sdk-for-unity/index.md +++ b/docs/dApps/unity.md @@ -1,5 +1,4 @@ --- -id: tezos-sdk-for-unity title: Tezos SDK for Unity authors: John Joubert lastUpdated: 5th June 2023 @@ -20,32 +19,32 @@ This Getting Started guide covers the following five steps essential for using t 1. Installation of the Unity Editor (if not already installed) 2. Installation of the Tezos Integration SDK in the Unity Editor within a new project -3. Obtaining a Tezos-compatible wallet as an app or browser plugin (we'll use the **Temple** wallet for our [Inventory Sample Game](/gaming/unity-sdk/inventory-sample-game)) +3. Obtaining a Tezos-compatible wallet as an app or browser plugin (we'll use the **Temple** wallet for our [Inventory Sample Game](https://opentezos.com/gaming/unity-sdk/inventory-sample-game)) 4. Creating a wallet account for a test network (`ghostnet`) and acquiring test currency from an appropriate faucet 5. Linking this wallet account with the new Unity project -By following these steps, your Unity app will be connected to the Tezos GhostNet test network via your specific wallet address. This allows you to invoke specific functionality on smart contracts you've created and deployed to GhostNet, as demonstrated in our [Inventory Sample Game](/gaming/unity-sdk/inventory-sample-game). +By following these steps, your Unity app will be connected to the Tezos GhostNet test network via your specific wallet address. This allows you to invoke specific functionality on smart contracts you've created and deployed to GhostNet, as demonstrated in our [Inventory Sample Game](https://opentezos.com/gaming/unity-sdk/inventory-sample-game). -Explore the [Inventory Sample Game](/gaming/unity-sdk/inventory-sample-game) project and consult our [API Documentation](https://opentezos.com/gaming/unity-sdk/api-documentation/) to learn more about the exposed methods of our SDK, both for establishing wallet connections and for calling specific smart-contract entrypoints and Tezos data-view functions. +Explore the [Inventory Sample Game](https://opentezos.com/gaming/unity-sdk/inventory-sample-game) project and consult our [API Documentation](https://opentezos.com/gaming/unity-sdk/api-documentation/) to learn more about the exposed methods of our SDK, both for establishing wallet connections and for calling specific smart-contract entrypoints and Tezos data-view functions. -This SDK documentation is designed for users with some familiarity with Unity game development but may have little to no experience with Web3 or Tezos blockchain. If you're well-versed in both domains, you might want to skip "Getting Started" and proceed directly to the [API documentation](https://opentezos.com/gaming/unity-sdk/api-documentation/). Nonetheless, the [Inventory Sample Game](/gaming/unity-sdk/inventory-sample-game) can still be valuable for visualizing potential SDK applications in your own game development. +This SDK documentation is designed for users with some familiarity with Unity game development but may have little to no experience with Web3 or Tezos blockchain. If you're well-versed in both domains, you might want to skip "Getting Started" and proceed directly to the [API documentation](https://opentezos.com/gaming/unity-sdk/api-documentation/). Nonetheless, the [Inventory Sample Game](https://opentezos.com/gaming/unity-sdk/inventory-sample-game) can still be valuable for visualizing potential SDK applications in your own game development. ## Installing the Unity Editor -{% callout title="Note" %} +:::note - Install Unity Editor version 2021.3.13 or above - Enable iOS Build Support, even if you don't plan to build for iOS -{% /callout %} +::: -The Tezos SDK has been developed and tested primarily in Unity 2021.3.13. If you're using an earlier version, you must install version 2021.3.13 or above. +The Tezos SDK has been developed and tested primarily in Unity 2021.3.13. If you're using an earlier version, you must install version 2021.3.13 or above. Newer Unity versions can coexist with older ones, allowing you to maintain older games built in previous editor versions. Manage different Unity installations through the **Installs** tab of your **Unity Hub**. This tool helps you track installations, projects, and required **modules** for publishing games or dApps to platforms like Windows, iOS, Android, WebGL, and others. If you're new to Unity, download the [Unity editor for free.](https://unity.com/download) The free "personal" Unity editor offers a comprehensive core feature set for creating 2D and 3D games, apps, and environments, including AR, VR, and Web3 development. -{% callout type="warning" title="Warning" %} +:::warning The current SDK version requires iOS Build Support, even if you don't plan to build for iOS. This will be fixed in a future update. In the meantime, enable iOS Build Support in the "Installs" tab of your Unity Hub. -{% /callout %} +::: ## Installing the Tezos SDK for Unity (Latest) @@ -130,6 +129,6 @@ The Tezos SDK utilizes modified versions of the following libraries for communic The SDK supports Windows, Linux, MacOS, iOS, Android, and WebGL platforms. -{% callout title="More information"%} +:::note More information For more information you can read detailed [documentation](https://opentezos.com/gaming/unity-sdk/api-documentation/) on OpenTezos. -{% /callout %} +::: diff --git a/src/pages/app-development/wallets-and-beacon-sdk/index.md b/docs/dApps/wallets.md similarity index 98% rename from src/pages/app-development/wallets-and-beacon-sdk/index.md rename to docs/dApps/wallets.md index 79b6283c1..845b2413c 100644 --- a/src/pages/app-development/wallets-and-beacon-sdk/index.md +++ b/docs/dApps/wallets.md @@ -1,6 +1,5 @@ --- -id: wallets-and-beacon-sdk -title: Wallets and Beacon SDK +title: Connecting to wallets authors: Claude Barde lastUpdated: 10th July 2023 --- @@ -155,6 +154,6 @@ In case your dapp is focussed around a specific time (eg. NFT drop or a countdow --- -{% callout title="More information"%} +:::note You can find more details about Beacon by visiting [https://docs.walletbeacon.io/](https://docs.walletbeacon.io/) -{% /callout%} +::: diff --git a/docs/developing.md b/docs/developing.md new file mode 100644 index 000000000..7b5ea3aad --- /dev/null +++ b/docs/developing.md @@ -0,0 +1,4 @@ +# Developing on Tezos + +- What the development, testing, and deploying process is like +- Do I need a contract, a dApp, or both? diff --git a/docs/developing/dev-environments.md b/docs/developing/dev-environments.md new file mode 100644 index 000000000..ba0409bc0 --- /dev/null +++ b/docs/developing/dev-environments.md @@ -0,0 +1,50 @@ +--- +title: Setting up developer environments +authors: "Tim McMackin" +lastUpdated: 24 October 2023 +--- + +Working with Tezos usually includes setting up an IDE to write code in and connecting to a test network or sandbox to test applications on. + + + +## IDEs and extensions + +You can work with Tezos from any IDE, but these IDEs have special features for working with Tezos: + +### VSCode + +VSCode provides extensions for working with Tezos including these: + +- [Taqueria](https://marketplace.visualstudio.com/items?itemName=PinnacleLabs.taqueria) +- [Archetype language](https://marketplace.visualstudio.com/items?itemName=edukera.archetype) +- [Michelson Syntax](https://marketplace.visualstudio.com/items?itemName=baking-bad.michelson) +- [Michelson debugger](https://marketplace.visualstudio.com/items?itemName=serokell-io.michelson-debugger) + +VSCode also has extensions for the LIGO language, primarily these extensions offered by ligolang.org: + +- [ligo-vscode](https://marketplace.visualstudio.com/items?itemName=ligolang-publish.ligo-vscode) +- [LIGO debugger](https://marketplace.visualstudio.com/items?itemName=ligolang-publish.ligo-debugger-vscode) + +### Online IDEs + +These online IDEs let you write, test, and deploy smart contracts from your web browser: + +- LIGO: https://ide.ligolang.org +- SmartPy: https://smartpy.io/ide + +## Development platforms + +Taqueria is a development platform for Tezos that helps you work on smart contracts and dApps at the same time and keep them in sync as you work through your development cycle. +See https://taqueria.io/. + +## Test environments + +To test smart contracts and dApps, you can use these test environments: + +- Test networks behave like Tezos mainnet but have differences that make it easier to test on them, such as faucets that provide free tokens and reduced block times for faster testing. +- Sandbox environments like [Flextesa](https://tezos.gitlab.io/flextesa/) run Tezos nodes locally on your computer in a sandbox mode. + +For more information about test environments, see [Using sandboxes and testnets](./testnets). diff --git a/src/pages/tezos-basics/block-explorers/index.md b/docs/developing/information/block-explorers.md similarity index 98% rename from src/pages/tezos-basics/block-explorers/index.md rename to docs/developing/information/block-explorers.md index 2acc6a41b..202b9631d 100644 --- a/src/pages/tezos-basics/block-explorers/index.md +++ b/docs/developing/information/block-explorers.md @@ -3,13 +3,11 @@ title: Block Explorers lastUpdated: 10th July 2023 --- -## Block Explorers - **What is a blockchain explorer?** A _blockchain explorer_, also known as a _block explorer_, is an app that tracks activity on a blockchain. All transactions ever performed on a network can be viewed using such a tool. -**Blockchain explorers are like search engines for blockchains.** +**Blockchain explorers are like search engines for blockchains.** You can think of it as a window into the blockchain world, allowing you to observe what's happening in it. diff --git a/src/pages/tezos-basics/block-explorers/tzstats-smart-contract/index.md b/docs/developing/information/block-explorers/inspect-contract-tzstats.md similarity index 93% rename from src/pages/tezos-basics/block-explorers/tzstats-smart-contract/index.md rename to docs/developing/information/block-explorers/inspect-contract-tzstats.md index 6e3727192..26c54622e 100644 --- a/src/pages/tezos-basics/block-explorers/tzstats-smart-contract/index.md +++ b/docs/developing/information/block-explorers/inspect-contract-tzstats.md @@ -1,6 +1,5 @@ --- -id: tzstats-smart-contract -title: Checkout your smart contract on TzStats +title: Inspecting deployed contracts authors: Benjamin Pila lastUpdated: 28th June 2023 --- @@ -17,11 +16,11 @@ Remember, the following TzStats website links are the following: Copy/paste your address in the search bar: -![](/images/tzstats-smart-contract/tzStats_search_bar.png) +![](/img/developing/tzStats_search_bar.png) TzStats then shows a page with information related to your smart contract, e.g. the balance of the contract, the amounts sent and received, the originator's address, etc. -![](/images/tzstats-smart-contract/tzStats_smart_contract_general_information.png) +![](/img/developing/tzStats_smart_contract_general_information.png) Below the general information, you have a list of tabs allowing you to see: @@ -48,31 +47,31 @@ You can see: - the calls made to the entrypoints with the name of the entrypoint in question - on the right the status of the block with the number of confirmations received -![](tzStats_smart_contract_calls.png) +![](/img/developing/tzStats_smart_contract_calls.png) ### Entrypoints Here you have a list of all your entrypoints and their parameters. Furthermore, you can see how many calls each entrypoint has received. -![](/images/tzstats-smart-contract/tzStats_smart_contract_entrypoints.png) +![](/img/developing/tzStats_smart_contract_entrypoints.png) ### Contract Code Here you have the Michelson code of your smart contract. -![](/images/tzstats-smart-contract/tzStats_smart_contract_code.png) +![](/img/developing/tzStats_smart_contract_code.png) ### Storage Here you have access to the content of your storage with the type of each variable and its current value. Notice that the content excludes big_maps as they are specific tabs for them. -![](/images/tzstats-smart-contract/tzStats_smart_contract_storage.png) +![](/img/developing/tzStats_smart_contract_storage.png) ### Big_map Here you have the content of your big_map. -![](/images/tzstats-smart-contract/tzStats_smart_contract_bigmap.png) +![](/img/developing/tzStats_smart_contract_bigmap.png) ## API Calls @@ -92,7 +91,7 @@ In this example, one of the contracts has been deployed on the Mainnet to `KT1Hb Let's retrieve the contract details: ```shell -$ curl https://api.tzstats.com/explorer/contract/KT1HbQepzV1nVGg8QVznG7z4RcHseD5kwqBn +$ curl https://api.tzstats.com/explorer/contract/KT1HbQepzV1nVGg8QVznG7z4RcHseD5kwqBn { account_id: 1571823, address: "KT1HbQepzV1nVGg8QVznG7z4RcHseD5kwqBn", @@ -197,7 +196,7 @@ $ curl https://api.tzstats.com/explorer/contract/KT1HbQepzV1nVGg8QVznG7z4RcHseD5 ``` The storage returned by the API does match the one displayed in the web interface. -The `swaps` big_map holds a big_map id, instead of the values. +The `swaps` big_map holds a big_map id, instead of the values. Indeed, a big_map is meant to hold unbounded data size. Thus, fetching the storage could quickly become expensive, if the big_map holds a lot of values. The values of a big_map have to be retrieved from a separate endpoint, thanks to its id (`6072` in this case): diff --git a/src/pages/tezos-basics/block-explorers/tzstats-main-features/index.md b/docs/developing/information/block-explorers/tzstats.mdx similarity index 59% rename from src/pages/tezos-basics/block-explorers/tzstats-main-features/index.md rename to docs/developing/information/block-explorers/tzstats.mdx index 271e4f973..c0e47313b 100644 --- a/src/pages/tezos-basics/block-explorers/tzstats-main-features/index.md +++ b/docs/developing/information/block-explorers/tzstats.mdx @@ -1,11 +1,12 @@ --- -id: tzstats-main-features -title: How to use the tzStats blockchain explorer? +title: The tzStats blockchain explorer authors: Maxime Sallerin lastUpdated: 28th June 2023 --- -In this chapter, we will use the [TzStats](https://tzstats.com/) explorer to illustrate the different features of an explorer, but similar features are usually available on others. Concerning the observation of smart contracts, the different aspects are discussed in the [following chapter](/explorer/tzstats-smart-contract). +import Figure from '@site/src/components/Figure'; + +In this chapter, we will use the [TzStats](https://tzstats.com/) explorer to illustrate the different features of an explorer, but similar features are usually available on others. Concerning the observation of smart contracts, the different aspects are discussed in the [following chapter](./inspect-contract-tzstats). [TzStats](https://tzstats.com/) is developed by _Blockwatch Data Inc._ It is a block explorer for public and private Tezos networks and it is based on the [TzIndex indexer](https://github.com/blockwatch-cc/tzindex). @@ -19,60 +20,44 @@ Each Tezos network has its own _TzStats_ version: TzStats has a complete guide available [here](https://tzstats.com/docs/guide). - [Main Dashboard](https://tzstats.com/): This page provides a quick view of all the main activity on the Tezos network, e.g. staking activity, gas price, tez supply, transaction volume, etc. -{% figure - src="/images/tzstats-main-features/tzStats_first_page.png" - alt="tzstats-main-dashboard" - caption="TzStats Main Dashboard" %} -{% /figure %} +
- [Cycle](https://tzstats.com/cycle/head): This page provides general information about a specific cycle number. A cycle is a way of measuring time. Every cycle is equal to 4096 blocks. -{% figure - src="/images/tzstats-main-features/tzStats_cycle.png" - alt="tzstats-cycle-page" - caption="TzStats Cycle Page" %} -{% /figure %} - +
+ - [Block](https://tzstats.com/1496426): This page provides general information about a specific block number along with its technical details such as gas used, block health (Endorsed Slots, Missed Priorities and Missed Endorsements), etc. -{% figure - src="/images/tzstats-main-features/tzStats_block.png" - alt="tzstats-block-page" - caption="TzStats Block Page" %} -{% /figure %} +
- [Network Activity](https://tzstats.com/activity): This page provides a world map with the location of where new blocks are being baked. There is also the list of _whale operations_ (i.e. a list of high-value transfers >= $100,000). -{% figure - src="/images/tzstats-main-features/tzStats_activity.png" - alt="tzstats-activity-page" - caption="TzStats Activity Page" %} -{% /figure %} +
- [Bakers](https://tzstats.com/bakers): This page provides the total number of Tezos bakers. Several lists are also available to gain an overview of the Tezos baker landscape. You can choose between several tabs, namely, Public, Private, Closing, and Leaderboard. -{% figure - src="/images/tzstats-main-features/tzStats_bakers.png" - alt="tzstats-bakers-page" - caption="TzStats Bakers Page" %} -{% /figure %} - -- [Protocols](https://tzstats.com/protocols): This page shows the past and current protocol used by Tezos and the overall age of the Tezos blockchain. Refer to the chapter on the [history of amendments](/tezos-basics/history-of-amendments) to understand each protocol. -{% figure - src="/images/tzstats-main-features/tzStats_protocols.png" - alt="tzstats-protocols-page" - caption="TzStats Protocols Page" %} -{% /figure %} - -- [Voting](https://tzstats.com/election/head): This page shows the past and current elections and indicates when it ends. Refer to chapter on the [governance on chain](/tezos-basics/governance-on-chain) to understand the voting process. -{% figure - src="/images/tzstats-main-features/tzStats_voting.png" - alt="tzstats-voting-page" - caption="TzStats Voting Page" %} -{% /figure %} +
+ +- [Protocols](https://tzstats.com/protocols): This page shows the past and current protocol used by Tezos and the overall age of the Tezos blockchain. See [History of amendments](../../../architecture/governance/amendment-history) to understand each protocol. +
+ +- [Voting](https://tzstats.com/election/head): This page shows the past and current elections and indicates when it ends. See [Governance](../../../architecture/governance) to understand the voting process. +
- [Markets](https://tzstats.com/markets): This page provides an overview of the current market activity, e.g. list of exchanges, 1 day's volume, overall market capitalization, etc. -{% figure - src="/images/tzstats-main-features/tzStats_markets.png" - alt="tzstats-markets-page" - caption="TzStats Markets Page" %} -{% /figure %} +
Here the main features have been presented and, in the next chapter, we will see how to check out your smart contract. diff --git a/src/pages/app-development/dipdup/index.md b/docs/developing/information/custom-indexers.md similarity index 80% rename from src/pages/app-development/dipdup/index.md rename to docs/developing/information/custom-indexers.md index af3668644..610a67578 100644 --- a/src/pages/app-development/dipdup/index.md +++ b/docs/developing/information/custom-indexers.md @@ -1,6 +1,5 @@ --- -id: dipdup -title: How to Use DipDup and Dappetizer +title: Custom indexers authors: Tezos Ukraine lastUpdated: 10th July 2023 --- @@ -25,13 +24,13 @@ DipDup only works on Unix systems: macOS and Linux distributions. If you have Wi First, you need to install [the Python environment](https://www.python.org/downloads/) in any convenient way. Then open a terminal and install DipDup using the command: -``` +```bash python -c "$(curl -sSL https://dipdup.io/install.py)" ``` If you have macOS 12 or higher, replace `python` with `python3`. -[![1](/images/indexers/dipdup1.png)](https://indexers.tezos.org.ua/static/733a2c452ea5390046a06f83f0dcc6f0/5ca22/1.png) +[![1](/img/developing/dipdup1.png)](https://indexers.tezos.org.ua/static/733a2c452ea5390046a06f83f0dcc6f0/5ca22/1.png) ### [](https://indexers.tezos.org.ua/dipdup-dappetizer#creating-a-project-in-dipdup)Creating a project in DipDup @@ -39,11 +38,11 @@ Now let's start configuring DipDup. First, let's create a folder in which we wil For example, let's index the contract of the tzBTC token since it is simple, and the creation of the indexer will not take much time. To do this, when choosing a configuration template, we will take the tzBTC option. -[![2](/images/indexers/dipdup2.png)](https://indexers.tezos.org.ua/static/a4ddf29abc78418f42b0aadbe536d42b/9bae8/2.png) +[![2](/img/developing/dipdup2.png)](https://indexers.tezos.org.ua/static/a4ddf29abc78418f42b0aadbe536d42b/9bae8/2.png) Next, you need to fill in information about the project: name, version, owner, select a database, and all that. In the end, DipDup will independently generate the structure and necessary files for the project. -[![3](/images/indexers/dipdup3.png)](https://indexers.tezos.org.ua/static/ce921a279cebd9fecacd4e86b0391c7f/91425/3.png) +[![3](/img/developing/dipdup3.png)](https://indexers.tezos.org.ua/static/ce921a279cebd9fecacd4e86b0391c7f/91425/3.png) ### [](https://indexers.tezos.org.ua/dipdup-dappetizer#indexer-configuration)Indexer configuration @@ -60,18 +59,19 @@ The most important thing here is templates. In these modules, we specify the ent In this example, we will be checking tzBTC holders' balances. They change when the transfer and mint entry points are called, so we specify two handlers by entry point names — on\_mint and on\_transfer. -[![4](/images/indexers/dipdup4.png)](https://indexers.tezos.org.ua/static/94fa88718212cf7f75282cce5fe2e141/4c530/4.png) +[![4](/img/developing/dipdup4.png)](https://indexers.tezos.org.ua/static/94fa88718212cf7f75282cce5fe2e141/4c530/4.png) Check [DipDup Config Documentation](https://docs.dipdup.io/getting-started/creating-config) to learn more about all available options. ### [](https://indexers.tezos.org.ua/dipdup-dappetizer#models-and-data-handlers)Models and data handlers Next, you need to create indexes, schemas, models, and handlers. To do this, go to the tzbtc folder in the terminal and execute the command: -``` + +```bash dipdup init ``` -[![5](/images/indexers/dipdup5.png)](https://indexers.tezos.org.ua/static/7c0f6b39910885a54a171086ff53ead6/5ca22/5.png) +[![5](/img/developing/dipdup5.png)](https://indexers.tezos.org.ua/static/7c0f6b39910885a54a171086ff53ead6/5ca22/5.png) DipDup will create several files — models and handlers — that describe working with the database and indexing on-chain data, and we need to modify them to set up the indexing process. @@ -82,7 +82,7 @@ The first file is models.py. It stores data models, roughly speaking, descriptio * the number of transactions * last activity time -[![6](/images/indexers/dipdup6.png)](https://indexers.tezos.org.ua/static/96c7b5f909c56975fdb566de6566e5b0/5ca22/6.png) +[![6](/img/developing/dipdup6.png)](https://indexers.tezos.org.ua/static/96c7b5f909c56975fdb566de6566e5b0/5ca22/6.png) The handlers are instructions on how the DipDup will process on-chain data when a tzBTC contract entry point call occurs. The handlers folder stores handlers for storage and calls to the tzBTC contract entry points. @@ -96,34 +96,35 @@ In it, we declared the on\_balance\_update function, to which we will pass three The function will first check if there is such a holder address in the database and then either create a new row and write the new holder or update the old record. -[![7](/images/indexers/dipdup7.png)](https://indexers.tezos.org.ua/static/5940c23853d35d2d52025ba3228538bb/5ca22/7.png) +[![7](/img/developing/dipdup7.png)](https://indexers.tezos.org.ua/static/5940c23853d35d2d52025ba3228538bb/5ca22/7.png) The second handler, on\_mint, will be called when the mint entry point of the tzBTC contract is called. It will read the mint entry point call parameters and then call the on\_balance\_update function to update the records in the database. -[![8](/images/indexers/dipdup8.png)](https://indexers.tezos.org.ua/static/1112282e7bde378195b94423911160ee/cce16/8.png) +[![8](/img/developing/dipdup8.png)](https://indexers.tezos.org.ua/static/1112282e7bde378195b94423911160ee/cce16/8.png) IMPORTANT: in the “amount” variable, we save the "mint.parameter.value" value, which we take from the mint entry point’s call parameters. -[![9](/images/indexers/dipdup9.png)](https://indexers.tezos.org.ua/static/7f6845fabfc7073a10e28eaad8343dfa/8643c/9.png) +[![9](/img/developing/dipdup9.png)](https://indexers.tezos.org.ua/static/7f6845fabfc7073a10e28eaad8343dfa/8643c/9.png) Similarly, we take the address of the recipient of fresh tokens: "address = mint.parameter.to"; The third handler – on\_transfer – deals with transactions, that is, operations with the transfer entry point. It is more complex. First, you need to compare the sender and recipient addresses. If they match, the holders' balances have not changed, and the database should not be updated. Secondly, the transfer of tokens means a change in the balances of the sender and recipient. Therefore, the on\_balance\_update function must be called twice for each address while subtracting the transaction amount from the sender's balance and adding it to the recipient's balance. -[![10](/images/indexers/dipdup10.png)](https://indexers.tezos.org.ua/static/6229151572035395d3becb0cd770c489/5ca22/10.png) +[![10](/img/developing/dipdup10.png)](https://indexers.tezos.org.ua/static/6229151572035395d3becb0cd770c489/5ca22/10.png) As in the on_mint handler, we get on-chain data from the call parameters of the transfer entry point: sender address from_, recipient address to, and transfer amount value. ### [](https://indexers.tezos.org.ua/dipdup-dappetizer#running-the-indexer)Running the indexer In the terminal, run the following command: -``` + +```bash dipdup run ``` DipDup will start downloading the required data from the TzKT public API. Upon completion, it will begin processing new blocks. -[![11](/images/indexers/dipdup11.png)](https://indexers.tezos.org.ua/static/bd30fc184f1b8dc3183fee5f7b52c3b3/5ca22/11.png) +[![11](/img/developing/dipdup11.png)](https://indexers.tezos.org.ua/static/bd30fc184f1b8dc3183fee5f7b52c3b3/5ca22/11.png) ### [](https://indexers.tezos.org.ua/dipdup-dappetizer#connecting-a-database-to-a-project)Connecting a database to a project @@ -133,29 +134,29 @@ Let's create a tzbtc\_dipdup.php file in the tzbtc\_dipdup folder and then conne In the $db\_dir variable, we specify the path to the database on the hard disk, and in $db\_handle - the new PDO($db\_dir) database connection method. -[![12](/images/indexers/dipdup12.png)](https://indexers.tezos.org.ua/static/2a16c6dd88a5963c6d228c28915506bc/a7a60/12.png) +[![12](/img/developing/dipdup12.png)](https://indexers.tezos.org.ua/static/2a16c6dd88a5963c6d228c28915506bc/a7a60/12.png) Then we will write a SQL query in which we select all addresses and balances of tzBTC holders with a non-zero balance and sorting in ascending order. To know exactly what tables you have in the database and how to reach them in SQL query, you can install [SQLite Browser](https://sqlitebrowser.org/) with GUI and check what's inside. -[![13](/images/indexers/dipdup13.png)](https://indexers.tezos.org.ua/static/8128e903d77665f4df43171d078c3953/5ca22/13.png) +[![13](/img/developing/dipdup13.png)](https://indexers.tezos.org.ua/static/8128e903d77665f4df43171d078c3953/5ca22/13.png) We use the iteration function forEach to sequentially get user addresses and balances from $row and then show them on the page. -[![14](/images/indexers/dipdup14.png)](https://indexers.tezos.org.ua/static/5a2d6682a268ce9bb9c9172a0a7c6725/d4913/14.png) +[![14](/img/developing/dipdup14.png)](https://indexers.tezos.org.ua/static/5a2d6682a268ce9bb9c9172a0a7c6725/d4913/14.png) Then we close the connection to the database with the $db\_handle = null command. In the terminal, go to the folder with tzbtc\_dipdup.php and start the PHP server with the command: -``` +```bash php -S localhost:8000 ``` -[![15](/images/indexers/dipdup15.png)](https://indexers.tezos.org.ua/static/b6a8333f49c6dc19a1bd91e22bb1457f/abe8a/15.png) +[![15](/img/developing/dipdup15.png)](https://indexers.tezos.org.ua/static/b6a8333f49c6dc19a1bd91e22bb1457f/abe8a/15.png) In the browser, open the page at [http://localhost:8000/tzbtc\_dipdup.php](http://localhost:8000/tzbtc_dipdup.php) -[![16](/images/indexers/dipdup16.png)](https://indexers.tezos.org.ua/static/4f88b13e8135e3a6897fd3c5bcdd4104/3f970/16.png) +[![16](/img/developing/dipdup16.png)](https://indexers.tezos.org.ua/static/4f88b13e8135e3a6897fd3c5bcdd4104/3f970/16.png) Since we already divided the balance by 10^8 when writing transaction handlers and minting tzBTC, they are displayed in the database with the correct number of decimal places. @@ -165,26 +166,27 @@ With Dappetizer, we will index the same tzBTC contract, but this time we will di First, install [Node.js](https://nodejs.org/) to work with the npm package manager. Then we will create a folder for the project and install Dappetizer there. The easiest way to do everything is from the terminal: -``` +```bash mkdir dappetizer cd dappetizer npm install @tezos-dappetizer/cli ``` Check if the installation was successful with the version check command: -``` + +```bash npx dappetizer --version ``` -[![17](/images/indexers/dipdup17.png)](https://indexers.tezos.org.ua/static/228af948a104a02c0587fb9cfb252081/1855e/17.png) +[![17](/img/developing/dipdup17.png)](https://indexers.tezos.org.ua/static/228af948a104a02c0587fb9cfb252081/1855e/17.png) Now initialize a new project with the tzBTC name and contract address: -``` +```bash npx dappetizer init --contractName=tzBTC KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn ``` -[![18](/images/indexers/dipdup18.png)](https://indexers.tezos.org.ua/static/513ca79035e04adb259631c74649b680/5ca22/18.png) +[![18](/img/developing/dipdup18.png)](https://indexers.tezos.org.ua/static/513ca79035e04adb259631c74649b680/5ca22/18.png) The Dappetizer will create the necessary files in the project folder. Among them are four main ones you will need to work with: @@ -195,15 +197,15 @@ The Dappetizer will create the necessary files in the project folder. Among them dappetizer.config.ts contains parameters for connecting to the database. Dappetizer uses SQLite by default, but PostgreSQL is fine, too. -[![19](/images/indexers/dipdup19.png)](https://indexers.tezos.org.ua/static/19952b3ff1adf15374abec328edd6b78/0f849/19.png) +[![19](/img/developing/dipdup19.png)](https://indexers.tezos.org.ua/static/19952b3ff1adf15374abec328edd6b78/0f849/19.png) You need to create entities.ts and specify the class (table) and database columns. We will record transactions with the tzBTC token, creating a transaction class with columns id (internal id in the database), sender, receiver, and amount. -[![20](/images/indexers/dipdup20.png)](https://indexers.tezos.org.ua/static/879869b9b7c64aea21f136dc236c71cb/5dd2a/20.png) +[![20](/img/developing/dipdup20.png)](https://indexers.tezos.org.ua/static/879869b9b7c64aea21f136dc236c71cb/5dd2a/20.png) The src folder contains tz-btc-indexer.ts, in which Dappetizer will generate functions for indexing all entry points of the specified contract. In the code of the corresponding entrypoint, you need to describe the indexing logic: which entry point call parameter to write to the database. -[![21](/images/indexers/dipdup21.png)](https://indexers.tezos.org.ua/static/4458d88f72d3cc315e464ea698b84da4/5ca22/21.png) +[![21](/img/developing/dipdup21.png)](https://indexers.tezos.org.ua/static/4458d88f72d3cc315e464ea698b84da4/5ca22/21.png) In tzBTC, the entry point for sending tokens is called transfer. Accordingly, we will find the code for this entry point and add logic to it: @@ -211,28 +213,29 @@ In tzBTC, the entry point for sending tokens is called transfer. Accordingly, we * in the indexTransfer function, we describe the indexing logic: create a tzBTCtransfer constant, in which we write the sender and recipient addresses, as well as the transaction volume, * at the end of the indexTransfer function, we will call the insert function to write the contents of tzBTCtransfer to the database. -[![22](/images/indexers/dipdup22.png)](https://indexers.tezos.org.ua/static/92bd0f1229f79e6bbf945c17cf6d14d7/5ca22/22.png) +[![22](/img/developing/dipdup22.png)](https://indexers.tezos.org.ua/static/92bd0f1229f79e6bbf945c17cf6d14d7/5ca22/22.png) Now we need to add the Transaction model to the index.ts module. To do this, we import Transaction from the entities.ts file and add Transaction to the dbEntities array. -[![23](/images/indexers/dipdup23.png)](https://indexers.tezos.org.ua/static/d63ac8bfb337449b014639d25817d083/5ca22/23.png) +[![23](/img/developing/dipdup23.png)](https://indexers.tezos.org.ua/static/d63ac8bfb337449b014639d25817d083/5ca22/23.png) ### [](https://indexers.tezos.org.ua/dipdup-dappetizer#starting-the-indexer)Starting the indexer In the terminal, go to the project folder and execute the command to build the project: -``` + +```bash npm run build ``` Then start indexing: -``` +```bash npx dappetizer start ``` Dappetizer will begin indexing the blocks and writing data to the database. -[![24](/images/indexers/dipdup24.png)](https://indexers.tezos.org.ua/static/1183e87c13a4569fc11aeca211dba725/5ca22/24.png) +[![24](/img/developing/dipdup24.png)](https://indexers.tezos.org.ua/static/1183e87c13a4569fc11aeca211dba725/5ca22/24.png) ### [](https://indexers.tezos.org.ua/dipdup-dappetizer#connecting-the-database-to-the-project)Connecting the database to the project @@ -240,11 +243,11 @@ Let's make a page similar to the DipDup project. Let's create a tzbtc\_dappetize In our example, we use SQL query to select sender, receiver, and amount fields from the "transaction" table and then sort them by internal id, so the most recent ones (with a higher id value) will be displayed first. -[![25](/images/indexers/dipdup25.png)](https://indexers.tezos.org.ua/static/6e12e4741cc38df7849681462501071f/46eb0/25.png) +[![25](/img/developing/dipdup25.png)](https://indexers.tezos.org.ua/static/6e12e4741cc38df7849681462501071f/46eb0/25.png) Let's start the PHP server in the Dappetizer folder and open the page in the browser: -[![26](/images/indexers/dipdup26.png)](https://indexers.tezos.org.ua/static/dd2993d74350f2f3cfc65f1fb276145d/5ca22/26.png) +[![26](/img/developing/dipdup26.png)](https://indexers.tezos.org.ua/static/dd2993d74350f2f3cfc65f1fb276145d/5ca22/26.png) ### [](https://indexers.tezos.org.ua/dipdup-dappetizer#homework)Homework @@ -258,13 +261,13 @@ In the DipDup example, we considered the volume (turnover) by adding the volume Open the tzbtc\_dappetizer file and create a $sql\_sum SQL query with SELECT SUM(amount) FROM “transaction”: -[![27](/images/indexers/dipdup27.png)](https://indexers.tezos.org.ua/static/ff992168c8b74794cd92405809640c37/c7591/27.png) +[![27](/img/developing/dipdup27.png)](https://indexers.tezos.org.ua/static/ff992168c8b74794cd92405809640c37/c7591/27.png) Then add a query($sql\_sum) function to query the database and output the value to the page. -[![28](/images/indexers/dipdup28.png)](https://indexers.tezos.org.ua/static/e6fcc58f872ad695eb84cadb7d5509e5/5ca22/28.png) +[![28](/img/developing/dipdup28.png)](https://indexers.tezos.org.ua/static/e6fcc58f872ad695eb84cadb7d5509e5/5ca22/28.png) -{% callout type="note" %} +:::note This content was created by [Tezos Ukraine](https://tezos.org.ua/en) under MIT Licence. The original version can be found [here](https://indexers.tezos.org.ua/) in multiple languages. -{% /callout %} +::: diff --git a/src/pages/app-development/indexers/index.md b/docs/developing/information/indexers.md similarity index 92% rename from src/pages/app-development/indexers/index.md rename to docs/developing/information/indexers.md index 417efe2cc..02daf45a8 100644 --- a/src/pages/app-development/indexers/index.md +++ b/docs/developing/information/indexers.md @@ -1,15 +1,14 @@ --- -id: indexers title: Indexers authors: Tezos Ukraine lastUpdated: 10th July 2023 --- -{% callout type="note" %} +:::note If you're just looking for API docs for a hosted indexer, [here is the one from TzKT](https://api.tzkt.io/), and [here is the one from TzStats](https://tzstats.com/docs/api/index.html) -{% /callout %} +::: -## What is an indexer ? +## What is an indexer ? A block explorer, or an app that tracks activity on the blockchain, is typically made of: - an indexer that is a node operator that extracts the on-chain data and stores it in a database @@ -23,7 +22,7 @@ So, the indexer is the part of the explorer that fetches the raw data from the n ## TzKT -For instance, [TzKT](https://github.com/baking-bad/tzkt) is a lightweight Tezos blockchain indexer with an advanced API created by [Baking Bad](https://baking-bad.org/docs).The indexer fetches raw data from the Tezos node, then processes it and stores it in the database in such a way as to provide effective access to the blockchain data. For example, getting operations by hash, getting all operations of the particular account, or getting detailed baking rewards, etc. None of this can be accessed via node RPC, but TzKT indexer makes this data \(and much more\) available. +For instance, [TzKT](https://github.com/baking-bad/tzkt) is a lightweight Tezos blockchain indexer with an advanced API created by [Baking Bad](https://baking-bad.org/docs).The indexer fetches raw data from the Tezos node, then processes it and stores it in the database in such a way as to provide effective access to the blockchain data. For example, getting operations by hash, getting all operations of the particular account, or getting detailed baking rewards, etc. None of this can be accessed via node RPC, but TzKT indexer makes this data (and much more) available. You can [install](https://github.com/baking-bad/tzkt#installation-docker) or [build](https://github.com/baking-bad/tzkt#installation-from-source) it, and [configure](https://github.com/baking-bad/tzkt#install-tzkt-indexer-and-api-for-testnets) it for the testnet. @@ -37,7 +36,7 @@ Indexers are node operators. The **ETL** extract, transform and load data into t * **ETL** stands for _extract, transform, and load_. The process of ETL plays a key role in data integration strategies. ETL allows businesses to gather data from multiple sources and consolidate it into a single, centralized location. * **API** is the acronym for _Application Programming Interface_, which is a software intermediary that allows two applications to talk to each other. -### Focus on BlockWatch Indexer \(TzIndex\) +### Focus on BlockWatch Indexer (TzIndex) The Blockwatch Indexer [TzIndex](https://github.com/blockwatch-cc/tzindex) is used for the [TzStats explorer](https://tzstats.com/). @@ -65,12 +64,12 @@ Now let’s return to the blockchain. To find a transaction by its hash or by th ## Why blockchain indexers are needed -Blockchain protocols work thanks to nodes that process transactions, ensure network security, and, most importantly, store copies of blocks in chronological order. Validator nodes are conditionally divided into light ones with a copy of the last blocks and archival ones with an entire blockchain. Users can get on-chain data from their nodes or third-party nodes using the Remote Procedure Call API to request data about the blockchain. +Blockchain protocols work thanks to nodes that process transactions, ensure network security, and, most importantly, store copies of blocks in chronological order. Validator nodes are conditionally divided into light ones with a copy of the last blocks and archival ones with an entire blockchain. Users can get on-chain data from their nodes or third-party nodes using the Remote Procedure Call API to request data about the blockchain. However, nodes and RPC API aren't designed to work with complex searches and queries. For example, a developer can access an operation's details only if they know where to look for them. -Let's try to get data about this transaction using Tezos client and RPC API — [opRjkzJxJ1xZaUnBDykGUjrRV8qgHFvchcYnbkkcotS1Y7idCSL](https://tzstats.com/opRjkzJxJ1xZaUnBDykGUjrRV8qgHFvchcYnbkkcotS1Y7idCSL). +Let's try to get data about this transaction using Tezos client and RPC API — [opRjkzJxJ1xZaUnBDykGUjrRV8qgHFvchcYnbkkcotS1Y7idCSL](https://tzstats.com/opRjkzJxJ1xZaUnBDykGUjrRV8qgHFvchcYnbkkcotS1Y7idCSL). ``` user:~/tezos % tezos-client rpc get /chains/main/blocks/2283690/operations/3/2 @@ -100,7 +99,7 @@ user:~/tezos % ``` -The highlighted part at the top of the screenshot is the command we used: +The highlighted part at the top of the screenshot is the command we used: `tezos-client rpc get /chains/main/blocks/2283698/operations/3/2` @@ -110,15 +109,15 @@ The numbers in the command mean the following: - 3 — the index of the operation's source type. "3" means the user initiated it. - 2 — the index of the operation in a particular block. -To get the details of a specific operation, we need to know its location in the blockchain: when it was included, what operation type table it was written in, and its number in that index. To know it, we need to check all blocks in turn for the presence of the specified hash, which is very slow and ineffective. +To get the details of a specific operation, we need to know its location in the blockchain: when it was included, what operation type table it was written in, and its number in that index. To know it, we need to check all blocks in turn for the presence of the specified hash, which is very slow and ineffective. -Indexers simplify the task of getting the data you need from the blockchain. They request whole blocks from public nodes and write them to their databases. Then indexers create indexes—-additional data structures optimized for fast data retrieval that store either the data or a link to the corresponding place in the central database. When searching for any data, the indexer looks for it in the corresponding index, not in the central database. For even faster searching, some indexers don't store all data in one table but create separate tables for any valuable data. +Indexers simplify the task of getting the data you need from the blockchain. They request whole blocks from public nodes and write them to their databases. Then indexers create indexes—-additional data structures optimized for fast data retrieval that store either the data or a link to the corresponding place in the central database. When searching for any data, the indexer looks for it in the corresponding index, not in the central database. For even faster searching, some indexers don't store all data in one table but create separate tables for any valuable data. -![](/images/usdt_que_pasa.png) +![](/img/usdt_que_pasa.png) Here is a USDT contract indexed with Que Pasa. It made tables for every entry point and big_map in the contract and an index for every table. It is an efficient way to fetch data. For example, the execution of a query to find a balance of a random USDT holder took only 0.064 milliseconds. -![](/images/que_pasa_sql.png) +![](/img/que_pasa_sql.png) The exact list of tables, indexes schemas, and command syntax depends on the indexer and database it uses. While using TzKT, a query for a USDT balance will look like this: @@ -143,7 +142,7 @@ kenId":"0","standard":"fal.2","firstLevel":1330112,"firstTime":"2021- 30T20:13:29Z", "transfersCount":323378,"balancesCount":9030, "holdersCo unt":3854,"totalMinted":"31442022884393231737144909","totalBurned":"2 9832264735683726828828184","totalSupply":"1609758148709504908316725", "metadata":{"name":"Kolibri USD","symbol": "kUSD","decimals":"18"}}] ``` -There are two types of blockchain indexers: full and selective. +There are two types of blockchain indexers: full and selective. Full indexers process and write all data from blocks, from simple transactions to validator's node software versions. Blockchain explorers commonly use them to provide users with advanced blockchain analytics and allow them to search for any type of on-chain data. Also, those who host full indexers often offer public APIs that other projects can use without hosting the indexer themselves. @@ -173,9 +172,9 @@ We took some interesting and simple examples for calling BetterCallDev and TzKT Many applications that work with on-chain data use an indexer. -The simplest example of working with an indexer is a blockchain wallet. For example, to display a user's token balances, Temple Wallet queries this data from the TzKT indexer and gets tokens' tickers and logos from the contract metadata. +The simplest example of working with an indexer is a blockchain wallet. For example, to display a user's token balances, Temple Wallet queries this data from the TzKT indexer and gets tokens' tickers and logos from the contract metadata. -![temple query](/images/temple_query.png) +![temple query](/img/temple_query.png) Try it yourself: [Go here](https://api.tzkt.io/v1/tokens/balances?account=tz1UEQzJbuaGJgwvkekk6HwGwaKvjZ7rr9v4) and replace tz1...9v4 with your wallet address to see which tokens you have. This is the same query to TzKT API that Temple uses: '/tokens/balances' in constants getTokenBalances and getNFTBalances. @@ -245,19 +244,19 @@ We will make a simple page where users can enter their addresses and check the b First, let's create an empty HTML file in VS Code (you may use another editor, of course) and add the essential elements: doctype, head, title, and body. -![check balance 1](/images/check_balance_html_1.png) +![check balance 1](/img/check_balance_html_1.png) We will use AJAX and the jQuery library to request data via the API and process it. Incorporating a library is simple: just provide a link to it in the script element. -![check balance 2](/images/check_balance_html_2.png) +![check balance 2](/img/check_balance_html_2.png) -Let's get the balance of our address via AJAX. +Let's get the balance of our address via AJAX. -![check balance ajax](/images/check_balance_ajax.png) +![check balance ajax](/img/check_balance_ajax.png) First, we added the $(document).ready() command. It ensures the page is loaded before the scripts are processed. -Then we wrote a request to TzKT using AJAX: in "URL,” the request link to get the balance; in "type," the type of the GET request to get information; and in "success," the function that will process the response. +Then we wrote a request to TzKT using AJAX: in "URL,” the request link to get the balance; in "type," the type of the GET request to get information; and in "success," the function that will process the response. In the function, we will declare the variable balance, assign the value of the answer (data), and immediately divide it by a million. You must do this because the indexer returns the balance in mutez, millionths of tez. @@ -267,23 +266,23 @@ In the end, we will add a h2 element, in which we will display the balance. To d Let's open the page and check the result. -![](/images/check_balance_result.png) +![](/img/check_balance_result.png) ### Adding a button and field to check specific address balance AJAX now sends an API request as soon as the page loads. Let's add a button, pressing which will launch the request. -![](/images/check_balance_button.png) +![](/img/check_balance_button.png) To do this, wrap the h2 in a div element and make it hidden with the style="display:none" parameter. -Let's create a button and add a call to the check function to it, in which we will place the entire request code. At the end of the function, add a change in the display style of the div to a visible block. +Let's create a button and add a call to the check function to it, in which we will place the entire request code. At the end of the function, add a change in the display style of the div to a visible block. Now we need to add a field for entering the user's address and tweak the check() function to insert it into the API request. -![](/images/check_balance_input.png) +![](/img/check_balance_input.png) -To do this, we did the following: +To do this, we did the following: 1. Added the address parameter to the check() function. 2. Changed the value of the "URL" field. When run, the script will make a valid API request using the received address. @@ -292,25 +291,25 @@ To do this, we did the following: Now you can enter any address and, by pressing the button, get its balance in tez. -![](/images/check_balance_input_result.png) +![](/img/check_balance_input_result.png) -Experiment: take [the code of this page](https://gist.github.com/pavelTU/e48c71d09ff5dcfb5343699d485760d9), paste it into an empty HTML file, and open it in a browser. +Experiment: take [the code of this page](https://gist.github.com/pavelTU/e48c71d09ff5dcfb5343699d485760d9), paste it into an empty HTML file, and open it in a browser. This is a simple example: the TzKT API returns the user's balance as JSON with only one number. The answer does not even need to be further processed: everything works as it is. -![](/images/tzkt_api_balance.png) +![](/img/tzkt_api_balance.png) When solving real-life cases, however, you will have to work with JSON arrays and carefully read API responses to select the necessary data. The next chapter explores this matter further. -## Displaying liquidity baking statistics +## Displaying liquidity baking statistics -That contract with 5 million tez is [Sirius DEX](https://siriustoken.io/), better known as liquidity baking. Here is its [contract on TzKT explorer](https://tzkt.io/KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5/operations/). +That contract with 5 million tez is [Sirius DEX](https://siriustoken.io/), better known as liquidity baking. Here is its [contract on TzKT explorer](https://tzkt.io/KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5/operations/). -Liquidity Baking is Tezos' unique DeFi protocol. Users contribute tez and tzBTC to it to provide liquidity for the exchange, and the Tezos network itself adds another 2.5 tez to the pool in each block. Thus, the balances of liquidity providers in this pool are constantly growing. +Liquidity Baking is Tezos' unique DeFi protocol. Users contribute tez and tzBTC to it to provide liquidity for the exchange, and the Tezos network itself adds another 2.5 tez to the pool in each block. Thus, the balances of liquidity providers in this pool are constantly growing. Since all liquidity backing data is stored on-chain, we can get it using API requests to public indexers and then calculate the annual yield and other helpful information. -First, we are interested in the balance of Sirius DEX, particularly how many tez and tzBTC the contract holds. We will receive these numbers from the indexer. +First, we are interested in the balance of Sirius DEX, particularly how many tez and tzBTC the contract holds. We will receive these numbers from the indexer. We need to calculate how much tez the protocol subsidies per year. Here you can calculate the number of seconds in a year, divide this value by the average block creation time—30 seconds—and multiply by one subsidy. @@ -318,7 +317,7 @@ It remains to find out the current value of assets in Sirius DEX and the value o We are starting a new page. First, let's try to get something simple, like the Sirius DEX internal contract id in the TzKT database. -![](/images/sirius_contract_id_html.png) +![](/img/sirius_contract_id_html.png) Let's copy the code of the first example and remove the button and the field for entering the address from it. Let's replace the API request URL with https://api.tzkt.io/v1/contracts/KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5 to get information about the contract from the indexer. @@ -326,37 +325,37 @@ Now it’s time to change the function for data processing. To get specific valu Ultimately, we assign an internal ID, "contractId", to the corresponding HTML element and display it on the page in the h2 element. -![](/images/sirius_contract_id_result.png) - +![](/img/sirius_contract_id_result.png) + We made sure everything worked, so now we can get the data we need: tez and tzBTC balances. First, we should examine TzKT's response to our API request. It has a balance field in tez, so we can get it without changing the request. -![](/images/tzkt_sirius_contract.png) +![](/img/tzkt_sirius_contract.png) Now, assign the value from the received array to the balanceInTez variable by the balance key. -![](/images/sirius_balance_html.png) +![](/img/sirius_balance_html.png) -![](/images/sirius_balance_result.png) +![](/img/sirius_balance_result.png) -Now we need to get the amount of tzBTC. Let's examine the storage of the liquidity backing contract on TzKT: it shows the amount of tzBTC under the tokenPool key. You can access it by requesting the contents of the storage. +Now we need to get the amount of tzBTC. Let's examine the storage of the liquidity backing contract on TzKT: it shows the amount of tzBTC under the tokenPool key. You can access it by requesting the contents of the storage. -![](/images/tzkt_sirius_storage.png) +![](/img/tzkt_sirius_storage.png) Now we should create another AJAX request. In the URL, we specify the API request for the storage content and assign the value of the corresponding entry, tokenPool, to the balanceInTZBTC variable. -![](/images/sirius_balance_tzbtc_html.png) +![](/img/sirius_balance_tzbtc_html.png) On the page, we will display the balance in tzBTC. -![](/images/sirius_balance_tzbtc_result.png) +![](/img/sirius_balance_tzbtc_result.png) Now it’s time to calculate the subsidies for the year. The average year has 31,556,926 seconds. We divide this value by the block creation time and multiply it by the subsidy amount. We can get the block creation time and subsidy amount from TzKT at https://api.tzkt.io/v1/protocols/current. They will be referred to as timeBetweenBlocks and lbSubsidy in the response. -![](/images/tzkt_protocols.png) +![](/img/tzkt_protocols.png) So, we need to get data from two API requests in one function and use it for calculations. But as the variables are local and can't be used in other functions, we need to use nested functions: @@ -369,13 +368,13 @@ So, we need to get data from two API requests in one function and use it for cal First, let's add a call to the checkTimeAndSubsidy function to get the Sirius DEX balance in tez. -![](/images/call_time_and_subsidy.png) +![](/img/call_time_and_subsidy.png) Below, we will declare the same function and add an AJAX call to request protocol data from TzKT. -![](/images/time_and_subsidy_function_1.png) - -We should assign three new variables: +![](/img/time_and_subsidy_function_1.png) + +We should assign three new variables: - secondsInYear: the average number of seconds in a year, in fact, a constant. - timeBetweenBlocks: block creation time. @@ -383,21 +382,21 @@ We should assign three new variables: We now have all the data to calculate the annual subsidy and APY liquidity backing. -![](/images/time_and_subsidy_function_2.png) +![](/img/time_and_subsidy_function_2.png) -Now we can calculate the necessary values by creating the variables yearlySubsidy and APY. +Now we can calculate the necessary values by creating the variables yearlySubsidy and APY. To calculate APY, it is not necessary to obtain asset prices. At any given moment, the value of all tez in the pool equals the value of all tzBTC. To simplify APY calculation, we assume that the user adds to the liquidity pool not tez and tzBTC, but twice as much tez. His APY would be a share of the yearly subsidy divided by the liquidity he provided. Roughly speaking, APY = yearlySubsidy / (balanceInTez × 2) × 100%. -It’s now possible to give the annual amount of subsidies and APY internal ID values and add them to the page. +It’s now possible to give the annual amount of subsidies and APY internal ID values and add them to the page. -![](/images/time_and_subsidy_result.png) +![](/img/time_and_subsidy_result.png) [Example code on Github](https://gist.github.com/pavelTU/5a56c940952f01e838a3ca98215eab15). ## Self study -Try to calculate the value of tez in the Sirius DEX liquidity pool. +Try to calculate the value of tez in the Sirius DEX liquidity pool. 1. Find a smart contract of any liquidity pool with a stablecoin against tez: tez/USDt, tez/kUSD, or tez/uUSD. 2. Get the number of tokens in the pool using an API request. @@ -407,25 +406,23 @@ Try to calculate the value of tez in the Sirius DEX liquidity pool. ### Solution -First, check [the tez/kUSD contract](https://tzkt.io/KT1K4EwTpbvYN9agJdjpyJm4ZZdhpUNKB3F6/storage/) on an exchange on TzKT. Then examine the storage and find the necessary keys: tez_pool is the amount of tez, and token_pool stands for the amount of kUSD. +First, check [the tez/kUSD contract](https://tzkt.io/KT1K4EwTpbvYN9agJdjpyJm4ZZdhpUNKB3F6/storage/) on an exchange on TzKT. Then examine the storage and find the necessary keys: tez_pool is the amount of tez, and token_pool stands for the amount of kUSD. + +![](/img/tez_kusd_contract.png) -![](/images/tez_kusd_contract.png) - And we need to remember that the token's amount in the contract's storage is a natural number. And to display the actual amount of tokens, we need to divide that number by the corresponding number of decimals written in the contract's metadata. For example, kUSD has 18 decimals, and when we get raw token amount data, we need to divide it by 10^18 to get a human-readable amount. -![](/images/kolibri_usd.png) +![](/img/kolibri_usd.png) Since we need to know the number of tez in the pool to calculate the cost of all tez, we need to use nested functions. After receiving the balanceInTez variable, we call the checkValueOfTez function with the balanceInTez argument. In this function, we use AJAX to get data from the tez/kUSD pool (remember to divide the number of tokens depending on the required decimals). Next, we calculate the price of one tez and the cost of all tez in the pool. In the end, we will add the readableValue variable: using the toLocaleString () method, we will add comma separators to the number. -![](/images/homework_value_of_tez.png) +![](/img/homework_value_of_tez.png) As a result, we get the cost of all tez in the Sirius DEX pool, which we get completely from on-chain data. -![](/images/homework_value_of_tez_result.png) - +![](/img/homework_value_of_tez_result.png) -{% callout type="note" %} +:::note This content was created by [Tezos Ukraine](https://tezos.org.ua/en) under MIT Licence. The original version can be found [here](https://indexers.tezos.org.ua/) in multiple languages. -{% /callout %} diff --git a/docs/developing/sandbox.md b/docs/developing/sandbox.md new file mode 100644 index 000000000..bb68585b3 --- /dev/null +++ b/docs/developing/sandbox.md @@ -0,0 +1,22 @@ +--- +title: Using a local sandbox +authors: 'Mathias Hiron, Nomadic Labs, Tim McMackin, TriliTech' +lastUpdated: 18th October 2023 +--- + +Local sandboxes allow you to test your work without sending any transactions to Tezos mainnet or testnets. + +The **sandboxed mode** of `octez-client` makes it possible to test your contracts or other projects while interacting with actual nodes, but without using a public test network or creating your own private network. In sandboxed mode, `octez-client` can create one or more local nodes for this. + +This is convenient if you want to run all your tests locally but in a mode where blocks are actually created through the consensus mechanism. In particular, if your contracts or tests must stay confidential until you decide to put them into production. + +In this mode, you can't use public services such as public block explorers or indexers. You may however install your own. + +One of the fastest ways to run a sandbox network is to use Docker. The [Flextesa](https://tezos.gitlab.io/flextesa/) Docker image allows you to set up a sandbox quickly with the protocol of your choice and pre-funded accounts. + +Find out more in the [documentation of the sandboxed mode](https://tezos.gitlab.io/user/sandbox.html). + +## Further reading + +- [Mockup mode](https://tezos.gitlab.io/user/mockup.html) +- [Sandboxed mode](https://tezos.gitlab.io/user/sandbox.html) diff --git a/src/pages/tezos-basics/test-networks/index.md b/docs/developing/testnets.md similarity index 81% rename from src/pages/tezos-basics/test-networks/index.md rename to docs/developing/testnets.md index 934962cc1..e5a5221d8 100644 --- a/src/pages/tezos-basics/test-networks/index.md +++ b/docs/developing/testnets.md @@ -1,13 +1,12 @@ --- -id: test-networks -title: Test Networks -authors: 'Mathias Hiron, Nomadic Labs' -lastUpdated: 5th June 2023 +title: Using sandboxes and testnets +authors: 'Mathias Hiron, Nomadic Labs, Tim McMackin, TriliTech' +lastUpdated: 18th October 2023 --- -{% callout type="note" %} -The Tezos testnets are overseen and coordinated by [Oxhead Alpha](https://oxheadalpha.com/). The current testnets are [listed here](https://teztnets.xyz/), with an overview of the various testnets [described here](https://teztnets.xyz/). -{% /callout %} +:::note +The Tezos testnets are overseen and coordinated by [Oxhead Alpha](https://oxheadalpha.com/). The current testnets and a description of what each is used for are listed at https://teztnets.xyz/. +::: ## Testing without a node @@ -21,28 +20,16 @@ To make testing a lot faster, options are available, depending on the language a - The **mockup mode** of `octez-client` can be used to test contract calls and other features such as some RPC calls, all without running an actual node, saving the time of going through the consensus mechanism and waiting to get blocks created and validated. Tools like **Completium**, built by the team behind the **Archetype** language, use this for their testing framework. Find out more in the [documentation of the mockup mode](https://tezos.gitlab.io/user/mockup.html). -## Testing with local nodes - -The **sandboxed mode** of `octez-client` makes it possible to test your contracts or other projects while interacting with actual nodes, but without using a public test network or creating your own private network. In sandboxed mode, `octez-client` can create one or more local nodes for this. - -This is convenient if you want to run all your tests locally but in a mode where blocks are actually created through the consensus mechanism. In particular, if your contracts or tests must stay confidential until you decide to put them into production. - -In this mode, you can't use public services such as public block explorers or indexers. You may however install your own. - -One of the fastest ways to run a sandbox network is to use Docker. The [Flextesa](https://tezos.gitlab.io/flextesa/) Docker image allows you to set up a sandbox quickly with the protocol of your choice and pre-funded accounts. - -Find out more in the [documentation of the sandboxed mode](https://tezos.gitlab.io/user/sandbox.html). - ## Testing with public test networks If you want to test your development in conditions closer to those of Tezos Mainnet, you can use one of several public test networks. -These behave like `Mainnet`, with a few differences: +These behave like Mainnet, with a few differences: - You can use faucets to obtain tez for free on these networks, so you don't need to (and can't) spend actual tez. -- They use different constants than `Mainnet`, for example, reduced block times and shorter cycles for faster testing, reduced windows for inserting rejections in rollups, etc. +- They use different constants than Mainnet, for example, reduced block times and shorter cycles for faster testing, reduced windows for inserting rejections in rollups, etc. - Tools like public block explorers or indexers may or may not be available, depending on the network. -- They either use a modified version of the amendment process (`Ghostnet` and `Dailynet`) or don't use it at all. +- They either use a modified version of the amendment process (Ghostnet and Dailynet) or don't use it at all. - Different test networks run on different versions of the protocol. Depending on your needs, you may pick between the three types of networks listed below. The different test networks provide different foresight into the changes brought by upcoming protocol amendments -- from a week to 6 months, under the current policy of [rolling protocol proposal publication](https://research-development.nomadic-labs.com/regular-scheduling-for-our-tezos-proposals.html). @@ -67,7 +54,7 @@ As the protocol on `Ghostnet` migrates to the newly adopted amendment a few days #### Getting tez testnet tokens -In order to get Tez tokens to use when testing your application on testnet, you can use a faucet. You +In order to get Tez tokens to use when testing your application on testnet, you can use a faucet. You can request some tokens from the [Ghostnet faucet](https://faucet.ghostnet.teztnets.xyz/) @@ -120,8 +107,5 @@ See the [Private blockchain](https://opentezos.com/private) section on OpenTezos ## Further reading -- Tezos reference: - - [Test networks by Nomadic Labs](https://tezos.gitlab.io/introduction/test_networks.html) - - [Mockup mode](https://tezos.gitlab.io/user/mockup.html) - - [Sandboxed mode](https://tezos.gitlab.io/user/sandbox.html) +- [Test networks by Nomadic Labs](https://tezos.gitlab.io/introduction/test_networks.html) - Medium post: [Introducing Ghostnet](https://medium.com/the-aleph/introducing-ghostnet-1bf39976e61f) diff --git a/docs/overview/common-applications.md b/docs/overview/common-applications.md new file mode 100644 index 000000000..11b1f9756 --- /dev/null +++ b/docs/overview/common-applications.md @@ -0,0 +1,31 @@ +--- +title: Common applications of Tezos +lastUpdated: 13 September 2023 +--- + +Here are some of the ways that people use Tezos: + +## NFTs on Tezos + +The rise of non-fungible tokens (NFTs) has become a core arena of activity and growth in the blockchain space, where new communities are growing around artists, musicians, and other creators with the use of blockchain tokens. NFTs allow collectors and fans to hold a piece of content produced by a creator, verifiable on the blockchain and providing proof of ownership. + +[Objkt](https://objkt.com/), [FxHash](https://www.fxhash.xyz/), [Teia](https://teia.art/), [DNS.xyz](https://dns.xyz/) are some of the marketplaces for Tezos art and music NFTs. They allow creators to mint and sell their work in addition to providing a platform for users to collect such works. + +Tezos is also being used for other NFT-related projects, such as [MoneyTrack](https://moneytrack.io/), which is a payment platform that uses NFTs to control directed payment flows. + +## Enterprise and Government Uses of Tezos + +Enterprises and regulatory bodies have been adopting Tezos as well. + +Tezos is being used by the French Armies and Gendarmerie's Information Center to [validate judicial expenses](https://cointelegraph.com/news/french-cybercrime-division-uses-smart-contacts-on-tezos-blockchain) incurred during investigations and record them on Tezos. + +In recent years, the concept of Central Bank Digital Currencies (CBDCs) has gained traction, with several countries around the world exploring their own CBDC projects. Société Générale carried out a series of successful tests [using Tezos](https://decrypt.co/112127/societe-generales-crypto-division-lands-regulatory-approval-france) to explore the potential of CBDCs. In September 2020, the bank announced that it had completed a pilot program using a custom-built version of the Tezos blockchain to simulate the issuance and circulation of CBDCs. The pilot involved testing the technology's ability to handle transactions, make payments, and settle transactions in a digital environment. + +The Califonia DMV is also using Tezos for its project to [put car titles on the blockchain](https://fortune.com/crypto/2023/01/26/california-announces-dmv-run-blockchain-through-partnership-with-tezos/). + +[Sword Group](https://www.sword-group.com/2020/09/28/sword-launches-tezos-digisign/) an international technology company, launched DigiSign, an open-source tool built on Tezos that enables users to digitally sign, certify, and verify the authenticity of digital documents. + + +## Tezos in Gaming + +Recently, the [Tezos SDK for Unity](https://tezos.com/unity/) promises to make blockchain game development easier and faster. It allows for the addition of web3 features such as allowing players to link their accounts across games, mint, and trade in-game items and currencies, and show off their ranks and accomplishments on public, on-chain leaderboards. \ No newline at end of file diff --git a/docs/overview/glossary.md b/docs/overview/glossary.md new file mode 100644 index 000000000..90847b1c2 --- /dev/null +++ b/docs/overview/glossary.md @@ -0,0 +1,367 @@ +--- +title: Glossary +lastUpdated: 24th October 2023 +--- + +## Tezos and tez + +The following is adapted from this [Agora post](https://forum.tezosagora.org/t/nomenclature/2376) by Tezos Co-founder Arthur Breitman. As noted in the post, there is no official body that can authoritatively set Tezos' nomenclature, but the following is recommended: + +- **Tezos** + + Used either as a noun or an adjective to designate: + + * An open-source project and software (as in, "contributing to the Tezos codebase") + * A peer-to-peer network of nodes maintaining a blockchain (as in "a Tezos node") + * The specific Tezos chain with the most economic relevance (as in "the Tezos chain"). In particular, the chain whose [millionth block](https://tzkt.io/BKtC4QCWoF73kxLj773vFpQuuwrnye6PS7T1aM3XEPvFXiQbNu7/endorsements) had hash `BKtC4QCWoF73kxLj773vFpQuuwrnye6PS7T1aM3XEPvFXiQbNu7`. + +- **Tez** + + A unit of the cryptocurrency native to a Tezos chain, such as in "I sent you 2 tez." Tez is invariable. It is not capitalized except at the beginning of a sentence or when you would otherwise capitalize a noun. "I sent you 2 tez" and not "2 Tez". + +- **XTZ** + + XTZ, tez, or ꜩ (`\ua729`, "Latin small letter tz") is the native currency of Tezos. + + "XTZ" is an ISO-4217-compatible code for representing tez on the most economically relevant Tezos chain. Unless there is a very specific reason to use an ISO code for it, the term tez is preferred. Situations where the ISO code might be useful typically involve accounting systems, exchange rates with other currencies, and anything that might need some sort of standardized code. + + + +## Tezos terms + +- **Block** + + The Tezos blockchain is a linked list of blocks (or actually, a tree when several competing branches exist). + Blocks conceptually contain a header and a list of operations, + which are specific to the economic protocol. + + The header itself decomposes into a shell header (common to all Tezos economic protocols), and a protocol-specific header. + The shell header contains protocol-agnostic data such as the predecessor's block hash and the block's timestamp. + +- **Context** + + The state of the blockchain. The context is defined by the + economic protocol and typically includes information such as + "this account is credited with this many tez" and "this is the + code for that smart contract." + + The context is modified by operations. For example, an + operation can transfer tez from one account to another, which modifies the + part of the context that tracks account credit. + +- **Economic protocol** + + The economic protocol is the set of rules defining valid operations and blocks, how the network agrees on the next block to build (the consensus algorithm), + and how operations update the blockchain state, also called context. + + In Tezos, the economic protocol can be upgraded without interruption or + forking of the blockchain. This is because the procedure for an upgrade is also defined within the economic protocol, which can thus update itself. + +- **Fitness** + + (a.k.a. score, weight) + For each block, the consensus algorithm can compute a score called fitness which determines the quality of the chain leading to that block. + The shell changes the head of the chain to the valid block that has the highest fitness. + +- **Height** + + See level. + +- **Level** + + (a.k.a. block height) + The position of a block in the blockchain, that is, the number of blocks + since the genesis block, where the genesis block is at level 0. + +- **Mempool** + + A (block or operation) metadata is a piece of data + computed as a result of the application of the + block or operation on an associated context. The metadata + consists of many pieces of information such as the operation receipts, + rewards updates, voting period, etc. + + A block's metadata is the collections of operations metadata for all the operations included in the block (if the validation was successful). + +- **Node** + + A peer in the P2P network. It maintains a local state and propagates blocks + and operations. + +- **Operation** + + An operation transforms the context; this is what makes the state of the chain + change. Operations are grouped into blocks; thus, the chain progresses in + batches. + +- **Score** + + See fitness. + +- **Shell** + + The shell is a software component of the node. It is parameterized by a + specific economic protocol. It serves as the bridge between the P2P layer + (handling communication between nodes) and the economic protocol layer + (handling the context, operation application, scoring, etc.). + +- **Weight** + + See fitness. + +## Protocol terms + +- **Accuser** + + When a delegate attempts double signing (or when it tries + to abuse the network in another similar way), another delegate can make an + accusation, by providing evidence of the offense. The delegate injecting the accusation in a newly baked block is called the accuser. + + The accuser is awarded some funds from the security deposit of the accused. + + When using Octez, accusation operations are emitted by the + accuser daemon. Note that this daemon is not associated to a delegate: accusation operations are anonymous, and any delegate can include them in a block. + +- **Account** + + An account is an address managed by the protocol. + In the context, each account is associated with a balance (an amount of + tez available). + + An account can be either an originated account or an implicit account. + +- **Baker** + + When a delegate creates a new block, it is called the baker of this block. + Baking rights are distributed to different delegates based on their + available stake. Only a delegate with baking rights + is allowed to bake. + The baker selects transactions from the mempool to be included in the block it bakes. + + When using Octez, baking and other consensus actions are handled by the baker + daemon, on behalf of one or more delegate accounts. + By extension, a baker designates the owner of such a delegate account, typically running the baker daemon on its behalf. + +- **Baking** + + The act of creating a new block by a baker. + +- **Baking rights** + + Baking/endorsing a block can only be done by a delegate who holds the + baking/endorsing right for that block level and round. At the start of a cycle, + baking and endorsing rights are computed for all the block levels and rounds in the + cycle, based on the proportion of the stake of each delegate. + + For each block level and round, there is exactly one account that is allowed to bake, but several accounts are allowed to endorse. + +- **Burn** + + To ensure responsible use of the storage space on the public blockchain, + there are some costs charged to users for consuming storage. These + costs are burnt (i.e., the amount of tez is destroyed). For example, + a per-byte storage cost is burnt for increasing the storage space of a + smart contract; a fixed amount is burnt for allocating a new contract + (which consumes space by storing its address on the blockchain). + + See also fee. + +- **Constant** + + Protocols are parameterized by several parameters called protocol constants, which may vary from one protocol to another or from one network to another. + +- **Contract** + + See account. + +- **Cycle** + + A cycle is a sequence of consecutive blocks of fixed length (given by a protocol constant). E.g., cycle 12 started at block + level 49152 and ended at block level 53248. + + Cycles are used as a unit of "time" in the block chain. For example, the + different phases in the amendment voting procedures are defined based on + numbers of cycles. + + The length of a cycle is a (parametric) protocol + constant, and thus might change across different + Tezos protocols. + +- **Delegate** + + An implicit account that can participate in consensus and in governance. + Actual participation is under further provisions, like having a minimal stake. + An implicit account becomes a delegate by registering as such. + Through delegation, other accounts can delegate their rights to a delegate account. + The delegate's rights are calculated based on its stake. + Note that `tz4` accounts cannot be delegates. + +- **Delegation** + + An operation in which an account designates a + delegate. The delegating account's balance increases the delegate's stake and consequently + its baking rights and endorsing rights. However, the delegate does not control the funds of + the delegating account, e.g., it can not spend them. + +- **Double signing** + + The situation when a baker signs two different blocks at the same level and same round, + is called double baking. Double baking is detrimental to the network and might be + indicative of an attempt to double spend. + The same goes for signing two different endorsements at the same level and the same round. + As such, double signing (i.e., double baking or double endorsing) is punished by the + network: an accuser can provide proof of the double signing to be awarded + part of the double signer's deposit -- see Slashing. + +- **Failing Noop** + + The `Failingnoop` operation implements a *No-op*, which always + fails at application time, and + should never appear in applied + blocks. This operation allows end-users to + sign arbitrary messages which have no + computational semantics. + +- **Endorsing** + + When a block is created and propagated on the network, delegates that have + endorsing rights for the matching block level and round can emit an endorsement operation. + Endorsement operations are included in the next block. + +- **Endorsing rights** + + See baking rights. + +- **Fee** + + To ensure responsible use of computation resources of other nodes, and also to encourage active participation in the consensus protocol, + users pay fees to bakers for including their operations in blocks. + For example, fees are paid to a baker for operations such as a transaction or a revelation of a public key. + + Currently, only manager operations + require collecting fees from its sender account. + + See also burn. + +- **Gas** + + A measure of the number of elementary steps performed during + the execution of a smart contract. Gas is used to measure how + much computing power is used to execute a smart contract. + +- **Implicit account** + + An account that is linked to a public key. Contrary to a smart + contract, an implicit account cannot include a script and it + cannot reject incoming transactions. + + If *registered*, an implicit account can act as a delegate. + + The address of an implicit account always starts with the + letters tz followed by 1, 2, 3, or 4 (depending on the + signature scheme) and finally the hash of the public key. + +- **Layer 1** + + The primary blockchain i.e. the Tezos chain. Within any blockchain ecosystem, Layer 1 (L1) refers to the main chain to + which side chains, rollups, or other protocols connect and settle to. The Layer 1 chain is deemed to be most + secure, since it has the most value (or stake) tied to it, and be most decentralized and censorship resistant. + However, transaction space is limited leading to low throughput and possibly high transaction costs. + See Layer 2. + +- **Layer 2** + + Layer 2 (L2) includes sidechains, rollups, payment channels, etc. that batch their transactions and + write to the layer 1 chain. By processing transactions on layer 2 networks, + greater scalability in speed and throughput can be achieved by the ecosystem overall, since the number of transactions + the layer 1 can process directly is limited. By cementing transactions from a L2 to L1, + the security of the L1 chain backs those operations. In Tezos there are a number of layer 2 solutions, + including Smart Optimistic Rollups, + validity or ZK-Rollups [Epoxy](https://research-development.nomadic-labs.com/files/cryptography.html) , + zkChannels, and sidechains such as [Deku](https://deku.marigold.dev/). + +- **Michelson** + + The built-in language used by a smart contract. + +- **Minimal stake** + + An amount of tez (e.g., 6000ꜩ) serving as a minimal amount for a + delegate to have baking rights and voting rights in a cycle. + +- **Operation kinds** + + The main kinds of operations in the protocol are transactions (to transfer funds + or to execute smart contracts), accusations, activations, delegations, + endorsements, and originations. + +- **Originated account** + + See smart contract. + +- **Origination** + + A manager operation whose purpose is to create -- that + is, to deploy -- a smart contract on the Tezos blockchain. + +- **Round** + + An attempt to reach consensus on a block at a given level. + A round is represented by an index, starting with 0. + Each round corresponds to a time span. + A baker with baking rights at a given round is only allowed to bake during + the round's corresponding time span. Baking outside of one's designated + round results in an invalid block. + +- **Roll** + + deprecated; see minimal stake. + +- **Smart contract** + + Account which is associated to a Michelson script. + They are created with an + explicit origination operation and are therefore sometimes called + originated accounts. The address of a smart contract always starts + with the letters `KT1`. + +- **Smart Optimistic Rollups** + + Smart optimistic rollups constitute a layer 2 solution that can be used to deploy either a general-purpose polyvalent layer 2 blockchain + (e.g., an EVM-compatible one), or an application-specific DApp. + +- **Stake** + + The amount of tokens that determines a delegate's weight in the + governance process and in the selection of its baking and + endorsing rights. A delegate's stake is usually given by the + delegate's own tokens plus the sum of tokens delegated to + it. However, there are cases when this is not the case, see + [here](https://tezos.gitlab.io/active/consensus.html#active-stake-nairobi) for details. + +- **Transaction** + + An operation to transfer tez between two accounts, or to run the code of a + smart contract. + +- **Validation pass** + + An index (a natural number) associated with a particular kind of + operations, allowing to group them into classes. Validation passes + enable prioritizing the validation and + application of certain classes of + operations. + +- **Voting period** + + Any of the `proposal`, `exploration`, `cooldown`, + `promotion` or `adoption` stages in the voting procedure when + amending the economic protocol. + +- **Voting listings** + + The list calculated at the beginning of each voting period that contains + the staking balance (in number of mutez) of each delegate that owns more + than the minimal stake at that moment. For each delegate, the voting listings + reflect the weight of the vote emitted by the delegate when amending the + economic protocol. \ No newline at end of file diff --git a/docs/overview/index.md b/docs/overview/index.md new file mode 100644 index 000000000..52ce26c6d --- /dev/null +++ b/docs/overview/index.md @@ -0,0 +1,16 @@ +--- +title: Tezos overview +lastUpdated: 11th September 2023 +--- + +Tezos is an open-source, decentralized blockchain [created in 2014](https://tezos.com/whitepaper.pdf) by Arthur and Kathleen Breitman. It raised awareness and support in 2017 with its crowdfunding and launched the following year. Since its inception, Tezos has gone through multiple iterations of upgrades and development, staying true to its ethos -- "a blockchain designed to evolve". + +Tezos has robust applications ranging from NFTs, DeFi, and gaming to enterprise and government use cases. + +## Cutting-edge developments on Tezos + +With recent Tezos upgrades heavily focusing on scaling solutions, Tezos has been at the forefront of blockchain research. Up to 1 million transactions per second (TPS) are theoretically possible on Tezos with the advent of smart rollups, which have emerged as a strong scaling solution. With smart rollups (also known as optimistic rollups), transactions can be performed more quickly and cheaply and use other VMs that “roll up” their state changes onto Tezos. + +[Epoxy](https://tarides.com/blog/2022-12-20-how-nomadic-labs-used-multicore-processing-to-create-a-faster-blockchain) is another exciting technology in development that will further improve the scalability, speed, and versatility of Tezos. Epoxy is a validity rollup solution (also known as zk-rollups) that doesn't rely on [fraud proofs](https://medium.com/@cpbuckland88/fraud-proofs-and-virtual-machines-2826a3412099) making it even more robust and powerful. + +These innovations demonstrate the ongoing dedication of Tezos to foster innovation in the blockchain industry. diff --git a/docs/overview/quickstart.md b/docs/overview/quickstart.md new file mode 100644 index 000000000..10bd53e33 --- /dev/null +++ b/docs/overview/quickstart.md @@ -0,0 +1,6 @@ +# Quickstart + +Simple page to provide links to tutorials and what you learn from each one. + +- To learn about smart contracts, go to 'Deploy your first smart contract' +- To learn about dApps, go to 'Build your first app on Tezos' \ No newline at end of file diff --git a/docs/overview/tezos-different.md b/docs/overview/tezos-different.md new file mode 100644 index 000000000..f5275787c --- /dev/null +++ b/docs/overview/tezos-different.md @@ -0,0 +1,30 @@ +--- +title: What makes Tezos different? +lastUpdated: 13 September 2023 +--- + +Here are some of the features that make Tezos different from other blockchains: + +## Tezos can upgrade itself + +Tezos has a built-in capability to upgrade itself, which allows the network to evolve without requiring a hard fork. Anyone can propose an upgrade to the protocol and have it adopted by the network without compromising the platform's stability or causing fragmentation. This feature allows Tezos to adapt to new technologies and to address user needs rapidly. + +## Stakeholders participate in governance + +Anyone who holds XTZ — the chain's native token — can propose changes to how Tezos works, such as changes to gas fees and block times, new features such as smart rollups, or even major changes like how the consensus mechanism works. + +## Formal verification ensures trust and code quality + +*Formal verification* is a process that ensures that a smart contract does what it says it does and has no side effects. Formal verification reduces errors, bugs, and security vulnerabilities in contracts and allows users to trust them. For more information, see [Formal Verification](https://opentezos.com/formal-verification) on opentezos.com. + +## Tezos uses proof of stake + +The proof-of-stake consensus model eliminates the need for high energy use, making it the "green" choice for blockchains. Instead of competing to achieve consensus as in proof-of-work models, Tezos nodes (called *bakers*) stake Tezos tokens to earn the right to create blocks and receive rewards. Users who want to participate without running a node themselves can delegate tokens to a baker for a share of the rewards. The bakers and delegators keep control of their tokens and can remove them at any time. Tezos's approach to consensus has been described as [Liquid Proof of Stake](https://medium.com/tezos/liquid-proof-of-stake-aec2f7ef1da7). + +The proof-of-stake model improves scalability and encourages incentive alignment. It also increases the cost of 51% attacks and avoids environmentally wasteful proof-of-work. Tezos launched in June 2018 as one of the first major proof-of-stake networks. + +For more information about how Tezos handles proof of stake, see https://tezos.gitlab.io/alpha/proof_of_stake.html. + +## Tezos accepts multiple languages + +Tezos lets developers use languages that make sense for their use case, including versions of Python and JavaScript/TypeScript. For more information, see [An Introduction to Smart Contracts](../smart-contracts/languages/). \ No newline at end of file diff --git a/src/pages/smart-contracts/token-standards/fa12-fa2-standards/index.md b/docs/reference/fa12-fa2-standards.md similarity index 97% rename from src/pages/smart-contracts/token-standards/fa12-fa2-standards/index.md rename to docs/reference/fa12-fa2-standards.md index 26bc081a3..6df44cb65 100644 --- a/src/pages/smart-contracts/token-standards/fa12-fa2-standards/index.md +++ b/docs/reference/fa12-fa2-standards.md @@ -1,5 +1,4 @@ --- -id: fa12-fa2-standards title: FA1.2 & FA2 token standards authors: Claude Barde lastUpdated: 29th June 2023 @@ -11,9 +10,9 @@ Token standards in a blockchain ecosystem are important for 2 reasons: The FA1.2 standard is the first token standard that was available on Tezos. It was followed a few years later by the FA2 standards. Both standards provide different interfaces and behaviors that developers can choose according to their needs. -{% callout type="note" title="Note" %} +:::note Note To read the full specification of the FA1.2 standard, [check this page](https://gitlab.com/tezos/tzip/-/blob/master/proposals/tzip-7/tzip-7.md). For the full specification of the FA2 standard, [follow this link](https://gitlab.com/tezos/tzip/-/blob/master/proposals/tzip-12/tzip-12.md). -{% /callout %} +::: ## FA1.2 standard The FA1.2 standard has been created for fungible tokens. This means that it is not possible to implement an NFT with this standard. A few common tokens used on Tezos are FA1.2, for example, kUSD or Ctez. @@ -46,7 +45,7 @@ No specific storage is required by the standard, however, these 2 values are sug ## FA2 standard -The FA2 standard was created to handle both fungible and non-fungible tokens (NFT). Unlike the standards on Ethereum and other blockchains, Tezos provides the same standard with a certain flexibility for fungible and non-fungible tokens. +The FA2 standard was created to handle both fungible and non-fungible tokens (NFT). Unlike the standards on other blockchains, Tezos provides the same standard with a certain flexibility for fungible and non-fungible tokens. The FA2 standard provides a safe interface to create and interact with tokens on Tezos. All the NFTs (at the time of writing) on Tezos are FA2 tokens. Multiple popular fungible tokens are also FA2 tokens like uUSD and USDT. diff --git a/src/pages/tezos-basics/get-started-with-octez/index.md b/docs/reference/octez.md similarity index 94% rename from src/pages/tezos-basics/get-started-with-octez/index.md rename to docs/reference/octez.md index e2e54dbe7..26f7267c8 100644 --- a/src/pages/tezos-basics/get-started-with-octez/index.md +++ b/docs/reference/octez.md @@ -1,11 +1,10 @@ --- -id: get-started-with-octez title: Getting Started with Octez authors: 'Thomas Zoughebi, Aymeric Bethencourt, and Maxime Fernandez' lastUpdated: 5th June 2023 --- -## Octez - The Tezos Client +## Octez - The Tezos Client _Octez_ is the official client to interact with a Tezos node via RPC (remote procedural calls). In theory, there can be multiple implementations of the Tezos protocol, but currently, there is only Octez. Octez consists of several binaries (i.e., executable files), including a client, a node, and a baker. @@ -36,7 +35,7 @@ dnf install -y tezos-client ### Connecting to a node -Below we'll connect to a community node () on the Ghostnet **testnet**. We'll use the `--endpoint` parameter to update the configuration of the Octez Client on a Ubuntu system: +Below we'll connect to a community node (https://ghostnet.tezos.marigold.dev) on the Ghostnet **testnet**. We'll use the `--endpoint` parameter to update the configuration of the Octez Client on a Ubuntu system: `octez-client --endpoint https://ghostnet.tezos.marigold.dev config update` @@ -45,9 +44,9 @@ The result should look like this: ```bash Warning: - + This is NOT the Tezos Mainnet. - + Do NOT use your fundraiser keys on this network. ``` @@ -73,9 +72,9 @@ The result should look like this: ```bash Warning: - + This is NOT the Tezos Mainnet. - + Do NOT use your fundraiser keys on this network. Hash: tz1VvyNvPUdypHaTgznTLSkumj9YMZxpmB9p @@ -86,9 +85,9 @@ You can now go to [the testnets website](https://teztnets.xyz/), select your tes ### Octez Client user manual and version -{% callout type="note" %} +:::note The full command list for *Octez client* is available [here](https://tezos.gitlab.io/shell/cli-commands.html). -{% /callout %} +::: ## Octez Client examples @@ -110,9 +109,9 @@ The response: ```bash Warning: - + This is NOT the Tezos Mainnet. - + Do NOT use your fundraiser keys on this network. 1 ꜩ @@ -132,9 +131,9 @@ Result example: ```bash Warning: - + This is NOT the Tezos Mainnet. - + Do NOT use your fundraiser keys on this network. 2022-10-04T13:34:00Z @@ -152,9 +151,9 @@ Example response: ```bash Warning: - + This is NOT the Tezos Mainnet. - + Do NOT use your fundraiser keys on this network. my_account: tz1VvyNvPUdypHaTgznTLSkumj9YMZxpmB9p (unencrypted sk known) @@ -172,9 +171,9 @@ Our example: ```bash Warning: - + This is NOT the Tezos Mainnet. - + Do NOT use your fundraiser keys on this network. my_account: tz1VvyNvPUdypHaTgznTLSkumj9YMZxpmB9p @@ -202,7 +201,7 @@ For our example, let's generate another account and feed it with tez from [the f ```bash $ octez-client gen keys my_account_2 -$ octez-client show address my_account_2 +$ octez-client show address my_account_2 Hash: tz1M9Snt3Sdcv9YkTrergj3ar6FuQ2g4T9y3 Public Key: edpktfqbZHfRRSRcJ86hqxQZvgfFMLwR6zMZAXA5UgE81L7WqHt579 ``` @@ -293,11 +292,11 @@ You can observe your actions on explorers like *tzkt* or *tzstats*: * Mainnet: [TzKT](https://tzkt.io/), [TzStats](https://tzstats.com) * Ghostnet: [TzKT](https://ghostnet.tzkt.io/), [TzStats](https://edo.tzstats.com) - + OpenTezos has a guide on [how to use an explorer](https://opentezos.com/explorer). -{% callout type="note" %} -For a more comprehensive guide on how to install Octez, including via Docker images, see the [docs](https://tezos.gitlab.io/introduction/howtoget.html) by Nomadic Labs. +:::note +For a more comprehensive guide on how to install Octez, including via Docker images, see the [docs](https://tezos.gitlab.io/introduction/howtoget.html) by Nomadic Labs. The above is an abridged version of the [Octez guide](https://opentezos.france-ioi.org/en/a/1332828229711949831;p=1,3556096645042535892;pa=0) found on OpenTezos. -{% /callout %} +::: diff --git a/src/pages/tezos-basics/get-started-with-octez/best-practices/index.md b/docs/reference/octez/best-practices.md similarity index 96% rename from src/pages/tezos-basics/get-started-with-octez/best-practices/index.md rename to docs/reference/octez/best-practices.md index cc5ce4817..491555844 100644 --- a/src/pages/tezos-basics/get-started-with-octez/best-practices/index.md +++ b/docs/reference/octez/best-practices.md @@ -1,6 +1,5 @@ --- -id: best-practices -title: Best practices +title: Octez best practices authors: Nomadic Labs lastUpdated: 27th June 2023 --- @@ -25,7 +24,7 @@ The rest of this document is structured around different aspects of the Octez no ## RPC interface -The Tezos node offers an [RPC programming interface](https://tezos.gitlab.io/shell/rpc.html), that is used by clients such as a wallet or a baker. This is a rich API providing many features. +The Tezos node offers an [RPC programming interface](https://tezos.gitlab.io/shell/rpc.html), that is used by clients such as a wallet or a baker. This is a rich API providing many features. Some of these RPC are sensitive in terms of security: @@ -49,9 +48,9 @@ Advanced users may also establish more complex configurations using the [proxy s Based on these protection mechanisms, the recommended practice is to enable the RPC interface only on the localhost interface, thus only serving local binaries such as octez-client and octez-baker. -{% callout type="warning" title="Caution" %} +:::warning Advanced users choosing to open the RPC interface for remote hosts do this at their own risks, and should carefully use the ACL mechanism for fine-grain configuration. -{% /callout %} +::: ## History modes @@ -61,7 +60,7 @@ The Rolling mode is also compatible with baking, when used with caution. Specifi These history modes also exhibit different CPU performance characteristics, which are worth taking into account. Specifically, nodes in Full mode are quicker in validating blocks than nodes in Archive mode (because in the latter case, data are searched in a larger file). This is especially true when nodes in Full mode have been restarted recently from a snapshot, and keep thus a limited history. -It is a recommended practice to use the Full mode for baking, and to regularly restart the baker from a recent snapshot, in order to ensure quick block validation. +It is a recommended practice to use the Full mode for baking, and to regularly restart the baker from a recent snapshot, in order to ensure quick block validation. It is not advised to set bakers in Archive mode, unless you have specific reasons to do so, as this typically slows down block validation. It is not advised to set bakers in Rolling mode either (even when it is not required to help other nodes to bootstrap), to always be able to reveal the nonce of the blocks they produced. @@ -81,9 +80,9 @@ The disk space consumed by a node depends on its history mode, as explained abov Prior to running a node, make sure that it has not only enough disk space for its regular functioning (which may depend on its history mode and other options), but also extra available space for a copy of its index (typically around 20G extra space). -{% callout type="warning" title="Disk space" %} +:::warning Disk space Not allocating enough disk space for a node, including for its dynamic variations, incurs the risk of seeing the node regularly stopped. -{% /callout %} +::: ## Memory space @@ -92,9 +91,9 @@ Running a Tezos node requires providing enough memory space (RAM) for its functi The memory consumption of the node varies in time for the same reason as its disk space consumption: the node regularly reorganizes its storage (about every 8 hours). During normal operation, a node can typically work with 4G of RAM. During the storage reorganization operation, the node can consume twice as memory (up to 8G), but as each such operation is rather short-lived, it is safe to allocate the extra space as swap space on the disk. -{% callout type="warning" title="RAM" %} +:::warning RAM Prior to running a node, make sure that enough RAM is available (typically 4GB), and also enough swap space on disk (typically 4GB). -{% /callout %} +::: ## Performance @@ -103,9 +102,9 @@ Ensuring a good performance level for a node requires allocating enough resource When dimensioning machines for running Tezos nodes, it is advised to ensure a good disk bandwidth, such as those offered by SSD disks (and ideally, SSD/NVE disks). Running several nodes on the same machine should be considered with caution: pay attention not to saturate the disk bandwidth. -{% callout type="warning" title="multi-CPU machine" %} +:::warning multi-CPU machine Running several nodes on a multi-CPU machine will likely lead to suboptimal performance, because the disk bandwith will probably constitute the main bottleneck. -{% /callout %} +::: ## Delayed endorsement @@ -115,7 +114,7 @@ One possible reason for missing an endorsement opportunity is when the endorseme Make sure that your baker process is not patched to delay endorsements, in order to avoid missed endorsements. So, if you are running an endorser with `--endorsement-delay `, we suggest that you restart your endorser without it. -{% callout type="warning" title="Delaying endorsements" %} +:::warning Delaying endorsements Delaying endorsements, for historical reasons or for any reasons, incurs the risk of the endorsements arriving too late to be considered by block creators, hence resulting in missed reward opportunities. -{% /callout %} +::: diff --git a/src/pages/tezos-basics/get-started-with-octez/cli-rpc/index.md b/docs/reference/octez/cli-rpc.md similarity index 97% rename from src/pages/tezos-basics/get-started-with-octez/cli-rpc/index.md rename to docs/reference/octez/cli-rpc.md index 9e1be0ccc..b9cda9920 100644 --- a/src/pages/tezos-basics/get-started-with-octez/cli-rpc/index.md +++ b/docs/reference/octez/cli-rpc.md @@ -1,9 +1,5 @@ --- -hide_table_of_contents: true -title: Tezos Clients -hide_title: true -sidebar_label: Introduction -sidebar_position: 1 +title: CLI and RPC lastUpdated: 30th June 2023 --- ## Connecting to the network @@ -67,14 +63,14 @@ $ brew install tezos-client * On Ubuntu with binaries: ```bash -$ sudo add-apt-repository ppa:serokell/tezos && sudo apt-get update +$ sudo add-apt-repository ppa:serokell/tezos && sudo apt-get update $ sudo apt-get install -y tezos-client ``` * On Fedora with binaries: ```bash -$ dnf copr enable -y @Serokell/Tezos && dnf update -y +$ dnf copr enable -y @Serokell/Tezos && dnf update -y $ dnf install -y tezos-client ``` diff --git a/src/pages/tezos-basics/get-started-with-octez/installation-and-setup/index.md b/docs/reference/octez/installing.md similarity index 84% rename from src/pages/tezos-basics/get-started-with-octez/installation-and-setup/index.md rename to docs/reference/octez/installing.md index 34b2e6dab..402af7aac 100644 --- a/src/pages/tezos-basics/get-started-with-octez/installation-and-setup/index.md +++ b/docs/reference/octez/installing.md @@ -1,5 +1,5 @@ --- -title: Installation and Setup +title: Installing Octez lastUpdated: 30th June 2023 --- @@ -7,13 +7,13 @@ To start, we'll download and install tezos-client and create a couple of test wa ## Installation -### Linux \(64-bit\) +### Linux (64-bit) A quick and easy way to get tezos-client running on Linux is to download the latest `tezos-client` binary, make it executable, and put it somewhere in your path. Alternatively, you can add a package repository for your distribution, and install it from there. Using a package is a good idea for production systems as it automates the installation and allows easy updates. #### Option 1: Install the binary -``` sh +```sh $ wget https://github.com/serokell/tezos-packaging/releases/latest/download/tezos-client $ chmod +x tezos-client $ mkdir -p $HOME/.local/bin @@ -27,16 +27,16 @@ This information is based on documentation from: [Get Tezos](https://tezos.gitla Tips: -* Use ```tab``` to autocomplete partial commands previously entered +* Use ```tab```to autocomplete partial commands previously entered * Use the up and down arrows to cycle through previously entered commands **1.** Make sure your system is up to date. -``` sh +```sh sudo apt-get update ``` -``` sh +```sh sudo apt-get upgrade ``` @@ -45,79 +45,79 @@ sudo apt-get upgrade **2.** Install rust. -``` sh +```sh sudo apt install -y rsync git m4 build-essential patch unzip wget pkg-config libgmp-dev libev-dev libhidapi-dev libffi-dev opam jq zlib1g-dev ``` -``` sh +```sh wget https://sh.rustup.rs/rustup-init.sh ``` -``` sh +```sh chmod +x rustup-init.sh ``` -``` sh +```sh ./rustup-init.sh --profile minimal --default-toolchain 1.52.1 -y ``` **3.** Loading the cargo environment variable -``` sh +```sh source $HOME/.cargo/env ``` **4.** Get the sources -``` sh +```sh git clone https://gitlab.com/tezos/tezos.git ``` -``` sh +```sh cd tezos ``` -``` sh +```sh git checkout latest-release ``` **5.** Install the Tezos dependencies. -``` sh +```sh opam init --bare ``` -* You will be asked: ```do you want to modify ~/.profile? [N/y/f]``` press ```n```. -* You will then be asked: ```A hook can be added to opam's init scripts to ensure that the shell remains in sync with the opam environment when they are loaded. Set that up? [y/N]``` press ```n```. +* You will be asked: ```do you want to modify ~/.profile? [N/y/f]```press ```n```. +* You will then be asked: ```A hook can be added to opam's init scripts to ensure that the shell remains in sync with the opam environment when they are loaded. Set that up? [y/N]```press ```n```. -``` sh +```sh make build-deps ``` **6.** Compile sources ( This step can take a long time depending on your hardware ) -``` sh +```sh eval $(opam env) ``` -``` sh +```sh make ``` **7.** Get rolling snapshot -``` sh +```sh wget https://mainnet.xtz-shots.io/rolling -O tezos-mainnet.rolling ``` **8.** Import the snapshot (This step can take a long time depending on your hardware) -``` sh +```sh ./tezos-node snapshot import tezos-mainnet.rolling ``` **9.** Run the node -``` sh +```sh ./tezos-node run --allow-all-rpc localhost:8732 --rpc-addr localhost:8732 --history-mode experimental-rolling ``` @@ -125,7 +125,7 @@ wget https://mainnet.xtz-shots.io/rolling -O tezos-mainnet.rolling * How do I stop the node? - * Press ```Ctrl-c``` from within the terminal tab it is running in. Give it a minute or two, if it still does not work press it again. + * Press ```Ctrl-c```from within the terminal tab it is running in. Give it a minute or two, if it still does not work press it again. * Where is Tezos installed? @@ -135,17 +135,17 @@ wget https://mainnet.xtz-shots.io/rolling -O tezos-mainnet.rolling * ```~/.tezos-node``` - * Note that the period in front of the directory denotes a hidden directory. Use ```ls -a``` to show all files and directories including hidden directories. + * Note that the period in front of the directory denotes a hidden directory. Use ```ls -a```to show all files and directories including hidden directories. * What do I do if my node data becomes corrupted and I need to re-import a new snapshot? - * You will need to first remove the old data. To do that run ```rm -rf .tezos-node``` from your home directory. - * Then from the ```tezos``` directory use the same commands above to re-import new snapshots. + * You will need to first remove the old data. To do that run ```rm -rf .tezos-node```from your home directory. + * Then from the ```tezos```directory use the same commands above to re-import new snapshots. **Updating the node** **1.** Pull updates from the git repo -``` sh +```sh git pull ``` @@ -153,21 +153,21 @@ git pull **2.** Install the latest dependencies and compile the sources -``` sh +```sh make build-deps ``` -``` sh +```sh eval $(opam env) ``` -``` sh +```sh make ``` #### Option 3: Using packages on Ubuntu or Fedora -``` sh +```sh sudo add-apt-repository ppa:serokell/tezos && sudo apt-get update sudo apt-get install -y tezos-client sudo apt-get install -y tezos-node @@ -178,13 +178,13 @@ sudo apt-get install -y tezos-accuser-010-ptgranad ### Windows -Install one of Linux distributions using [Windows Subsystem for Linux \(WSL\)](https://docs.microsoft.com/en-us/windows/wsl/about) \(e.g. Ubuntu 18.04 LTS\) and follow instructions for Linux. +Install one of Linux distributions using [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/about) (e.g. Ubuntu 18.04 LTS) and follow instructions for Linux. ### Mac OS With [Homebrew](https://brew.sh/): -``` sh +```sh $ brew tap serokell/tezos-packaging https://github.com/serokell/tezos-packaging.git $ brew install tezos-client ``` @@ -195,19 +195,19 @@ $ brew install tezos-client We'll configure `tezos-client` to use a public test network Tezos node: -``` sh +```sh $ tezos-client --endpoint https://rpcalpha.tzbeta.net config update ``` `--endpoint` parameter specifies the address of the server, `config update` writes it to `tezos-client`'s configuration filed at `$HOME/.tezos-client/config`. -Alternatively, one can use an isolated sandboxed network instead of using a public test-network, which we'll do in the [“Sandbox”](run-a-sandbox.md) section. +Alternatively, one can use an isolated sandboxed network instead of using a public test-network, which we'll do in the [“Sandbox”](./sandbox.md) section. ### Try it out Verify that you can run tezos-client and that it points to test network: -``` sh +```sh $ tezos-client Warning: @@ -244,7 +244,7 @@ Global options (must come before the command): Now that we know we are on a test network we can temporarily disable this warning so that we don't see it with each command. -``` sh +```sh $ export TEZOS_CLIENT_UNSAFE_DISABLE_DISCLAIMER=yes ``` @@ -254,14 +254,14 @@ $ export TEZOS_CLIENT_UNSAFE_DISABLE_DISCLAIMER=yes * Go to the [faucet](https://faucet.tzalpha.net/). * Complete the captcha and download the wallet in the form of a .json file. -* The file name is the wallet address \(also known as the public key hash, or PKH\) with a .json extension. +* The file name is the wallet address (also known as the public key hash, or PKH) with a .json extension. * If you look inside the file you will see a property called *pkh* which contains the address. * The public key hash is used to identify the account on the Tezos blockchain and can be thought of as an address or account number. * Next, we'll activate the account, passing it the path to the `.json` wallet we just downloaded * We'll first create an account for Alice, then Bob, so we can perform some test transactions. * Don't be alarmed by the blank `Error:` we'll explain why shortly. -``` sh +```sh $ tezos-client activate account alice with ~/Downloads/tz1QLne6uZFxPRdRfJG8msx5RouENpJoRsfP.json Node is bootstrapped, ready for injecting operations. Operation successfully injected in the node. @@ -271,17 +271,17 @@ Error: ``` -> Note empty `Error:` message at the end of the output. `tezos-client` attempts to wait for operation inclusion but the public Tezos node we are using disallows access \(as a security measure\) to the part of node api that is necessary for this functionality. We use `--wait none` throughout these tutorials to avoid this error. If you use your own local Tezos node you can omit `--wait none`, the error won't happen. +> Note empty `Error:` message at the end of the output. `tezos-client` attempts to wait for operation inclusion but the public Tezos node we are using disallows access (as a security measure) to the part of node api that is necessary for this functionality. We use `--wait none` throughout these tutorials to avoid this error. If you use your own local Tezos node you can omit `--wait none`, the error won't happen. -Make a variable for Alice's account address \(PKH\) \(notice that the address is the same as the name of your faucet `.json` file\): +Make a variable for Alice's account address (PKH) (notice that the address is the same as the name of your faucet `.json` file): -``` sh +```sh $ ALICE_ADDRESS="tz1QLne6uZFxPRdRfJG8msx5RouENpJoRsfP" ``` Ensure that the activation was successful: -``` sh +```sh $ tezos-client get balance for $ALICE_ADDRESS 56828.546322 ꜩ ``` @@ -290,7 +290,7 @@ Now, we'll create a new wallet for Bob so we can do some test transactions in th * Go back to the [faucet](https://faucet.tzalpha.net/) and download a second wallet -``` sh +```sh $ tezos-client activate account bob with tz1ZQYMDETodNBAc2XVbhZFGme8KniuPqrSw.json $ BOB_ADDRESS="tz1ZQYMDETodNBAc2XVbhZFGme8KniuPqrSw" $ tezos-client get balance for $BOB_ADDRESS diff --git a/src/pages/tezos-basics/get-started-with-octez/monitor-a-node/index.md b/docs/reference/octez/monitoring.md similarity index 96% rename from src/pages/tezos-basics/get-started-with-octez/monitor-a-node/index.md rename to docs/reference/octez/monitoring.md index 083546ff0..51fd64a92 100644 --- a/src/pages/tezos-basics/get-started-with-octez/monitor-a-node/index.md +++ b/docs/reference/octez/monitoring.md @@ -1,6 +1,5 @@ --- -id: monitor-a-node -title: Monitor a Node +title: Monitoring nodes authors: Jean-Baptiste Col lastUpdated: 29th June 2023 --- @@ -30,14 +29,14 @@ Netdata is a light and open-source software that collects and exposes hardware m Grafana is software that takes JSON in input and makes dashboards that you can display using your browser (the high-level web interface that displays all the metrics). In our case, JSONs are provided by Grafazos. -### [Grafazos](https://gitlab.com/nomadic-labs/grafazos) +### [Grafazos](https://gitlab.com/nomadic-labs/grafazos) Grafazos is a jsonnet library written by Nomadic Labs, which uses itself [grafonet-lib](https://github.com/grafana/grafonnet-lib), which is a jsonnet library to write Grafana dashboards as code. ### [jsonnet](https://jsonnet.org/) Jsonnet is a programming language that allows to create JSONs easily. -### [Prometheus](https://prometheus.io/docs/introduction/overview/#what-is-prometheus) +### [Prometheus](https://prometheus.io/docs/introduction/overview/#what-is-prometheus) Prometheus server is a toolkit that scrapes and stores time series data by making requests to the nodes. Basically, prometheus is fed by both netdata and tezos-metrics (which is deprecated and not used), and then, grafana displays the data gathered by prometheus. @@ -160,7 +159,7 @@ sudo systemctl restart netdata You have in fact two ways to [open your dashboard](https://learn.netdata.cloud/docs/dashboard/how-dashboard-works#open-the-dashboard): -- You can access Netdata's dashboard by navigating to in your browser (replace NODE by either localhost or the hostname/IP address of a remote node) +- You can access Netdata's dashboard by navigating to http://NODE:19999 in your browser (replace NODE by either localhost or the hostname/IP address of a remote node) - You can also use [Netdata Cloud](https://app.netdata.cloud/) to create custom dashboards, monitor several nodes, and invite users to watch your dashboard... It's free of charges and your data are never stored in a remote cloud server, but rather in the local disk of your machines. @@ -193,7 +192,7 @@ You can also monitor relevant hardware data (metrics names may differ depending Plenty of others metrics are available, depending on your machine and needs. This is an example of a Demo Dashboard with the following metrics: -- `octez_version` +- `octez_version` - `octez_validator_chain_is_bootstrapped` - `Disk Space Usage` - `CPU Usage` @@ -202,7 +201,7 @@ This is an example of a Demo Dashboard with the following metrics: - `octez_p2p_peers_running` - `octez_store_last_written_block_size` -![Example of a light monitoring dashboard](/images/monitor-a-node/netdata_dashboard.png) +![Example of a light monitoring dashboard](/img/reference/netdata_dashboard.png) ### Monitoring several nodes @@ -244,7 +243,7 @@ template: 10min_cpu_usage #Name of the alarm/template.(required) units: % every: 1m #The frequency of the alarm. #"warn" and "crit" expressions evaluating to true or false, and when true, will trigger the alarm. - warn: $this > (($status >= $WARNING) ? (75) : (85)) + warn: $this > (($status >= $WARNING) ? (75) : (85)) crit: $this > (($status == $CRITICAL) ? (85) : (95)) delay: down 15m multiplier 1.5 max 1h #Optional hysteresis settings to prevent floods of notifications. info: average cpu utilization for the last 10 minutes (excluding iowait, nice and steal) @@ -262,8 +261,8 @@ As an example, here is a warning alert if the metric octez_p2p_connections_activ ``` alarm: tezos_node_p2p_connections_active (cannot be chart name, dimension name, family name, or chart variables names.) on: octez_p2p_connections_active - hosts: * - lookup: average -10m unaligned of user,system,softirq,irq,guest + hosts: * + lookup: average -10m unaligned of user,system,softirq,irq,guest warn: $this<3 crit: $this==0 info: "tezos_node_p2p_connections_actives" represents the current number of active p2p connections with your node. @@ -304,7 +303,7 @@ To calculate the space needed to store your metrics you will need: For 2000 metrics, collected every second and retained for a month, Tier 0 needs: 1 byte x 2,000 metrics x 3,600 secs per hour x 24 hours per day x 30 days per month = 5,184MB. -![Number of metrics location in the dashboard](/images/monitor-a-node/number-of-metrics.jpeg) +![Number of metrics location in the dashboard](/img/reference/number-of-metrics.jpeg) #### Modify netdata.conf file @@ -344,11 +343,11 @@ Now you just have to change the value of "dbengine multihost disk space" in [db] Here is the global picture of a monitoring system, connecting all these tools together: -![](/images/monitor-a-node/all-in-all.png) +![](/img/reference/all-in-all.png) A Grafazos dashboard looks like this: -![](/images/monitor-a-node/octez-metrics-dashboard.gif) +![](/img/reference/octez-metrics-dashboard.gif) Table 1: Grafana dashboard of a Tezos node @@ -395,9 +394,8 @@ For each RPC called, two metrics are associated: `octez_rpc_calls_sum{endpoint=" 2. The block validator validates blocks and notifies the corresponding chain validator. 3. Each peer validator treats new head proposals from its associated peer, retrieving all the operations, and if valid, triggers a validation of the new head. -{% callout title="Octez version" %} +:::note Octez version Note that the metrics described here are those available with Octez v14--it is likely to evolve with future Octez versions. -{% /callout %} ### Dashboards @@ -433,7 +431,7 @@ Some metrics are self-explanatory, such as *P2P total connections*, which shows Another useful metric is the *Block validation time*, which measures the time between when a request is registered in the worker till the worker pops the request and marks it complete. This should generally be under 1 second. If it's persistently longer, that could indicate trouble too. -![](/images/monitor-a-node/metrics-block-validation-time.png) +![](/img/reference/metrics-block-validation-time.png) Graph 2: Block validation time @@ -442,7 +440,7 @@ The *P2P connections* graph will show you immediately if your node is having tro A healthy node should typically have a few dozen peer connections (depending on how it was configured). -![](/images/monitor-a-node/metrics-p2p-connections.png) +![](/img/reference/metrics-p2p-connections.png) Graph 3: P2P connections @@ -461,5 +459,5 @@ Grafana is a relatively user-friendly tool, so play with creating a custom one a ## Conclusion -Octez Metrics gives Tezos users insight into how their node is performing, and ability to observe the overall network health. The best way to keep your node healthy and keep the entire Tezos network healthy is with monitoring tools to gain insite into network health. +Octez Metrics gives Tezos users insight into how their node is performing, and ability to observe the overall network health. The best way to keep your node healthy and keep the entire Tezos network healthy is with monitoring tools to gain insite into network health. diff --git a/src/pages/tezos-basics/get-started-with-octez/node-cluster/index.md b/docs/reference/octez/node-cluster.md similarity index 97% rename from src/pages/tezos-basics/get-started-with-octez/node-cluster/index.md rename to docs/reference/octez/node-cluster.md index d0a7c87b7..62e51110d 100644 --- a/src/pages/tezos-basics/get-started-with-octez/node-cluster/index.md +++ b/docs/reference/octez/node-cluster.md @@ -1,13 +1,12 @@ --- -id: node-cluster -title: Deploy a cluster of nodes using Pulumi +title: Deploying a cluster of nodes using Pulumi authors: 'Oxhead Alpha, Daniel, Nomadic Labs' lastUpdated: 14th June 2023 --- **(Thank you to [Oxhead Alpha](https://www.oxheadalpha.com/) for coding this great tool)** -Deploying a Tezos node is a good way to address certain needs when working with the Tezos blockchain. It can be used to broadcast operations or to query specific information such as the latest block of the chain or the storage of a particular smart contract. +Deploying a Tezos node is a good way to address certain needs when working with the Tezos blockchain. It can be used to broadcast operations or to query specific information such as the latest block of the chain or the storage of a particular smart contract. But when working with decentralized applications (dApps), the node can become a bottleneck. @@ -15,11 +14,11 @@ The more people interact with a decentralized application, the more queries the In those situations, it becomes necessary to set up an infrastructure that can handle the load – by deploying a **cluster of nodes**. -This tutorial, inspired by [Oxhead Alpha's medium article](https://medium.com/the-aleph/deploy-scalable-tezos-nodes-in-the-cloud-bbe4f4f4ddcc), aims to be a practical guide to deploying your own cluster of Tezos nodes using AWS cloud’s managed Kubernetes offering (EKS). For further technical explanations, we refer you to the above-mentioned article. +This tutorial, inspired by [Oxhead Alpha's medium article](https://medium.com/the-aleph/deploy-scalable-tezos-nodes-in-the-cloud-bbe4f4f4ddcc), aims to be a practical guide to deploying your own cluster of Tezos nodes using AWS cloud’s managed Kubernetes offering (EKS). For further technical explanations, we refer you to the above-mentioned article. -For our setup, we will be using [Pulumi](https://www.pulumi.com/), an amazingly flexible infrastructure-as-code (IaC) tool. At the end of the tutorial, we will expose the nodes’ RPC endpoint to the internet via a load balancing system. +For our setup, we will be using [Pulumi](https://www.pulumi.com/), an amazingly flexible infrastructure-as-code (IaC) tool. At the end of the tutorial, we will expose the nodes’ RPC endpoint to the internet via a load balancing system. -The resulting infrastructure is highly available, scalable, customizable, and supports rolling upgrades (a must-have, given Tezos' amendment pace). The tool enables us to scale the number of Tezos nodes as desired (0 to n). +The resulting infrastructure is highly available, scalable, customizable, and supports rolling upgrades (a must-have, given Tezos' amendment pace). The tool enables us to scale the number of Tezos nodes as desired (0 to n). To consult the associated code on Github, please check [this link](https://github.com/oxheadalpha/tezos-pulumi) out. @@ -34,7 +33,7 @@ To consult the associated code on Github, please check [this link](https://githu Follow [the Pulumi tutorial](https://www.pulumi.com/docs/get-started/aws/begin/) to create an AWS account if you don’t already have one, and install Pulumi. *Your AWS IAM user must have the ability to create a VPC and EKS cluster*. -# 1 Create a Pulumi project +# 1 Create a Pulumi project Create a Pulumi project using the following lines: @@ -278,11 +277,11 @@ Now it's time to deploy our Tezos infrastructure! Run the following command to launch your cluster: ```bash -pulumi up +pulumi up ``` :::caution -You may probably have to execute the following command, before launching the cluster. Chose your prefered AWS region (`us-east-2` +You may probably have to execute the following command, before launching the cluster. Chose your prefered AWS region (`us-east-2` for Ohio, `eu-central-1` for Frankfurt, etc.): ```sh pulumi config set region @@ -290,11 +289,11 @@ pulumi config set region ::: Pulumi will display a url that you can visit to view the status of your deployment on the Pulumi web console. -# 4 Monitoring +# 4 Monitoring In order to monitor the cluster liveness, we have chosen [Lens](https://k8slens.dev/) (An IDE for Kubernetes) as a monitoring tool. -Execute the following command to provide the kubeconfig file to Lens: +Execute the following command to provide the kubeconfig file to Lens: ```sh pulumi stack output kubeconfig --show-secrets --json > kubeconfig.json @@ -304,7 +303,7 @@ Now, you can graphically monitor your cluster liveness (in our case, our 3 rolli

-![lens](developers/docs/images/node-cluster/lens.png) +![lens](/img/reference/lens.png) Lens monitoring

@@ -315,8 +314,8 @@ curl http://
/chains/main/chain_id "NetXdQprcVkpaWU" ``` -:::info -The `
` RPC endpoint is a URL generated by AWS. It is possible to deploy the RPC behind a specific domain name. This would require buying or importing a domain and configuring it with [Route53](https://aws.amazon.com/route53/). +:::info +The `
` RPC endpoint is a URL generated by AWS. It is possible to deploy the RPC behind a specific domain name. This would require buying or importing a domain and configuring it with [Route53](https://aws.amazon.com/route53/). ::: :::info diff --git a/src/pages/tezos-basics/get-started-with-octez/run-a-sandbox/index.md b/docs/reference/octez/sandbox.md similarity index 91% rename from src/pages/tezos-basics/get-started-with-octez/run-a-sandbox/index.md rename to docs/reference/octez/sandbox.md index f7df62f81..3b5781893 100644 --- a/src/pages/tezos-basics/get-started-with-octez/run-a-sandbox/index.md +++ b/docs/reference/octez/sandbox.md @@ -1,6 +1,4 @@ --- -sidebar_position: 3 -hide_table_of_contents: true title: Run a Sandbox hide_title: true lastUpdated: 30th June 2023 @@ -18,29 +16,29 @@ This example requires Docker, available for Linux, Mac, or Windows at [https://w ### Starting and Using a Sandbox -Start the sandbox _in the background_ \(will run with baking enabled\): +Start the sandbox _in the background_ (will run with baking enabled): -``` sh +```sh docker run --rm --name my-sandbox --detach -p 20000:20000 \ oxheadalpha/flextesa:20230502 mumbaibox start ``` After a few seconds, this should succeed: -``` sh +```sh tezos-client config reset # Cleans-up left-over configuration. tezos-client --endpoint http://localhost:20000 bootstrapped ``` Configure the client to communicate with the sandbox: -``` sh +```sh tezos-client --endpoint http://localhost:20000 config update ``` Then, instead of using a public faucet, you can just use tez by importing accounts already existing in the sandbox. They are visible with: -``` sh +```sh $ docker run --rm oxheadalpha/flextesa:20230502 mumbaibox info Usable accounts: @@ -59,14 +57,14 @@ Root path (logs, chain data, etc.): /tmp/mini-box (inside container). You may then just import them: -``` sh +```sh tezos-client import secret key alice unencrypted:edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq --force tezos-client import secret key bob unencrypted:edsk3RFfvaFaxbHx8BMtEW1rKQcPtDML3LXjNqMNLCzC3wLC1bWbAt --force ``` Check their balances: -``` sh +```sh tezos-client get balance for alice ``` @@ -76,7 +74,7 @@ See also the [Tezos Client](https://assets.tqtezos.com/docs/setup/1-tezos-client For instance, you can originate the most minimalistic [contract](https://gitlab.com/tezos/tezos/blob/mainnet/src/bin_client/test/contracts/attic/id.tz): -``` sh +```sh # Download the contract: wget https://gitlab.com/tezos/tezos/raw/mainnet/src/bin_client/test/contracts/attic/id.tz # Run origination: @@ -87,7 +85,7 @@ tezos-client originate contract hello-id transferring 0 from bob running id.tz - When you're done playing, just destroy the container: -``` sh +```sh docker kill my-sandbox ``` @@ -97,15 +95,15 @@ docker kill my-sandbox One can see the configuration of the protocol running in the sandbox with: -``` sh +```sh tezos-client rpc get /chains/main/blocks/head/context/constants ``` -One important field is `"time_between_blocks": [ "5" ],` which means that blocks are baked every 5 seconds \(as opposed to 60 seconds on mainnet\). +One important field is `"time_between_blocks": [ "5" ],` which means that blocks are baked every 5 seconds (as opposed to 60 seconds on mainnet). This constant can be configured with the `block_time` environment variable, see the example below: -``` sh +```sh docker run --rm --name my-sandbox -e block_time=2 --detach -p 20000:20000 \ oxheadalpha/flextesa:20230502 mumbaibox start ``` @@ -114,7 +112,7 @@ The above command runs a full sandbox with the Florence protocol and a faster ti Many other parameters are set by the `mumbaibox` [script](https://gitlab.com/tezos/flextesa/-/blob/master/src/scripts/tutorial-box.sh). All the configuration options available can be seen with the command: -``` sh +```sh docker run --rm -it oxheadalpha/flextesa:20230502 flextesarl mini-net --help ``` @@ -122,14 +120,14 @@ docker run --rm -it oxheadalpha/flextesa:20230502 flextesarl mini-net --help The Docker image also contains a `nairobibox` script: -``` sh +```sh docker run --rm --name my-sandbox --detach -p 20000:20000 \ oxheadalpha/flextesa:20230502 nairobibox start ``` You can then check that the protocol hash is `PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf`: -``` sh +```sh $ tezos-client rpc get /chains/main/blocks/head/metadata | grep protocol { "protocol": "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf", @@ -138,7 +136,7 @@ You can then check that the protocol hash is `PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z or that there are new constants like the one related to liquidity baking: -``` sh +```sh $ tezos-client rpc get /chains/main/blocks/head/context/constants | grep liquidity "liquidity_baking_subsidy": "2500000", "liquidity_baking_sunset_level": 525600, @@ -147,5 +145,5 @@ or that there are new constants like the one related to liquidity baking: ### Further Reading -For more issues or questions, see the [Flextesa](https://gitlab.com/tezos/flextesa) repository, and for even more advanced usage, see the [documentation](https://tezos.gitlab.io/flextesa/) \(esp. for the [`mini-net` command](https://tezos.gitlab.io/flextesa/mini-net.html)\). +For more issues or questions, see the [Flextesa](https://gitlab.com/tezos/flextesa) repository, and for even more advanced usage, see the [documentation](https://tezos.gitlab.io/flextesa/) (esp. for the [`mini-net` command](https://tezos.gitlab.io/flextesa/mini-net.html)). diff --git a/src/pages/tezos-basics/get-started-with-octez/upgrade/index.md b/docs/reference/octez/upgrading.md similarity index 87% rename from src/pages/tezos-basics/get-started-with-octez/upgrade/index.md rename to docs/reference/octez/upgrading.md index bc5ce397f..9a3bd8783 100644 --- a/src/pages/tezos-basics/get-started-with-octez/upgrade/index.md +++ b/docs/reference/octez/upgrading.md @@ -1,6 +1,5 @@ --- -id: upgrade -title: Node upgrade +title: Upgrading nodes authors: Nomadic Labs lastUpdated: 29th June 2023 --- @@ -20,7 +19,7 @@ The following commands help to upgrade your node to the latest Octez version. To upgrade your node to the latest Octez version, run the lastest image. Note that if you run the latest image, restarting your container is sufficient. -See the [list of releases](https://tezos.gitlab.io/releases/releases.html) for the latest version number, and replace v17 below with that. +See the [list of releases](https://tezos.gitlab.io/releases/releases.html) for the latest version number, and replace v17 below with that. To upgrade to version 17 for instance, run: @@ -55,9 +54,8 @@ eval $(opam env) make ``` -{% callout type="warning" title="Opam switch remove" %} +:::warning Opam switch remove `opam switch remove .` is only needed if you are updating an already compiled repository, not if you are compiling from a freshly cloned repository. -{% /callout %} #### Upgrade using opam packages @@ -69,10 +67,8 @@ opam depext opam upgrade ``` -{% callout type="warning" title="Closing terminal" %} +:::warning Closing terminal Be careful when closing terminal windows because this stops the node. -{% /callout %} -{% callout type="note" title="Using screen" %} +:::note Using screen Use [screen](https://doc.ubuntu-fr.org/screen), or [nohup](https://www.computerhope.com/unix/unohup.htm) to keep the node running in the background. -{% /callout %} diff --git a/src/pages/smart-contracts/token-standards/index.md b/docs/reference/token-standards.mdx similarity index 81% rename from src/pages/smart-contracts/token-standards/index.md rename to docs/reference/token-standards.mdx index 02e4dced5..798310eb2 100644 --- a/src/pages/smart-contracts/token-standards/index.md +++ b/docs/reference/token-standards.mdx @@ -1,11 +1,12 @@ --- -id: token-standards title: Token Standards author: Aymeric Bethencourt lastUpdated: 10th July 2023 --- -In the blockchain ecosystem, any digitally transferable asset between two people is called a **token**. Tokens can be native to a blockchain, e.g., BTC is the native token of Bitcoin or tokens can also be created and hosted on an existing blockchain via a smart contract. Some tokens, called [stablecoins](/defi/stablecoins), follow the price of fiat currencies (e.g., USD, EUR). Others, called [_NFT_](/defi/token-standards#fungible--non-fungible-tokens), can represent collectibles or art pieces. Finally, tokens can represent rights of ownership of real-world estates or companies (i.e., [stock tokens](https://www.investopedia.com/terms/t/tokenized-equity.asp)). In this chapter, we will see the main types of tokens and the token standards on Tezos. +import Figure from '@site/src/components/Figure'; + +In the blockchain ecosystem, any digitally transferable asset between two people is called a **token**. Tokens can be native to a blockchain, e.g., BTC is the native token of Bitcoin or tokens can also be created and hosted on an existing blockchain via a smart contract. Some tokens, called stablecoins, follow the price of fiat currencies (e.g., USD, EUR). Others, called NFTs, can represent collectibles or art pieces. Finally, tokens can represent rights of ownership of real-world estates or companies (i.e., [stock tokens](https://www.investopedia.com/terms/t/tokenized-equity.asp)). In this chapter, we will see the main types of tokens and the token standards on Tezos. ## Token standard @@ -13,7 +14,7 @@ A token standard is an interface, and a set of rules, that a smart contract must Multiple implementations of a standard can co-exist, but they must all respect the interface and rules of the standard. Standards ensure that smart contracts remain compatible, so for instance, when a new project issues a token, it remains compatible with the existing decentralized exchanges, wallets, etc. -{% figure src="/images/token-standards/standards.svg" alt="token-standard-implementation" caption="FIGURE 1: Illustration of 2 implementations of the same token standard" %} {% /figure %} +
## Fungible & Non-Fungible Tokens @@ -43,14 +44,14 @@ The FA2 standard (standing for _Financial Application 2_) refers to the unified As you can see, FA2 is a very powerful standard that allows many forms of tokens. It aims to provide significant expressivity to contract developers, allowing them to create new types of tokens while maintaining a common interface standard for wallet integrators and external developers. A variety of transfer permission policies can also be defined, such as how most tokens can be transferred, who can perform a transfer, and who can receive tokens. A token contract can be designed to support a single token type or multiple token types to optimize batch transfers and atomic swaps. A particular FA2 implementation may include hybrid implementations where multiple token kinds (fungible, non-fungible, non-transferable etc) can coexist (e.g. in a fractionalized NFT contract). -Note that FA2 is the successor to [FA1.2](/defi/token-standards#fa12) that only supports fungible tokens, it is still widely used in the Tezos ecosystem. +Note that FA2 is the successor to FA1.2 that only supports fungible tokens, it is still widely used in the Tezos ecosystem. -To learn more on how to implement FA2 tokens, please refer to the corresponding Tezos Improvments Proposal, the TZIP-12[[3]](/defi/token-standards#references). +To learn more on how to implement FA2 tokens, please refer to the corresponding Tezos Improvements Proposal, [TZIP-12](https://tzip.tezosagora.org/proposal/tzip-12/). -{% figure src="/images/token-standards/tokens.svg" alt="fa2-token-standard" caption="FIGURE 2: Illustration of the multi-purpose aspect of the FA2 token standard." %} {% /figure %} +
-To learn more on how to implement FA2 tokens, please refer to the corresponding Tezos Improvements Proposal, the [TZIP-12](https://tzip.tezosagora.org/proposal/tzip-12/). +To learn more on how to implement FA2 tokens, please refer to the corresponding Tezos Improvements Proposal, [TZIP-12](https://tzip.tezosagora.org/proposal/tzip-12/). ## Regulations @@ -60,11 +61,11 @@ If you plan to create a token, make sure to check the regulations in your countr Always be cautious as anyone can create tokens on Tezos. Before purchasing a token, make sure to question its value. Is the smart contract of the token open-source? Has it been audited? Is there a hard cap? Indeed, any rule regarding creating tokens or their transfer can be coded into the smart contract. For instance, uncapped tokens could be infinitely minted by their author, rendering their value null. -{% callout type="warning" title="Warning" %} +:::warning Keep in mind that holding a token in your wallet doesn't, in itself, guarantee that your token is safe. Indeed, holding a token means that the token's smart contract holds a record that associates your public address with a balance. But if the smart contract is malicious or has bugs, that record could be altered, erased, or frozen, making your tokens unusable even if they are in your wallet. -{% /callout %} +::: ## Resources on Tezos diff --git a/docs/smart-contracts.mdx b/docs/smart-contracts.mdx new file mode 100644 index 000000000..b2b574c32 --- /dev/null +++ b/docs/smart-contracts.mdx @@ -0,0 +1,117 @@ +--- +title: An introduction to smart contracts +authors: 'Thomas Zoughebi, Aymeric Bethencourt, Maxime Fernandez, and Tim McMackin' +lastUpdated: 18th October 2023 +--- + +import Figure from '@site/src/components/Figure'; + +A smart contract is a piece of code stored on the blockchain. It contains a set of instructions and rules to trigger them. Once deployed, it becomes immutable, but a user can trigger the execution of the code without modifying it. + +## Smart contract metaphor + +Smart contracts can achieve different kinds of operations with coins and other smart contracts. They're comparable to snack vending machines: +- Each machine has a contract saying "Give me cryptocurrency, then I give you a food item or drink." +- Each machine can have a different smart contract for various food or drink items. +- Other smart contracts can work with the machines behind the scenes, such as a contract that represents an employee gathering the money from the machines. + +Each machine doesn't operate until enough currency is delivered (*Gas*). Note that the quantities of foods or drinks change while their *types* can't (ever). + +Of course, smart contracts go beyond this metaphor. Thanks to *transparency* and *immutability*, they allow an **agreement** to be secured between two or more parties. + +For example, it is common to create financial instruments like various *tokens* (usually worth a fraction of the blockchain's *coin*) with different usability and characteristics inside a multiple smart contracts system. Other more or less complex projects can propose *lending*, *stablecoins*, or *crowdfunding*. + +In most cases, smart contracts remove intermediates and drastically reduce costs compared to classic paper contracts and their validations. + +Notice that a smart contract can only run and interact with the blockchain it's stored on. It can't interact with the outside world. That's where *decentralized applications* or "dApps" come in ,because they provide interfaces for the outside world. + +## Components of a smart contract + +A smart contract is composed of three elements: + +- Its balance: a contract is a kind of account, and can receive and send tez +- Its [storage](./smart-contracts/storage): data that is dedicated to and can be read and written by the contract +- Its code: one or more [entrypoints](./smart-contracts/entrypoints), which are a kind of function that can be called either from outside the chain or from other contracts + +:::note VisualTez +[VisualTez](https://visualtez.com/editor) allows you to visualize the fundamental logic of a smart contract without relying on any specific syntax. +::: + +## Limitations of smart contracts + +All a contract can do can be summarized as: + +- Performing computations +- Reading or updating the value of its own storage +- Generating a list of operations, such as calls to other contracts (see [Operations](./smart-contracts/logic/operations)) + +Smart contracts can't do these things: + +- Access programs outside the blockchain, including calling external APIs +- Access other contracts' storage +- Change their code +- Catch and respond to errors (see [Handling errors](./smart-contracts/logic/errors)) + +## Smart contract languages + +The code of smart contracts is written in Michelson, a Turing-complete stack-based language that includes common features as well as some very specific blockchain-related features: + +- It doesn’t have variables but can manipulate data directly on a stack, through a set of stack manipulation instructions. For example, the _ADD_ instruction consumes two elements from the top of the stack and puts their sum on top of the stack. +- It is strongly typed, with basic types such as integers, amounts of tez, strings, account addresses, as well as pairs, lists, key-value stores (big-maps), or pieces of code (lambdas). +- It has limited access to data, and can only read data from its own storage, data passed as parameters during calls to its entrypoints, and a few special values such as the balance of the contract, the amount of tez sent to it during a call, and the creation time of the current block. It can also access a table of constants. + +Tezos has several popular high-level languages which offer more approachable syntaxes and a more familiar developer experience (e.g. local variables) compared to writing Michelson directly. While Michelson is the domain-specific smart contract language that was developed for Tezos, SmartPy and LIGO are the most popular and widely-supported languages for writing Tezos smart contracts. + +For more information about smart contract languages, see [Languages](./smart-contracts/languages). + +## Features of Tezos smart contracts + +Tezos smart contracts support these features: + +- [Storage](./smart-contracts/storage) of data that the contract can read and write to +- [Entrypoints](./smart-contracts/entrypoints) that users can call +- [Data types](./smart-contracts/data-types) from simple to complex and logic that can be used on them, including [Comparing values](./smart-contracts/logic/comparing) and [Loops](./smart-contracts/logic/loops) +- [Operations](./smart-contracts/logic/operations), which are calls to other smart contracts +- [Views](./smart-contracts/views), which expose data to other contracts +- [Handling errors](./smart-contracts/logic/errors), although error handling in Tezos is very different from other platforms +- [Constants](./smart-contracts/constants) that are available to all contracts +- [Sapling](./smart-contracts/sapling), a way to run private transactions + +## Lifecycle of a Tezos smart contract + +Tezos contracts have a two-step lifecycle: + +1. Deployment +2. Interactions through calls + +### Deployment of a Tezos smart contract + +The deployment of a Tezos smart contract is called _origination_. + +When a smart contract is originated, an address and a corresponding persistent storage are allocated to it. The smart contract address is like its identity and where it lives on the ledger. + +After it is deployed, anyone or anything can call the smart contract, including contracts on the chain and applications off the chain, by submitting an operation to its address with arguments. This call triggers the execution of the pre-defined instructions in the contract's code. + +The origination of a Tezos smart contract must define: +* A complex parameter type in the low-level Michelson language, which is a list or tuple of each parameter type (see more below with high-level languages) +* The storage type +* The initial value of the storage +* A set of instructions in Michelson + +
+ +After the contract is deployed, it cannot be changed or removed from the blockchain. + + + +### Call of a Tezos smart contract + +A smart contract can be called by a classic account or by a smart contract account. The operation or transaction specifies one or more arguments. In the below example, we increase or decrease a value in the storage: + +
+ +Users can call smart contracts from different platforms, including: + +- The Octez command-line program, which is provided by Tezos to send transactions to Tezos and interact with the chain in other ways, including hosting a node. For more information about the Octez client, see https://tezos.gitlab.io/. +- Remote Procedure Calls (RPCs) via HTTP. +- SDKs such as [Taquito](https://tezostaquito.io/). diff --git a/docs/smart-contracts/constants.md b/docs/smart-contracts/constants.md new file mode 100644 index 000000000..149aee42f --- /dev/null +++ b/docs/smart-contracts/constants.md @@ -0,0 +1,19 @@ +--- +title: Global table of constants +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +Tezos provides a feature that lets user store data in a global table of constants. +This makes it possible to reuse code or data between contracts, and by doing so, reducing the size of these contracts. +It is a write-only key-value store, where anyone can add data as long as they pay for the storage costs. +When you register a piece of data in this table, you obtain its address, which is a Base58-encoded Blake2b hash of the binary serialization of the data. + +The data can then be referenced anywhere in your code. +It can be used to store code, types, or data. + +## Implementation details + +- Michelson: [Global constants](https://tezos.gitlab.io/active/global_constants.html) +- LIGO: [Global constants](https://ligolang.org/docs/protocol/hangzhou#global-constant) +- Archetype: [Global constants](https://archetype-lang.org/docs/cli/contract/) diff --git a/docs/smart-contracts/data-types.md b/docs/smart-contracts/data-types.md new file mode 100644 index 000000000..4e9a11301 --- /dev/null +++ b/docs/smart-contracts/data-types.md @@ -0,0 +1,13 @@ +--- +title: Data types +authors: 'Tim McMackin' +lastUpdated: 12 October 2023 +--- + +See these pages for information about the data types that Tezos supports: + +- [Primitive data types](./data-types/primitive-data-types) +- [Complex data types](./data-types/complex-data-types) +- [Cryptographic data types](./data-types/crypto-data-types) + +Higher-level languages may treat data types differently, but they all behave the same way when they are compiled to Michelson and run on Tezos. diff --git a/docs/smart-contracts/data-types/complex-data-types.md b/docs/smart-contracts/data-types/complex-data-types.md new file mode 100644 index 000000000..aa4f3c2c8 --- /dev/null +++ b/docs/smart-contracts/data-types/complex-data-types.md @@ -0,0 +1,457 @@ +--- +title: Complex data types +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +Tezos contracts support these complex data types. +The high-level languages may implement these data types slightly differently, but they all behave the same way in the compiled Michelson code: + +- [Pairs](#pairs) +- [Records](#records) +- [Options](#options) +- [Big-maps and maps](#big-maps) +- [Lists](#lists) +- [Sets](#sets) +- [Variants and Unions](#variants) +- [Lambdas](#lambdas) +- [Tickets](#tickets) + +## Pairs {#pairs} + +A pair is a complex type made of two other types. +For example, a pair of an `int` and a `string` can hold a value such as `(42, "Hello")`. +Languages have instructions to create pairs and to extract the left or right value from a pair. + +Pairs can be nested, which makes it possible to create more complex structures with many values of different types. +The two main ways to nest pars is by using right combs or binary trees: + +### Right combs + +The most common way to nest pairs on Tezos is to create a right comb. +A right comb is a pair whose second element is a pair, whose second element is a pair, and so on. + +For example, this right comb stores an int, a string, and a bool using nested pairs: `{-42; {"Hello"; True}}`. + +To add another unit, the right value of the most nested pair becomes a pair, as in this example: `{-42; {"Hello"; {True; 21}}}`. + +This is a way to create a Tuple (a sequence of elements of different types) using only pairs. +Because right combs are used often in Michelson, there are shorter ways to express them. +For example, the notation `{42; "Hello"; True; 21}` is equivalent to `{-42; {"Hello"; {True; 21}}}`. + +### Binary trees + +Another way to use pairs to combine multiple values is to use a binary tree layout. +In this layout, both sides of the main pair contain a pair, then both sides of these pairs contain pairs, and so on. + +Here is an example of a binary tree: `{{-42; "Hello"}; {True; 21}}` + +The binary tree layout is be more efficient than a right comb when accessing arbitrary elements. +For example, to access the last element, you can get the second element of the main pair (`{True; 21}`) and the second element of that pair (`21`). +If the tree is balanced, the number of operations to get to any element is +$$O(\log_2 (size))$$, whereas for a right comb, it's $$O(size)$$. + +### Implementation details + +- Michelson: [Operations on pairs and right combs](https://archetype-lang.org/docs/reference/instructions/operation) +- LIGO: [Tuples](https://ligolang.org/docs/language-basics/sets-lists-tuples#tuples) +- SmartPy: [Tuples and Records](https://smartpy.io/manual/syntax/tuples-and-records) +- Archetype: [Composite types](https://archetype-lang.org/docs/language-basics/composite#tuple), [Tuple](https://archetype-lang.org/docs/reference/types#tuple) + +## Records {#records} + +To make it easier to create type that combine multiple elements, high-level languages provide the `record` data type. +The `record` data type assigns a name to each element, which makes it much easier to get the element that you need because you don't have to remember the location of the element in the data. +Records are similar to Python dictionaries and JavaScript objects. + +Different high-level languages represent records in different ways, but here is a simple abstract representation of a record definition: + +```bash +type person: record + - age: nat + - name: string + - registered: bool +``` + +Here is an abstract example of a value of that record type: + +```bash +person: record + - age: 21 + - name: "Laura" + - registered: True +``` + +When you compile the high-level code, Michelson represents records with nested pairs and annotations. + + +In most cases, you can nest records. +For example, if you have a record type named "address," you can add it as an element to the previous record like this: + +```bash +type person: record +- age: nat +- name: string +- registered: bool +- homeAddress: record + - number: nat + - street: string + - city: string + - zipcode: nat + - country: string +``` + +### Implementation details + +- Archetype: [Record](https://archetype-lang.org/docs/language-basics/composite#record) +- LIGO: [Records](https://ligolang.org/docs/language-basics/maps-records#records) +- SmartPy: [Tuples and Records](https://smartpy.io/manual/syntax/tuples-and-records) + +## Options {#options} + +Options represent a value that may or may not be defined. +Primitive types do not provide the possibility of a null or empty value; for example, an `int` type must always contain a number. +If you want to include the possibility that a value is unknown, undefined, or nonexistent, you can make a type into an option. +For example, an option based on an `int` type can hold a number or no value at all. +You can create an `option` type based on almost any other type. + +For example, an `option` type based on an `int` is denoted as `option` and can contain these values: + +- An `int` value, represented as `Some(42)` +- No value, represented as `None` + +Each time that you manipulate the value within an `option` you must check if it contains a value or not. + +The features available for options are: + +- Creating an option that contains a given value (`SOME`) +- Creating an option that contains nothing (`NONE`) +- Testing if an option contains something or none (`IF_NONE`) +- Getting the value contained in an option (`IF_NONE`) + +### Using options instead of failures + +Options are used for operations that can't always provide a result, which allows the code to handle the situation without failing and leads to good programming practice. + +Here are a few examples where an `option` is used: + +- Converting an `int` to a `nat` returns an `option`, which is `None` if the `int` is negative +- Dividing (`EDIV`), returns `None` when trying to divide by zero +- Extracting a portion of a `string` or a `bytes` value returns `None` if the extract is beyond the bounds of the value +- Fetching a value for a given key in a `big-map` or `map` returns `None` if the entry doesn't exist +- Fetching the contract that corresponds to an `address` returns `None` if the `address` is not a contract +- Unpacking `bytes` returns `None` if the data is not valid + +### When not to use options + +Using an `option` is convenient when you need it, but it makes the corresponding code harder to write and read and slightly slower and more costly. + +When a value may be undefined only at the initial contract deployment, it may be more convenient and efficient to initialize the value instead of making it an option, as in these examples: + +- For a `timestamp`, consider initializing it with epoch: January 1st, 1970. +- For an `address`, consider initializing it with the address of the owner of the contract. +Alternatively (but harder to understand without comments), you can use the special null address, `"tz1burnburnburnburnburnburnburjAYjjX"`, which does not correspond to an actual account + +### Implementation details + +- Michelson: [Operations on optional values](https://tezos.gitlab.io/active/michelson.html#operations-on-optional-values) +- LIGO: [Optional values](https://ligolang.org/docs/language-basics/unit-option-pattern-matching#optional-values) +- SmartPy: [Options](https://smartpy.io/docs/types/options/) +- Archetype: [Options](https://archetype-lang.org/docs/reference/types#option%3CT%3E) + +## Big-maps and maps {#big-maps} + +Smart contracts often need to store a database of records where each record is identified by a key and can be fetched quickly. + +For example, an NFT contract may store a database of NFTs, each identified by a unique numeric ID. +For each NFT it stores metadata, such as the current owner. + +A `big-map` is a key-value store that associates values to different keys. +This example big-map uses `int` and `string` types to associate numbers with their names: + +```bash +{ + Elt 1 "One"; + Elt 3 "Three"; + Elt 12 "Twelve"; + Elt 24 "Twenty four" +} +``` + +The main operations available for `big-maps` are: + +- Creating an empty `big-map` (`EMPTY_BIG_MAP`) +- Checking if there is an entry for a given key (`MEM`) +- Accessing the entry associated with a given key (`GET`) +- Assigning an entry to a given key (`UPDATE`) +- Deleting the entry for a given key (`UPDATE`) + +### Big-maps vs maps + +Big-maps are a special type of `map` type that is optimized so that it can contain very large amounts of data without necessarily causing issues with gas limits. +This is because the content of a big-map is lazily deserialized; only the entries that are manipulated by a contract are deserialized/reserialized, as opposed to maps and all the other data types, where all of the content is deserialized/reserialized for each call of the contract. + +This makes big-maps more useful in practice than maps, because using maps can quickly cause gas consumption issues if the number of entries gets large. + +Maps support all the features of big-maps plus these: + +- Iterating through each element of the map, and applying some code to it (`ITER`) +- Getting the size (number of elements) of the map (`SIZE`) + +Furthermore, unlike big-maps, maps can be passed as parameters and included in records or big-maps. +You cannot pass big-maps as parameters or include them in records because doing so would require manipulating the serialized content of the big-map and defeat the purpose of big-maps. + +In general, developers use big-maps unless there is a good reason to use maps because big-maps. +If you choose to use a map, take precautions and optimize your code. + +### Example contract using big-maps + +Here is a table representing an example of a contract that uses two big-maps: + +{ + + + + + + + + + + + + +
StorageEntrypoint effects
+
    +
  • nextID: int:
  • +
  • tokens: big-map:
      +
    • tokenID: int
    • +
    • owner: address
    • +
    • author: address
    • +
    • metadata: string
    • +
    • price: tez
    • +
    +
  • +
  • ledger: big-map +
      +
    • key: address
    • +
    • value: tez
    • +
    +
  • +
+
+
    +
  • buy(tokenID) +
      +
    • Checks that tokens[tokenID] exists
    • +
    • Check that the amount transferred is correct
    • +
    • Send 5% of the price to the author of the token
    • +
    • If ledger[owner] doesn’t exist, create it with value=0
    • +
    • Add the price minus 5% to ledger[owner].value
    • +
    • Replace owner with the caller in the token metadata
    • +
    • Increase price by 10% in the token
    • +
    +
  • +
  • mint(metadata, price) +
      +
    • Create a new entry in tokens, with key nextID
    • +
    • Set owner and author to the address of the caller
    • +
    • Set metadata and price to input values
    • +
    • Increment nextID
    • +
    +
  • +
  • claim() +
      +
    • Verify that ledger[caller] exists
    • +
    • Create a transaction to send ledger[caller].value to caller
    • +
    • Delete ledger[caller]
    • +
    +
  • +
+
} + +### Implementation details + +- Michelson: [Operations on big-maps](https://tezos.gitlab.io/active/michelson.html#operations-on-big-maps) +- Archetype: [Assets](https://archetype-lang.org/docs/reference/instructions/asset), [Map](https://archetype-lang.org/docs/language-basics/container#map) +- LIGO: [Maps](https://ligolang.org/docs/language-basics/maps-records#maps), [Big-maps](https://ligolang.org/docs/language-basics/maps-records#big-maps) +- SmartPy: [Maps and big-maps](https://smartpy.io/manual/syntax/lists-sets-and-maps#maps) + +## Lists {#lists} + +Lists can store and iterate through values of the same type. +For example, they can do these operations: + +- Inserting an element at the beginning of a list (`CONS`) +- Getting the first element and the rest of a list (`IF_CONS`) +- Iterating through a list (`ITER`) +- Getting the number of items in a list (`SIZE`) + +:::note High-level language list methods +Some high level languages may offer additional features such as getting an extract of a list. +Refer to the language documentation to see what is supported. +::: + +:::warning List security considerations +To prevent attacks, make sure that the number of elements in a list can't be increased arbitrarily. +An attacker could make the list increase and cause problems. +In general, use big-maps to store large amounts of data. +::: + +### Implementation details + +- Michelson: [Operations on lists](https://tezos.gitlab.io/active/michelson.html#operations-on-lists) +- SmartPy: [Lists](https://smartpy.io/manual/syntax/lists-sets-and-maps#lists) +- Archetype: [List](https://archetype-lang.org/docs/language-basics/container#list) +- LIGO: [List](https://ligolang.org/docs/reference/list-reference) + +## Sets {#sets} + +Like lists, sets contain elements of the same data type, but in sets, each element can be present only once. +Sets are ordered, and the order is the natural order of the values in the set; see [Comparing values](../logic/comparing). + +The main operations available on sets are: + +- Creating an empty set (`EMPTY_SET`) +- Adding an element to the set (`UPDATE`) +- Removing an element from the set (`UPDATE`) +- Checking if an element is present in the set (`MEM`) +- Iterating through the set in the order of the value of the elements (`ITER`) +- Getting the number of items in the set (`SIZE`) + +### Implementation details + +- Michelson: [Operations on sets](https://tezos.gitlab.io/active/michelson.html#operations-on-sets) +- Archetype: [Set](https://archetype-lang.org/docs/language-basics/container#set) +- SmartPy: [Sets](https://smartpy.io/manual/syntax/lists-sets-and-maps#sets) +- LIGO: [Set](https://ligolang.org/docs/reference/set-reference) + +## Variants and Unions {#variants} + +A variant (or union) can hold values of multiple types. +For example, a variant can hold either an `int` or a `string`. + +- When you use a variant, you can check which of the types it holds and run corresponding code. +- Variants are used internally as a way to implement entrypoints +- Some high-level languages use variants to implement enumerations, which is a type that has a list of valid named values. + +### Implementation details + +- Michelson: [Operations on unions](https://tezos.gitlab.io/active/michelson.html#operations-on-unions) +- LIGO: [Variant types](https://ligolang.org/docs/language-basics/unit-option-pattern-matching#variant-types) +- SmartPy: [Variants](https://smartpy.io/manual/syntax/options-and-variants#variants) +- Archetype: [Enum](https://archetype-lang.org/docs/language-basics/composite#enum) + +## Lambdas {#lambdas} + +A lambda is a piece of code that is also a value. +It can be stored or passed as a parameter to an entrypoint. + +The code of a lambda takes parameters and returns a value but it has no side effects. +Unlike other code, it doesn't have access to the contract storage and cannot modify the storage. + + +Here are some common uses for lambdas: + +- Lambdas allow you to reuse code in multiple places when the language does not support reuse. +In high-level languages, you can reuse code with functions or similar structures, but in Michelson, you may need to use a lambda for the same purpose. +- Lambdas can make parts of a contract upgradeable. +For example, the contact can store some of its logic in a lambda and an admin can call an entrypoint to change the lambda to change how the contract works. +Note that the ability to upgrade the contract can cause users to worry about the trustworthiness of the contract. +- You can use lambdas to implement a generic multi-sig or DAO contract where a proposal takes the form of a lambda that performs some action and people vote on whether to execute the action or not. + +### Implementation details + +- Michelson: [Control structures](https://tezos.gitlab.io/active/michelson.html#control-structures) +- Archetype: [apply_lambda](https://archetype-lang.org/docs/reference/expressions/builtins#apply_lambda%28f%20:%20lambda%3CA%20*%20T,%20R%3E,%20x%20:%20A%29) +- SmartPy: [Lambdas](https://smartpy.io/manual/syntax/lambdas) +- LIGO: [Anonymous functions](https://ligolang.org/docs/language-basics/functions#anonymous-functions-aka-lambdas) +- [Simplified DAO contract](https://opentezos.com/smart-contracts/simplified-contracts/#dao-decentralized-autonomous-organization) + +## Tickets {#tickets} + +A ticket is a data type that includes security mechanisms that make it suitable for issuing new tokens or granting portable permissions. +Tickets cannot be duplicated, so a single contract is always in control of a ticket. +In this way, a ticket can represent control over something or permission to do something. + +A ticket contains three pieces of information: + +- The address of the contract that created it, called the _ticketer_ +- Some data with a type and value assigned by the contract, called the _wrapped value_ or the _payload_ of the ticket +- An amount in the form of a natural number + +Tickets have a type, which is based on the type of the data. +For example, a ticket with a payload of a string value is referred to as a "string ticket." + +The ticket's information is public and can be read by any contract that holds the ticket. + +### Passing tickets + +Contracts can pass tickets to entrypoints to change which contract is in control of the ticket. +If contract A passes a ticket to contract B, contract A loses all access to the ticket. +Contracts can pass tickets only to other contracts (implicit accounts) because the entrypoint must accept a ticket of the correct type; contracts cannot pass tickets to user accounts. + +### Ticket features + +There are three main features at the core of tickets, each associated with one of its three pieces of information: + +#### Guaranteed origin + +The ticketer address always refers to the contract that created the ticket. +Contracts can't change the ticketer address or create tickets that reference other contracts as the creator. + +#### Immutability of the wrapped value + +The data stored in a ticket (the wrapped value) can't be changed after the creation of the ticket, even by the contract that created it. + +#### Splitting and joining tickets + +The contract that creates the ticket sets the initial amount to any natural number. +From then on, contracts that control tickets can change them in the following ways: + +- `SPLIT_TICKET`: A contract splits a ticket into two tickets. +Both new tickets have the same ticketer address and payload, but the amount of the initial ticket is split between the two. +The initial ticket is destroyed. +- `JOIN_TICKETS`: A contract merges two tickets into a single ticket. +The tickets must have the same ticketer address and payload. +The new ticket has the same ticketer address and payload as the originals, and its amount is the sum of the amounts of the joined tickets. +The two initial tickets are destroyed. + +For example, a contract can create a single ticket with a large amount and send it to another contract. +The other contract can split the ticket and send the resulting tickets to other contracts, which can split and join the ticket. +Eventually, many contracts may have a ticket that was split from the original or one of its descendants. +The ticketer address and payload stays the same for all of these tickets and the sum of the amounts is always the same as the amount of the original ticket. + +:::note Differentiating tickets +Because the only identifying information of a ticket is the address of the contract that created it and its payload, it is possible to create multiple indistinguishable tickets. +For example, a contract can create multiple tickets with the same payload. +After other contracts split and join these tickets, there is no on-chain way to tell which descendant ticket can from which original ticket. +For this reason, your code should verify the address of the contract that mints tickets before trusting them. +::: + +### Benefits of tickets used as tokens + +The key benefit of `tickets` is that they continue existing independently of the contract that issued them. +This is very different from how tokens are usually managed, such as tokens that use the FA 1.2 or FA 2 standards. +Such tokens are fully under the control of the issuing contract; for example, transferring such a token may only be done by calling the smart contract that issued it. +Wrapping can be used as a way to work around this, but this is not technically transferring the token itself. +This helps bring extra trust in the value of the tokens represented by tickets, because there is no risk of the tokens suddenly becoming unusable if the issuing contract fails. +Tickets increase the decentralization of tokens and make them behave more like the native tez token, but with many more features and additional trust. + +### Operations on tickets + +Contracts can run these operations on tickets: + +- Creating a new ticket with a given content and amount, and the current contract as the ticketer (`TICKET`) +- Reading a ticket, which returns the three values contained in the ticket plus the ticket itself (`READ_TICKET`) +- Splitting a ticket into two tickets with the same content and ticketer, but splitting the amount (`SPLIT_TICKET`) +- Joining two tickets that have the same content and ticketer into a new ticket with the sum of the amounts (`JOIN_TICKETS`) + +### Implementation details + +- Michelson: [Operations on tickets](https://tezos.gitlab.io/active/michelson.html#operations-on-tickets) +- LIGO: [Tickets](https://ligolang.org/docs/reference/current-reference#tickets) +- Archetype: [create_ticket and related](https://archetype-lang.org/docs/reference/expressions/builtins/#create_ticket%28s%20:%20T,%20n%20:%20nat%29) +- SmartPy: [Tickets](https://smartpy.io/manual/syntax/tickets) diff --git a/docs/smart-contracts/data-types/crypto-data-types.md b/docs/smart-contracts/data-types/crypto-data-types.md new file mode 100644 index 000000000..10e11a7f0 --- /dev/null +++ b/docs/smart-contracts/data-types/crypto-data-types.md @@ -0,0 +1,100 @@ +--- +title: Cryptographic data types +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +Tezos provides hash functions for cryptographic purposes. + +By default, use `BLAKE2B`, which computes a cryptographic hash of the value contents using the Blake2b-256 cryptographic hash function. + +These other hash functions are available: + +- `KECCAK`: Compute a cryptographic hash of the value contents using the Keccak-256 cryptographic hash function. +- `SHA256`: Compute a cryptographic hash of the value contents using the Sha256 cryptographic hash function. +- `SHA512`: Compute a cryptographic hash of the value contents using the Sha512 cryptographic hash function. +- `SHA3`: Compute a cryptographic hash of the value contents using the SHA3-256 cryptographic hash function. + +## Checking signatures + +Tezos lets you check that a given piece of data, a sequence of bytes in a `bytes` data type, has been signed by the holder of the private key corresponding to a given public key. + +The primitive `CHECK_SIGNATURE` takes as parameters the sequence of bytes, the `signature` and the `public key`, and returns a Boolean that indicates if the `signature` is indeed a `signature` of that sequence of bytes, by the holder of ths key. + +## BLS12-381 primitives + +BLS12-381 is the name of an elliptic curve, a cryptographic primitive that can be used for digital `signatures` and zero-knowledge proofs. + +It has the particularity of being pairing-friendly, which makes it possible to create short digital `signatures` that can be efficiently aggregated. +It can also be used for identity-based cryptography, single-round multi-party key exchanges, or and efficient polynomial commitment schemes such as KZG commitments. + +## Implementation details + +- Michelson: [Cryptographic primitives](https://tezos.gitlab.io/active/michelson.html#cryptographic-primitives), [BLS12-381 primitives](https://tezos.gitlab.io/active/michelson.html#bls12-381-primitives) +- LIGO: [Crypto](https://ligolang.org/docs/reference/crypto-reference) +- Archetype: [Blake2b and related](https://archetype-lang.org/docs/reference/expressions/builtins#blake2b%28b%20:%20bytes%29), [Elliptic curves](https://archetype-lang.org/docs/language-basics/crypto#elliptic-curves) +- SmartPy: [Cryptography](https://smartpy.io/manual/scenarios/cryptography#cryptography) +- Taquito: [Signing data](https://tezostaquito.io/docs/signing/) + +## Timelocks + +A `timelock` is a cryptographic primitive that can be used as part of a **commit & reveal** scheme, to provide a guarantee that the information associated to the commit is eventually revealed. + +### Classical commit & reveal scheme + +Commit & reveal is a scheme that consists of two steps, involving one or more participants: + +- Before a set deadline, each participant makes a decision and publishes a commitment, which is a proof that they have taken a decision that they won't be able to change. +The proof often takes the form of a hash of the data that corresponding to the decision. +- After the deadline, each participant reveals the data corresponding to their commitment. +Other participants can check that the hash of this data indeed corresponds to their previous commitment. + +This scheme makes it possible to prove that a certain decision was taken before some information was revealed. +This information may be the decision of other participants, or some external independent information. + +As an example, imagine that two players want to play the game [rock, paper, scissors](https://en.wikipedia.org/wiki/Rock_paper_scissors) via a smart contract. +As it is impossible to force and verify that the two players reveal their choice between rock, paper or scissors simultaneously, they can use a commit & reveal scheme to do so. + +During the first step, they pick their choice, identified by a number from 1 to 3, put it in a pair with some random data, compute a hash of the result. +This hash is the commitment that they can then send to the contract. + +After both players have sent their commitment, they can reveal by sending the actual data to the contract including the random data. +The contract can verify that the hash of this data matches the previous commitment. +When the two players have revealed their data, the smart contract determines the outcome of the game and distributes rewards accordingly. + +### Not revealing + +One issue with the classical commit & reveal scheme is that after the first step is closed and some information is revealed, one participant may find it advantageous to not reveal at all. +Why reveal if it will only make you lose? For some use cases, this can ruin the whole process. + +One way to address this problem is by setting a financial incentive, such as tokens that people deposit along with their commitments. +After they reveal, they get the tokens back, which encourages them to reveal. + +### Forcing the reveal with a time lock + +In some cases, a financial incentive is not enough by itself. +For example, the benefit of not revealing may outweigh the benefit of revealing, or multiple participants may collaborate and decide not to reveal. + +In this case, you can use a time lock to produce a commitment and force the reveal. + +In this case, instead of using a hash, the data is encrypted using an encryption method that can be cracked with a known algorithm. +The amount of time that it takes to crack the encryption is bounded, which provides a time limit. + +The algorithm used to crack it can't be parallelized, which means there is a limit to how much computing power can be applied to it. +You can estimate the time that it takes for an ordinary computer to crack it and for the fastest possible dedicated hardware to crack it. +Then you can set the time limit by setting the number of iterations in the data encryption. + +For example, assume that you encrypt data in a time lock that you know takes between 10 minutes and 10 hours to decrypt, depending on the hardware. +You can use a commit phase that takes less than 10 minutes, which is not enough time to crack the encryption, so no one can decrypt anyone's commitment. +Then you can use a reveal phase that gives the participants a few minutes to reveal their data. +If a participant doesn't reveal, you can provide a financial reward (funded by the non-revealed participants' deposits) to anyone else to crack the encryption and reveal the data. + +Because it's possible to reveal the data eventually, all participants have an incentive to reveal because they will eventually lose their deposit when someone else cracks and reveals the data. +In this way, time locks work as a deterrent; in practice, participants nearly always reveal rather than forcing someone else to crack the encryption. + +Some use cases involve collectively generating a random value or preventing [BPEV attacks](https://opentezos.com/smart-contracts/avoiding-flaws/#6-not-protecting-against-bots-bpev-attacks). + +## Implementation details + +- Michelson: [Operations on timelock](https://tezos.gitlab.io/active/michelson.html#operations-on-timelock) +- Archetype: [Timelock](https://archetype-lang.org/docs/language-basics/crypto#timelock) diff --git a/docs/smart-contracts/data-types/primitive-data-types.md b/docs/smart-contracts/data-types/primitive-data-types.md new file mode 100644 index 000000000..3074a2f3d --- /dev/null +++ b/docs/smart-contracts/data-types/primitive-data-types.md @@ -0,0 +1,182 @@ +--- +title: Primitive data types +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 4th October 2023 +--- + +Tezos contracts support these primitive data types. +The high-level languages may implement these data types slightly differently, but they all behave the same way in the compiled Michelson code: + +- [Numeric data types: `int` and `nat`](#numeric) +- [Token amounts: `mutez` and `tez`](#token-amounts) +- [Strings](#strings) +- [Bytes](#bytes) +- [Booleans](#booleans) +- [Timestamps](#timestamps) +- [Addresses](#addresses) + +## Numeric data types: `int` and `nat` {#numeric} + +Integers (`int`) are whole numbers that can be positive or negative. + +Naturals (`nat`) are whole numbers that can only be positive or zero. + +Tezos differentiates these two types to prevent problems such as performing operations that may not always return a positive number. + +On Tezos, there is no hard limit to how large `nat` and `int` values can be. +The only limits are those associated with the storage and gas costs. +This means you never need to worry about overflow issues. + +You can perform these ordinary arithmetic operations on `int` and `nat` or a mix of the two: + +- Getting the opposite of a number (`NEG`) +- Adding (`ADD`), subtracting(`SUB`) or multiplying (`MUL`) two values +- Performing an integer division between two values (`EDIV`), which returns a pair with the result and the remainder + +The type of the output may not be the same type as the inputs. +In general, the output type depends on whether the result can be negative. +For example, subtraction always returns an `int`, but addition returns a `nat` if both inputs are `nat` and an `int` if either input was an `int`. + +You can perform bitwise logical operations: the usual `OR`, `AND`, `XOR`, `NOT`. + +You can also perform bitwise left and right shifts (`LSL` and `LSR`), with a parameter that indicates by how many bits you shift the value. + +For information about comparing values, see [Comparing values](../logic/comparing). + +Finally, you can convert an `int` to a `nat` or vice versa: + +- To convert an `int` to a `nat`, use the absolute value function (`ABS`). +- To convert a `nat` into an `int`, use the `INT` function. + +You can also convert an `int` to an `option` on a `nat` (ISNAT). + + +### Why are decimal numbers not supported? + +Tezos does not support floating point or decimal numbers. +These kinds of numbers and their associated rounding errors cause many problems. + +For example, Tezos protocol upgrades could cause inconsistencies with floating point numbers. +If this happens, different nodes may get different results for the same transactions, which would lead to inconsistencies on the blockchain. +Also, code that uses floating point numbers is much harder to run formal verification on. + +## Token amounts: `mutez` and `tez` {#token-amounts} + +The `mutez` type (or micro tez) stores amounts of tokens from the native cryptocurrency of Tezos, the tez. +One mutez is equal to one millionth of a tez. + +Some languages also support the `tez` type, but the internal type is always the mutez, so you can see a value of type tez as a shortcut for the corresponding value in `mutez`. + +`mutez` values, like `nat` values, are whole non-negative numbers. +However, contrary to `nat`, they can't hold arbitrarily large values. + +More precisely, `mutez` are stored as signed 64 bit values. +This means their value can only be between $$0$$ and $$2^{63} - 1$$, which is approximately $$9.223 \cdot 10^{18}$$ `mutez`, and corresponds to 9 trillion tez. + +Although it is rare to work with mutez amounts this large, there is still a risk of overflow. +For example, if code performs intermediate computations such as squaring a number, it might reach the storage limit. + +You can do these arithmetic operations on `mutez`: + +- Adding two mutez values (`ADD`) +- Subtracting two `mutez` values (`SUB_MUTEZ`), which returns an `option` because the result could be negative +- Multiplying a `mutez` value with a `nat` (`MUL`), which returns a result in `mutez` +- Performing an integer division (`EDIV`) + +For information about comparing values, see [Comparing values](../logic/comparing). + +## Strings {#strings} + +On Tezos, a `string` is a sequence of standard non-extended [ASCII](https://en.wikipedia.org/wiki/ASCII) characters. +This means there are only 128 possible values for each character, which excludes any accented letters. +This limited list of characters prevents compatibility issues with unicode characters. +If you need to store unicode text, store it as [bytes](#bytes). + +Like `int` and `nat`, there is no limit on the size of a `string` other than the indirect limits caused by the associated costs of storage. + +You can do these operations on strings: + +- Concatenate two `string` types (`CONCAT`) +- Get the size of a `string` (`SIZE`), which returns a `nat` +- Extract a substring of a `string` (`SLICE`) +- Compare two `string` types based on their lexicographical order; see [Comparing values](../logic/comparing) + +## Bytes {#bytes} + +You can store any piece of information as a sequence of `bytes`. +This type has no limits on its size other than the indirect limits caused by the associated costs. + +`bytes` have the same operations as `strings`: + +- Concatenate two `bytes` types (`CONCAT`) +- Get the size of a `bytes` (`SIZE`), which returns a `nat` +- Extract a substring of a `bytes` (`SLICE`) +- Compare two `bytes` types based on their lexicographical order; see [Comparing values](../logic/comparing) + +To save space, you can store most other data types in a `bytes` type. +To convert + +Furthermore, `bytes` can be used to store values of most other valid types in an optimized binary representation. +To convert values to and from `bytes`, use these functions: + +- To convert any value of a supported type to `bytes`, use `PACK` +- To convert `bytes` to the encoded type, use `UNPACK` + +Serialization is also useful in applying cryptographic functions to data, as in these examples: + +- Computing a cryptographic hash of some data using one of several hash functions, such as `Blake2b-256` +- Checking that a sequence of `bytes` has been signed with a given key +- Applying elliptic-curve cryptographic primitives (`BLS12-381`) + +For more information about serialization, see [Serialization](../serialization). + +`bytes` are also used in [Sapling](../sapling). + +## Booleans {#booleans} + +Boolean types on Tezos (`bool`) work the same way as in most programming languages. + +- A boolean value can be `True` or `False` +- Comparison operators produce boolean values +- Boolean values can be used in conditional statements or `while` loops +- The usual logic operators are supported: `AND`, `OR`, `XOR`, `NOT` + +## Timestamps {#timestamps} + +Dates are very important in smart contracts, such as verifying that a call is made before or after a given deadline. + +The `timestamp` type represents the number of seconds since January 1st, 1970, also known as UNIX time. +Internally, timestamps are stored as an `int`, so like `int` types, timestamps can have arbitrarily large positive or negative numbers, representing times long before or after January 1st, 1970. + +The special instruction `NOW` represents the timestamp of the current block. + +The following operations are supported on timestamps: + +- Adding a number of seconds to a `timestamp` (`ADD`) +- Subtracting a number of seconds from a `timestamp` (`SUB`) +- Computing the difference in seconds between two `timestamp` values (`SUB`) +- Comparing two `timestamps` (`COMPARE`); see [Comparing values](../logic/comparing) + +## Addresses {#addresses} + +On Tezos, each account is uniquely identified by its `address`, whether it is a user account (implicit account) or a contract (originated account). + +Internally, addresses take the form of a `string` type. +For implicit accounts, the string starts with "tz1", "tz2", "tz3" or "tz4". +For originated accounts, the string starts with "KT1". + +| Type of Account | Example | +| --- | --- | +| Implicit Account | `tz1YWK1gDPQx9N1Jh4JnmVre7xN6xhGGM4uC` | +| Originated Account | `KT1S5hgipNSTFehZo7v81gq6fcLChbRwptqy` | + +The next part of the string is a `Base58` encoded hash, followed by a 4-byte checksum. + +## Data type implementations + +See these links for technical information about how different languages handle different data types: + +- Michelson: [int and nat](https://tezos.gitlab.io/active/michelson.html#operations-on-integers-and-natural-numbers), [booleans](https://tezos.gitlab.io/active/michelson.html#operations-on-booleans), [strings](https://tezos.gitlab.io/active/michelson.html#operations-on-strings), [timestamps](https://tezos.gitlab.io/active/michelson.html#operations-on-timestamps), [mutez](https://tezos.gitlab.io/active/michelson.html#operations-on-mutez). +- Archetype: [Types basics](https://archetype-lang.org/docs/language-basics/types), [Types](https://archetype-lang.org/docs/reference/types), [Arithmetic operators](https://archetype-lang.org/docs/reference/expressions/operators/arithmetic) +- SmartPy: [Integers and mutez](https://smartpy.io/manual/syntax/integers-and-mutez), [Booleans](https://smartpy.io/manual/syntax/booleans), [Strings and Bytes](https://smartpy.io/manual/syntax/strings-and-bytes), [Timestamps](https://smartpy.io/manual/syntax/timestamps) +- LIGO: [numbers and tez](https://ligolang.org/docs/language-basics/math-numbers-tez), [strings & bytes](https://ligolang.org/docs/language-basics/strings-bytes), [booleans](https://ligolang.org/docs/language-basics/boolean-if-else) diff --git a/docs/smart-contracts/delegation.md b/docs/smart-contracts/delegation.md new file mode 100644 index 000000000..07eb438ca --- /dev/null +++ b/docs/smart-contracts/delegation.md @@ -0,0 +1,22 @@ +--- +title: Delegation +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +Placing your tez in a smart contract means you can't stake them towards baking or delegate them to get rewards. +However, the smart contract itself can delegate the tez it holds and distribute the rewards to the original owners of the tez or keep them in its balance. + +To manage delegation, you can implement these features: + +- Set, update, or remove the address of the baker that you want the contract to delegate its tez to (`SET_DELEGATE`). +- Obtain the voting power of a contract (a delegate), which is based on its total staking balance as computed at the beginning of the voting period (`VOTING_POWER`). +- Obtain the total voting power of all contracts (`TOTAL_VOTING_POWER`). + +In practice, both the voting power of a contract and the total voting power of all contracts are expressed as a number of mutez, but this may change with time as the protocol evolves. + +## Implementation details + +- Michelson: [Operations on contracts](https://tezos.gitlab.io/active/michelson.html#operations-on-contracts) +- Archetype: [Total voting power](https://archetype-lang.org/docs/reference/expressions/constants#total_voting_power), [Voting power](https://archetype-lang.org/docs/reference/expressions/builtins#voting_power%28k%20:%20key_hash%29), [set_delegate](https://archetype-lang.org/docs/reference/expressions/builtins#set_delegate%28opkh%20:%20option%3Ckey_hash%3E%29) +- SmartPy: [Operations](https://smartpy.io/manual/syntax/operations) diff --git a/docs/smart-contracts/entrypoints.md b/docs/smart-contracts/entrypoints.md new file mode 100644 index 000000000..5531c6202 --- /dev/null +++ b/docs/smart-contracts/entrypoints.md @@ -0,0 +1,90 @@ +--- +title: Entrypoints +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 4th October 2023 +--- + +The entrypoints of a contract represent the different ways that it can be called, similar to a method or function in many programming languages or an endpoint of an API. +The entrypoints in a Tezos smart contract must meet these specifications: + +- Contracts must have at least one entrypoint. +- Each entrypoint must have a name. +- Entrypoints may accept parameters, which can be of almost any data type that Tezos supports. + +Unlike functions and API endpoints, entrypoints do not return a value. +To return a value from a smart contract, see [Views](./views). + +For examples of contracts, see [Examples of contracts](https://opentezos.com/smart-contracts/simplified-contracts/) on opentezos.com. + +## Entrypoint logic + +An entrypoint may run all kinds of logic based on: + +- Its storage +- The parameters that senders pass +- Global values such as the address of the caller +- The table of constants + + +Entrypoints may not access information outside Tezos, such as calling external APIs. +If an entrypoint needs information from outside Tezos it must use oracles; see [Using and trusting Oracles](https://opentezos.com/smart-contracts/oracles/) on opentezos.com. + +The only effects that an entrypoint can have are changes to its storage and new transactions that are run after the entrypoint completes. +For example, an entrypoint can call other entrypoints in its contract or entrypoints in other contracts. + +## Example entrypoints + +Here is a very basic example of contract with two entrypoints: + +| Entrypoint | Description | +| --- | --- | +| `add` | `add` takes an `int` as a parameter and adds it to the previous value of the storage | +| `reset` | `reset` takes no parameter and replaces the storage with 0 | + + + + + + + + +## Entrypoint implementation + +Internally, entrypoints are implemented using a variant data type. +The contract contains a single piece of logic that branches based on the value of that variant. +In Michelson, the different values of the variant are annotated with the name of the corresponding entrypoint. + + +When calling a smart contract, senders provide either the full parameter as a variant or specify the name of the entrypoint and the corresponding parameter value. + +Other languages have different ways of indicating entrypoints. +For information about coding entrypoints in specific languages, see these links: + +- Michelson: [Entrypoint](https://tezos.gitlab.io/active/michelson.html#entrypoints) +- Archetype: [Entrypoint](https://archetype-lang.org/docs/reference/declarations/entrypoint) +- SmartPy: [entry_points](https://smartpy.io/docs/introduction/entry_points/) +- LIGO: [Main function and Entrypoints](https://ligolang.org/docs/advanced/entrypoints-contracts) diff --git a/docs/smart-contracts/languages.md b/docs/smart-contracts/languages.md new file mode 100644 index 000000000..4947320ea --- /dev/null +++ b/docs/smart-contracts/languages.md @@ -0,0 +1,14 @@ +--- +title: Languages +authors: 'Tim McMackin' +lastUpdated: 4th October 2023 +--- + +You can write Tezos smart contracts in any of these languages: + +- [LIGO](./languages/ligo), which has versions with syntaxes similar to JavaScript/TypeScript and OCaml +- [SmartPy](./languages/smartpy), which has a syntax similar to Python +- [Archetype](./languages/archetype), which is a high-level language developed specifically for Tezos + +Each of these languages are eventually compiled to Michelson, the base language for Tezos smart contracts. +For information about Michelson, see [Michelson](./languages/michelson). diff --git a/src/pages/smart-contracts/smart-contract-languages/archetype/index.md b/docs/smart-contracts/languages/archetype.md similarity index 79% rename from src/pages/smart-contracts/smart-contract-languages/archetype/index.md rename to docs/smart-contracts/languages/archetype.md index 7cb3062bc..c983a39d2 100644 --- a/src/pages/smart-contracts/smart-contract-languages/archetype/index.md +++ b/docs/smart-contracts/languages/archetype.md @@ -1,11 +1,9 @@ --- -id: archetype title: Archetype lastUpdated: 29th June 2023 --- -## Introduction -Archetype is an elegant generic-purpose language to develop smart contracts on the Tezos blockchain. It's a DSL \(domain-specific language \) for Tezos that facilitates formal verification and transcodes contracts to SmartPy and LIGO. +Archetype is an elegant generic-purpose language to develop smart contracts on the Tezos blockchain. It's a DSL (domain-specific language) for Tezos that facilitates formal verification and transcodes contracts to SmartPy and LIGO. It supports all [Michelson](https://tezos.gitlab.io/michelson-reference/) features but also provides exclusive high-level features for a precise and concise source code, that make contracts easier to develop, read and maintain. @@ -32,7 +30,7 @@ archetype escrow /* ... */ ``` -#### Parameters +### Parameters A contract may have parameters. A parameter value is not in the source code and is provided at deployment (origination) time. For example, the address of the contract owner is typically a contract parameter. @@ -57,7 +55,7 @@ $ npm install -g @completium/completium-cli $ completium-cli init ``` -Then you can deploy the contract with +Then you can deploy the contract with ``` completium-cli deploy hello.arl @@ -69,11 +67,9 @@ Call contract's entrypoint `input` with argument "Archetype": completium-cli call hello --entry input --arg '{ "name": "Archetype" }' ``` -{% callout type="note" %} -The full documentation for Archetype can be found on [archetype-lang.org](https://archetype-lang.org/docs/introduction). Also, see the material on OpenTezos [here](https://opentezos.com/archetype). -{% /callout %} - -#### Further reading: +## Further reading +* [Archetype documentation](https://archetype-lang.org/docs/introduction) +* [OpenTezos](https://opentezos.com/archetype) * [Medium article](https://medium.com/coinmonks/archetype-a-dsl-for-tezos-6f55c92d1035%20) * [How To Verify a smart contract with Archetype](https://medium.com/coinmonks/verify-a-smart-contract-with-archetype-6e0ea548e2da%20) diff --git a/docs/smart-contracts/languages/ligo.md b/docs/smart-contracts/languages/ligo.md new file mode 100644 index 000000000..7c2e649aa --- /dev/null +++ b/docs/smart-contracts/languages/ligo.md @@ -0,0 +1,73 @@ +--- +title: Ligo +lastUpdated: 29th June 2023 +--- + +LIGO is a functional programming language that is intended to be both user-friendly and to avoid patterns that make formal verification difficult. + +LIGO offers two syntaxes: + +- JsLIGO, a sytax that is inspired by TypeScript/JavaScript +- CameLIGO, a syntax that is inspired by OCaml + +You can use either syntax and compile to Michelson to run on Tezos. + +To learn LIGO, see these tutorials: + +- [Deploy a smart contract with CameLIGO](../../tutorials/smart-contract/cameligo) +- [Deploy a smart contract with jsLIGO](../../tutorials/smart-contract/jsligo) + +Let's define a LIGO contract in the two flavours above. + +## CameLIGO + +``` +type storage = int + +type parameter = + Increment of int +| Decrement of int +| Reset + +type return = operation list * storage + +let main (action, store : parameter * storage) : return = + [], + (match action with + Increment n -> store + n + | Decrement n -> store - n + | Reset -> 0) +``` + +## JsLIGO + +``` +type storage = int; + +type parameter = + ["Increment", int] +| ["Decrement", int] +| ["Reset"]; + +type return_ = [list, storage]; + +let main = (action: parameter, store: storage) : return_ => { + return [ + list([]), + match(action, { + Increment: n => store + n, + Decrement: n => store - n, + Reset: () => 0 + }) + ]; +}; +``` + +This LIGO contract accepts the following LIGO expressions: `Increment(n)`, `Decrement(n)` and `Reset`. Those serve as `entrypoint` identification. + +## Further reading + +- [LIGO documentation](https://ligolang.org/docs/intro/introduction?lang=jsligo) +- [LIGO tutorials](https://ligolang.org/docs/tutorials/getting-started?lang=jsligo) +- [OpenTezos](https://opentezos.com/ligo) + diff --git a/src/pages/smart-contracts/smart-contract-languages/michelson/index.md b/docs/smart-contracts/languages/michelson.mdx similarity index 50% rename from src/pages/smart-contracts/smart-contract-languages/michelson/index.md rename to docs/smart-contracts/languages/michelson.mdx index 119c6e339..536d0603a 100644 --- a/src/pages/smart-contracts/smart-contract-languages/michelson/index.md +++ b/docs/smart-contracts/languages/michelson.mdx @@ -1,30 +1,19 @@ --- -sidebar_position: 2 -hide_table_of_contents: true title: Michelson -hide_title: true lastUpdated: 30th June 2023 --- -## Michelson +import Figure from '@site/src/components/Figure'; Michelson is the domain-specific language used to write smart contracts on the Tezos blockchain. Michelson is a stack-based language and does not have variables. Stack-oriented languages operate on one or more stacks, each of which may serve a different purpose. -##### Key Michelson Resources - -* [Michelson documentation](http://tezos.gitlab.io/007/michelson.html) -* [Michelson Reference](https://tezos.gitlab.io/michelson-reference/) -* [Michelson tutorial series](https://gitlab.com/camlcase-dev/michelson-tutorial/tree/master) - -### An Overview of Michelson - Michelson is a low-level, stack-based programming language used to write smart contracts on the Tezos blockchain. Michelson was designed to facilitate formal verification, allowing users to prove the properties of their contracts. -It uses a stack rewriting paradigm, whereby each function rewrites an input stack into an output stack. \(The meaning of this will be fully explained below.\) This runs in a purely functional way and does not modify the inputs at all. Thus, all data structures are **immutable**. +It uses a stack rewriting paradigm, whereby each function rewrites an input stack into an output stack. (The meaning of this will be fully explained below.) This runs in a purely functional way and does not modify the inputs at all. Thus, all data structures are **immutable**. -### What is a stack? +## What is a stack? -A stack is an abstract data type that serves as a collection of elements, with two principal operations: push \(adds an element to the collection\) and pop \(removes the most recently added element that has not yet been removed\). The order in which elements come off a stack gives rise to its alternative name, LIFO \(last in, first out\). Additionally, a peek operation may give access to the top without modifying the stack. +A stack is an abstract data type that serves as a collection of elements, with two principal operations: push (adds an element to the collection) and pop (removes the most recently added element that has not yet been removed). The order in which elements come off a stack gives rise to its alternative name, LIFO (last in, first out). Additionally, a peek operation may give access to the top without modifying the stack. ![](https://upload.wikimedia.org/wikipedia/commons/9/9f/Stack_data_structure.gif) @@ -34,15 +23,35 @@ Source: Wikipedia. To see what mean it means to rewrite stacks, we will run through a transaction in Michelson. First, before a transaction runs, the blockchain state at a certain hash is deserialized and put onto the stack as the variable `storage`. We have a `from` function that receives the transaction data `amount`, the amount of attached tez, and the `parameter`, the function's parameters. -``` sh +```sh from [ (Pair (Pair amount parameter) storage) ] ``` After running the function, without any updates to the stack, the program will call a `to` function that has the parameters `result`, which is the result of the function, and the output `storage` that is serialized and stored on the blockchain. -``` sh +```sh to [ (Pair result storage) ] ``` In the example, Michelson only manipulates the stack functionally and a new stack is passed from function to function. +## Entrypoints + +Depending on the high-level language used, a smart contract deployment also defines its *entrypoints* using the complex **Parameter Type**. These are special functions used to dispatch invocations of the smart contract. Each entrypoint is in charge of triggering an instruction. Below is the same example as before, abstracting the complex Parameter Type: + +
+ +Each type and position of a parameter in the list (or pair) allows you to define an entrypoint (a function). For instance, in our example, there are two parameters, hence two types. Both types are integers (to increase or decrease a value). Because the type is the same, its position (left, right, or index number) determines which entrypoint is correct. +It could be: +- Left type: "Increment" entrypoint +- Right type: "Decrement" entrypoint + +Below is another illustration of this process: + +
+ +## Further reading + +* [Michelson documentation](http://tezos.gitlab.io/007/michelson.html) +* [Michelson Reference](https://tezos.gitlab.io/michelson-reference/) +* [Michelson tutorial series](https://gitlab.com/camlcase-dev/michelson-tutorial/tree/master) diff --git a/src/pages/smart-contracts/smart-contract-languages/smartpy/index.md b/docs/smart-contracts/languages/smartpy.mdx similarity index 96% rename from src/pages/smart-contracts/smart-contract-languages/smartpy/index.md rename to docs/smart-contracts/languages/smartpy.mdx index cdfa02577..21660bde3 100644 --- a/src/pages/smart-contracts/smart-contract-languages/smartpy/index.md +++ b/docs/smart-contracts/languages/smartpy.mdx @@ -1,14 +1,15 @@ --- -id: smartpy title: SmartPy authors: Mathias Hiron and Maxime Sallerin lastUpdated: 29th June 2023 --- -## Introduction +import Figure from '@site/src/components/Figure'; SmartPy is a comprehensive solution for developing, testing, and deploying smart contracts on Tezos. With its easy-to-use Python syntax, developers can create contracts in a familiar and intuitive way, while SmartPy's type inference provides added safety. +To learn SmartPy, see the tutorial [Deploy a smart contract with SmartPy](../../tutorials/smart-contract/smartpy). + Before deployment, contracts can be tested in simulated scenarios, including complex cases with multiple interacting contracts. Once ready, SmartPy contracts are compiled to Michelson, the Tezos blockchain's native language, for deployment. The SmartPy online IDE offers a user-friendly interface for trying out the system directly in a web browser. It comes with an origination feature for deployment of contracts to the blockchain at the click of a button. For those who prefer to write smart contracts and tests in their favourite editor, SmartPy also offers a command-line interface. @@ -21,11 +22,9 @@ SmartPy is a **Python library**. SmartPy scripts are regular Python scripts that **Meta-programming** is when we can write a program that writes a program, i.e., constructs a contract. Indeed, the functions of the SmartPy library are used to construct a smart contract. -{% callout type="note" %} -For a complete _SmartPy_ guide please refer to the [manual here](https://smartpy.dev/docs/manual/introduction/overview). -{% /callout %} +For complete documentation on SmartPy, see https://smartpy.dev. -Smart contracts are executed once they are deployed in the Tezos blockchain (although they can be simulated). +Smart contracts are executed once they are deployed in the Tezos blockchain (although they can be simulated). Like most languages, SmartPy has expressions. For example: - `self.data.x` represents the contract storage field `x` @@ -64,17 +63,16 @@ sp.if self.data.x > 2: self.data.x += 1 ``` -If we would have used the `if` native to Python it would not be interpreted and compiled in Michelson. +If we would have used the `if` native to Python it would not be interpreted and compiled in Michelson. ## About the raffle contract A raffle is a game of chance that distributes a winning prize. The organizer is in charge of defining a jackpot and selling tickets that will either be winners or losers. In the case of our example, we will only have one winning ticket. -Fig.3 represents our smart contract. +Fig. 1 represents our smart contract. -![](/images/smart-contracts/raffle_schema.svg) -FIGURE 3: Raffle contract +
Three entrypoints allow interaction with the contract: @@ -90,8 +88,7 @@ This section illustrates the coding of the smart contract in the [online editor] #### Create your contract To start, create a new contract in the online editor and name it _Raffle Contract_. -![](/images/smart-contracts/online_editor_create_contract.png) -FIGURE 4: Online Editor Create Contract +
#### Template @@ -121,7 +118,7 @@ class Raffle(sp.Contract): #### A few concepts first **A _SmartPy_ contract** is a class definition that inherits from the `sp.Contract`. -- **A class** is a code template for creating objects. Objects have member variables and have a behaviour associated with them. In Python a class is created by the keyword `class`. +- **A class** is a code template for creating objects. Objects have member variables and have a behaviour associated with them. In Python a class is created by the keyword `class`. - **Inheritance** allows us to define a class that can inherit all the methods and properties of another class. - **The _SmartPy_ storage** is defined into the constructor `__init__` which makes a call to `self.init()` that initializes the fields and sets up the storage. @@ -260,7 +257,7 @@ def __init__(self, address): ) ``` -The definition of the storage is done in the constructor `__init__` and the different fields of the storage are stated as follows: +The definition of the storage is done in the constructor `__init__` and the different fields of the storage are stated as follows: `self.init(field1=value1, field2=value2, field3=value3)` where: @@ -291,9 +288,9 @@ For the storage of the raffle contract, we have defined five fields for the mome - **jackpot** is the amount in `tez` that will be distributed to the winner. - **raffle_is_open** is a `boolean` to indicate if the raffle is open or not. - **hash_winning_ticket** is the hash of the winning ticket indicated by the admin. It is of type `bytes`. - - It's not possible to generate a truly random number from a smart contract, so an easy alternative is to use a hash that the admin will reveal the value later. - + + It's not possible to generate a truly random number from a smart contract, so an easy alternative is to use a hash that the admin will reveal the value later. + This example is for educational purposes and is not intended to be deployed on the real Tezos network. #### Entrypoint implementation @@ -316,9 +313,9 @@ def open_raffle(self, jackpot_amount, close_date, hash_winning_ticket): An entrypoint is a method of the contract class and is always preceded by the keyword `@sp.entry_point`. It can take several parameters. In our case, the first entrypoint we use, is called `open_raffle` and does the following: - With `sp.verify()` or `sp.verify_equal()`, we check that a statement is true or if it returns an error message (more info at [Checking a Condition](https://smartpy.io/reference.html#_checking_a_condition)). Here we check four statements : - + 1. The address that calls the entrypoint must be the administrator indicated in the storage. We compare here `sp.source` and `self.data.admin`. - > `sp.sender` is the address that calls the current entrypoint. + > `sp.sender` is the address that calls the current entrypoint. > `sp.source` is the address that initiates the current transaction. It may or may not be equal to `sp.sender`, but in our case, it is. 2. No raffle must be open. For this, we use the boolean `raffle_is_open` defined in the storage. @@ -390,8 +387,7 @@ The result is displayed in an HTML document in the output panel of the online ed Let's run our code: -![](/images/smart-contracts/online_editor_summary_contract.png) -FIGURE 4: Online Editor Contract Summary +
You can see a summary of our smart contract with the following information: - Address of the contract @@ -401,12 +397,11 @@ You can see a summary of our smart contract with the following information: By clicking on the _Types_ tab, we have access to the types of the storage elements and the parameters of the entrypoints. -![](/images/smart-contracts/online_editor_Types.png) -FIGURE 5: Online Editor Types +
-> As with Python, most of the time, it is not necessary to specify the type of an object in _SmartPy_. -> But it may be required because the target language of SmartPy, Michelson, requires types. -> Each _SmartPy_ expression, however, needs a type. This is why _SmartPy_ uses type inference to determine the type of each expression. +> As with Python, most of the time, it is not necessary to specify the type of an object in _SmartPy_. +> But it may be required because the target language of SmartPy, Michelson, requires types. +> Each _SmartPy_ expression, however, needs a type. This is why _SmartPy_ uses type inference to determine the type of each expression. > See doc [Typing](https://smartpy.io/reference.html#_typing). By clicking on the _Deploy Michelson Contract_ tab, we have access to the codes compiled in Michelson for the storage (_Storage_ tab) and the smart contract (_Code_ tab). @@ -505,8 +500,7 @@ code By scrolling down a little, we have access to the results of the test scenario, and within each step a summary of the contract. -![](/images/smart-contracts/online_editor_scenario_output.png) -FIGURE 4: Online Editor Scenario Output +
### buy_ticket entrypoint @@ -570,7 +564,7 @@ class Raffle(sp.Contract): alice = sp.test_account("Alice") jack = sp.test_account("Jack") admin = sp.test_account("Administrator") - + r = Raffle(admin.address) scenario = sp.test_scenario() scenario.h1("Raffle") @@ -933,7 +927,7 @@ Here are some precisions about the `sp.TBytes` type and its functionality which We are getting to the end of our smart contract. Run it one last time and explore the result. Don't hesitate to read the test scenario, to make sure your smart contract is working correctly. You can, of course, modify the scenarios or create new ones. -Check out the final Michelson code generated by SmartPy for this smart contract. Note that you can use this _Michelson_ code to create additional tests with _PyTezos_ as described in the [LIGO Module](/ligo/unit-testing). +Check out the final Michelson code generated by SmartPy for this smart contract. Note that you can use this _Michelson_ code to create additional tests with PyTezos as described in [Unit Testing](https://opentezos.com/ligo/unit-testing/) on OpenTezos. ## Conclusion @@ -948,6 +942,8 @@ There is no need for a **main** function like LIGO which dispatches the actions SmartPy was designed to help developers build smart contracts by providing them with a syntax familiar to them and a powerful analysis tool. -{% callout type="note" %} -On SmartPy's website you can find the [manual](https://smartpy.dev/docs/manual/introduction/overview) and [guides](https://smartpy.dev/docs/guides/) and explore contract examples on SmartPy's [online IDE](https://smartpy.dev/ide). In addition, see the [SmartPy material](https://opentezos.com/smartpy) on OpenTezos. -{% /callout %} +## Further reading + +- [SmartPy documentation](https://smartpy.dev/docs/) +- [Online IDE](https://smartpy.dev/ide) +- [OpenTezos](https://opentezos.com/smartpy) diff --git a/docs/smart-contracts/logic/comparing.md b/docs/smart-contracts/logic/comparing.md new file mode 100644 index 000000000..009cd3a99 --- /dev/null +++ b/docs/smart-contracts/logic/comparing.md @@ -0,0 +1,41 @@ +--- +title: Comparing values +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 4th October 2023 +--- + +The ways that you can compare values depends on the types of those values. + +Many types allow the usual comparison operators: `=`, `!=`, `<`, `>`, `≤` and `≥`. +The syntax depends on the language. +Comparing values in this way produces a Boolean type that you can use in conditional instructions or to continue or terminate loops. + +How values are compared depends on the type of the values: + +- `nat`, `int`, `mutez` and timestamp values are compared numerically. +- Strings, `bytes`, `key_hash`, `key`, `signature` and `chain_id` values are compared lexicographically. +- Boolean values are compared so that false is strictly less than true. +- Address are compared as follows: + - Addresses of implicit accounts are strictly less than addresses of originated accounts. + - Addresses of the same type are compared lexicographically. +- Pair values (and therefore records) are compared component by component, starting with the first component. +- Options are compared as follows: + - `None` is strictly less than any `Some`. + - `Some x` and `Some y` are compared as `x` and `y`. +- Values of `union` types built with `or` are compared as follows: + - any `Left x` is smaller than any `Right y`, + - `Left x` and `Left y` are compared as `x` and `y`, + - `Right x` and `Right y` are compared as `x` and `y`. +- Values of type `Unit` are all equal. + +In Michelson, comparisons are done in two steps: + +1. A `COMPARE` instruction consumes the values and produces a value that is 0 if the two elements are equal, negative if the first element in the stack is less than the second, and positive otherwise. +1. The instructions `EQ` (equal), `NEQ` (not equal), `LT` (lower than), `GT` (greater than), `LE` (lower or equal) and `GE` (greater or equal) consume this value and return the corresponding Boolean value. + +### Implementation details + +- Michelson: [Generic comparison](https://tezos.gitlab.io/active/michelson.html#generic-comparison) +- Archetype: [Comparison operators](https://archetype-lang.org/docs/reference/expressions/operators/arithmetic#a--b-7) +- SmartPy: [Comparing sp.int and sp.nat](https://smartpy.io/manual/syntax/integers-and-mutez#comparison) +- LIGO: [Comparing values](https://ligolang.org/docs/language-basics/boolean-if-else#comparing-values) diff --git a/docs/smart-contracts/logic/errors.md b/docs/smart-contracts/logic/errors.md new file mode 100644 index 000000000..ea77e8a5c --- /dev/null +++ b/docs/smart-contracts/logic/errors.md @@ -0,0 +1,71 @@ +--- +title: Handling errors +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +Unlike in many programming languages, there is no exception management on Tezos. +More precisely, there is no way to catch or intercept problems and trigger some alternate behavior when problems happen. + +Instead, Tezos uses _failures_, which immediately cancel operations. +When code introduces a failure, all of the operations are canceled and any completed operations are reverted, as if the initial call to the contract never happened. +To reduce the risk of bugs, there is no way to catch or prevent a failure after code introduces it. + +## What happens after a failure? + +On Tezos, a failure causes several things to happen: + +- The execution of the contract is immediately stopped and all of its potential effects are cancelled. +- All prior effects of the contract are reverted, as if they never happened, like a database rollback. +- Any changes to the storage are reverted. +- The contract's balance is restored to what it was before execution started. + +Furthermore, if the contract was called by another contract, or if it generated a call to another contract, all of these operations are cancelled as well. +The entire execution of everything, from the initial contract call by a user to the failure, is undone. + +This is a double-edged sword that you must keep in mind when designing a contract: + +- **positive impact**: If something doesn't happen as intended and a single failure happens somewhere during a contract call or subsequent calls it produces, nothing at all happens, and you don't end up in an inconsistent state corresponding to a partial execution. +- **negative impact**: It takes only one small issue in one of the contracts called as a consequence of your initial call for everything that you wanted to happen to be undone. +In some cases, this can mean that your contract becomes unusable. + +## Automatic failures + +Some instructions automatically cause a failure. +Here are a few examples: + +- Causing an overflow on a `mutez` type, such as when adding or multiplying +- Trying to do a bitwise left shift or right shift of a `nat` type by more than 256 +- Generating a transaction where the amount of tez transferred is greater than the balance of the contract that creates the transaction +- Generating a transaction for an address that doesn't exist + +There aren't too many of these cases, as most instructions that could cause an error use options as their return values, which allows (and also forces) you to explicitly handle the error case. +For example, integer division (`EDIV`) returns an option; if the division is successful, it returns `Some` and if the code tried to divide by zero, it returns `None`. + +## Raising failures + +If your code encounters a problem, you can raise a failure. +The failure includes an error value that can help users or tools of a contract understand what went wrong. +See the documentation for your language for how to raise a failure. + +## Error values + +The error value is meant to be used off-chain as information to identify the cause of the error. +Nothing can be done with it on-chain, because nothing at all happens on-chain when an error is produced. + +The typical error value is a string with an error message, such as `Error: deadline has expired`. +Internally, all kinds of error values can be produced, such as integers or records. +The types supported depend on the language. + +In particular, the error value is often used when testing contracts, where the test verifies that a specific invalid call produces a specific error. + +## Implementation details + +- Michelson: + - [Failures](https://tezos.gitlab.io/active/michelson.html#failures) + - [Control structures](https://tezos.gitlab.io/active/michelson.html#control-structures) + - [FAIL](https://tezos.gitlab.io/active/michelson.html#fail) + - [Assertion macros](https://tezos.gitlab.io/active/michelson.html#assertion-macros), +- Archetype: [require](https://archetype-lang.org/docs/reference/declarations/entrypoint/#require), [fail if](https://archetype-lang.org/docs/reference/declarations/entrypoint/#fail-if) +- SmartPy: [Exceptions](https://smartpy.io/manual/scenarios/testing_contracts#exceptions) +- LIGO: [Exceptions](https://ligolang.org/docs/language-basics/exceptions) diff --git a/docs/smart-contracts/logic/loops.md b/docs/smart-contracts/logic/loops.md new file mode 100644 index 000000000..28b8b4665 --- /dev/null +++ b/docs/smart-contracts/logic/loops.md @@ -0,0 +1,22 @@ +--- +title: Loops and iterations +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +A smart contract can contain loops, which take two general forms: + +- Conditional loops, which keep iterating as long as a given condition is true, such as while loops +- Loops that iterate through every element of a data structure such as a list, map, or set + +:::warning +When using loops, be careful of attacks that could increase the number of iterations in the loop. +::: + +In many cases, it is possible to avoid performing loops in the contract itself by doing most of the computations off-chain. + +## Implementation details + +- Michelson: [Control structures](https://tezos.gitlab.io/active/michelson.html#control-structures) +- Archetype: [Asset - iteration](https://archetype-lang.org/docs/asset#iteration), [for](https://archetype-lang.org/docs/reference/instructions/control#for), [while](https://archetype-lang.org/docs/reference/instructions/control#while), [iter](https://archetype-lang.org/docs/reference/instructions/control#iter) +- LIGO: [Iteration](https://ligolang.org/docs/language-basics/loops) diff --git a/docs/smart-contracts/logic/operations.md b/docs/smart-contracts/logic/operations.md new file mode 100644 index 000000000..633495f92 --- /dev/null +++ b/docs/smart-contracts/logic/operations.md @@ -0,0 +1,131 @@ +--- +title: Operations +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +The execution of the code of an entrypoint can have only two effects: + +- Changing the value of the storage of the contract +- Generating new operations that run after the entrypoint execution is over + +These operations can include: + +- Transferring tez to an account or to a smart contract entrypoint (`TRANSFER_TOKENS`) +- Originating a new smart contract (`CREATE_CONTRACT`) +- Setting the delegate of the current smart contract (`SET_DELEGATE`) + +Only the first type is technically a transaction, but the terms "operation" and "transaction" are often used interchangeably in courses, documentation, and tools. +Don't worry too much about the difference. + +:::note Sending tez +Sending tez to an address is just a special case of calling a smart contract (via the `default` entrypoint). +However, some languages have a specific syntax for simply sending tez to a contract that is different from the syntax to call an entrypoint. +A call to a smart contract always includes a transfer of a certain amount of tez, even if that amount is zero. +::: + +## Order of execution + +The code of a contract never directly executes an operation or a transfer of tez. +Instead, it adds operations to a list and the list is added to a stack of operations to run after code of the entrypoint is complete. + +The operations generated by a contract are executed in the order that they are added to the list. +All the operations generated by a contract and the operations these end up generating are executed before any other operations previously added to the stack. + +For example, if a contract generates operations A and B, and operation A generates operation C, operation C runs before operation B. + +## Operation examples + +For example, assume three contracts named A, B, and C that each have an entrypoint named "Start." +Contract A's storage has a value named "text," which is a string. +Contract A also has an entrypoint named "Add," which adds text to the storage string based on a string that the sender passes. + +This table shows the logic of the entrypoints: + +{ + + + + + + + + + + + + + +
Entrypoint Logic
Contract AContract BContract C
+
    +
  • start():
      +
    1. Replace text with "Start A,"
    2. +
    3. Call B.start()
    4. +
    5. Call C.start()
    6. +
    7. Append "End A" to text
    8. +
    +
  • +
  • add(str):
      +
    1. Append str to text
    2. +
    +
  • +
+
+
    +
  • start():
      +
    1. Call A.add("Start B,")
    2. +
    3. Call A.add("End B,")
    4. +
    +
  • +
+
+
    +
  • start():
      +
    1. Call A.add("Start C,")
    2. +
    3. Call A.add("End C,")
    4. +
    +
  • +
+
} + +## Operation Walkthrough + +If a user calls `A.start()`, the following happens: + +1. `A.start()` runs: + 1. Replaces its storage text with "Start A," + 1. Adds operation` B.start()` to the list of operations + 1. Adds operation `C.start()` to the list of operations + 1. Adds "End A," to its storage, which becomes "Start A, End A" + 1. Pushes the operations from the list `[B.start(), C.start()]` to the stack;` B.start()` is on the top +1. `B.start()` runs: + 1. Adds operation `A.add("Start B,")` to the list of operations + 1. Adds operation `A.add("End B,")` to the list of operations + 1. Pushes the operations from the list `[A.add("Start B,"), A.add("End B,")]` to the top of the stack; the operation stack is now `[A.add("Start B,"), A.add("End B,"), C.start()]` +1. `A.add("Start B")` runs: + 1. Replaces its storage with "Start A,End A,Start B," +1. `A.add("End B")` runs: + 1. Replaces its storage with "Start A,End A,Start B,End B," +1. `C.start()` runs: + 1. Adds operation `A.add("Start C,")` to the list of operations + 1. Adds operation `A.add("End C,")` to the list of operations + 1. Pushes the operations from the list `[A.add("Start C,"), A.add("End C,")]` to the top of the stack +1. `A.add("Start C")` runs: + 1. Replaces its storage with "Start A,End A,Start B,End B,Start C," +1. `A.add("End C")` runs: + 1. Replaces its storage with "Start A,End A,Start B,End B,Start C, End C," + +At the end of all operations, A's storage is "Start A,End A,Start B,End B,Start C, End C,". + +To summarize: + +- All of the code in an entrypoint runs before the operations it generates run +- If a contract A generates a call to a contract B then a call to a contract C, all of the operations generated by B run before contract C runs. +- If any of these operations cause a failure, everything is cancelled, including operations that have already completed. + +## Implementation details + +- Michelson: [Operations on contracts](https://tezos.gitlab.io/active/michelson.html#operations-on-contracts) +- Archetype: [Operation](https://archetype-lang.org/docs/reference/instructions/operation) +- LIGO: [Inter-contract invocations](https://ligolang.org/docs/advanced/entrypoints-contracts#inter-contract-invocations) +- SmartPy: [Operations](https://smartpy.io/manual/syntax/operations) diff --git a/src/pages/smart-contracts/multisig-specialized/1-multisig-specialized-intro/index.md b/docs/smart-contracts/multisig-specialized.md similarity index 86% rename from src/pages/smart-contracts/multisig-specialized/1-multisig-specialized-intro/index.md rename to docs/smart-contracts/multisig-specialized.md index 4dd82988b..aa4a77ada 100644 --- a/src/pages/smart-contracts/multisig-specialized/1-multisig-specialized-intro/index.md +++ b/docs/smart-contracts/multisig-specialized.md @@ -1,5 +1,4 @@ --- -id: 1-multisig-specialized-intro title: Specialized Multisig Introduction sidebar_label: Introduction lastUpdated: 29th June 2023 @@ -16,7 +15,7 @@ What is meant by _"arbitrary action"_? That generic multisig contract accepts arbitrary Michelson code as its main input: signers need to know what this code is doing to know what they're voting on. -We use another approach: the multisig contract is specialized to the particular contract type you'd like to use with it. That is, the multisig contract's parameters must match those of the contract it is administering. +We use another approach: the multisig contract is specialized to the particular contract type you'd like to use with it. That is, the multisig contract's parameters must match those of the contract it is administering. It will only perform the exact actions your contract expects. This prevents any action that the base contract does not support from being executed. @@ -28,14 +27,13 @@ To set up and interact with a specialized multisig contract: ## Setting up -Follow instructions in [Client Setup](/docs/setup/1-tezos-client) to set up - `tezos-client` and create a test network wallet +Set up `tezos-client` and create a test network wallet Clone the [`lorentz-contract-multisig` repository](https://github.com/tqtezos/lorentz-contract-multisig), and follow the [instructions in the README]( https://github.com/tqtezos/lorentz-contract-multisig/blob/master/README.md) to install the dependencies required to use the `lorentz-contract-multisig` -Don't forget to set up an `ALICE_ADDRESS` and `BOB_ADDRESS` on the test network [as described here](/docs/setup/1-tezos-client#createtestwallets:); we will be using these variables throughout this tutorial. +Don't forget to set up an `ALICE_ADDRESS` and `BOB_ADDRESS` on the test network as described in [Installing Octez](../reference/octez/installing); we will be using these variables throughout this tutorial. ## Getting your public key diff --git a/src/pages/smart-contracts/multisig-specialized/2-originate-and-use-multisig-contract/index.md b/docs/smart-contracts/multisig-usage.md similarity index 98% rename from src/pages/smart-contracts/multisig-specialized/2-originate-and-use-multisig-contract/index.md rename to docs/smart-contracts/multisig-usage.md index 088a1351b..1c0684115 100644 --- a/src/pages/smart-contracts/multisig-specialized/2-originate-and-use-multisig-contract/index.md +++ b/docs/smart-contracts/multisig-usage.md @@ -1,12 +1,11 @@ --- -id: 2-originate-and-use-multisig-contract -title: Originate and Use +title: Using multisig contracts lastUpdated: 29th June 2023 --- ## Generating the Specialized Multisig Contract Code -Make sure you have already followed the [setup steps](/docs/token-contracts/multisig-specialized/1-multisig-specialized-intro#setting-up) before continuing. +Make sure you have already followed the [setup steps](./multisig-specialized/#setting-up) before continuing. To see a list of supported contracts and actions, run: `stack exec -- lorentz-contract-multisig --help` @@ -54,7 +53,7 @@ CallStack (from HasCallStack): ## Generating the Initial Storage Note, this section uses the -[bash functions defined here](/docs/token-contracts/multisig-specialized/1-multisig-specialized-intro#getting-your-public-key). +[bash functions defined here](./multisig-specialized/#getting-your-public-key). The Generic Multisig allows us to set administrators of the contract (`signerKeys`) and the number of those administrators required to sign @@ -269,7 +268,7 @@ $ tezos-client rpc get /chains/main/chain_id Set a bash variable for the chain ID: ```shell -$ CHAIN_ID="NetXjD3HPJJjmcd" +$ CHAIN_ID="NetXjD3HPJJjmcd" ``` First, we'll generate the bytes diff --git a/docs/smart-contracts/quickstart.md b/docs/smart-contracts/quickstart.md new file mode 100644 index 000000000..234631888 --- /dev/null +++ b/docs/smart-contracts/quickstart.md @@ -0,0 +1,5 @@ +# Quickstart + +Really this should be a link to a tutorial and not duplicated information. + +A very basic contract in smartpy (no choice here), just so that they practice and get a feeling. They then deploy it with octez and interact with it Part of one of the tutorials \ No newline at end of file diff --git a/docs/smart-contracts/samples.md b/docs/smart-contracts/samples.md new file mode 100644 index 000000000..40ce573b0 --- /dev/null +++ b/docs/smart-contracts/samples.md @@ -0,0 +1,14 @@ +--- +title: Sample smart contracts +author: "Tim McMackin" +lastUpdated: 19 October 2023 +--- + +Here are some places to find sample smart contacts: + +- Completed applications from the tutorials are in the repository https://github.com/trilitech/tutorial-applications +- For conceptual examples of contracts, see https://opentezos.com/smart-contracts/simplified-contracts/ +- For examples of contracts that manage FA2 tokens, see https://github.com/trilitech/tqtezos-smart-contracts +- For examples of contracts in LIGO, see https://packages.ligolang.org/contracts +- For examples of contracts in Archetype, see https://archetype-lang.org/docs/templates/overview +- For examples of contracts in SmartPy, see https://smartpy.io/guides/examples/ diff --git a/docs/smart-contracts/sapling.md b/docs/smart-contracts/sapling.md new file mode 100644 index 000000000..a39817924 --- /dev/null +++ b/docs/smart-contracts/sapling.md @@ -0,0 +1,40 @@ +--- +title: Private transactions (sapling) +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 4th October 2023 +--- + +Sapling is a protocol that enables transactions of fungible tokens while increasing privacy. +It hides transactions from the public, but allows specific entities to view them to comply with regulations. + +The key steps are as follows: + +1. A _shielded pool_ is created within a contract which a number of users can call to perform transactions whilst keeping details private. +1. The users send tokens to this shielded pool, which is called _shielding tokens_. +Information about these transactions is public. +1. Users perform _shielded transactions_, in such a way that the amount, sender of receiver of each transactions are not revealed publicly. +Only the origin and destination of each transaction have access to the transaction information. +1. Later, users may get some or all of their tokens out of the pool by _unshielding their tokens_. +Information about these transactions is public. + +If a regulator needs access to the transactions of a user, this user may share a _viewing key_, which gives access to all the transactions made by this user. + +Note that using the sapling protocol in a _shielded pool_ and expecting a high degree of privacy requires taking a number of precautions, including: + +- Making sure there are enough members in the pool to ensure anonymity. +For example, if there are only two members, it becomes very easy to identify the source and destination of transactions. +- Adding dummy transactions, or dummy inputs and outputs of transactions, to hide the actual number of parties involved in each transaction. +- Making sure to use shielded tokens in multiple transactions. +For example, if a user shields exactly 16.32 tokens and another user later unshields exactly 16.32 tokens, the transaction may be traceable. +- Being careful about information that can be deduced from the timing of transactions. + +The internals of sapling are quite technical. +The system is based on an UTXO (bitcoin-like) transaction system, where each transaction consumes some unspent output and produces new unspent outputs. +It uses a system of cryptographic commitments in place of public amounts and addresses, that can then be "consumed" using a system of nullifiers. +The process uses a mix of cryptographic tools including SNARKs, incremental Merkle trees, and Diffie-Hellman key exchanges. + +## Implementation information + +- Michelson: [Sapling integration](https://tezos.gitlab.io/active/sapling.html) +- Archetype: [Sapling](https://archetype-lang.org/docs/language-basics/crypto#sapling) +- LIGO: [Sapling](https://ligolang.org/docs/reference/current-reference#sapling) diff --git a/docs/smart-contracts/serialization.md b/docs/smart-contracts/serialization.md new file mode 100644 index 000000000..63e5bfadd --- /dev/null +++ b/docs/smart-contracts/serialization.md @@ -0,0 +1,36 @@ +--- +title: Serialization +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 4th October 2023 +--- + +Between contract calls, the code of a contract, as well as its storage, are stored as a serialized sequence of bytes, for efficiency purposes. +Every time the contract is called, the serialized code and storage are deserialized, unless the deserialized version is still cached. +Similarly, after the execution of the contract, the storage needs to be serialized to be stored again as a sequence of bytes. + +This takes CPU time, which means that when you call an entrypoint, on top of paying for the gas for the execution of the code of the entrypoint itself, you also need to pay for this serialization/deserialization. +The cost to call a very simple entrypoint may get large if there is a lot of data in its storage. + +Remember that unlike the rest of the storage, `big-maps` are not entirely serialized/deserialized for each call. +Instead, only the values that are read are deserialized, and only the values that are added or updated are serialized. +This makes using `big-maps` more efficient in these cases. + +## PACK and UNPACK + +Tezos provides the ability to serialize and deserialize data or code yourself: + +- The `PACK` instruction takes a value of (almost) any type, and serializes it into a `bytes` value. +- The `UNPACK` instruction takes a `bytes` value, and deserializes it into its original value. +As the deserialization may be impossible if the sequence of bytes doesn't represent valid serialized data, it returns an option type. + +Serializing your own data in this way may be useful if you want to apply operations that are only available on `bytes` values. + +For example, you may want to compute the hash of some data. +You can do so by packing it first and then applying a hash function such as `BLAKE2B` on the resulting `bytes` value. + +## Implementation details + +- Michelson: [Operations on bytes](https://tezos.gitlab.io/active/michelson.html#operations-on-bytes) +- LIGO: [Pack and Unpack](https://ligolang.org/docs/language-basics/tezos-specific#pack-and-unpack) +- SmartPy: [Packing and Unpacking](https://smartpy.io/manual/syntax/strings-and-bytes#packing-and-unpacking) +- Archetype: [pack](https://archetype-lang.org/docs/reference/expressions/builtins#pack%28o%20:%20T%29), [unpack](https://archetype-lang.org/docs/reference/expressions/builtins#unpack%3CT%3E%28b%20:%20bytes%29) diff --git a/docs/smart-contracts/special-values.md b/docs/smart-contracts/special-values.md new file mode 100644 index 000000000..2d03307d4 --- /dev/null +++ b/docs/smart-contracts/special-values.md @@ -0,0 +1,63 @@ +--- +title: Special values +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +The code of a contract can access some special values. +See the reference for your language for information about accessing these values: + +- `caller`: The address of the direct caller of the current entrypoint. + + This value is often used for these reasons: + + - To check that the caller is allowed to call the entrypoint. + For example, only a member of a DAO may call its vote entrypoint. + Only the owner of an NFT may call an `addToMarket` entrypoint of a marketplace to put the NFT on sale. + - To assign or transfer resources to the caller or to store information about them. + For example, a user may call a `buy` entrypoint of an NFT marketplace and the contract assigns ownership of the NFT to them. + The contract assigns ownership by storing the caller address in the record that is associated with the NFT. + +- `source`: The address of the initiator of the sequence of calls that led to this entrypoint. +For example, assume that user A called contract B that in turn called contract C: + + A -> B -> C + + When C runs, `source` is the address of A, while `caller` is the address of B. + +:::warning Access permissions +It is best practice to implement permissioning based on `caller` instead of `source` because any implicit account can call any entrypoint on Tezos. +::: + +- `self`: The address of the contract itself. +For example, you can ensure that an entrypoint is called only by the contract itself by verifying that `caller` = `self`. + +- `balance`: The amount of tez (in `mutez`) in the contract, including any tez that have been transferred to the contract by the current transaction. + +- `amount`: The number of tez that have been transferred to the contract during the current transaction. + + - These tez are added to the balance, _except_ if the execution ends in a failure. + - Some languages refer to this amount with the name `transferred`. + +:::note Rejecting tez +By default, an entrypoint automatically accepts any tez that is sent to it. +If the contract should not accept tez, it can reject tez by verifying that the amount is zero. +::: + +- `now`: The timestamp of the current block. +This value is the same during the execution of all of the contract calls from the same block. + + - Technically, this value is equal to the timestamp of the previous block plus the minimum block delay (the expected duration between two blocks). + This prevents the baker of the current block from manipulating this value, while keeping it predictable to everyone. + + This value is often used to check deadlines, for example, if someone has to vote before a certain date. + +- `level`: The level of a block corresponds to the number of blocks in the chain since the beginning of the chain (genesis block) until that block. +It increments by one for each new block. + +## Implementation details + +- Michelson: [Special operations](https://tezos.gitlab.io/active/michelson.html#special-operations), [Operations on contracts](https://tezos.gitlab.io/active/michelson.html#operations-on-contracts) +- Archetype: [Constants](https://archetype-lang.org/docs/reference/expressions/constants/#now) +- SmartPy: [Timestamps](https://smartpy.io/manual/syntax/timestamps) +- LIGO: [Tezos](https://ligolang.org/docs/reference/current-reference), [Tezos specific built-ins](https://ligolang.org/docs/advanced/entrypoints-contracts#tezos-specific-built-ins), [Tezos.now](https://ligolang.org/docs/advanced/timestamps-addresses#starting-time-of-the-current-block) diff --git a/docs/smart-contracts/storage.md b/docs/smart-contracts/storage.md new file mode 100644 index 000000000..e5ba08b6f --- /dev/null +++ b/docs/smart-contracts/storage.md @@ -0,0 +1,24 @@ +--- +title: Storage +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +Each contract has associated storage, which is persistent internal data that it can read and write to. +Contracts can access only their own storage; they can't access the storage of other contracts. +To provide information to other contracts, use [Views](./views). + +However, the content of the storage of a contract is public, like everything else in the state of the blockchain. +Therefore, you can see the current value of the storage of any contract using an explorer such as [Better Call Dev](https://better-call.dev/). + +The type of the storage is fixed by the code of the contract and cannot change. +It can be any type, from a basic primitive type such as a `nat`, to a complex type that includes `lists`, `sets`, `big-maps`, and `variants`. + +See [Examples of contracts](https://opentezos.com/smart-contracts/simplified-contracts/) on opentezos.com for ideas about how storage can be used. + +## Implementation details + +- Michelson: [Semantic of contracts and transactions](https://ligolang.org/docs/advanced/entrypoints-contracts) +- Archetype: [Storage](https://archetype-lang.org/docs/reference/declarations/storage) +- SmartPy: [Contracts](https://smartpy.io/manual/syntax/overview#contracts) +- LIGO: [Main function](https://ligolang.org/docs/advanced/entrypoints-contracts) diff --git a/docs/smart-contracts/testing.md b/docs/smart-contracts/testing.md new file mode 100644 index 000000000..84b096116 --- /dev/null +++ b/docs/smart-contracts/testing.md @@ -0,0 +1,65 @@ +--- +title: Testing +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +The hardest part of writing smart contracts is avoiding bugs. +Even though most contracts are small compared to regular software applications, they run in an adversarial environment with high financial stakes. +Therefore, the potential for bugs with dramatic consequences is high. + +- Due to the public nature of the blockchain, malicious users can exploit bugs for their own profit at the expense of legitimate users. +- Due to the immutable nature of contracts (even with upgradeability), you must test your smart contracts extensively before production deployment. + +High-level languages come with tools to help write tests, and some testing tools can be used independently of the language used to write the smart contract. +For example, [SmartPy](https://smartpy.io/manual/scenarios/overview) includes syntax dedicated to testing. + +## Structure of a test scenario + +A test scenario usually consists of the following: + +- Instructions to deploy the contract with a given initial storage and balance. +- Valid calls to entrypoints, with different parameters and context information such as: + - the address of the `caller` + - the amount of `tez` sent + - the `timestamp` of the block (value of `now` during the call) + - the `level` of the block +- Verification of the value of the storage or `balance`, after each execution of an entrypoint. +- Invalid calls to entrypoints, with the indication that they are expected to fail. +- Verification of the error caused by these invalid calls. + +When executed, the test scenario is successful if all verifications are correct, and all invalid calls fail with the expected errors. + +More advanced scenarios may involve a local sandbox deployment and calls to multiple contracts to test interactions. + +## Programming languages for testing + +The test scenarios are usually written using a full classical programming language, such as JavaScript or Python, with a library that gives you access to special features to: + +- Deploy contracts +- Make calls to entrypoints +- Manipulate all the types/values supported by Tezos +- Generate testing accounts, to simulate calls from multiple accounts +- Perform cryptographic computations similar to the ones available in the contract + +## Rules for testing + +Testing a contract thoroughly is not easy and requires experience. +Here are some tips to follow when getting started: + +- Write tests without looking at the implementation of the contract to avoid copying mistakes. +- If possible, have another developer write the test to avoid testing semantic errors incorrectly. +- Make sure to cover every possible execution path, whether it's valid or invalid. +- Create many small tests, each checking something very specific, rather than a long test that tries to do many things at once. +- Test around the limits. +For example, if a value should be always above 10, include a call with the value 10 that should fail and a call with the value 11 that should succeed. +- Test the extremes. + +For more information about avoiding flaws in contracts, see [Avoiding flaws](https://opentezos.com/smart-contracts/avoiding-flaws/) on opentezos.com. + +## Implementation details + +- Michelson: [Mockup mode](https://tezos.gitlab.io/user/mockup.html) +- Archetype: [Completium test scenario](https://completium.com/docs/contract/test-scenario) +- SmartPy: [Tests and scenarios](https://smartpy.io/manual/scenarios/overview) +- LIGO: [Testing LIGO](https://ligolang.org/docs/advanced/testing) diff --git a/docs/smart-contracts/views.md b/docs/smart-contracts/views.md new file mode 100644 index 000000000..24c42fbd6 --- /dev/null +++ b/docs/smart-contracts/views.md @@ -0,0 +1,86 @@ +--- +title: Views +authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)' +lastUpdated: 5th October 2023 +--- + +Views are a way for contracts to expose information to other contracts. + +A view is similar to an entrypoint, with a few differences: + +- Views return a value. +- Contracts can call views and use the returned values immediately. +In other words, calling a view doesn't produce a new operation. +The call to the view runs immediately and the return value can be used in the next instruction. +- Calling a view doesn't have any effect other than returning that value. +In particular, it doesn't modify the storage of its contract and doesn't generate any operations. + +## Example View + +Here is an example that uses a view. +The following contract is a ledger that handles a fungible token and keeps track of how many tokens are owned by each user. + +{ + + + + + + + + + + + + + +
Ledger contract
StorageEntrypoint effects
+
    +
  • ledger: big-map +
      +
    • Key:
        +
      • user: address
      • +
      +
    • +
    • Value:
        +
      • tokens: nat
      • +
      +
    • +
    +
  • +
+
+
    +
  • view getBalance(user: address) +
      +
    • return ledger[user].tokens
    • +
    +
  • +
  • transfer(nbTokens, destination) +
      +
    • Check that tokens[caller].tokens >= nbTokens
    • +
    • Create an entry tokens[destination] (value = 0 if it doesn't exist)
    • +
    • Add nbTokens to tokens[destination].nbTokens
    • +
    • Subtract nbTokens from tokens[caller].nbTokens
    • +
    +
  • +
+
} + +Another contract might provide an `equalizeWith` entrypoint such that if they have more tokens than another user, they can make their balances equal (plus or minus one if the total amount is odd). +The following example code for this contract takes advantage of the `getBalance(user)` view of the first contract: to determine the balance of each user: + +```javascript +equalizeWith(destination) + destinationBalance = ledger.getBalance(destination) + totalBalance = ledger.getBalance(caller) + destinationBalance + targetBalance = totalBalance // 2 + ledger.transfer(targetBalance - destinationBalance, destination) +``` + +## Implementation details + +- Michelson: [Operations on views](https://tezos.gitlab.io/active/michelson.html#operations-on-views) +- Archetype: [View](https://archetype-lang.org/docs/reference/declarations/view) +- SmartPy: [Views in testing](https://smartpy.io/manual/scenarios/testing_contracts#views) +- LIGO: [On-chain views](https://ligolang.org/docs/protocol/hangzhou#on-chain-views) diff --git a/docs/tutorials.mdx b/docs/tutorials.mdx new file mode 100644 index 000000000..2177699b8 --- /dev/null +++ b/docs/tutorials.mdx @@ -0,0 +1,88 @@ +--- +title: Tutorials +--- + +These tutorials can help you get started developing different kinds of applications on Tezos in as little as 15 minutes. + +import TutorialCard from '@site/src/components/TutorialCard'; +import TutorialCardContainer from '@site/src/components/TutorialCardContainer'; + +## Beginner + +These tutorials are intended for developers who are starting work with Tezos: + + + + + + + + + +## Intermediate + +These tutorials contain multiple parts and are intended for developers with some application development experience: + + + + + + + + + + + +## Advanced + +These tutorials are intended for developers who are familiar with Tezos and want to get into more powerful applications: + + + + + + + + diff --git a/src/pages/tutorials/build-an-nft-marketplace/index.md b/docs/tutorials/build-an-nft-marketplace/index.md similarity index 98% rename from src/pages/tutorials/build-an-nft-marketplace/index.md rename to docs/tutorials/build-an-nft-marketplace/index.md index d01713ff1..bee1f833f 100644 --- a/src/pages/tutorials/build-an-nft-marketplace/index.md +++ b/docs/tutorials/build-an-nft-marketplace/index.md @@ -1,5 +1,4 @@ --- -id: build-an-nft-marketplace title: NFT Marketplace Part 1 lastUpdated: 11th October 2023 --- @@ -13,7 +12,7 @@ In the first part, you learn: - The concepts of FA, IPFS, and smart contracts. - How to build an NFT Marketplace from the ligo/fa library. -{% callout type="note" %} +:::note This training course is provided by [Marigold](https://www.marigold.dev/). You can find the 4 parts on github (solution + materials to build the UI) @@ -21,7 +20,7 @@ You can find the 4 parts on github (solution + materials to build the UI) - [NFT 2](https://github.com/marigold-dev/training-nft-2): finish FA2 NFT marketplace to introduce sales - [NFT 3](https://github.com/marigold-dev/training-nft-3): use FA2 single asset template to build another kind of marketplace - [NFT 4](https://github.com/marigold-dev/training-nft-4): use FA2 multi asset template to build last complex kind of marketplace -{% /callout %} +::: ## Key Concepts @@ -70,7 +69,7 @@ The Wine marketplace is adding these features on top of a generic NFT contract : You can play with the [final demo](https://demo.winefactory.marigold.dev/). -![nftfactory.png](/images/nftfactory.png) +![nftfactory.png](/img/tutorials/nftfactory.png) | Token template | # of token_type | # of item per token_type | | -------------- | --------------- | ------------------------ | @@ -78,9 +77,9 @@ You can play with the [final demo](https://demo.winefactory.marigold.dev/). | single asset | 0..1 | 1..n | | multi asset | 0..n | 1..n | -{% callout type="note" %} +:::note Because of web3, buy or sell features are a real payment system using on-chain XTZ tokens as money. This differs from traditional web2 applications where you have to integrate a payment system and so, pay extra fees -{% /callout %} +::: ## Prerequisites @@ -108,14 +107,14 @@ Before building an NFT marketplace, ensure you have the following tools on hand. Use **Taqueria** to shape the project structure, then create the NFT marketplace smart contract thanks to the `ligo/fa` library. -{% callout type="note" %} +:::note You require to copy some code from this git repository later, so you can clone it with: ```bash git clone https://github.com/marigold-dev/training-nft-1.git ``` -{% /callout %} +::: ### Step 1: Taq'ify your project @@ -273,9 +272,9 @@ Explanation: - every `FA2Impl.NFT.xxx()` called function is taking the storage type of the NFT library, so you need to send a partial object from our storage definition to match the type definition - the return type contains also the storage type of the library, so you need to reconstruct the storage by copying the modified fields -{% callout type="note" %} +:::note The LIGO team is working on merging type definitions, so you then can do **type union** or **merge 2 objects** like in Typescript -{% /callout %} +::: Let's add the `Mint` function now. Add the new function @@ -388,9 +387,9 @@ taq install @taqueria/plugin-taquito taq deploy nft.tz -e "testing" ``` -{% callout type="note" %} +:::note If this is the first time you're using **taqueria**, you may want to run through [this training](https://github.com/marigold-dev/training-dapp-1#ghostnet-testnet-wallet). -{% /callout %} +::: > For advanced users, just go to `.taq/config.local.testing.json` and change the default account by alice one's (publicKey,publicKeyHash,privateKey) and then redeploy: > @@ -798,7 +797,7 @@ const mint = async (newTokenDefinition: TZIP21TokenMetadata) => { > Note : organize/fix duplicated import declarations if necessary -![mint form](/images/mintForm.png) +![mint form](/img/tutorials/mintForm.png) Explanations: @@ -979,7 +978,7 @@ const handleStepChange = (step: number) => { - Click on **Upload an image** and select a bottle picture on your computer - Click on the Mint button -![minting](/images/minting.png) +![minting](/img/tutorials/minting.png) Your picture is be pushed to IPFS and displayed. @@ -987,7 +986,7 @@ Then, Temple Wallet _(or whatever other wallet you choose)_ asks you to sign the Now you can see all NFTs -![wine collection](/images/winecollection.png) +![wine collection](/img/tutorials/winecollection.png) ## Summary @@ -995,4 +994,4 @@ You are able to create an NFT collection marketplace from the `ligo/fa` library. On next training, you will add the buy and sell functions to your smart contract and update the frontend to allow these actions. -To continue, let's go to [Part 2](/tutorials/build-an-nft-marketplace/part-2). +To continue, let's go to [Part 2](./part-2). diff --git a/src/pages/tutorials/build-an-nft-marketplace/part-2.md b/docs/tutorials/build-an-nft-marketplace/part-2.md similarity index 99% rename from src/pages/tutorials/build-an-nft-marketplace/part-2.md rename to docs/tutorials/build-an-nft-marketplace/part-2.md index 5ab5dd420..44fd785b7 100644 --- a/src/pages/tutorials/build-an-nft-marketplace/part-2.md +++ b/docs/tutorials/build-an-nft-marketplace/part-2.md @@ -1,5 +1,4 @@ --- -id: build-an-nft-marketplace title: NFT Marketplace Part 2 lastUpdated: 11th October 2023 --- @@ -595,7 +594,7 @@ Your picture is pushed to IPFS and displayed, then your wallet ask you to sign t 6. Click on the submenu entry -![sell.png](/images/sell.png) +![sell.png](/img/tutorials/sell.png) You are the owner of this bottle so you can create an offer to sell it. @@ -840,7 +839,7 @@ export default function WineCataloguePage() { Now you can see on **Trading** menu the **Wine catalogue** submenu, click on it. -![buy.png](/images/buy.png) +![buy.png](/img/tutorials/buy.png) As you are connected with the default administrator you can see your own unique offer on the market @@ -858,4 +857,4 @@ This concludes the NFT training! In the next lesson, you will see another kind of NFT called **single asset**. Instead of creating _X_ token types, you will be allowed to create only 1 token*id 0, on the other side, you can mint a quantity \_n* of this token. -To continue, let's go to [Part 3](/tutorials/build-an-nft-marketplace/part-3). +To continue, let's go to [Part 3](./part-3). diff --git a/src/pages/tutorials/build-an-nft-marketplace/part-3.md b/docs/tutorials/build-an-nft-marketplace/part-3.md similarity index 99% rename from src/pages/tutorials/build-an-nft-marketplace/part-3.md rename to docs/tutorials/build-an-nft-marketplace/part-3.md index e01e2400e..39a933461 100644 --- a/src/pages/tutorials/build-an-nft-marketplace/part-3.md +++ b/docs/tutorials/build-an-nft-marketplace/part-3.md @@ -1,5 +1,4 @@ --- -id: build-an-nft-marketplace title: NFT Marketplace Part 3 lastUpdated: 11th October 2023 --- @@ -1361,14 +1360,14 @@ export default function WineCataloguePage() { - Click on **Upload an image** and select a bottle picture on your computer - Click on the Mint button -![minting.png](/images/minting.png) +![minting.png](/img/tutorials/minting.png) Your picture is pushed to IPFS and displayed, then your wallet asks you to sign the `mint` operation. - Confirm operation - Wait less than 1 minute to get the confirmation notification, the page is automatically refreshed. -![minted.png](/images/minted.png) +![minted.png](/img/tutorials/minted.png) Now you can see the **Trading** menu and the **Bottle offers** sub menu @@ -1381,7 +1380,7 @@ You are the owner of this bottle so you can make an offer on it - Click on the **SELL** button - Wait a bit for the confirmation, then once automatically refreshed you have an offer attached to your NFT -![offer.png](/images/offer.png) +![offer.png](/img/tutorials/offer.png) For buying, @@ -1392,7 +1391,7 @@ For buying, - Click on **bottle offers** sub menu - You are now the owner of some bottles, you can resell a part of it at your own price, etc ... -![buy.png](/images/buy_part3.png) +![buy.png](/img/tutorials/buy_part3.png) ## Conclusion @@ -1400,4 +1399,4 @@ You are now able to play with a unique NFT collection from the Ligo library. In the next lesson, you will use the last template **multi-asset** that will allow multiple NFT collections on the same contract -To continue, let's go to [Part 4](/tutorials/build-an-nft-marketplace/part-4). +To continue, let's go to [Part 4](./part-4). diff --git a/src/pages/tutorials/build-an-nft-marketplace/part-4.md b/docs/tutorials/build-an-nft-marketplace/part-4.md similarity index 99% rename from src/pages/tutorials/build-an-nft-marketplace/part-4.md rename to docs/tutorials/build-an-nft-marketplace/part-4.md index 775345f51..7fe622f6e 100644 --- a/src/pages/tutorials/build-an-nft-marketplace/part-4.md +++ b/docs/tutorials/build-an-nft-marketplace/part-4.md @@ -1,5 +1,4 @@ --- -id: build-an-nft-marketplace title: NFT Marketplace Part 4 lastUpdated: 11th October 2023 --- @@ -1422,14 +1421,14 @@ export default function WineCataloguePage() { - Click on **Upload an image** and select a bottle picture on your computer - Click on the Mint button -![minting.png](./images/minting.png) +![minting.png](/img/tutorials/minting.png) Your picture is pushed to IPFS and is displayed, then your wallet asks you to sign the `mint` operation. - Confirm operation - Wait less than 1 minute to get the confirmation notification, the page is automatically refreshed -![minted_part4.png](/images/minted_part4.png) +![minted_part4.png](/img/tutorials/minted_part4.png) Now you can see the **Trading** menu and the **Bottle offers** sub-menu @@ -1442,7 +1441,7 @@ You are the owner of this bottle so you can create an offer on it - Click on **SELL** button - Wait a bit for the confirmation, then once automatically refreshed you have an offer attached to your NFT! -![sell_part4.png](/images/sell_part4.png) +![sell_part4.png](/img/tutorials/sell_part4.png) For buying, @@ -1453,7 +1452,7 @@ For buying, - Click on the **bottle offers** submenu - You are now the owner of some bottles, you can resell a part of it at your own price, etc ... -![buy_part4.png](/images/buy_part4.png) +![buy_part4.png](/img/tutorials/buy_part4.png) To add more collections, go to the Mint page and repeat the process. diff --git a/docs/tutorials/build-your-first-app.md b/docs/tutorials/build-your-first-app.md new file mode 100644 index 000000000..60c28c36f --- /dev/null +++ b/docs/tutorials/build-your-first-app.md @@ -0,0 +1,47 @@ +--- +title: Build your first app on Tezos +authors: 'Claude Barde, Tim McMackin' +lastUpdated: 17th October 2023 +--- + +This tutorial shows you how to create a simple web application that uses Tezos. +Specifically, this application will be the user-facing web front end for a bank application that accepts deposits and returns withdrawals of test tokens. + +You will learn: + +- How to create a web application and import libraries that access Tezos +- How to connect to a user's wallet +- How to send a transaction to a smart contract on behalf of a user +- How to get information from Tezos and show it on a web page + +## Prerequisites + +This tutorial uses JavaScript, so it will be easier if you are familiar with JavaScript. + +You do not need any familiarity with any of the libraries in the tutorial, including [Taquito](https://tezostaquito.io/), a library that helps developers access Tezos. + +## The tutorial application + +In this tutorial, you build a web application that allows users to send test tokens to a simulated bank on Tezos and withdraw them later. + +The application looks like this: + +![Completed bank application, showing information about the user's wallet and buttons to deposit or withdraw tez](/img/tutorials/bank-app-complete.png) + +The application connects to a user's cryptocurrency wallet and shows the balance of that wallet in Tezos's native currency, which is referred to as tez, by the ticker symbol XTZ, or the symbol ꜩ. +It provides an input field and slider for the user to select an amount of tez to deposit and a button to send the deposit transaction to Tezos. +It also provides a button to withdraw the amount from Tezos. + +The application is based on JavaScript, so it uses several JS-based tools to build and package the application: + +- **[Svelte](https://svelte.dev/)** for the JavaScript framework +- **[Vite](https://vitejs.dev/)** (pronounced like _veet_) to bundle the application and provide the libraries to the user's browser + +To access the user's wallet and run transactions on Tezos, the application uses these libraries: + +- **[Taquito](https://tezostaquito.io/)** to interact with the Tezos blockchain +- **[Beacon](https://docs.walletbeacon.io/)** to access users' wallets + +The code for the completed application is in this GitHub repository: https://github.com/trilitech/tutorial-applications/tree/main/bank-tutorial. + +When you're ready, move to the next section to begin setting up the application. diff --git a/docs/tutorials/build-your-first-app/getting-information.md b/docs/tutorials/build-your-first-app/getting-information.md new file mode 100644 index 000000000..899c4747d --- /dev/null +++ b/docs/tutorials/build-your-first-app/getting-information.md @@ -0,0 +1,90 @@ +--- +title: "Part 4: Getting information" +authors: "Tim McMackin" +lastUpdated: 17 October 2023 +--- + +In this section, you improve the user experience of the application by providing information from Tezos on the page. +Specifically, you show the amount of tez that the user has stored in the smart contract and that is available to withdraw. + +Your app can do this because information on Tezos is public, including the code of smart contracts and their data storage. + +In this case, the contract's storage is a data type called a big-map. +It maps account addresses with a number that indicates the amount of tez that address has deposited. +Your app can query that amount by getting the contract's storage and looking up the value for the user's account. + +You can look up the storage manually by going to a block explorer and going to the Storage tab. +For example, Better Call Dev shows the storage for this contract like this: + +![The block explorer, showing the storage for the contract in one big-map object](/img/tutorials/bank-app-block-explorer-storage.png) + +You can expand the big-map object and search for the record that is related to your account address to see how much tez you have deposited. + +## Accessing the contract storage + +Your application can use the Taquito library to access the storage for the contract and look up the user's balance in the contract: + +1. In the `App.svelte` file, in the ` + +
+

Tezos bank dApp

+ +
+ {#if wallet} +

The address of the connected wallet is {address}.

+

Its balance in tez is {balance}.

+

+ To get tez, go to + https://faucet.ghostnet.teztnets.xyz/ + . +

+

+ Deposit tez: + + + +

+

+ Withdraw tez: + +

+

+ +

+ {:else} + + {/if} +
+
+ + +``` diff --git a/docs/tutorials/build-your-first-app/setting-up-app.md b/docs/tutorials/build-your-first-app/setting-up-app.md new file mode 100644 index 000000000..5e0ccb521 --- /dev/null +++ b/docs/tutorials/build-your-first-app/setting-up-app.md @@ -0,0 +1,156 @@ +--- +title: "Part 1: Setting up the application" +authors: 'Claude Barde, Tim McMackin' +lastUpdated: 17th October 2023 +--- + +You can access Tezos through any JavaScript framework. +This tutorial uses the Svelte framework, and the following steps show you how to start a Svelte application and add the Tezos-related dependencies. + +## Setting up the app + +1. Run these commands to install Svelte with TypeScript and Vite: + + ```bash + npm create vite@latest bank-tutorial -- --template svelte + cd bank-tutorial + npm install + ``` + +1. Install the Tezos-related dependencies: + + ```bash + npm install @taquito/taquito @taquito/beacon-wallet @airgap/beacon-sdk + ``` + +1. Install the `buffer`, `events`, and `vite-compatible-readable-stream` libraries: + + ```bash + npm install --save-dev buffer events vite-compatible-readable-stream + ``` + +1. Update the `vite.config.js` file to the following code: + + ```javascript + import { defineConfig, mergeConfig } from "vite"; + import path from "path"; + import { svelte } from "@sveltejs/vite-plugin-svelte"; + + export default ({ command }) => { + const isBuild = command === "build"; + + return defineConfig({ + plugins: [svelte()], + define: { + global: {} + }, + build: { + target: "esnext", + commonjsOptions: { + transformMixedEsModules: true + } + }, + server: { + port: 4000 + }, + resolve: { + alias: { + "@airgap/beacon-sdk": path.resolve( + path.resolve(), + `./node_modules/@airgap/beacon-sdk/dist/${ + isBuild ? "esm" : "cjs" + }/index.js` + ), + // polyfills + "readable-stream": "vite-compatible-readable-stream", + stream: "vite-compatible-readable-stream" + } + } + }); + }; + ``` + + This updated file includes these changes to the default Vite configuration: + + - It sets the `global` object to `{}` so the application can provide the value for this object in the HTML file + - It includes the a path to the Beacon SDK + - It provides polyfills for `readable-stream` and `stream` + +1. Update the default HTML file `index.html` to the following code: + + ```html + + + + + + + + + Tezos Bank dApp + + + + + + ``` + + This updated file sets the `global` variable to `globalThis` and adds a buffer object to the window. + The Beacon SDK requires this configuration to run in a Vite app. + +1. Replace the `src/main.js` file with this code: + + ```javascript + import './app.css' + import App from './App.svelte' + + const app = new App({ + target: document.body, + }) + + export default app + ``` + +## Configuring Svelte + +Svelte files include several different types of code in a single file. +The application's files have separate sections for JavaScript, style, and HTML code, as in this example: + +```html + + + + +
+ +
+``` + +Svelte components are fully contained, which means that the style and code that you apply inside a component doesn't leak into the other components. +Styles and scripts that are shared among components typically go in the `src/styles` and `scripts` or `src/scripts` folders. + +Follow these steps to set up the `src/App.svelte` file, which is the main component and container for other Svelte components: + +1. Replace the default `src/App.svelte` file with this code: + + ```html + + +
+
+ + + ``` + +You will add code to connect to the user's wallet in the next section. diff --git a/docs/tutorials/build-your-first-app/wallets-tokens.md b/docs/tutorials/build-your-first-app/wallets-tokens.md new file mode 100644 index 000000000..2dbf60e7c --- /dev/null +++ b/docs/tutorials/build-your-first-app/wallets-tokens.md @@ -0,0 +1,279 @@ +--- +title: "Part 2: Accessing wallets" +authors: 'Claude Barde, Tim McMackin' +lastUpdated: 17th October 2023 +--- + +Accessing the user's wallet is a prerequisite for interacting with the Tezos blockchain. +Accessing the wallet allows your app to see the tokens in it and to prompt the user to submit transactions, but it does not give your app direct control over the wallet. +Users must still confirm all transactions in their wallet application. + +Using a wallet application in this way saves you from having to implement payment processing and security in your application. +As you see in this section, it takes only a few lines of code to connect to a user's wallet. + +## Creating and funding a wallet + +To use the application, you need a wallet and some tez tokens. + +1. Install a Tezos-compatible wallet. +Which wallet you install is up to you and whether you want to install a wallet on your computer, in a browser extension, or as a mobile app. + + If you don't know which one to choose, try the [Temple](https://templewallet.com/) browser extension, because then you can use it in the same browser that you are using to view the web app. + + Desktop wallets for Tezos include the [Temple](https://templewallet.com/) browser extension, [Kukai](https://wallet.kukai.app/), and [Umami](https://umamiwallet.com/). + + Mobile apps include [Temple](https://templewallet.com/), [Kukai](https://wallet.kukai.app/), and [Umami](https://umamiwallet.com/). + +1. Switch the wallet to use the Ghostnet testnet instead of Tezos Mainnet. +Ghostnet is a network for testing Tezos applications where tokens are free so you don't have to spend real currency to work with your applications. + + For example, for the Temple browser wallet, click **Tezos Mainnet** at the top and then click **Ghostnet Testnet**, as in this picture: + + ![Selecting the Ghostnet testnet in the Temple wallet](/img/tutorials/temple-switch-network.png) + +1. From your wallet, get the address of your account, which starts with `tz1`. +This is the address that applications use to work with your wallet. + +1. Go to the Ghostnet faucet page at https://faucet.ghostnet.teztnets.xyz. + +1. On the faucet page, paste your wallet address into the input field labeled "Or fund any address" and click the button for the amount of tez to add to your wallet. +20 tez is enough to work with the tutorial application, and you can return to the faucet later if you need more tez. + + It may take a few minutes for the faucet to send the tokens and for those tokens to appear in your wallet. + + You can use the faucet as much as you need to get tokens on the testnet, but those tokens are worthless and cannot be used on mainnet. + + ![Fund your wallet using the Ghostnet Faucet](/img/tutorials/wallet-funding.png) + +1. If you created a new account, initialize the account by sending any amount of tez to any other account. + + Before the new account can use dApps, it must send at least one transaction to Tezos. + This first transaction reveals the public key that provesthat transactions came from this account. + + If your account is new, you can send 1 tez to any other account, including your own account, via your wallet application to reveal the account. + +Now you have an account and funds that you can use in dApps. + +## Connecting to the user's wallet + +In this section, you add code to connect to the user's wallet with the Taquito `TezosToolkit` and Beacon `BeaconWallet` objects. +Taquito accesses Tezos and Beacon accesses wallets. + +IMPORTANT: however you design your app, it is essential to use a single instance of the `BeaconWallet` object. +It is also highly recommended use a single instance of the `TezosToolkit` object. +Creating multiple instances can cause problems in your app and with Taquito in general. + +This application keeps these objects in the `App.svelte` file because this is the only component in the application. +If you add more components, you should move these objects to a separate file to maintain a single instance of them. + +1. In the `App.svelte` file, add these imports to the ` + +
+

Tezos bank dApp

+ +
+ {#if wallet} +

The address of the connected wallet is {address}.

+

Its balance in tez is {balance}.

+

+ To get tez, go to + https://faucet.ghostnet.teztnets.xyz/ + . +

+

+ +

+ {:else} + + {/if} +
+
+ + +``` + +## Using the application + +To try the application, run `npm run dev` and open the page http://localhost:4000/ in a web browser. + +Because no wallet is connected, the app shows the "Connect wallet" button, as in this picture: + +![The initial page of the bank dApp, showing a title and the button that connects to the user's wallet](/img/tutorials/bank-app-connect-button.png) + +When you click **Connect wallet**, the `connectWallet` function runs and the Beacon toolkit opens, showing some of the types of wallets it can connect to: + +![The Beacon wallet connection popup](/img/tutorials/beacon-connect-wallet-options.png) + +The procedure for connecting each type of wallet is different. +For example, if you are using the Temple browser extension, you click **Temple** and then **Connect now**. +Then the Temple wallet shows a popup that allows you to confirm that you want to connect your wallet to the application, as in this picture: + +![Connecting to the application in the Temple wallet](/img/tutorials/temple-connect-wallet.png) + +Then the application runs the `getWalletBalance` function, which gets the wallet's balance in tez tokens. +Because the Svelte component's variables changed, the application refreshes automatically and shows the wallet address, balance, and "Disconnect wallet" button: + +![The application showing information about the connected wallet](/img/tutorials/bank-app-first-connection.png) + +If you click **Disconnect wallet**, the application goes back to its initial state. + +Now the application can connect to user wallets. +In the next section, you add code to use the wallet to get the user's approval to send transactions to Tezos. + +## Design considerations + +Interacting with a wallet in a decentralized application is a new paradigm for many developers and users. +Follow these practices to make the process easier for users: + +- Let users manually connect their wallets instead of prompting users to connect their wallet immediately when the app loads. +Getting a wallet pop-up window before the user can see the page is annoying. +Also, users may hesitate to connect a wallet before they have had time to look at and trust the application, even though connecting the wallet is harmless. + +- Provide a prominent button to connect and disconnect wallets. + +- Put the button in a predictable position, typically at the top right or left corner of the interface. + +- Use "Connect" as the label for the button. +Avoid words like "sync" because they can have different meanings in dApps. + +- Display the status of the wallet clearly in the UI. +You can also add information about the wallet, including token balances and the connected network for the user's convenience, as this tutorial application does. +Showing information about the tokens and updating it after transactions allows the user to verify that the application is working properly. + +- Enable and disable functions of the application based on the status of the wallet connection. +For example, if the wallet is not connected, disable buttons for transactions that require a wallet connection. +Also, disable transaction buttons while transactions are pending to prevent users from making duplicate transactions. diff --git a/docs/tutorials/create-an-nft.md b/docs/tutorials/create-an-nft.md new file mode 100644 index 000000000..3daca3f93 --- /dev/null +++ b/docs/tutorials/create-an-nft.md @@ -0,0 +1,10 @@ +--- +title: Create an NFT +--- + +There are many ways to create (or "mint") NFTs; in particular, you can create all of the NFTs in a collection at once or set up an application that can create NFTs as users request them. +Try one of these tutorials to see different ways of minting NFTs: + +- [Create NFTs with the `tznft` tool](./create-an-nft/nft-tznft): Create metadata files to describe NFTs and then use a command-line tool to mint them and manipulate them +- [Mint NFTs from a web app](./create-an-nft/nft-web-app): Use a pre-existing contract to create NFTs from a web application +- [Create a contract and web app that mints NFTs](./create-an-nft/nft-taquito): Set up a web application that authorized users can use to create NFTs and all users can use to see the NFTs in a collection diff --git a/src/pages/tutorials/create-an-nft/fa12/index.md b/docs/tutorials/create-an-nft/fa12/index.md similarity index 99% rename from src/pages/tutorials/create-an-nft/fa12/index.md rename to docs/tutorials/create-an-nft/fa12/index.md index 028abe661..404640c76 100644 --- a/src/pages/tutorials/create-an-nft/fa12/index.md +++ b/docs/tutorials/create-an-nft/fa12/index.md @@ -1,5 +1,4 @@ --- -id: 2-fa12-ligo title: Working with FA1.2 using LIGO and Taquito sidebar_label: FA1.2 LIGO lastUpdated: 29th June 2023 diff --git a/docs/tutorials/create-an-nft/fa2.md b/docs/tutorials/create-an-nft/fa2.md new file mode 100644 index 000000000..3cd652d99 --- /dev/null +++ b/docs/tutorials/create-an-nft/fa2.md @@ -0,0 +1,532 @@ +--- +title: Create an NFT +lastUpdated: 5th June 2023 +--- + +This guide shows how to originate and interact with the FA2 NFT contract +implementation. We use a pre-compiled FA2 NFT contract written in the +[LIGO](https://ligolang.org/) smart contract language and a command line interface +(CLI) to originate and interact with the NFT contracts either on the +[Flextesa](https://tezos.gitlab.io/flextesa/) sandbox or Tezos testnet. + +## Introduction + +### What is FA2 (TZIP-12)? + +FA2 refers to a token standard ([TZIP-12](https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-12/tzip-12.md)) +on Tezos. FA2 proposes a unified token contract interface, supporting a wide range +of token types. The FA2 provides a standard API to transfer tokens, check +token balances, manage operators (addresses that are permitted to transfer tokens +on behalf of the token owner), and manage token metadata. + +### What is a Non-Fungible Token (NFT)? + +An NFT (non-fungible token) is a special type of cryptographic token that represents +something unique; non-fungible tokens are thus not mutually interchangeable. +NFTs can represent ownership over digital or physical assets like virtual collectibles +or unique artwork. + +For each non-fungible token, the FA2 assigns a unique +token ID and associates it with the token owner's address. The FA2 API enables the +inspection of token balances for the specific token ID and token owner address. +For NFTs the balance can be either 0 (which means that the address does not own +this particular token) or 1 (the address owns the token). + +The FA2 contract also associates some metadata with each token. This tutorial supports +token symbol and token name metadata attributes. However, the implementation can +be easily extended to support custom metadata attributes such as an associated +image or document URL and its crypto-hash. + +## Tutorial + +### Prerequisites + +- [Node.js](https://nodejs.org/) must be installed. The Node installation must also + include `npm` (Node package manager). + +- [Docker](https://www.docker.com/) must be installed. You need docker to run + Flextesa sandbox. You might skip Docker installation if you plan to run this + tutorial on the testnet (Mumbainet) only. + +### The CLI Tool + +You will need to install `tznft` CLI tool. After the installation, you can invoke +various commands in the form of `tznft [options]`. `tznft` provides the +following commands: + +- mint (contract origination) NFT with metadata command +- token inspection commands +- NFT transfer command +- configuration commands to bootstrap the Tezos network and configure address aliases + +The commands will be explained in more detail below. You can always run + +```sh +$ tznft --help +``` + +to list all available commands. + +### Initial Setup + +1. Create a new local directory to keep your tutorial configuration: + + ```sh + $ mkdir nft-tutorial + $ cd nft-tutorial + ``` + +2. Install `@tqtezos/nft-tutorial` npm package: + + ```sh + $ npm install -g https://github.com/tqtezos/nft-tutorial.git + + /usr/local/bin/tznft -> /usr/local/lib/node_modules/@tqtezos/nft-tutorial/lib/tznft.js + + + @tqtezos/nft-tutorial@1.0.0 + added 3 packages from 1 contributor and updated 145 packages in 11.538s + ``` + + The command installs `tznft` CLI tool. + +3. Initialize tutorial config: + + ```sh + $ tznft init-config + + tznft.json config file created + ``` + +4. Check that the default active network is `sandbox`: + + ```sh + $ tznft show-network + + active network: sandbox + ``` + +5. Bootstrap Tezos network: + + ```sh + $ tznft bootstrap + + ebb03733415c6a8f6813a7b67905a448556e290335c5824ca567badc32757cf4 + + starting sandbox... + sandbox started + originating balance inspector contract... + originated balance inspector KT1Pezr7JjgmrPcPhpkbkH1ytG7saMZ34sfd + ``` + + If you are bootstrapping a `sandbox` network for the first time, Docker will download + the Flextesa Docker image as well. + + The default configuration comes with two account aliases `bob` and `alice` + that can be used for token minting and transferring. + +### Mint NFT Token(s) + +This tutorial uses an NFT collection contract. Each time the user mints a new set +(collection) of tokens, a new NFT contract is created. The user cannot add more +tokens or remove (burn) existing tokens within the contract. However, tokens can +be transferred to other owners. + +`mint` command requires the following parameters: + +- <owner> alias or address of the new token's owner +- `--tokens` new tokens metadata. Each token metadata is represented as comma + delimited string: `', , '`: + +```sh +$ tznft mint --tokens ` +``` + +Example: + +```sh +$ tznft mint bob --tokens '0, T1, My Token One' '1, T2, My Token Two' + +originating new NFT contract... +originated NFT collection KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh +``` + +### Inspecting The NFT Contract + +Using `KT1...` address of the NFT contract created by the `mint` command, we can +inspect token metadata and balances (i. e. which addresses own the tokens). + +#### Inspect Token Metadata + +`show-meta` command requires the following parameters: + +- `--nft` address of the FA2 NFT contract to inspect +- `--signer` alias on behalf of which contract is inspected +- `--tokens` a list of token IDs to inspect + +```sh +$ tznft show-meta --nft --signer --tokens +``` + +Example: + +```sh +$ tznft show-meta --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --signer bob --tokens 0 1 + +token_id: 0 symbol: T1 name: My Token One extras: { } +token_id: 1 symbol: T2 name: My Token Two extras: { } +``` + +#### Inspect Token Balances + +`show-balance` command requires the following parameters: + +- `--nft` address of the FA2 NFT contract to inspect +- `--signer` alias on behalf of which contract is inspected +- `--owner` alias of the token owner to check balances +- `--tokens` a list of token IDs to inspect + +```sh +$ tznft show-balance --nft --signer --owner --tokens +``` + +Example 1, check `bob`'s balances: + +```sh +$ tznft show-balance --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --signer bob --owner bob --tokens 0 1 + +querying NFT contract KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh using balance inspector KT1Pezr7JjgmrPcPhpkbkH1ytG7saMZ34sfd +requested NFT balances: +owner: tz1YPSCGWXwBdTncK2aCctSZAXWvGsGwVJqU token: 0 balance: 1 +owner: tz1YPSCGWXwBdTncK2aCctSZAXWvGsGwVJqU token: 1 balance: 1 +``` + +Example 2, check `alice` balances: + +```sh +$ tznft show-balance --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --signer bob --owner alice --tokens 0 1 + +querying NFT contract KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh using balance inspector KT1Pezr7JjgmrPcPhpkbkH1ytG7saMZ34sfd +requested NFT balances: +owner: tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb token: 0 balance: 0 +owner: tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb token: 1 balance: 0 +``` + +### Tokens With External Metadata + +Token metadata can store a reference to some external document and/or image. +This tutorial supports storing external data on [IPFS](https://ipfs.io) and keeping +an IPFS hash as a part of the token metadata. + +Let's create a single NFT token that references an image on IPFS. + +1. Upload your image to IPFS and obtain an image file hash. There are + multiple ways to do that. One of the possible solutions is to install the + [IPFS Companion](https://github.com/ipfs-shipyard/ipfs-companion) web plugin and + upload an image file from there. You can upload multiple images and/or documents + if you plan to create a collection of multiple NFTs. + +2. Copy the IPFS file hash code (`CID`). For this example, we will use + `QmRyTc9KbD7ZSkmEf4e7fk6A44RPciW5pM4iyqRGrhbyvj` + +3. Execute `tznft mint` command adding IPFS hash as a fourth parameter in the token + description. + +```sh +$ tznft mint bob -t '0, TZT, Tezos Token, QmRyTc9KbD7ZSkmEf4e7fk6A44RPciW5pM4iyqRGrhbyvj' + +originating new NFT contract... +originated NFT collection KT1SgzbcfTtdHRV8qHNG3hd3w1x23oiC31B8 +``` + +4. Now we can inspect new token metadata and see that the IPFS hash (`ipfs_cid`) + is there. + +```sh +$ tznft show-meta -s bob --nft KT1SgzbcfTtdHRV8qHNG3hd3w1x23oiC31B8 --tokens 0 + +token_id: 0 symbol: TZT name: Tezos Token extras: { ipfs_cid=QmRyTc9KbD7ZSkmEf4e7fk6A44RPciW5pM4iyqRGrhbyvj } +``` + +5. You can inspect the file on the web by opening a URL `https://ipfs.io/ipfs/`. + For our example, the URL would be + [https://ipfs.io/ipfs/QmRyTc9KbD7ZSkmEf4e7fk6A44RPciW5pM4iyqRGrhbyvj](https://ipfs.io/ipfs/QmRyTc9KbD7ZSkmEf4e7fk6A44RPciW5pM4iyqRGrhbyvj) + +### Transferring Tokens + +`transfer` command requires the following parameters: + +- `--nft` address of the FA2 NFT contract that holds tokens to be transferred +- `--signer` alias or address that initiates the transfer operation +- `--batch` a list of individual transfers. Each individual transfer is represented + as a comma-delimited string: `, , `. + We do not need to specify the amount of the transfer for NFTs since we can only + transfer a single token for any NFT type. + +```sh +$ tznft transfer --nft --signer --batch ` +``` + +Example, `bob` transfers his own tokens `0` and `1` to `alice`: + +```sh +$ tznft transfer --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --signer bob --batch 'bob, alice, 0' 'bob, alice, 1' + +transferring tokens... +tokens transferred +``` + +Now, we can check token balances after the transfer: + +```sh +$ tznft show-balance --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --signer bob --owner bob --tokens 0 1 + +querying NFT contract KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh using balance inspector KT1Pezr7JjgmrPcPhpkbkH1ytG7saMZ34sfd +requested NFT balances: +owner: tz1YPSCGWXwBdTncK2aCctSZAXWvGsGwVJqU token: 0 balance: 0 +owner: tz1YPSCGWXwBdTncK2aCctSZAXWvGsGwVJqU token: 1 balance: 0 + +$ tznft show-balance --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --signer bob --owner alice --tokens 0 1 + +querying NFT contract KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh using balance inspector KT1Pezr7JjgmrPcPhpkbkH1ytG7saMZ34sfd +requested NFT balances: +owner: tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb token: 0 balance: 1 +owner: tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb token: 1 balance: 1 +``` + +### Operator Transfer + +It is also possible to transfer tokens on behalf of the owner. + +`bob` is trying to transfer one of `alice`'s tokens back: + +```sh +$ tznft transfer --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --signer bob --batch 'alice, bob, 1' + +transferring tokens... +Tezos operation error: FA2_NOT_OPERATOR +``` + +As we can see, this operation has failed. The default behavior of the FA2 token +contract is to allow only token owners to transfer their tokens. In our example, +Bob (as an operator) tries to transfer token `1` that belongs to `alice`. + +However, `alice` can add `bob` as an operator to allow him to transfer any tokens on +behalf of `alice`. + +`update-ops` command has the following parameters: + +- `` alias or address of the token owner to update operators for +- `--nft` address of the FA2 NFT contract +- `--add` list of pairs aliases or addresses and token id to add to the operator set +- `--remove` list of aliases or addresses and token id to remove from the operator set + +```sh +$ tznft update-ops --nft --add [add_operators_list] --remove [add_operators_list] +``` + +Example, `alice` adds `bob` as an operator: + +```sh +$ tznft update-ops alice --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --add 'bob, 1' + +updating operators... +updated operators +``` + +Now `bob` can transfer a token on behalf of `alice` again: + +```sh +$ tznft transfer --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --signer bob --batch 'alice, bob, 1' + +transferring tokens... +tokens transferred +``` + +Inspecting balances after the transfer: + +```sh +$ tznft show-balance --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --signer bob --owner bob --tokens 0 1 + +querying NFT contract KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh using balance inspector KT1Pezr7JjgmrPcPhpkbkH1ytG7saMZ34sfd +requested NFT balances: +owner: tz1YPSCGWXwBdTncK2aCctSZAXWvGsGwVJqU token: 0 balance: 0 +owner: tz1YPSCGWXwBdTncK2aCctSZAXWvGsGwVJqU token: 1 balance: 1 + +$ tznft show-balance --nft KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh --signer bob --owner alice --tokens 0 1 + +querying NFT contract KT1XP3RE6S9t44fKR9Uo5rAfqHvHXu9Cy7fh using balance inspector KT1Pezr7JjgmrPcPhpkbkH1ytG7saMZ34sfd +requested NFT balances: +owner: tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb token: 0 balance: 1 +owner: tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb token: 1 balance: 0 +``` + +Token `1` now belongs to `bob`. + +### Configuration + +`tznft` can be configured to interact with different Tezos networks. The user can +also configure address aliases to sign Tezos operations and/or use them as command +parameters when addresses are required. The default configuration that is created +by `tznft init-config` command includes two pre-configured networks: `sandbox` +and `testnet` (Carthagenet). Each pre-configured network has two bootstrap aliases: +`bob` and `alice`. + +#### Network Configuration Commands + +- `set-network ` selects a specified pre-configured network as an active one. + All subsequent commands will operate on the active network + + Example: + + ```sh + $ tznft set-network sandbox + + network sandbox is selected + ``` + +- `show-network [--all]` show currently selected network. If `--all` flag is + specified, show all pre-configured networks + + Example: + + ```sh + $ tznft show-network --all + + * sandbox + testnet + ``` + +- `bootstrap` bootstrap selected network and deploy helper balance inspector contract. + If the selected network is `sandbox`, this command needs to be run each time the sandbox + is restarted, for other public networks like `testnet` it is enough to run this + command once. + + Example: + + ```sh + $ tznft bootstrap + + 366b9f3ead158a086e8c397d542b2a2f81111a119f3bd6ddbf36574b325f1f03 + + starting sandbox... + sandbox started + originating balance inspector contract... + originated balance inspector KT1WDqPuRFMm2HwDRBotGmnWdkWm1WyG4TYE + ``` + +- `kill-sandbox` stop Flextesa sandbox process if the selected network is `sandbox`. + This command has no effect on other network types. + + Example: + + ```sh + $ tznft kill-sandbox + + flextesa-sandbox + + killed sandbox. + ``` + +The sandbox network (selected by default) is configured to bake new Tezos blocks +every 5 seconds. It makes running the commands that interact with the network +faster. However, all originated contracts will be lost after the sandbox is stopped. + +If you are using `testnet`, your originated contracts will remain on the blockchain +and you can inspect them afterwards using a block explorer like [BCD](https://better-call.dev/). + +_Note: Although `testnet` configuration already has two bootstrap aliases `bob` +and `alice`, it is a good practice to create your own alias from the faucet file +(see `tznft add-alias-faucet` command described below) and use it as a signer for +the commands like `mint`, `transfer` and `show_balance`. In this way, your Tezos +operations will not interfere with the operations initiated by other users._ + +#### Alias Configuration Commands + +`tznft` allows user to configure and use short names (aliases) instead of typing +in full Tezos addresses when invoking `tznft` commands. +Each network comes with two pre-configured aliases `bob` and `alice`. The user +can manage aliases by directly editing `tznft.json` file or using the following +commands: + +- `show-alias [alias]` show address and private key (if configured) of the + specified `[alias]`. If `[alias]` option is not specified, show all configured + aliases. + + Example: + + ```sh + $ tznft show-alias bob + + bob tz1YPSCGWXwBdTncK2aCctSZAXWvGsGwVJqU edsk3RFgDiCt7tWB2oe96w1eRw72iYiiqZPLu9nnEY23MYRp2d8Kkx + + $ tznft show-alias + + bob tz1YPSCGWXwBdTncK2aCctSZAXWvGsGwVJqU edsk3RFgDiCt7tWB2oe96w1eRw72iYiiqZPLu9nnEY23MYRp2d8Kkx + alice tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq + ``` + +- `add-alias ` add alias using its private key. Aliases + that are configured with the private key can be used to sign operations that + originate or call smart contracts on-chain. `tznft` commands that require Tezos + operation signing have `--signer` option. + + Example: + + ```sh + $ tznft add-alias jane edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq + + alias jane has been added + + $ tznft show-alias jane + + jane tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq + ``` + +- `add-alias
` add alias using Tezos address (public key hash). + Such aliases do not have an associated private key and cannot be used to sign + Tezos operations. + + Example: + + ```sh + $ tznft add-alias michael tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb + + alias michael has been added + + $ tznft show-alias michael + + michael tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb + ``` + +- `add-alias-faucet ` add alias with private key + from the faucet file (see [Tezos Faucet](https://faucet.tzalpha.net/)). This + command will not work on `sandbox` network. An alias configured from the faucet + has the private key and can be used to sign Tezos operations. + + Example: + + ```sh + $ tznft add-alias-faucet john ~/Downloads/tz1NfTBQM9QpZpEY6GSvdw3XBpyEjLLGhcEU.json + + activating faucet account... + faucet account activated + alias john has been added + + $ tznft show-alias john + + john tz1NfTBQM9QpZpEY6GSvdw3XBpyEjLLGhcEU edskRzaCrGEDr1Ras1U55U73dXoLfQQJyuwE95rSkqbydxUS4oS3fGmWywbaVcYw7DLH34zedoJzwMQxzAXQdixi5QzYC5pGJ6 + ``` + +- `remove-alias ` remove the alias from the selected network configuration. + + Example: + + ```sh + $ tznft remove-alias john + + alias john has been deleted + ``` + +:::note +This guide was created by Oxhead Alpha and can be found [here](https://github.com/oxheadalpha/nft-tutorial/blob/master/packages/tznft/README.md). +:::note diff --git a/src/pages/tutorials/create-an-nft/fa2/index.md b/docs/tutorials/create-an-nft/fa2/index.md similarity index 98% rename from src/pages/tutorials/create-an-nft/fa2/index.md rename to docs/tutorials/create-an-nft/fa2/index.md index bade7d8cf..37eaea41a 100644 --- a/src/pages/tutorials/create-an-nft/fa2/index.md +++ b/docs/tutorials/create-an-nft/fa2/index.md @@ -1,5 +1,4 @@ --- -id: 1-fa2-smartpy title: "Using\_FA2-SmartPy" sidebar_label: FA2-SmartPy lastUpdated: 30th June 2023 @@ -21,7 +20,7 @@ This part requires 4 accounts with a few ꜩ imported into `tezos-client`, as In the case of the sandbox tutorial we use `alice` also as `originator` and `administrator`: -``` sh +```sh $ tezos-client import secret key alice \ unencrypted:edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq \ --force @@ -41,12 +40,12 @@ In the case of the sandbox tutorial we use `alice` also as `originator` and FA2-SmartPy uses SmartPy's meta-programming facilities to provide more than one Michelson contract, a.k.a. *“builds.”*. A few of the builds are available at -, see +https://gitlab.com/smondet/fa2-smartpy/-/tree/master/michelson, see [below](#originate) for a description of the various builds. Let's download the “default” one: -``` sh +```sh $ wget -O fa2_default.tz \ 'https://gitlab.com/smondet/fa2-smartpy/-/raw/4acac092/michelson/20200910-203659+0000_5060996_contract.tz' @@ -74,7 +73,7 @@ to fill the contract. Let's originate such an unpaused empty contract while setting the `administrator` address: -``` sh +```sh $ tezos-client originate contract myfa2 \ transferring 0 from originator \ running fa2_default.tz \ @@ -88,9 +87,9 @@ Let's originate such an unpaused empty contract while setting the ┃ Operation hash is 'opa4ZVgJGkXzeRypcnqso1CF8LrgVEYq4R2QwGkFT2kzw2L9Tqp' ┃ Waiting for the operation to be included... ┃ Operation found in block: BM2FVXcXeYxBaDPkt1X2etZrnkJTG19pazm6wd5FVCrxGm6tS2o (pass: 3, offset: 0) -┃ +┃ ┃ ... -┃ +┃ ┃ tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb ... -ꜩ0.257 ┃ New contract KT1FQrHRqqqZ23Md9Ec5KJ3WK66fNxi9izZJ originated. ┃ The operation has only been included 0 blocks ago. @@ -120,7 +119,7 @@ contract (see [documentation](https://gitlab.com/smondet/fa2-smartpy/)). For instance, let's, as `administrator`, mint 100 `TK0` tokens to `alice`: -``` sh +```sh $ tezos-client transfer 0 from administrator to myfa2 \ --entrypoint mint \ --arg '(Pair (Pair "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb" 100) (Pair "TK0" 0))' \ @@ -132,9 +131,9 @@ For instance, let's, as `administrator`, mint 100 `TK0` tokens to `alice`: ┃ Operation hash is 'ooL9T4cK1RyYz4HxjfyixPW3n5iJf2hX6G47iQToa7sDTb6fjHr' ┃ Waiting for the operation to be included... ┃ Operation found in block: BMGWJeRyTtUL2Pi9xgAi3MU7kkgMCr4pUeYALaVhQAi4uJS37ae (pass: 3, offset: 0) -┃ +┃ ┃ ... -┃ +┃ ┃ Consumed gas: 117731 ┃ Balance updates: ┃ tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb ... -ꜩ0.163 @@ -161,7 +160,7 @@ a “from-address” and a list of outgoing transactions: Here we, as `alice`, transfer 5 of our 100 TK0 to `bob`: -``` sh +```sh $ tezos-client transfer 0 from alice to myfa2 \ --entrypoint transfer \ --arg '{ Pair "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb" {Pair "tz1aSkwEot3L2kmUvcoxzjMomb9mvBNuzFK6" (Pair 0 5)} }' \ @@ -174,9 +173,9 @@ Here we, as `alice`, transfer 5 of our 100 TK0 to `bob`: ┃ Waiting for the operation to be included... ┃ Operation found in block: BM2yNL1kjRJvrSeuzX2P6iid4f5Fx7JBjn2K2MYYsYTF3eFcVQ4 (pass: 3, offset: 0) ┃ This sequence of operations was run: -┃ +┃ ┃ ... -┃ +┃ ┃ Consumed gas: 119800 ┃ Balance updates: ┃ tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb ... -ꜩ0.067 @@ -228,13 +227,13 @@ code In this case, we expect the `tezos-client` command to fail, since we want to read the error message: -``` sh +```sh $ tezos-client run script get-balance.tz on storage Unit \ and input \ "$(tezos-client get contract storage for myfa2)" -‖ +‖ ‖ ... -‖ +‖ ‖ 22: GET ; # Get the value in the ledger at the above key ‖ 23: FAILWITH ‖ 24: }; @@ -256,7 +255,7 @@ In this section we use the `fatoo` command line interface to some *builds* of FA2-SmartPy. You need `fatoo` installed in your `$PATH` or you may use Docker: -``` sh +```sh $ fatoo --version # or: docker run -it --rm --entrypoint fatoo registry.gitlab.com/smondet/fa2-smartpy:4acac092-run --version @@ -275,7 +274,11 @@ Two environment variables can be used to configure See command `fatoo show-client-uri-documentation`: -
+ + +
The URI follows the usual pattern: `://:/?`: @@ -301,7 +304,7 @@ Assuming we are using the [sandbox](https://assets.tqtezos.com/docs/setup/2-sandbox) setup, we can configure the client using `alice`'s private key as follows: -``` sh +```sh export fatoo_client='http://:20000/unencrypted:edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq?wait=0' # Or, for docker, use: @@ -312,7 +315,7 @@ alias fatoo='docker run -it -u "$UID" --network host -v "$PWD:/work" -w /work -- The application has a `client` subcommand which just calls `tezos-client` properly, one may test their setup with: -``` sh +```sh $ fatoo client bootstrapped ┃ Node is bootstrapped. ``` @@ -322,7 +325,7 @@ properly, one may test their setup with: Here we create four key-pairs from mnemonic seeds, to be used in the following sections: -``` sh +```sh $ fatoo account-of-seed \ "the-only-administrator-of-the-contract" \ --output admin.csv @@ -342,7 +345,7 @@ The resulting CSVs are in the same format as with [flextesa](https://tezos.gitlab.io/flextesa/), they contain: `,,,` see for instance: -``` sh +```sh $ echo "Public key hash: $(cut -d, -f 3 admin.csv)" echo "Secret key: $(cut -d, -f 4 admin.csv)" ┃ Public key hash: tz1ZnxqPNMXyiZLTANYJLJ9ZTBpQ5Qu16BXe @@ -351,7 +354,7 @@ The resulting CSVs are in the same format as with Let's name all of these: -``` sh +```sh $ export admin_pkh="$(cut -d, -f 3 admin.csv)" export admin_sk="$(cut -d, -f 4 admin.csv)" export owner0_pkh="$(cut -d, -f 3 owner0.csv)" @@ -367,7 +370,7 @@ Let's name all of these: The application contains the code for a few variants of the contract: -``` sh +```sh $ fatoo list-contract-variants \ --details description --format markdown ┃ * `contract`: The default. @@ -393,7 +396,7 @@ application. Let's originate `mutran_contract`, the full blown FA2 implementation with an extra entry-point which allows the administrator to transfer funds which may potentially end-up in the contract's balance. -``` sh +```sh $ fatoo originate mutran_contract \ --administrator "${admin_pkh}" \ --output-address kt1_mutran_contract.txt @@ -406,14 +409,14 @@ transfer funds which may potentially end-up in the contract's balance. The command has saved the contract address in the file: -``` sh +```sh $ cat kt1_mutran_contract.txt ┃ KT1Qmqtc6pYnivEkR1Pedt684XSH4RjmoU6w ``` And we can already display the state of the contract (storage): -``` sh +```sh $ fatoo show-storage "$(cat kt1_mutran_contract.txt)" ‖ [FA2->Info]: ‖ Contract: KT1Qmqtc6pYnivEkR1Pedt684XSH4RjmoU6w @@ -434,7 +437,7 @@ contract on chain, for this we need to transfer at least a few μꜩ to that address. One can use `tezos-client` but `fatoo` has shortcut command to transfer from the configured “funding” account (amounts are in `mutez`): -``` sh +```sh $ fatoo fund-address \ "${admin_pkh}" \ 10_000_000 @@ -445,7 +448,7 @@ transfer from the configured “funding” account (amounts are in `mutez`): Note that for now `owner0` does not exist on chain, we're still minting tokens to them: -``` sh +```sh $ fatoo call-mint --token-id 0 --token-symbol TQ0 \ "${owner0_pkh}" 1_000_000 \ --source "${admin_sk}" \ @@ -455,7 +458,7 @@ tokens to them: Let's add another token `TQ1` still minting some to `owner0`: -``` sh +```sh $ fatoo call-mint --token-id 1 --token-symbol TQ1 \ "${owner0_pkh}" 2_000 \ --source "${admin_sk}" \ @@ -467,7 +470,7 @@ Let's see the storage; we see the new tokens `TQ0` and `TQ1` and, since we provide a “known token owner” on the command-line, we can see their balances: -``` sh +```sh $ fatoo show-storage "$(cat kt1_mutran_contract.txt)" \ --known-address "$(cut -d, -f 3 owner0.csv)" ‖ [FA2->Info]: @@ -489,7 +492,7 @@ balances: Now let's get `owner0` to do a batch-transfer. First, we need to feed some gas to that address: -``` sh +```sh $ fatoo fund-address \ "${owner0_pkh}" \ 1_000_000 @@ -500,7 +503,7 @@ gas to that address: Then, since the token-owner can do self-transfer we use `owner0`'s secret-key to transfer TQ0s and TQ1s to `owner1` and `owner2`: -``` sh +```sh $ fatoo call-transfer \ "from:${owner0_pkh} to:${owner1_pkh} amount: 10 token: 0" \ "from:${owner0_pkh} to:${owner1_pkh} amount: 100 token: 1" \ @@ -512,7 +515,7 @@ to transfer TQ0s and TQ1s to `owner1` and `owner2`: We can then observe the resulting state: -``` sh +```sh $ fatoo show-storage "$(cat kt1_mutran_contract.txt)" \ --known-address "$(cut -d, -f 3 owner0.csv)" \ --known-address "$(cut -d, -f 3 owner1.csv)" \ @@ -542,7 +545,7 @@ We can then observe the resulting state: Let's create an `operator` key-pair: -``` sh +```sh $ fatoo account-of-seed \ "youve-been-operated-ill-be-back" \ --output operator.csv @@ -553,7 +556,7 @@ Let's create an `operator` key-pair: We will now get all the owners to delegate _all_ their tokens to “operator,” see also the command `fatoo call-update-operators --help`: -``` sh +```sh $ fatoo call-update-operators \ "add@ operator: ${operator_pkh} owner: ${owner0_pkh} token: 0" \ "add@ operator: ${operator_pkh} owner: ${owner0_pkh} token: 1" \ @@ -579,7 +582,7 @@ We will now get all the owners to delegate _all_ their tokens to We see that now, the same operator is present in every account: -``` sh +```sh $ fatoo show-storage "$(cat kt1_mutran_contract.txt)" \ --known-address "$(cut -d, -f 3 owner0.csv)" \ --known-address "$(cut -d, -f 3 owner1.csv)" \ @@ -613,7 +616,7 @@ We see that now, the same operator is present in every account: Finally, let's get `operator` to run a *batch-transfer-heist* of all the tokens: -``` sh +```sh $ fatoo fund-address \ "${operator_pkh}" \ 2_000_000_000 @@ -622,7 +625,7 @@ tokens: ‖ 5999358655 mutez. ``` -``` sh +```sh $ fatoo call-transfer \ "from:${owner0_pkh} to:${operator_pkh} amount: 999990 token: 0" \ "from:${owner0_pkh} to:${operator_pkh} amount: 1890 token: 1" \ @@ -638,7 +641,7 @@ tokens: We can then observe the resulting state where all the balances are `0` except for `operator` who owns the total supply: -``` sh +```sh $ fatoo show-storage "$(cat kt1_mutran_contract.txt)" \ --known-address "$(cut -d, -f 3 owner0.csv)" \ --known-address "$(cut -d, -f 3 owner1.csv)" \ @@ -683,16 +686,16 @@ itself (this may be a convoluted excuse to put XTZ on the contract …). We call the `transfer` entry-point with an empty list of transfer-items but with a few XTZ as amount: -``` sh +```sh $ tezos-client import secret key operator \ "${operator_sk}" --force tezos-client transfer 1_000 from operator \ to "$(cat kt1_mutran_contract.txt)" \ --entrypoint transfer \ --arg '{}' --burn-cap 1 -┃ +┃ ┃ ... -┃ +┃ ┃ Balance updates: ┃ tz1NkpWhHsBSZHPg2Ljz2hycRiZvcYdcyu85 ... -ꜩ1000 ┃ KT1Qmqtc6pYnivEkR1Pedt684XSH4RjmoU6w ... +ꜩ1000 @@ -705,7 +708,7 @@ a few XTZ as amount: We see that `fatoo` shows a non-zero balance for the contract now: -``` sh +```sh $ fatoo show-storage "$(cat kt1_mutran_contract.txt)" ‖ [FA2->Info]: ‖ Contract: KT1Qmqtc6pYnivEkR1Pedt684XSH4RjmoU6w @@ -723,7 +726,7 @@ We see that `fatoo` shows a non-zero balance for the contract now: Let's make `admin` retrieve that money for themselves; the entry-point is called `mutez_transfer` and takes a pair `mutez × address`: -``` sh +```sh $ tezos-client import secret key admin \ "${admin_sk}" --force tezos-client transfer 0 from admin \ @@ -731,9 +734,9 @@ called `mutez_transfer` and takes a pair `mutez × address`: --entrypoint mutez_transfer \ --arg "Pair 1000000000 \"${admin_pkh}\"" \ --burn-cap 1 -┃ +┃ ┃ ... -┃ +┃ ┃ Balance updates: ┃ KT1Qmqtc6pYnivEkR1Pedt684XSH4RjmoU6w ... -ꜩ1000 ┃ tz1ZnxqPNMXyiZLTANYJLJ9ZTBpQ5Qu16BXe ... +ꜩ1000 @@ -746,7 +749,7 @@ called `mutez_transfer` and takes a pair `mutez × address`: We see that the balance is gone from the KT1: -``` sh +```sh $ fatoo show-storage "$(cat kt1_mutran_contract.txt)" ‖ [FA2->Info]: ‖ Contract: KT1Qmqtc6pYnivEkR1Pedt684XSH4RjmoU6w @@ -763,7 +766,7 @@ We see that the balance is gone from the KT1: … and see that `admin` is wealthier: -``` sh +```sh $ tezos-client get balance for \ "${admin_pkh}" ┃ 5057.816076 ꜩ diff --git a/src/pages/tutorials/create-an-nft/nft-taquito/index.md b/docs/tutorials/create-an-nft/nft-taquito.md similarity index 94% rename from src/pages/tutorials/create-an-nft/nft-taquito/index.md rename to docs/tutorials/create-an-nft/nft-taquito.md index b2f2e841d..920354c01 100644 --- a/src/pages/tutorials/create-an-nft/nft-taquito/index.md +++ b/docs/tutorials/create-an-nft/nft-taquito.md @@ -1,6 +1,5 @@ --- -id: nft-taquito -title: Create a web app that mints NFTs +title: Create a contract and web app that mints NFTs authors: 'Sol Lederer, Tim McMackin' lastUpdated: 20th September 2023 --- @@ -41,16 +40,16 @@ The application that you set up in this tutorial has three parts: This diagram shows what happens when the user creates an NFT with the application. The rest of this tutorial covers these steps in detail: -![Flow diagram of the tutorial application and interaction between the user and the parts of the application](/images/nft-create/taquito-application-flow.png) +![Flow diagram of the tutorial application and interaction between the user and the parts of the application](/img/tutorials/taquito-application-flow.png) The frontend application looks like this, with fields for the image to represent the NFT and for its metadata: -![The home page of the frontend application](/images/nft-create/taquito-application-home.png) +![The home page of the frontend application](/img/tutorials/taquito-application-home.png) ## Prerequisites To run this tutorial you need Node.JS and NPM installed. -See . +See https://nodejs.org/. You can verify that they are installed by running these commands: ```bash @@ -69,13 +68,13 @@ In this section, you set up storage for the NFT metadata using the InterPlanetar IPFS requires authentication just like blockchain transactions, so in this section you set up an account with the Pinata IPFS provider and use it to upload (or _pin_) the NFT data to IPFS. -1. Create a free Pinata account at . +1. Create a free Pinata account at https://app.pinata.cloud/developers/api-keys. 1. Go to the API Keys tab and click **New Key**. 1. On the Create New API Key page, expand **API Endpoint Access > Pinning** and enable the `pinFileToIPFS` and `pinJSONToIPFS` permissions, as in this picture: - ![Selecting the permissions for the Pinata key](/images/nft-create/pinata-key-permissions.png) + ![Selecting the permissions for the Pinata key](/img/tutorials/pinata-key-permissions.png) 1. In the **Key Name** field, give the key a name, such as "My Key." @@ -88,7 +87,7 @@ You need these values in the next section. You can see the new API key on the API Keys tab: - ![The new Pinata API key in the Pinata web app](/images/nft-create/created-pinata-key.png) + ![The new Pinata API key in the Pinata web app](/img/tutorials/created-pinata-key.png) Now your applications can use your Pinata account to pin NFT data to IPFS. @@ -100,7 +99,7 @@ The tutorial application has three parts: - The backend application that handles uploading data to IPFS - The frontend application that connects to the user's wallet, sends the data to the backend application, and sends the transactions to the smart contract to mint the NFTs -The tutorial application files are in this GiHub repository: . +The tutorial application files are in this GiHub repository: https://github.com/trilitech/tutorial-applications/tree/main/nft-taquito. If you have the `git` program installed, you can clone the repository with this command: @@ -108,7 +107,7 @@ If you have the `git` program installed, you can clone the repository with this git clone https://github.com/trilitech/tutorial-applications.git ``` -If you don't have git installed, go to and click "Code > Download ZIP" and extra the ZIP file on your computer. +If you don't have git installed, go to https://github.com/trilitech/tutorial-applications/tree/main/nft-taquito> and click "Code Download ZIP" and extra the ZIP file on your computer. Then, go to the application in the `nft-taquito` folder. @@ -271,21 +270,21 @@ For this contract, the initial storage state is in the comment at the end of the ## Originate (deploy) the smart contract to the testnet There are many ways to originate a contract on Tezos. -For a tutorial on using the command line, see [Deploy a smart contract](../../deploy-your-first-smart-contract/). +For a tutorial on using the command line, see [Deploy a smart contract](../smart-contract/). Before you originate your contract to the main Tezos network (referred to as *mainnet*), you can originate it to a testnet. Testnets are useful for testing Tezos operations because testnets provide tokens for free so you can work with Tezos without spending real tokens. -This tutorial uses the online LIGO IDE at because you don't have to install any tools to use it. +This tutorial uses the online LIGO IDE at https://ide.ligolang.org/ because you don't have to install any tools to use it. Follow these steps to originate the smart contract to Tezos: -1. In a web browser, open the IDE at . +1. In a web browser, open the IDE at https://ide.ligolang.org/. 1. At the top right, click the **Network** drop-down list and next to **Tezos**, select the **Ghostnet** testnet. The network changes to the Ghostnet testnet, as in this picture: - ![The IDE menu, showing the Ghostnet testnet selected](/images/nft-create/web-ligo-ide-ghostnet.png) + ![The IDE menu, showing the Ghostnet testnet selected](/img/tutorials/web-ligo-ide-ghostnet.png) 1. Create an account to use to originate the contract: @@ -303,7 +302,7 @@ The network changes to the Ghostnet testnet, as in this picture: 1. Send funds to the account from the testnet faucet: - 1. Go to the Ghostnet faucet at . + 1. Go to the Ghostnet faucet at https://faucet.ghostnet.teztnets.xyz/. 1. Put the new account address in the **Or fund any address** field. @@ -311,7 +310,7 @@ The network changes to the Ghostnet testnet, as in this picture: 1. When you see a message that the tokens are sent to your address, go back to the web IDE, open the "Keypair Manager" window and verify that the account has tokens, as in this example: - ![The IDE Keypair Manager window, showing an account with funds](/images/nft-create/web-ligo-ide-account.png) + ![The IDE Keypair Manager window, showing an account with funds](/img/tutorials/web-ligo-ide-account.png) 1. In the IDE, Click the **New** button. @@ -354,7 +353,7 @@ If you see an error, make sure that you copied the entire contract file. 1. Leave the other fields blank and click **Estimate**. The IDE calculates the fees for the deployment. - 1. Click **Deploy** and leave the window open to wait for the contract to be originated. + 1. Click **Deploy** and leave the window open to wait for the contract to be originate. Originating the contract can take a few minutes. When the transaction completes, the window shows a message that the contract was deployed. @@ -645,7 +644,7 @@ To test the application, you must have a Tezos wallet and a small amount of XTZ 1. Send funds to the wallet from the testnet faucet: - 1. Go to the Ghostnet faucet at . + 1. Go to the Ghostnet faucet at https://faucet.ghostnet.teztnets.xyz/. 1. Put the wallet account address in the **Or fund any address** field. @@ -654,7 +653,7 @@ To test the application, you must have a Tezos wallet and a small amount of XTZ 1. When you see a message that the tokens are sent to your address, open your wallet and verify that the tokens are there. It can take a few minutes for them to appear. -1. When the frontend application starts, open the web browser to . +1. When the frontend application starts, open the web browser to http://localhost:5173/. 1. Click **Connect your wallet** and approve the connection in your wallet. @@ -669,12 +668,12 @@ To test the application, you must have a Tezos wallet and a small amount of XTZ 1. Wait for the transaction to complete. When it completes, the screen changes to a success message with links to the NFT information, as in this picture: - ![The success message, with links to the NFT information](/images/nft-create/taquito-application-created-nft.png) + ![The success message, with links to the NFT information](/img/tutorials/taquito-application-created-nft.png) In the "Your NFTs" list, you can click on a number (starting at 0) to see the information that is in the NFT, which includes the name and description that you added and links to data on IPFS. The page also shows a link to a block explorer where you can see technical information about the minting transaction. -To see information about the smart contract and NFT collection, go to a block explorer such as , set it to Ghostnet, and enter the address of the smart contract. +To see information about the smart contract and NFT collection, go to a block explorer such as https://tzkt.io/, set it to Ghostnet, and enter the address of the smart contract. The explorer shows information such a list of the tokens in the collection and who owns them. You can also see the current state of the storage for the contract. diff --git a/src/pages/tutorials/create-an-nft/nft-tznft/index.md b/docs/tutorials/create-an-nft/nft-tznft.md similarity index 93% rename from src/pages/tutorials/create-an-nft/nft-tznft/index.md rename to docs/tutorials/create-an-nft/nft-tznft.md index 82e5d172a..fccfd2085 100644 --- a/src/pages/tutorials/create-an-nft/nft-tznft/index.md +++ b/docs/tutorials/create-an-nft/nft-tznft.md @@ -1,6 +1,5 @@ --- -id: nft-tznft -title: Create an NFT with the `tznft` tool +title: Create NFTs with the `tznft` tool authors: 'Sol Lederer, Tim McMackin' lastUpdated: 18th September 2023 --- @@ -13,7 +12,7 @@ In this tutorial, you will learn: - What NFTs are - How to install and start a local Tezos sandbox environment - How to create metadata files to describe NFT collections and individual NFTs -- How to create (or _mint_) the NFTs in the sandbox +- How to deploy (or _mint_) the NFTs to the sandbox - How to transfer NFTs and change operator permissions for them - How to mint NFTs to a testnet @@ -26,7 +25,6 @@ NFTs can represent ownership over digital or physical assets like virtual collec Like other types of Tezos tokens, a collection of NFTs is managed by a smart contract. The smart contract defines what information is in each token and how the tokens behave, such as what happens when a user transfers an NFT to another user. -It also keeps a ledger that records which account owns each NFT. In this tutorial, you create NFTs that comply with the FA2 standard (formally known as the [TZIP-12](https://gitlab.com/tezos/tzip/-/blob/master/proposals/tzip-12/tzip-12.md) standard), the current standard for tokens on Tezos. The FA2 standard creates a framework for how tokens behave on Tezos, including fungible, non-fungible, and other types of tokens. @@ -37,7 +35,7 @@ It provides a standard API to transfer tokens, check token balances, manage oper To run this tutorial you need Node.JS, NPM, and Docker Desktop to install and use the `tznft` CLI tool, which helps you create and test NFT collections on Tezos. - Install Node.JS version 18 (not 20) and NPM. -See . +See https://nodejs.org/. You can verify that they are installed by running these commands: ```bash @@ -47,7 +45,7 @@ You can verify that they are installed by running these commands: If you see a message with the versions of Node.JS and NPM, they are installed correctly. -- To install Docker Desktop, see . +- To install Docker Desktop, see https://www.docker.com. Make sure to start Docker Desktop after you install it. - To install the `tznft` tool, run this command: @@ -106,7 +104,7 @@ Make sure to start Docker Desktop after you install it. You can verify that the sandbox is running by running the command `docker ps` and looking for a container named `flextesa-sandbox`. To stop the container, run the command `tznft kill-sandbox`, but beware that stopping the container sets the sandbox back to its initial state, which removes any changes you made or contracts or tokens that you created. - Unlike the live Tezos networks, this sandbox bakes a new block every 5 seconds, by default. + Unlike the live Tezos networks, this sandbox bakes a new block every 5 seconds. Therefore, commands that you run on the sandbox can take a few seconds to complete. ## Create NFT metadata @@ -142,7 +140,7 @@ The first step in creating NFTs is to create local metadata files that describe This command creates a metadata file named `Token1.json` with default information about the NFT. It includes the minter's account address and URIs to pictures that represent the NFT. - In this case, the `ipfs` URI links to a picture of the Tezos logo, which you can see at this link: . + In this case, the `ipfs` URI links to a picture of the Tezos logo, which you can see at this link: https://ipfs.io/ipfs/QmRyTc9KbD7ZSkmEf4e7fk6A44RPciW5pM4iyqRGrhbyvj. 1. Optional: Edit the metadata such as the name and description fields in the `Token1.json` file. @@ -225,29 +223,28 @@ Because storage space on blockchains is expensive, developers don't put entire t Instead, they configure decentralized storage for the NFT data and put only the link to that data on Tezos itself. In this section, you set up storage for the NFT metadata using the InterPlanetary File System (IPFS) protocol. -There are many services that provide access to IPFS, but in this tutorial you use the [Pinata](https://www.pinata.cloud/) IPFS provider. -Pinata requires authentication, so in this section you set up an account with Pinata and use it to upload (or _pin_) the NFT data to IPFS. +IPFS requires authentication just like blockchain transactions, so in this section you set up an account with the Pinata IPFS provider and use it to upload (or _pin_) the NFT data to IPFS. -1. Create a free Pinata account at . +1. Create a free Pinata account at https://app.pinata.cloud/developers/api-keys. 1. Go to the API Keys tab and click **New Key**. -1. On the Create New API Key page, expand **API Endpoint Access > Pinning,** and enable the `pinFileToIPFS` permission, as in this picture: +1. On the Create New API Key page, expand API Endpoint Access and enable the `pinFileToIPFS` permission, as in this picture: - ![Selecting the permissions for the Pinata key](/images/nft-create/pinata-key-permissions.png) + ![Selecting the permissions for the Pinata key](/img/tutorials/pinata-key-permissions.png) 1. In the **Key Name** field, give the key a name, such as "My Key." 1. Click **Create Key**. - The API Key Info window shows the API key and secret, which you must copy immediately, because they are not shown again. + The API Key Info window shows the API key and secret, which you must copy immediately, because it is not shown again. 1. Copy the API Key and API Secret fields and save the values on your computer. You need these values in the next section. You can see the new API key on the API Keys tab: - ![The new Pinata API key in the Pinata web app](/images/nft-create/created-pinata-key.png) + ![The new Pinata API key in the Pinata web app](/img/tutorials/created-pinata-key.png) 1. Add the API key and secret to your local `tznft` configuration by running this command, replacing `$PINATA_KEY` and `$PINATA_SECRET` with your API key and secret: @@ -271,7 +268,7 @@ You need these values in the next section. 1. Optional: Verify that the files are pinned successfully by opening the Pinata app to the Files page, as in this picture: - ![The Files tab on Pinata, showing three NFT metadata files](/images/nft-create/pinned-nft-meta.png) + ![The Files tab on Pinata, showing three NFT metadata files](/img/tutorials/pinned-nft-meta.png) Now that the metadata is pinned to IPFS, you can create NFTs that link to this metadata. @@ -348,7 +345,7 @@ This command takes the alias or address of the collection, the signer of the tra Because NFTs are unique, the response shows a balance of 1 if the account owns the token and 0 if it does not, as in this picture: - ![THe results of the `show-balance` command, with two NFTs in Bob's account](/images/nft-create/show-balance-bob.png) + ![THe results of the `show-balance` command, with two NFTs in Bob's account](/img/tutorials/show-balance-bob.png) 1. Use the `tznft show-balance` command to print information about Alice's NFTs: @@ -459,7 +456,7 @@ You can do this in either of these two ways: The response includes the hash, public key, and secret key for the wallet. For example, in this response, the secret key starts with "edsk3WR": - ![The keys for the new account](/images/nft-create/new-key-output.png) + ![The keys for the new account](/img/tutorials/new-key-output.png) 1. Add the secret key as an alias with the `tznft` command, replacing `$TEZOS_PRIVATE_KEY` with the value of the secret key from the previous command: @@ -467,7 +464,7 @@ You can do this in either of these two ways: tznft add-alias my-account $TEZOS_PRIVATE_KEY ``` - 1. Add funds to the new wallet by going to the Ghostnet faucet at , pasting the wallet's hash in the "Or fund any address" field, and clicking a button to request tokens. + 1. Add funds to the new wallet by going to the Ghostnet faucet at https://faucet.ghostnet.teztnets.xyz/, pasting the wallet's hash in the "Or fund any address" field, and clicking a button to request tokens. The wallet needs tokens to pay the fees to create the collection and mint the tokens on Ghostnet. 1. Create the collection on the testnet. @@ -499,7 +496,7 @@ The command is the same as for the sandbox: 1. Get the address of the collection on the testnet from the `testnet` section of the `tznft.json` file. The address starts with "KT1". - 1. Go to a block explorer, such as . + 1. Go to a block explorer, such as https://tzkt.io. 1. Set the block explorer to use testnet instead of Tezos mainnet. @@ -520,4 +517,7 @@ tznft transfer --nft my_collection --signer my-account --batch 'my-account, othe Now you can create, test, and deploy NFTs locally and to testnets. The process for minting NFTs to Tezos mainnet is the same, but you must use an account with real XTZ in it to pay the transaction fees. + diff --git a/docs/tutorials/create-an-nft/nft-web-app.md b/docs/tutorials/create-an-nft/nft-web-app.md new file mode 100644 index 000000000..2ae471702 --- /dev/null +++ b/docs/tutorials/create-an-nft/nft-web-app.md @@ -0,0 +1,56 @@ +--- +title: Mint NFTs from a web app +authors: 'Yuxin' +lastUpdated: 19th October 2023 +--- + +This tutorial shows you how to create a web application that interacts with the Tezos blockchain to mint non-fungible tokens (NFTs). NFTs are unique digital assets that can represent art, collectibles, or virtually any kind of digital content on the blockchain. Specifically, this application will be the user-facing web front end for a smart contract that performs operations such as mint. + +You will learn: + +- How to create a web application and import JavaScript libraries that access Tezos blockchain +- How to call a smart contract from a web application +- How to connect to a user's wallet +- How to mint NFTs on behalf of a user + +## Prerequisites + +This tutorial uses [Javascript](https://www.javascript.com/), so it will be easier if you are familiar with JavaScript. + +- You do not need any familiarity with any of the libraries in the tutorial, including [Taquito](https://tezostaquito.io/), a JavaScript library that helps developers access Tezos. + +Before start creating this dApp, we will need a [wallet](../../dApps/wallets) and some ghostnet tez(ꜩ). + +## The smart contract + +The backbone of this application is the smart contract deployed on the Tezos blockchain. The contract we'll be using is already deployed and is written in [SmartPy](../../smart-contracts/languages/smartpy). It defines the rules and processes for interactions with the Tezos blockchain, such as minting NFTs. All you need to do is integrate it into your web app. + + +## The tutorial application + +In this tutorial, you build a web application that allows users to mint NFTs via the smart contract. +The interface of the application will look like this: + +![Mint UI](/img/tutorials/mint-ui.png "Mint UI") + +The application can perform many individual actions, including: + +- Connecting and disconnecting users' wallets +- Displaying users' information, including their wallet address and tez balance +- Allowing users to mint NFTs on the Tezos blockchain + + +The application is based on JavaScript, so it uses several JS and TS-based tools to build and package the application: + +- **[Svelte](https://svelte.dev/)** for the JavaScript framework +- **[JavaScript](https://www.javascript.com/)** to make the JavaScript code safer and more expressive +- **[Vite](https://vitejs.dev/)** (pronounced like _veet_) to bundle the application and provide the libraries to the user's browser + +Also, to access the user's wallet and run transactions on Tezos, the application uses these libraries: + +- **[Taquito](https://tezostaquito.io/)** to interact with the Tezos blockchain +- **[Beacon](https://docs.walletbeacon.io/)** to access users' wallets + +You can see the completed tutorial application here: https://github.com/trilitech/tutorial-applications/simple-nft-svelte + +When you're ready, move to the next section to begin setting up the application. diff --git a/docs/tutorials/create-an-nft/nft-web-app/defining-functions.md b/docs/tutorials/create-an-nft/nft-web-app/defining-functions.md new file mode 100644 index 000000000..49cea94fe --- /dev/null +++ b/docs/tutorials/create-an-nft/nft-web-app/defining-functions.md @@ -0,0 +1,175 @@ +--- +title: "Part 2: Accessing wallets and minting NFTs" +authors: 'Yuxin Li' +lastUpdated: 20th October 2023 +--- + +Accessing the user's wallet is essential before your application can engage with the Tezos blockchain. It enables your app to view the tokens within the wallet and request the user to initiate transactions. However, it's important to note that accessing the wallet doesn't grant your app direct control over it. + +## Connecting to the user's wallet + +In this section, you add code to connect to the user's wallet with the `TezosToolkit` and `BeaconWallet` objects. + +IMPORTANT: however you design your app, it is essential to use a single instance of the `BeaconWallet` object. +It is also highly recommended use a single instance of the `TezosToolkit` object. +Creating multiple instances can cause problems in your app and with Taquito in general. + +1. Open the file named `src/App.svelte` and add the following code in the ` + ``` + + The `connectWallet` function creates a `BeaconWallet` object that represents the user's wallet. + It provides a name for the app, which appears in the wallet UI when it asks the user to allow the connection. + It also includes the network to use, such as the Tezos main network or test network. + +1. Add the following code in ` + + Simple NFT dApp + + + + + + ``` + + This updated file sets the `global` variable to `globalThis` and adds a buffer object to the window. + The Beacon SDK requires this configuration to run in a Vite app. + +## File structure + +The final structure of the tutorial application will look like this: + +``` +- src + - assets + - lib + - app.css + - App.svelte + - main.js + - vite-env.d.ts +- index.html +- jsconfig.json +- package-lock.json +- package.json +- svelte.config.js +- vite.config.js +``` + +Here are descriptions for each of these files: + +- **assets** -> Contains the favicon and other static files such as images for the application. +- **lib** -> Contains the components that make up the app interface: +- **app.css** -> Contains global styles that apply to the entire app. +- **App.svelte** -> The entrypoint of the application, which contains the components that are bundled into the final application. +- **main.js** -> Where the JavaScript for the app is bundled before being injected into the HTML file. +- **vite-env.d.ts** -> A JavaScript declaration file automatically generated by Vite to provide type definitions for environment variables. +- **index.html** -> Contains the root element where the Svelte app gets attached. +- **jsconfig.json** -> +- **package.json** -> Contains metadata about the project like its name, version, and dependencies. +- **svelte.config.js** -> Configuration file for the Svelte application. +- **vite.config.js** -> Used to customize Vite's behavior, including defining plugins, setting up aliases, and more. + +## Importing the style sheets + +These steps set up the style sheets for the application: + +1. In the `src/main.js` file, import the style sheets by replacing the default code of the file with this code: + + ```javascript + import './app.css' + import App from './App.svelte' + + const app = new App({ + target: document.body + }) + + export default app + ``` + + This code targets the `body` tag to inject the HTML produced by JavaScript instead of a `div` tag inside the `body` tag as Svelte apps do by default. + Your applications can target any tag on the page. + +## Configuring Svelte + +Svelte files include several different types of code in a single file. +The files you will create have separate sections for JavaScript, style, and HTML code, as in this example: + +```html + + + + +
+ +
+``` + +Svelte components are fully contained, which means that the style and JS/TS code that you apply inside a component doesn't leak into the other components of your app. +Styles and scripts that are shared among components typically go in the `src/styles` and `scripts` or `src/scripts` folders. + +Follow these steps to set up the `src/App.svelte` file, which is the container for the other Svelte components: + +1. In the `App.svelte` file, replace the default `
` section with this code to set up a title for the interface: + + ```html +
+

Simple NFT dApp

+ +
+ ``` + + The interface will change after connecting to the wallet and minting an NFT. + +1. Remove the default ` + ``` + +1. Remove the default JavaScript section and replace it with this code, which imports the libraries and components that the app uses: + + ```html + + ``` + + The imports include these elements: + + - `BeaconWallet`: The class provides a user interface for transaction requests, ensuring that users can securely and easily sign transactions or execute contract calls. + - `TezosToolkit`: The class that gives you access to all the features of Taquito + - `NetworkType`: The class represents the different types of networks on the Tezos blockchain. Developers can ensure that their applications communicate with the desired network version or testnet such as ghostnet, + - `MichelsonMap`: The class helps developers work with Michelson's native map data type. + +1. In the ` - - Liquidity Baking DEX - - - - - - ``` - - This updated file sets the `global` variable to `globalThis` and adds a buffer object to the window. - The Beacon SDK requires this configuration to run in a Vite app. - -## File structure - -The final structure of the tutorial application will look like this: - -``` -- src - - assets - - svelte.png - - lib - - AddLiquidityView.svelte - - Interface.svelte - - RemoveLiquidity.svelte - - Sidebar.svelte - - SirsStats.svelte - - SwapView.svelte - - Toast.svelte - - UserInput.svelte - - UserStats.svelte - - Wallet.svelte - - styles - - index.scss - - settings.scss - - App.svelte - - config.ts - - lbUtils.ts - - main.ts - - store.ts - - types.ts - - utils.ts -- index.html -- svelte.config.js -- tsconfig.json -- vite.config.js -``` - -Here are descriptions for each of these files: - -- **assets** -> Contains the favicon and other static files such as images for the application -- **lib** -> Contains the components that make up the app interface: - - `SwapView.svelte`: The interface to swap XTZ and tzBTC tokens - - `AddLiquidityView.svelte`: The interface to add liquidity to the LB DEX - - `RemoveLiquidity.svelte`: The interface to remove liquidity from the LB DEX - - `Interface.svelte`: The higher-order component that contains the different views to interact with the LB DEX - - `Sidebar.svelte`: The component that navigates between the different interfaces and that hosts the button to connect or disconnect the wallet - - `SirsStats.svelte`: The component to display the amount of XTZ, tzBTC, and SIRS present in the LB contract - - `Toast.svelte`: A simple component to display the progress of the transactions and other messages - - `UserInput.svelte`: A utility component to make it easier to interact with input fields - - `UserStats.svelte`: The component to display the user's balance in XTZ, tzBTC, and SIRS - - `Wallet.svelte`: The component that manages wallet interactions -- **styles** -> Contains the Sass files to style different elements of our interface -- **App.svelte** -> The entrypoint of the application, which contains the components that are bundled into the final application -- **config.ts** -> Constants for the application -- **lbUtils.ts** -> Methods to calculate values needed to interact with the LB contract, such as calculating the amount of output tokens -- **main.ts** -> Where the JavaScript for the app is bundled before being injected into the HTML file -- **store.ts** -> A file with a [Svelte store](https://svelte.dev/tutorial/writable-stores) to handle the app state -- **types.ts** -> Custom TypeScript types -- **utils.ts** -> Utility methods - -## Setting up the style sheets - -Svelte uses Sass, which allows you to create powerful and simple CSS style sheets. -These steps set up the style sheets for the application: - -1. Create a file in the `src/styles` folder (creating the folder if necessary) named `index.scss` and paste in this code: - - ```css - @import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap"); - @import "./settings.scss"; - - html, - body { - height: 100%; - width: 100%; - padding: 0px; - margin: 0px; - font-family: "Montserrat", sans-serif; - font-size: $font-size; - background-color: $honeydew; - color: $prussian-blue; - } - - button { - cursor: pointer; - padding: calc(#{$padding} / 2); - outline: none; - transition: 0.3s; - display: flex; - justify-content: center; - align-items: center; - gap: 10px; - - &.primary { - border: solid 2px $celadon-blue; - border-radius: 5px; - background-color: $celadon-blue; - color: white; - font-family: inherit; - font-size: 0.9rem; - - &:hover { - transform: translateY(-2px); - } - - &:disabled { - text-decoration: line-through; - } - } - - &.wallet-button { - align-items: center; - appearance: none; - background-color: #fcfcfd; - border-radius: 4px; - border-width: 0; - box-shadow: rgba(45, 35, 66, 0.4) 0 2px 4px, - rgba(45, 35, 66, 0.3) 0 7px 13px -3px, #d6d6e7 0 -3px 0 inset; - box-sizing: border-box; - color: inherit; - cursor: pointer; - display: inline-flex; - justify-content: center; - height: 48px; - line-height: 1; - list-style: none; - overflow: hidden; - padding: 0px 16px; - position: relative; - text-align: center; - text-decoration: none; - transition: box-shadow 0.15s, transform 0.15s; - user-select: none; - -webkit-user-select: none; - touch-action: manipulation; - white-space: nowrap; - will-change: box-shadow, transform; - font-size: inherit; - - &:focus { - box-shadow: #d6d6e7 0 0 0 1.5px inset, rgba(45, 35, 66, 0.4) 0 2px 4px, - rgba(45, 35, 66, 0.3) 0 7px 13px -3px, #d6d6e7 0 -3px 0 inset; - } - - &:hover { - box-shadow: rgba(45, 35, 66, 0.4) 0 4px 8px, - rgba(45, 35, 66, 0.3) 0 7px 13px -3px, #d6d6e7 0 -3px 0 inset; - transform: translateY(-2px); - } - - &:active { - box-shadow: #d6d6e7 0 3px 7px inset; - transform: translateY(2px); - } - } - - &.sidebar-button { - background-color: transparent; - border: solid 3px transparent; - font-size: inherit; - font-family: inherit; - color: inherit; - margin: 10px; - border-radius: 4px; - - &:hover { - background-color: $powder-blue; - } - - &.active { - border-color: $powder-blue; - } - } - - &.transparent { - background-color: transparent; - border: none; - padding: 0px; - margin: 0px; - color: inherit; - } - - &:disabled { - cursor: not-allowed; - - &:hover { - transform: translateY(0px); - } - } - } - - h1 { - font-size: 2rem; - font-weight: bold; - margin: 0px; - margin-bottom: $padding; - } - - .input-with-logo { - img { - height: 32px; - width: 32px; - } - input { - height: 28px; - padding: 5px 10px; - border: solid 2px transparent; - border-radius: $std-border-radius; - outline: none; - background-color: darken($honeydew, 8); - transition: 0.3s; - font-size: inherit; - color: inherit; - - &:focus { - border-color: $powder-blue; - } - - &.error { - border-color: $imperial-red; - } - } - - .input-with-logo__input { - display: flex; - justify-content: center; - align-items: center; - gap: 10px; - padding: 5px 0px; - } - - .input-with-logo__max { - font-size: 0.8rem; - color: inherit; - } - &.left-logo .input-with-logo__max { - float: left; - padding-left: 10px; - } - &.right-logo .input-with-logo__max { - float: right; - padding-right: 10px; - } - } - - .container { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 20px; - border: solid 3px darken($powder-blue, 10); - border-radius: $std-border-radius; - padding: calc(#{$padding} * 3); - margin: 20px; - background-color: $powder-blue; - } - - @media screen and (max-height: 700px) { - .container { - padding: 15px; - } - } - - .spinner { - display: inline-block; - position: relative; - width: $font-size; - height: $font-size; - } - .spinner div { - box-sizing: border-box; - display: block; - position: absolute; - width: $font-size; - height: $font-size; - border: 2px solid #fff; - border-radius: 50%; - animation: spinner 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; - border-color: #fff transparent transparent transparent; - } - .spinner div:nth-child(1) { - animation-delay: -0.45s; - } - .spinner div:nth-child(2) { - animation-delay: -0.3s; - } - .spinner div:nth-child(3) { - animation-delay: -0.15s; - } - @keyframes spinner { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } - } - ``` - -1. Create a file in the `src/styles` folder named `settings.scss` and paste in this code: - - ```css - /* Color palette: https://coolors.co/palette/e63946-f1faee-a8dadc-457b9d-1d3557 */ - - $imperial-red: rgba(230, 57, 70, 1); - $honeydew: rgba(241, 250, 238, 1); - $powder-blue: rgba(168, 218, 220, 1); - $celadon-blue: rgba(69, 123, 157, 1); - $prussian-blue: rgba(29, 53, 87, 1); - - $font-size: 18px; - $padding: 20px; - $std-border-radius: 10px; - ``` - -1. In the `src/main.ts` file, import the style sheets by replacing the default code of the file with this code: - - ```typescript - import App from './App.svelte' - import "./styles/index.scss"; - - const app = new App({ - target: document.body - }) - - export default app - ``` - - This code targets the `body` tag to inject the HTML produced by JavaScript instead of a `div` tag inside the `body` tag as Svelte apps do by default. - Your applications can target any tag on the page. - -## Configuring Svelte - -Svelte files include several different types of code in a single file. -The files you will create have separate sections for TypeScript, Sass, and HTML code, as in this example: - -```html - - - - -
- -
-``` - -Svelte components are fully contained, which means that the style and JS/TS code that you apply inside a component doesn't leak into the other components of your app. -Styles and scripts that are shared among components typically go in the `src/styles` and `scripts` or `src/scripts` folders. - -Follow these steps to set up the `src/App.svelte` file, which is the container for the other Svelte components: - -1. In the `App.svelte` file, replace the default `
` section with this code: - - ```html -
- - {#if $store.Tezos && $store.dexInfo} - - - {:else} -
Loading
- {/if} -
- ``` - - The interface will change after different elements are available to the app, mostly, the data about the liquidity pools from the liquidity baking contract. - -1. Replace the default ` - ``` - -1. Remove the default TypeScript section and replace it with this code, which imports the libraries and components that the app uses: - - ```html - - ``` - - You will add these imported files later, so your IDE may show errors for them now. - The imports include these elements: - - - `onMount`: A method exported by Svelte that runs code when the component mounts - - `TezosToolkit`: The class that gives you access to all the features of Taquito - - `store`: A Svelte feature that manages the state of the app - - `rpcUrl` and `dexAddress`: The URL of the Tezos RPC node and the address of the LB contract - - `Storage`: A custom type that represents the signature type of the LB DEX storage - - `fetchExchangeRates`: A function that fetches the exchange rates of XTZ and tzBTC - -1. In the ` - ``` - - The `connectWallet` function creates a `BeaconWallet` object that represents the user's wallet or if the wallet is already connected, retrieves the connection from the store. - It provides a name for the app, which appears in the wallet UI when it asks the user to allow the connection. - It also includes the network to use, such as the Tezos main network or test network. - Then it stores or updates the wallet object in the Svelte store so other parts of the application can use it. - - The Beacon SDK keeps track of live connections in the store, so if a user has connected to your app before and returns later, their wallet is connected automatically. - - The wallet object also provides a `client` property, which allows you to retrieve the wallet address and token balances and save them to the store so the app can display them on the interface. - - This code uses a custom type named `TezosAccountAddress`, which validates Tezos addresses for implicit accounts. - Tezos addresses start with `tz1`, `tz2`, or `tz3`, so the type checks addresses for these strings. - Its code looks like this: - - ```typescript - type TezosAccountAddress = tz${"1" | "2" | "3"}${string} - ``` - - TypeScript raises a warning if you try to use a string that doesn't match this pattern. - -1. Add the following code to the `