diff --git a/.all-contributorsrc b/.all-contributorsrc index 1368252e3f6..40bede61c16 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -5873,7 +5873,8 @@ "profile": "https://github.com/MiConnell", "contributions": [ "content", - "code" + "code", + "bug" ] }, { @@ -10700,7 +10701,7 @@ "login": "g0rbe", "name": "Dániel Görbe", "avatar_url": "https://avatars.githubusercontent.com/u/36860942?v=4", - "profile": "http://www.danielgorbe.com", + "profile": "https://www.gorbe.io", "contributions": [ "doc" ] @@ -10965,6 +10966,105 @@ "contributions": [ "content" ] + }, + { + "login": "sminempepe", + "name": "sminempepe", + "avatar_url": "https://avatars.githubusercontent.com/u/76882704?v=4", + "profile": "https://github.com/sminempepe", + "contributions": [ + "doc" + ] + }, + { + "login": "aslikaya", + "name": "aslikaya", + "avatar_url": "https://avatars.githubusercontent.com/u/9151261?v=4", + "profile": "https://github.com/aslikaya", + "contributions": [ + "doc" + ] + }, + { + "login": "lucas-amberg", + "name": "Lucas Amberg", + "avatar_url": "https://avatars.githubusercontent.com/u/102396588?v=4", + "profile": "http://lucasamberg.dev", + "contributions": [ + "doc" + ] + }, + { + "login": "a-hagi613", + "name": "Abdullahi", + "avatar_url": "https://avatars.githubusercontent.com/u/92589940?v=4", + "profile": "https://a-hagi.dev/", + "contributions": [ + "bug" + ] + }, + { + "login": "pranavkonde", + "name": "Pranav Konde", + "avatar_url": "https://avatars.githubusercontent.com/u/76070589?v=4", + "profile": "https://www.linkedin.com/in/pranav-konde-56aa141b5/", + "contributions": [ + "content" + ] + }, + { + "login": "MohitKambli", + "name": "Mohit Kambli", + "avatar_url": "https://avatars.githubusercontent.com/u/31406633?v=4", + "profile": "https://github.com/MohitKambli", + "contributions": [ + "code" + ] + }, + { + "login": "oleksandr-hyriavets", + "name": "Oleksandr Hyriavets", + "avatar_url": "https://avatars.githubusercontent.com/u/19614509?v=4", + "profile": "https://github.com/oleksandr-hyriavets", + "contributions": [ + "code" + ] + }, + { + "login": "titanism", + "name": "titanism", + "avatar_url": "https://avatars.githubusercontent.com/u/101466223?v=4", + "profile": "https://github.com/titanism", + "contributions": [ + "doc" + ] + }, + { + "login": "Maxservais", + "name": "Maxime Servais", + "avatar_url": "https://avatars.githubusercontent.com/u/43566493?v=4", + "profile": "https://www.ethereum-ecosystem.com/", + "contributions": [ + "code" + ] + }, + { + "login": "nebolax", + "name": "Alexey Nebolsin", + "avatar_url": "https://avatars.githubusercontent.com/u/63492346?v=4", + "profile": "https://t.me/nebolax", + "contributions": [ + "doc" + ] + }, + { + "login": "jimgreen2013", + "name": "jimgreen2013", + "avatar_url": "https://avatars.githubusercontent.com/u/15890793?v=4", + "profile": "https://github.com/jimgreen2013", + "contributions": [ + "doc" + ] } ], "contributorsPerLine": 7, diff --git a/.github/workflows/get-translation-progress.yml b/.github/workflows/get-translation-progress.yml new file mode 100644 index 00000000000..a476785c909 --- /dev/null +++ b/.github/workflows/get-translation-progress.yml @@ -0,0 +1,64 @@ +name: Update Crowdin translation progression + +on: + schedule: + - cron: "20 16 * * FRI" + workflow_dispatch: + +jobs: + create_pr: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install dependencies + run: yarn install + + - name: Install ts-node + run: yarn global add ts-node + + - name: Set up git + run: | + git config --global user.email "actions@github.com" + git config --global user.name "GitHub Action" + + - name: Generate timestamp and readable date + id: date + run: | + echo "TIMESTAMP=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV + echo "READABLE_DATE=$(date +'%B %-d')" >> $GITHUB_ENV + + - name: Fetch latest dev and create new branch + run: | + git fetch origin dev + git checkout -b "automated-update-${{ env.TIMESTAMP }}" origin/dev + + - name: Run script + run: npx ts-node -O '{"module":"commonjs"}' ./src/scripts/crowdin/getTranslationProgress.ts + env: + CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }} + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + + - name: Commit and push + run: | + git add -A + git commit -m "Update Crowdin translation progress" + git push origin "automated-update-${{ env.TIMESTAMP }}" + + - name: Create PR body + run: | + echo "This PR was automatically created to update Crowdin translation progress." > pr_body.txt + echo "This workflows runs every Friday at 16:20 (UTC)." >> pr_body.txt + echo "" >> pr_body.txt + echo "Thank you to everyone contributing to translate ethereum.org ❤️" >> pr_body.txt + + - name: Create Pull Request + run: | + gh auth login --with-token <<< ${{ secrets.GITHUB_TOKEN }} + gh pr create --base dev --head "automated-update-${{ env.TIMESTAMP }}" --title "Update translation progress from Crowdin - ${{ env.READABLE_DATE }}" --body-file pr_body.txt diff --git a/README.md b/README.md index 67710751b64..f88848028fb 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![gitpoap badge](https://public-api.gitpoap.io/v1/repo/ethereum/ethereum-org-website/badge)](https://www.gitpoap.io/gh/ethereum/ethereum-org-website)
- ethereum logo + ethereum logo

👋 Welcome to ethereum.org!

@@ -154,7 +154,7 @@ Learn more about how we review pull requests [here](docs/review-process.md).
-![POAP Logo](src/assets/poap-logo.svg) +![POAP Logo](public/poap-logo.svg) ## Claim your POAP! @@ -1001,7 +1001,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Patrick Aljord
Patrick Aljord

📖 decifer
decifer

🤔 aghArdeshir
aghArdeshir

💻 - Michael Connell
Michael Connell

🖋 💻 + Michael Connell
Michael Connell

🖋 💻 🐛 Ahmed Mustafa Malik
Ahmed Mustafa Malik

💻 @@ -1673,7 +1673,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Costanza
Costanza

📖 joao
joao

📖 Eugene
Eugene

🖋 - Dániel Görbe
Dániel Görbe

📖 + Dániel Görbe
Dániel Görbe

📖 s-crypt
s-crypt

🖋 iwantanode
iwantanode

🖋 shak58
shak58

🖋 @@ -1711,6 +1711,21 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Tarun Mohandas Daryanani
Tarun Mohandas Daryanani

🖋 Shubh
Shubh

🖋 duckdegen
duckdegen

🖋 + sminempepe
sminempepe

📖 + aslikaya
aslikaya

📖 + + + Lucas Amberg
Lucas Amberg

📖 + Abdullahi
Abdullahi

🐛 + Pranav Konde
Pranav Konde

🖋 + Mohit Kambli
Mohit Kambli

💻 + Oleksandr Hyriavets
Oleksandr Hyriavets

💻 + titanism
titanism

📖 + Maxime Servais
Maxime Servais

💻 + + + Alexey Nebolsin
Alexey Nebolsin

📖 + jimgreen2013
jimgreen2013

📖 diff --git a/docs/best-practices.md b/docs/best-practices.md index 8246d8ed2fd..15828f12933 100644 --- a/docs/best-practices.md +++ b/docs/best-practices.md @@ -85,7 +85,7 @@ Markdown will be translated as whole pages of content, so no specific action is // Example import React, { useState, useEffect } from "react" -const ComponentName: React.FC = (props) => { +const ComponentName = () => { // useState hook for managing state variables const [greeting, setGreeting] = useState("") diff --git a/docs/code-conventions.md b/docs/code-conventions.md index f849daef6a0..7f7e87c971c 100644 --- a/docs/code-conventions.md +++ b/docs/code-conventions.md @@ -61,7 +61,7 @@ For the props type signature use the naming convention `Props` to **Do not use `React.FC`** and instead annotate the props object directly. `React.FC` implies the `children` prop, but this is not always desired when there is a component that should not accept this prop. `React.FC` also does not allow for use of Generic types, or use of Generic type when doing type guarding like function overloading. It is also not generally recommended to use and [was removed from the create-react-app template](https://github.com/facebook/create-react-app/pull/8177). -A positive side-effect to directly annoting the props object is for IDE intellisense where you can view the props when hovering over the component name to see it's signature. +A positive side-effect to directly annotating the props object is for IDE intellisense where you can view the props when hovering over the component name to see it's signature. i.e. `const Component: ({ label, title, ...props }: ComponentProps) => React.JSX.Element` diff --git a/i18n.config.json b/i18n.config.json index 06b6c673ced..f6b9d006b66 100644 --- a/i18n.config.json +++ b/i18n.config.json @@ -297,7 +297,7 @@ }, { "code": "ne-np", - "crowdinCode": "ne-np", + "crowdinCode": "ne-NP", "name": "Nepali", "localName": "नेपाली", "langDir": "ltr", @@ -457,7 +457,7 @@ }, { "code": "ur", - "crowdinCode": "ur", + "crowdinCode": "ur-IN", "name": "Urdu", "localName": "اردو", "langDir": "rtl", diff --git a/public/content/community/get-involved/index.md b/public/content/community/get-involved/index.md index 2a581192859..ec658bedfa4 100644 --- a/public/content/community/get-involved/index.md +++ b/public/content/community/get-involved/index.md @@ -105,11 +105,9 @@ The Ethereum ecosystem is on a mission to fund public goods and impactful projec - [Ethereum Foundation job board (BambooHR)](https://ethereum.bamboohr.com/jobs/) - [JobStash](https://jobstash.xyz) - [Cryptocurrency Jobs](https://cryptocurrencyjobs.co/ethereum/) -- [Crypto.jobs](https://crypto.jobs/) - [Careers at ConsenSys](https://consensys.net/careers/) - [Crypto Jobs List](https://cryptojobslist.com/ethereum-jobs) - [Bankless jobs board](https://pallet.xyz/list/bankless/jobs) -- [useWeb3 Jobs](https://www.useweb3.xyz/jobs) - [Web3 Jobs](https://web3.career) - [Web3 Army](https://web3army.xyz/) - [Crypto Valley Jobs](https://cryptovalley.jobs/) diff --git a/public/content/community/grants/index.md b/public/content/community/grants/index.md index 88a227b64ec..0b69aac8c3a 100644 --- a/public/content/community/grants/index.md +++ b/public/content/community/grants/index.md @@ -27,14 +27,14 @@ These programs support the broad Ethereum ecosystem by offering grants to a wide These projects have created their own grants for projects aimed at developing and experimenting with their own technology. - [Aave Grants Program](https://aavegrants.org/) – _[Aave](https://aave.com/) grants DAO_ -- [Balancer](https://quark-ceres-740.notion.site/Balancer-Grants-938f1b979810427f8d903a904315da41) – _[Balancer](https://balancer.fi/) ecosystem fund_ +- [Balancer](https://grants.balancer.community/) – _[Balancer](https://balancer.fi/) ecosystem fund_ - [Chainlink Grants Program](https://chain.link/community/grants) - _[Chainlink](https://chain.link/) community grants_ - [Decentraland Grants Program](https://governance.decentraland.org/grants/) – _[Decentraland](https://decentraland.org/) DAO Metaverse_ - [Lido Ecosystem Grants Organisation (LEGO)](https://lido.fi/lego) – _[Lido](https://lido.fi/) finance ecosystem_ - [MetaMask Program](https://metamaskgrants.org/) - _[MetaMask](https://metamask.io/) employee-led grants DAO_ - [SKALE Network Grants Program](https://skale.space/developers#grants) - _[SKALE Network](https://skale.space/) ecosystem_ -- [The Graph](https://airtable.com/shrdfvnFvVch3IOVm) – _[The Graph](https://thegraph.com/) ecosystem_ -- [Uniswap Grants Program](https://www.uniswapfoundation.org/apply-for-a-grant) - _[Uniswap](https://uniswap.org/) community_ +- [The Graph](https://thegraph.com/ecosystem/grants/) – _[The Graph](https://thegraph.com/) ecosystem_ +- [Uniswap Grants Program](https://www.uniswapfoundation.org/grants) – _[Uniswap](https://uniswap.org/) community_ - [Web3 Grants](https://web3grants.net) - _An extensive list of web3/crypto related grant programs_ ## Quadratic funding {#quadratic-funding} diff --git a/public/content/contributing/adding-desci-projects/index.md b/public/content/contributing/adding-desci-projects/index.md index 51d2b0a9b67..b7702921f78 100644 --- a/public/content/contributing/adding-desci-projects/index.md +++ b/public/content/contributing/adding-desci-projects/index.md @@ -8,7 +8,7 @@ lang: en We want to make sure we show a variety of projects and give a good snapshot of the DeSci landscape. -Anyone is free to suggest a project to list on the DeSci page on ethereum.org. Equally, anyone who notices a project that is no longer relevant or no longer meets our eligibility criteria, they are free to suggest we remove it. +Anyone is free to suggest a project to list on the DeSci page on ethereum.org. Equally, anyone who notices a project that is no longer relevant or no longer meets our eligibility criteria is free to suggest its removal. ## The decision framework {#the-decision-framework} @@ -16,26 +16,26 @@ Anyone is free to suggest a project to list on the DeSci page on ethereum.org. E - **Open source code/data** - Openness of code and data is a core DeSci principle, so DeSci projects must not be closed source. The codebase should be accessible and ideally open to PRs. - **DeSci projects should be demonstrably decentralized** - This could include being governed by a DAO, or by building with a decentralized tech stack including non-custodial wallets. It probably involves auditable smart contracts on Ethereum. -- **Honest and accurate listing information** - it is expected that any suggested listings from projects come with honest and accurate information. Products that falsify listing information, such as declaring your product is “open source” when it is not, will be removed. +- **Honest and accurate listing information** - It is expected that any suggested listings from projects come with honest and accurate information. Products that falsify listing information, such as declaring your product is “open source” when it is not, will be removed. - **Demonstrable commitment to widening access to science** - A DeSci project should be able to articulate how they widen participation in science to the general public, not just to token/NFT holders. -- **Globally accessible** - your project doesn’t have geographic limitations or KYC requirements that exclude certain people from accessing your service. -- **Informative website and documentation** - it is important that visitors to the project website can understand what the project actually does, how it contributes to decentralization of science infrastructure and how to participate. +- **Globally accessible** - Your project doesn’t have geographic limitations or KYC requirements that exclude certain people from accessing your service. +- **Informative website and documentation** - It is important that visitors to the project website can understand what the project actually does, how it contributes to decentralization of science infrastructure and how to participate. - **Project should be part of the Ethereum ecosystem** - At ethereum.org we believe Ethereum (and its Layer 2's) to be the appropriate base layer for the DeSci movement. - **The project is fairly well established** - The project has real users that have been able to access the project's services for several months. ### Nice-to-haves -- **Available in multiple languages** - your project is translated into multiple languages allowing users around the world to access it. -- **Educational resources** - your product should have a well-designed onboarding experience to help and educate users. Or evidence of how-to content like articles or videos. -- **Third party audits** - your product has been professionally audited for vulnerabilities by a trusted third party. +- **Available in multiple languages** - Your project is translated into multiple languages allowing users around the world to access it. +- **Educational resources** - Your product should have a well-designed onboarding experience to help and educate users. Or evidence of how-to content like articles or videos. +- **Third-party audits** - Your product has been professionally audited for vulnerabilities by a trusted third party. - **Point of contact** - A point of contact for the project (this might be by a representative from a DAO or community) will greatly help us get accurate information when changes are made. This will keep updating ethereum.org manageable when gathering future information. ## Maintenance {#maintenance} As is the fluid nature of Ethereum, teams and products come and go and innovation happens daily, so we'll undertake routine checks of our content to: -- ensure that all projects listed still fulfil our criteria -- verify there aren't products that have been suggested that meet more of our criteria than the ones currently listed +- Ensure that all projects listed still fulfil our criteria +- Verify there aren't products that have been suggested that meet more of our criteria than the ones currently listed Ethereum.org is maintained by the open source community & we rely on the community to help keep this up to date. If you notice any information about listed projects that needs to be updated, please open an issue or a pull request on our GitHub repository. diff --git a/public/content/contributing/style-guide/content-standardization/index.md b/public/content/contributing/style-guide/content-standardization/index.md index aaa30266316..fb92e55c25f 100644 --- a/public/content/contributing/style-guide/content-standardization/index.md +++ b/public/content/contributing/style-guide/content-standardization/index.md @@ -155,6 +155,21 @@ Sentences using active voice are more concise and efficient, making your writing _This isn't an easy one, especially for non-native English speakers. If you aren't sure, don't worry. We'll help with any of these._ +### Date Format {#date-format} + +When including dates in markdown content across Ethereum documentation, it is essential to maintain a consistent and clear presentation. In order to achieve this, we recommend the following guidelines: + +**Format:** + +Use the "D-Mon-YYYY" format for dates. This format eliminates ambiguity between the month and day, providing a standardized and easily understandable representation. + +**Examples:** + +- Preferred: 2-Nov-2023, 11-Feb-2023 +- Avoid: Nov-2-2023, 2/11/2023, 11/2/2023 + +By adhering to these guidelines, we create a unified approach to presenting dates, fostering clarity and comprehension throughout Ethereum documentation. + ### Linking to internal pages {#internal-links} When linking to another page on Ethereum.org, use the relative path over the absolute path. Do not hard-code the language path (i.e. `/en/`) in any links. This maintains consistent functionality across different language versions of the site. diff --git a/public/content/contributing/translation-program/index.md b/public/content/contributing/translation-program/index.md index 478458ac5a3..94759801cbd 100644 --- a/public/content/contributing/translation-program/index.md +++ b/public/content/contributing/translation-program/index.md @@ -38,7 +38,7 @@ Read more about the ethereum.org Translation Program [mission and vision](/contr - [**5,600 +** translators](/contributing/translation-program/contributors/) - [**62** languages live on site](/languages/) -- [**3 million** words translated in 2022](/contributing/translation-program/acknowledgements/) +- [**3 million** words translated in 2023](/contributing/translation-program/acknowledgements/) diff --git a/public/content/desci/index.md b/public/content/desci/index.md index c5bc80a3dd6..c9e7ae8f6ea 100644 --- a/public/content/desci/index.md +++ b/public/content/desci/index.md @@ -93,22 +93,18 @@ Explore projects and join the DeSci community. - [DeSci.Global: global events and meetup calendar](https://desci.global) - [Blockchain for Science Telegram](https://t.me/BlockchainForScience) -- [Molecule: Fund and get funded for your research projects](https://discover.molecule.to/) +- [Molecule: Fund and get funded for your research projects](https://www.molecule.xyz/) - [VitaDAO: receive funding through sponsored research agreements for longevity research](https://www.vitadao.com/) - [ResearchHub: post a scientific result and engage in a conversation with peers](https://www.researchhub.com/) - [LabDAO: fold a protein in-silico](https://alphafodl.vercel.app/) - [dClimate API: query climate data collected by a decentralized community](https://api.dclimate.net/) - [DeSci Foundation: DeSci publishing tool builder](https://descifoundation.org/) - [DeSci.World: one-stop shop for users to view, engage with decentralized science](https://desci.world) -- [Fleming Protocol: open-source data economy that fuels collaborative biomedical discovery](https://medium.com/@FlemingProtocol/a-data-economy-for-patient-driven-biomedical-innovation-9d56bf63d3dd) -- [OceanDAO: DAO governed funding for data-related science](https://oceanprotocol.com/dao) +- [OceanDAO: DAO governed funding for data-related science](https://oceanprotocol.com/) - [Opscientia: open decentralized science workflows](https://opsci.io/research/) -- [LabDAO: fold a protein in-silico](https://alphafodl.vercel.app/) - [Bio.xyz: get funded for your biotech DAO or desci project](https://www.bio.xyz/) -- [ResearchHub: post a scientific result and engage in a conversation with peers](https://www.researchhub.com/) -- [VitaDAO: receive funding through sponsored research agreements for longevity research](https://www.vitadao.com/) -- [Fleming Protocol: open-source data economy that fuels collaborative biomedical discovery](https://medium.com/@FlemingProtocol/a-data-economy-for-patient-driven-biomedical-innovation-9d56bf63d3dd) -- [Active Inference Lab](https://www.activeinference.org/) +- [Fleming Protocol: open-source data economy that fuels collaborative biomedical discovery](http://flemingprotocol.io/) +- [Active Inference Institute](https://www.activeinference.org/) - [CureDAO: Community-Owned Precision Health Platform](https://docs.curedao.org/) - [IdeaMarkets: enabling decentralized scientific credibility](https://ideamarket.io/) - [DeSci Labs](https://www.desci.com/) @@ -122,9 +118,8 @@ We welcome suggestions for new projects to list - please look at our [listing po - [The case for DeSci](https://gitcoin.co/blog/desci-the-case-for-decentralised-science/) - [Guide to DeSci](https://future.com/what-is-decentralized-science-aka-desci/) - [Decentralized science resources](https://www.vincentweisser.com/decentralized-science) -- [Molecule’s Biopharma IP-NFTs - A Technical Description](https://molecule.to/blog/molecules-biopharma-ip-nfts-a-technical-description) +- [Molecule’s Biopharma IP-NFTs - A Technical Description](https://www.molecule.xyz/blog/molecules-biopharma-ip-nfts-a-technical-description) - [Building Trustless Systems of Science by Jon Starr](https://medium.com/@jringo/building-systems-of-trustless-science-1cd2d072f673) -- [The Emergence of Biotech DAOs](https://molecule.to/blog/the-emergence-of-biotech-daos) - [Paul Kohlhaas - DeSci: The Future of Decentralized Science (podcast)](https://anchor.fm/andrew-steinwold/episodes/Paul-Kohlhaas---DeSci-The-Future-of-Decentralized-Science---Zima-Red-ep-117-e1h683a) - [An Active Inference Ontology for Decentralized Science: from Situated Sensemaking to the Epistemic Commons](https://zenodo.org/record/6320575) - [DeSci: The Future of Research by Samuel Akinosho](https://lucidsamuel.medium.com/desci-the-future-of-research-b76cfc88c8ec) diff --git a/public/content/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md b/public/content/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md index 9b08d0fbe4d..57874b13ecd 100644 --- a/public/content/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md +++ b/public/content/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md @@ -50,7 +50,7 @@ PROPOSER_WEIGHT uint64(8) These weights sum to 64. The reward is calculated as the sum of the applicable weights divided by 64. A validator that has made timely source, target and head votes, proposed a block and participated in a sync committee could receive `64/64 * base_reward == base_reward`. However, a validator is not usually a block proposer, so their maximum reward is `64-8 /64 * base_reward == 7/8 * base_reward`. Validators that are neither block proposers nor in a sync committee can receive `64-8-2 / 64 * base_reward == 6.75/8 * base_reward`. -An additional reward is added to incentivize rapid attestations. This is the `inclusion_delay_reward`. This has a value equal to the `base_reward` multiplied by `1/delay` where `delay` is the number of slots separating the block proposal and attestation. For example, if the attestation is submitted within one slot of the block proposal the attestor receives `base_reward * 1/1 == base_reward`. If the attestation arrives in the next slot, the attestor received `base_reward * 1/2` and so on. +An additional reward is added to incentivize rapid attestations. This is the `inclusion_delay_reward`. This has a value equal to the `base_reward` multiplied by `1/delay` where `delay` is the number of slots separating the block proposal and attestation. For example, if the attestation is submitted within one slot of the block proposal the attestor receives `base_reward * 1/1 == base_reward`. If the attestation arrives in the next slot, the attestor receives `base_reward * 1/2` and so on. Block proposers receive `8 / 64 * base_reward` for **each valid attestation** included in the block, so the actual value of the reward scales with the number of attesting validators. Block proposers can also increase their reward by including evidence of misbehavior by other validators in their proposed block. These rewards are the "carrots" that encourage validator honesty. A block proposer which includes slashing will be rewarded with the `slashed_validators_effective_balance / 512`. diff --git a/public/content/developers/docs/design-and-ux/index.md b/public/content/developers/docs/design-and-ux/index.md index aa6f11b259c..31622f3993b 100644 --- a/public/content/developers/docs/design-and-ux/index.md +++ b/public/content/developers/docs/design-and-ux/index.md @@ -83,6 +83,7 @@ Get involved in professional community-driven organizations or join design group - [Ethereum.org Design system](https://www.figma.com/@ethdotorg) (Figma) - [Finity, a design system by Polygon](https://www.figma.com/community/file/1073921725197233598/finity-design-system) (Figma) - [Kleros Design System](https://www.figma.com/community/file/999852250110186964/kleros-design-system) (Figma) +- [Safe Design System](https://www.figma.com/community/file/1337417127407098506/safe-design-system) (Figma) - [ENS Design system](https://thorin.ens.domains/) - [Mirror Design System](https://degen-xyz.vercel.app/) diff --git a/public/content/developers/docs/development-networks/index.md b/public/content/developers/docs/development-networks/index.md index b2469a80fa1..206a1b4f29b 100644 --- a/public/content/developers/docs/development-networks/index.md +++ b/public/content/developers/docs/development-networks/index.md @@ -66,9 +66,9 @@ There are also two maintained public test implementations of Ethereum: Goerli an Kurtosis is a build system for multi-container test environments which enables developers to locally spin up reproducible instances of blockchain networks. -The Ethereum Kurtosis package locally instantiates a containerized and parameterizable Ethereum testnet, with support for multiple different Execution Layer (EL) and Consensus Layer (CL) clients and an n-number of nodes. Kurtosis gracefully handles all local port mappings and service connections for easy dApp and smart contract prototyping and testing. +The Ethereum Kurtosis package can be used to quickly instantiate a parameterizable, highly scaleable, and private Ethereum testnet over Docker or Kubernetes. The package supports all major Execution Layer (EL) and Consensus Layer (CL) clients. Kurtosis gracefully handles all local port mappings and service connections for a representative network to be used in validation and testing workflows relating to Etheruem core infrastructure. -- [Ethereum network package](https://github.com/kurtosis-tech/eth-network-package) +- [Ethereum network package](https://github.com/kurtosis-tech/ethereum-package) - [Website](https://www.kurtosis.com/) - [GitHub](https://github.com/kurtosis-tech/kurtosis) - [Documentation](https://docs.kurtosis.com/) diff --git a/public/content/developers/docs/gas/index.md b/public/content/developers/docs/gas/index.md index 5e4ad237a91..0d0db6ae680 100644 --- a/public/content/developers/docs/gas/index.md +++ b/public/content/developers/docs/gas/index.md @@ -119,22 +119,6 @@ The Ethereum [scalability upgrades](/roadmap/) should ultimately address some of Layer 2 scaling is a primary initiative to greatly improve gas costs, user experience and scalability. [More on layer 2 scaling](/developers/docs/scaling/#layer-2-scaling). -## What was the London Upgrade / EIP-1559? {#what-was-the-london-upgrade-eip-1559} - -Before the London Upgrade, Ethereum had fixed-sized blocks. In times of high network demand, these blocks operated at full capacity. As a result, users often had to wait for demand to reduce to get included in a block, which led to a poor user experience. The London Upgrade introduced variable-sized blocks to Ethereum. - -The way transaction fees on the Ethereum network were calculated changed with [the London Upgrade](/history/#london) of August 2021. Before the London upgrade, fees were calculated without separating `base` and `priority` fees, as follows: - -Let's say Alice had to pay Bob 1 ETH. In the transaction, the gas limit is 21,000 units, and the gas price is 200 gwei. - -The total fee would have been: `Gas units (limit) * Gas price per unit` i.e `21,000 * 200 = 4,200,000 gwei` or 0.0042 ETH - -The implementation of [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) in the London Upgrade made the transaction fee mechanism more complex, but made gas fees more predictable, resulting in a more efficient transaction fee market. Users can submit transactions with a `maxFeePerGas` corresponding to how much they are willing to pay for the transaction to be executed, knowing that they will not pay more than the market price for gas (`baseFeePerGas`), and get any extra, minus their tip, refunded. - -This video explains EIP-1559 and the benefits it brings: - - - ## Monitoring gas fees {#moitoring-gas-fees} If you want to monitor gas prices, so you can send your ETH for less, you can use many different tools such as: diff --git a/public/content/developers/docs/mev/index.md b/public/content/developers/docs/mev/index.md index 067b1110e34..0aff138ad20 100644 --- a/public/content/developers/docs/mev/index.md +++ b/public/content/developers/docs/mev/index.md @@ -6,7 +6,7 @@ lang: en Maximal extractable value (MEV) refers to the maximum value that can be extracted from block production in excess of the standard block reward and gas fees by including, excluding, and changing the order of transactions in a block. -## Miner extractable value {#miner-extractable-value} +## Maximal extractable value {#maximal-extractable-value} Maximal extractable value was first applied in the context of [proof-of-work](/developers/docs/consensus-mechanisms/pow/), and initially referred to as "miner extractable value". This is because in proof-of-work, miners control transaction inclusion, exclusion, and ordering. However, since the transition to proof-of-stake via [The Merge](/roadmap/merge) validators have been responsible for these roles, and mining is no longer part of the Ethereum protocol. The value extraction methods still exist, though, so the term "Maximal extractable value" is now used instead. diff --git a/public/content/developers/docs/nodes-and-clients/client-diversity/index.md b/public/content/developers/docs/nodes-and-clients/client-diversity/index.md index 1a925d6a02c..6a0971d7ebe 100644 --- a/public/content/developers/docs/nodes-and-clients/client-diversity/index.md +++ b/public/content/developers/docs/nodes-and-clients/client-diversity/index.md @@ -46,7 +46,7 @@ _Diagram data from [ethernodes.org](https://ethernodes.org) and [clientdiversity The two pie charts above show snapshots of the current client diversity for the execution and consensus layers (at time of writing in January 2022). The execution layer is overwhelmingly dominated by [Geth](https://geth.ethereum.org/), with [Open Ethereum](https://openethereum.github.io/) a distant second, [Erigon](https://github.com/ledgerwatch/erigon) third and [Nethermind](https://nethermind.io/) fourth, with other clients comprising less than 1 % of the network. The most commonly used client on the consensus layer - [Prysm](https://prysmaticlabs.com/#projects) - is not as dominant as Geth but still represents over 60% of the network. [Lighthouse](https://lighthouse.sigmaprime.io/) and [Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) make up ~20% and ~14% respectively, and other clients are rarely used. -The execution layer data were obtained from [Ethernodes](https://ethernodes.org) on 23/01/2022. Data for consensus clients was obtained from [Michael Sproul](https://github.com/sigp/blockprint). Consensus client data is more difficult to obtain because the consensus layer clients do not always have unambiguous traces that can be used to identify them. The data was generated using a classification algorithm that sometimes confuses some of the minority clients (see [here](https://twitter.com/sproulM_/status/1440512518242197516) for more details). In the diagram above, these ambiguous classifications are treated with an either/or label (e.g. Nimbus/Teku). Nevertheless, it is clear that the majority of the network is running Prysm. The data is a snapshot over a fixed set of blocks (in this case Beacon blocks in slots 2048001 to 2164916) and Prysm's dominance has sometimes been higher, exceeding 68%. Despite only being snapshots, the values in the diagram provide a good general sense of the current state of client diversity. +The execution layer data were obtained from [Ethernodes](https://ethernodes.org) on 23-Jan-2022. Data for consensus clients was obtained from [Michael Sproul](https://github.com/sigp/blockprint). Consensus client data is more difficult to obtain because the consensus layer clients do not always have unambiguous traces that can be used to identify them. The data was generated using a classification algorithm that sometimes confuses some of the minority clients (see [here](https://twitter.com/sproulM_/status/1440512518242197516) for more details). In the diagram above, these ambiguous classifications are treated with an either/or label (e.g. Nimbus/Teku). Nevertheless, it is clear that the majority of the network is running Prysm. The data is a snapshot over a fixed set of blocks (in this case Beacon blocks in slots 2048001 to 2164916) and Prysm's dominance has sometimes been higher, exceeding 68%. Despite only being snapshots, the values in the diagram provide a good general sense of the current state of client diversity. Up to date client diversity data for the consensus layer is now available at [clientdiversity.org](https://clientdiversity.org/). diff --git a/public/content/developers/docs/nodes-and-clients/nodes-as-a-service/index.md b/public/content/developers/docs/nodes-and-clients/nodes-as-a-service/index.md index a1ac64a38da..596983b16c4 100644 --- a/public/content/developers/docs/nodes-and-clients/nodes-as-a-service/index.md +++ b/public/content/developers/docs/nodes-and-clients/nodes-as-a-service/index.md @@ -110,7 +110,7 @@ Here is a list of some of the most popular Ethereum node providers, feel free to - Analytics - [**BlockPI**](https://blockpi.io/) - [Docs](https://docs.blockpi.io/) - - Fetures + - Features - Robust & distributed node structure - Up to 40 HTTPS and WSS endpoints - Free signup package and monthly package diff --git a/public/content/developers/docs/scaling/sidechains/index.md b/public/content/developers/docs/scaling/sidechains/index.md index 73ca67a2373..ba246c90a25 100644 --- a/public/content/developers/docs/scaling/sidechains/index.md +++ b/public/content/developers/docs/scaling/sidechains/index.md @@ -51,7 +51,7 @@ While bridges help users move funds between Ethereum and the sidechain, the asse | Pros | Cons | | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -| The technology underpinning sidechains is well-established and benefits from extensive research and improvements in design. | Sidechains trade off some measure of decentralization and trustlesness for scalability. | +| The technology underpinning sidechains is well-established and benefits from extensive research and improvements in design. | Sidechains trade off some measure of decentralization and trustlessness for scalability. | | Sidechains support general computation and offer EVM compatibility (they can run Ethereum-native dapps). | A sidechain uses a separate consensus mechanism and doesn't benefit from Ethereum's security guarantees. | | Sidechains use different consensus models to efficiently process transactions and lower transaction fees for users. | Sidechains require higher trust assumptions (e.g., a quorum of malicious sidechain validators can commit fraud). | | EVM-compatible sidechains allow dapps to expand their ecosystem. | | diff --git a/public/content/governance/index.md b/public/content/governance/index.md index 733a42210c3..f2e36aa7e02 100644 --- a/public/content/governance/index.md +++ b/public/content/governance/index.md @@ -121,7 +121,7 @@ Forks are when major technical upgrades or changes need to be made to the networ The DAO fork was in response to the [2016 DAO attack](https://www.coindesk.com/understanding-dao-hack-journalists) where an insecure [DAO](/glossary/#dao) contract was drained of over 3.6 million ETH in a hack. The fork moved the funds from the faulty contract to a new contract allowing anyone who lost funds in the hack to recover them. -This course of action was voted on by the Ethereum community. Any ETH holder was able to vote via a transaction on [a voting platform](http://v1.carbonvote.com/). The decision to fork reached over 85% of the votes. +This course of action was voted on by the Ethereum community. Any ETH holder was able to vote via a transaction on [a voting platform](https://web.archive.org/web/20170620030820/http://v1.carbonvote.com/). The decision to fork reached over 85% of the votes. It's important to note that whilst the protocol did fork to revert the hack, the weight the vote carried in deciding to fork is debatable for a few reasons: diff --git a/public/content/history/index.md b/public/content/history/index.md index 353277ebc52..517b84c81b7 100644 --- a/public/content/history/index.md +++ b/public/content/history/index.md @@ -172,6 +172,20 @@ Altair was the first major network upgrade that had an exact rollout time. Every The London upgrade introduced [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), which reformed the transaction fee market, along with changes to how gas refunds are handled and the [Ice Age](/glossary/#ice-age) schedule. +#### What was the London Upgrade / EIP-1559? {#eip-1559} + +Before the London Upgrade, Ethereum had fixed-sized blocks. In times of high network demand, these blocks operated at full capacity. As a result, users often had to wait for demand to reduce to get included in a block, which led to a poor user experience. The London Upgrade introduced variable-sized blocks to Ethereum. + +The way transaction fees on the Ethereum network were calculated changed with [the London Upgrade](/history/#london) of August 2021. Before the London upgrade, fees were calculated without separating `base` and `priority` fees, as follows: + +Let's say Alice had to pay Bob 1 ETH. In the transaction, the gas limit is 21,000 units, and the gas price is 200 gwei. + +The total fee would have been: `Gas units (limit) * Gas price per unit` i.e `21,000 * 200 = 4,200,000 gwei` or 0.0042 ETH + +The implementation of [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) in the London Upgrade made the transaction fee mechanism more complex, but made gas fees more predictable, resulting in a more efficient transaction fee market. Users can submit transactions with a `maxFeePerGas` corresponding to how much they are willing to pay for the transaction to be executed, knowing that they will not pay more than the market price for gas (`baseFeePerGas`), and get any extra, minus their tip, refunded. + +This video explains EIP-1559 and the benefits it brings: [EIP-1559 Explained](https://www.youtube.com/watch?v=MGemhK9t44Q) + - [Are you a dapp developer? Be sure to upgrade your libraries and tooling.](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/london-ecosystem-readiness.md) - [Read the Ethereum Foundation announcement](https://blog.ethereum.org/2021/07/15/london-mainnet-announcement/) - [Read the Ethereum Cat Herder's explainer](https://medium.com/ethereum-cat-herders/london-upgrade-overview-8eccb0041b41) diff --git a/public/content/roadmap/index.md b/public/content/roadmap/index.md index 6a218c2e655..ef683bb7ddf 100644 --- a/public/content/roadmap/index.md +++ b/public/content/roadmap/index.md @@ -59,7 +59,7 @@ Ethereum gets regular upgrades that enhance its scalability, security, or sustai -The roadmap is mostly the result of years of work by researchers and developers - because the protocol is very technical - but any motivated person can participate. Ideas usually start off as discussions on a forum such as [ethresear.ch](https://ethresear.ch/), [Ethereum magicians](https://www.figma.com/exit?url=https%3A%2F%2Fethereum-magicians.org%2F) or the Eth R&D discord server. They may be responses to new vulnerabilities that are discovered, suggestions from organizations working in the application layer (such as dapps and exchanges) or from known frictions for end users (such as costs or transaction speeds). When these ideas mature, they can be proposed as [Ethereum Improvement Proposals](https://eips.ethereum.org/). This is all done in public so that anyone from the community can weigh in at any time. +The roadmap is mostly the result of years of work by researchers and developers - because the protocol is very technical - but any motivated person can participate. Ideas usually start off as discussions on a forum such as [ethresear.ch](https://ethresear.ch/), [Ethereum Magicians](https://ethereum-magicians.org/) or the Eth R&D discord server. They may be responses to new vulnerabilities that are discovered, suggestions from organizations working in the application layer (such as dapps and exchanges) or from known frictions for end users (such as costs or transaction speeds). When these ideas mature, they can be proposed as [Ethereum Improvement Proposals](https://eips.ethereum.org/). This is all done in public so that anyone from the community can weigh in at any time. [More on Ethereum governance](/governance/) diff --git a/public/content/roadmap/pbs/index.md b/public/content/roadmap/pbs/index.md index 645759b68a2..d9f79124074 100644 --- a/public/content/roadmap/pbs/index.md +++ b/public/content/roadmap/pbs/index.md @@ -20,7 +20,7 @@ For example, inclusion lists can be introduced so that when validators know abou -Powerful organizations can pressure validators to censor transactions to or from certain addresses. Validators comply with this pressure by detecting blacklisted addresses in their transaction pool and omitting them from the blocks the propose. After PBS this will no longer be possible because block proposers will not know which transactions they are broadcasting in their blocks. It might be important for certain individuals or apps to comply with censorship rules, for example when it is made law in their region. In these cases, compliance happens at the application level, while the protocol remains permissionless and censorship free. +Powerful organizations can pressure validators to censor transactions to or from certain addresses. Validators comply with this pressure by detecting blacklisted addresses in their transaction pool and omitting them from the blocks they propose. After PBS this will no longer be possible because block proposers will not know which transactions they are broadcasting in their blocks. It might be important for certain individuals or apps to comply with censorship rules, for example when it is made law in their region. In these cases, compliance happens at the application level, while the protocol remains permissionless and censorship free. diff --git a/public/content/translations/de/community/code-of-conduct/index.md b/public/content/translations/de/community/code-of-conduct/index.md index a8cb0f0031b..e2332654972 100644 --- a/public/content/translations/de/community/code-of-conduct/index.md +++ b/public/content/translations/de/community/code-of-conduct/index.md @@ -52,7 +52,7 @@ Beispiele für inakzeptables Verhalten von Teilnehmenden: - Körperliche Gewalt, Androhung körperlicher Gewalt oder Aufforderung zu körperlicher Gewalt jeglicher Art - Verwendung einer sexualisierten Sprache oder Bildsprache oder Signalisierung unerwünschter sexueller Aufmerksamkeit -- Sich als eine andere Person auszugeben oder auf andere Weise unredlich zu behaupten, eine Verbindung zu einer Person oder Organisation zu haben. +- Sich als eine andere Person auszugeben oder auf andere Weise unredlich zu behaupten, eine Verbindung zu einer Person oder Organisation zu haben - Trolling, beleidigende/abwertende Kommentare und persönliche oder politische Angriffe - Belästigung anderer Community-Mitglieder in öffentlichen oder privaten Kanälen - Veröffentlichung privater Informationen anderer, wie z. B. einer physischen oder elektronischen Adresse, ohne ausdrückliche Erlaubnis diff --git a/public/content/translations/de/community/get-involved/index.md b/public/content/translations/de/community/get-involved/index.md index 0e4d4d6ca66..a552bf7a44c 100644 --- a/public/content/translations/de/community/get-involved/index.md +++ b/public/content/translations/de/community/get-involved/index.md @@ -28,7 +28,7 @@ Haben Sie einen Hintergrund in Mathematik, Kryptographie oder Wirtschaftswissens - Ethereum-Verbesserungsvorschläge formulieren oder prüfen - Ein EIP schreiben 1. Reichen Sie Ihre Idee auf [Ethereum Magicians](https://ethereum-magicians.org) ein. - 2. Lesen Sie [EIP-1](https://eip.ethereum.org/EIPS/eip-1) – **Ja, das ist das _ganze_ Dokument**. + 2. Lesen Sie [EIP-1](https://eips.ethereum.org/EIPS/eip-1) – **Ja, das ist das _ganze_ Dokument**. 3. Folgen Sie den Anweisungen in EIP-1. Beziehen Sie sich auf die darin enthaltenen Informationen, während Sie Ihren Entwurf schreiben. - Erfahren Sie, wie Sie ein [EIP Editor](https://eips.ethereum.org/EIPS/eip-5069) werden. - Sie können direkt in das Peer-Review von EIPs einsteigen. Sehen Sie [Öffnen von PRs mit dem `e-review`-Tag](https://github.com/ethereum/EIPs/pulls?q=is%3Apr+is%3Aopen+label%3Ae-review). Geben Sie technisches Feedback über den `discussion-to`-Link. diff --git a/public/content/translations/de/community/grants/index.md b/public/content/translations/de/community/grants/index.md index 03ad25bd0f7..0759da1e17b 100644 --- a/public/content/translations/de/community/grants/index.md +++ b/public/content/translations/de/community/grants/index.md @@ -15,31 +15,27 @@ Diese Liste wird von unserer Community verwaltet. Wenn Informationen fehlen oder Diese Programme unterstützen das breit gefächerte Ethereum-Ökosystem, indem sie Finanzierungen für zahlreiche Projekte bereitstellen. Dazu gehören unter anderem Lösungen zu Skalierbarkeit, Community-Aufbau, Sicherheit und Privatsphäre. Diese Fördermaßnahmen sind nicht spezifisch für eine bestimmte Ethereum-Plattform und sind ein guter Ausgangspunkt, wenn Sie unsicher sind. - [EF-Ökosystem Unterstützungsprogramm](https://esp.ethereum.foundation) - _Finanzierung von Open-Source-Projekten, die Ethereum zugutekommen, mit besonderem Fokus auf universelle Werkzeuge, Infrastruktur, Forschung und öffentliche Güter_ -- [Ethereum RFPs](https://github.com/ethereum/requests-for-proposals) – _Ausschreibungen der Ethereum Foundation für Arbeiten und Projekte im Ethereum-Ökosystem_ - [MetaCartel](https://www.metacartel.org/grants/) - _DApp-Entwicklung, DAO-Erstellung_ -- [Moloch DAO](https://www.molochdao.com/) – _Datenschutz, Layer-2-Skalierung, Kundensicherheit und mehr_ -- [Offene Zuschüsse](https://opengrants.com/explore) -- [DAO-Stipendien](https://docs.google.com/spreadsheets/d/1XHc-p_MHNRdjacc8uOEjtPoWL86olP4GyxAJOFO0zxY/edit#gid=0) - _Google-Tabelle der Organisationen, die Stipendien anbieten_ -- [Crunchbase für Web3-Grants](https://www.cryptoneur.xyz/web3-grants) - _Filter und suche nach Grants nach Kategorie, Anwendungsfall, Betrag und mehr. Hilf anderen dabei, die richtige Zuwendung zu finden._ +- [Moloch DAO](https://www.molochdao.com/) – _Datenschutz, Layer-2-Skalierung, Client-Sicherheit und mehr_ +- [DAO-Zuschüsse](https://docs.google.com/spreadsheets/d/1XHc-p_MHNRdjacc8uOEjtPoWL86olP4GyxAJOFO0zxY/edit#gid=0) – _Google-Tabelle der Organisationen, die Zuschüsse anbieten_ +- [Crunchbase für Web3-Zuschüsse](https://www.cryptoneur.xyz/web3-grants) – _Filtere und suche nach Zuschüssen nach Kategorie, Anwendungsfall, Betrag und mehr. Hilf anderen dabei, den richtigen Zuschuss zu finden._ - [Akademische Stipendien](https://esp.ethereum.foundation/academic-grants) – _Stipendien zur Untstützung akademischer Arbeiten in Bezug auf Ethereum_ +- [Blockworks Grantfarm](https://blockworks.co/grants/programs) - _Blockworks hat ein umfassendes Verzeichnis aller Zuschüsse, Ausschreibungen und Bug-Bounties zusammengestellt._ ## Projektspezifisch {#project-specific} Diese Projekte haben ihre eigenen Zuschüsse für Projektvorhaben zur Entwicklung und Erprobung ihrer eigenen Technologie geschaffen. - [Aave-Zuschussprogramm](https://aavegrants.org/) – _[Aave](https://aave.com/) Grants DAO_ -- [Balancer](https://balancergrants.notion.site/Balancer-Community-Grants-23e562c5bc4347cd8304637bff0058e6) – _[Balancer](https://balancer.fi/)-Ökosystemfonds_ +- [Balancer](https://quark-ceres-740.notion.site/Balancer-Grants-938f1b979810427f8d903a904315da41) – _[Balancer](https://balancer.fi/)-Ökosystemfonds_ - [Chainlink-Förderprogramm](https://chain.link/community/grants) - _[Chainlink](https://chain.link/) Gemeinschaftsförderungen_ -- [Programm für Verbundzuschüsse](https://compoundgrants.org/) – _[Verbund](https://compound.finance/)-Finanzökosystem_ -- [Decentraland-Zuschussprogramm](https://governance.decentraland.org/grants/) – _[Decentraland](https://decentraland.org/) DAO Metaverse_ -- [Lido Ecosystem Grants Organisation (LEGO)](https://lego.lido.fi/) – _[Lido](https://lido.fi/)-Finanzökosystem_ -- [MetaMask-Programm](https://metamaskgrants.org/) – _Von Mitarbeitern geleitete DAO für[MetaMask](https://metamask.io/)-Stipendien_ -- [mStable-Zuschussprogram](https://docs.mstable.org/advanced/grants-program) – _[mStable](https://mstable.org/)-Gemeinschaft_ -- [SKALE Network-Förderprogramm](https://skale.space/developers#grants) – _[SKALE Network](https://skale.space/)-Ökosystem_ -- [The Graph](https://airtable.com/shrdfvnFvVch3IOVm) – _[The Graph](https://thegraph.com/)-Ökosystem_ -- [UMA Grants Program](https://grants.umaproject.org/) – _[UMA](https://umaproject.org/)-Entwicklerunterstützung_ -- [Uniswap-Zuschussprogramm](https://www.unigrants.org/) – _[Uniswap](https://uniswap.org/)-Community_ -- [Web3-Förderung](https://web3grants.net) – _Eine umfangreiche Liste von Web3-/Krypto-verwandten Förderprogrammen_ +- [Decentraland-Zuschussprogramm](https://governance.decentraland.org/grants/) – _[Decentraland](https://decentraland.org/)-DAO-Metaverse_ +- [Lido Ecosystem Grants Organisation (LEGO)](https://lido.fi/lego) – _[Lido](https://lido.fi/)-Finanzökosystem_ +- [MetaMask-Programm](https://metamaskgrants.org/) – _Mitarbeitergeleitete DAO für[MetaMask](https://metamask.io/)-Zuschüsse_ +- [SKALE-Network-Förderprogramm](https://skale.space/developers#grants) – _[SKALE-Network](https://skale.space/)-Ökosystem_ +- [The Graph](https://airtable.com/shrdfvnFvVch3IOVm) – _[The-Graph](https://thegraph.com/)-Ökosystem_ +- [Uniswap-Förderprogramm](https://www.uniswapfoundation.org/apply-for-a-grant) – _[Uniswap](https://uniswap.org/)-Community_ +- [Web3-Zuschüsse](https://web3grants.net) – _Eine umfangreiche Liste von Förderprogrammen mit Bezug zu Web3/Krypto_ ## Quadratische Finanzierung {#quadratic-funding} diff --git a/public/content/translations/de/community/language-resources/index.md b/public/content/translations/de/community/language-resources/index.md index a75323bbcd7..2afd16f4719 100644 --- a/public/content/translations/de/community/language-resources/index.md +++ b/public/content/translations/de/community/language-resources/index.md @@ -72,7 +72,7 @@ Wenn Sie zweisprachig sind und uns helfen möchten, mehr Menschen zu erreichen, - [Gwei.cz](https://gwei.cz) - Lokale Gemeinschaft für Web3, die akademische Inhalte erstellt und Veranstaltungen organisiert, sowohl online als auch persönlich - [Gwei.cz Leitfaden](https://prirucka.gwei.cz/) - Ethereum Leitfaden für Anfänger - [DAO Leitfaden](https://dao.gwei.cz/) - Leitfaden über DAOs für Anfänger -- [Ethereum meistern](https://ipfs.infura-ipfs.io/ipfs/bafybeidvuxhnsgfx3tncpfxheqglkjwmdxclknlgd7s7qggd2a6bzgb27m) - Ethereum meistern auf Tschechisch +- [Ethereum meistern](https://ipfs.io/ipfs/bafybeidvuxhnsgfx3tncpfxheqglkjwmdxclknlgd7s7qggd2a6bzgb27m) – Ethereum meistern auf Tschechisch ### Französisch {#fr} diff --git a/public/content/translations/de/community/online/index.md b/public/content/translations/de/community/online/index.md index 567cadbb4c1..66d0cdcdeb6 100644 --- a/public/content/translations/de/community/online/index.md +++ b/public/content/translations/de/community/online/index.md @@ -24,13 +24,13 @@ Hunderttausende von Ethereum-Enthusiasten treffen sich in diesen Online-Foren, u Ethereum Cat Herders - Gemeinschaft orientiert am Angebot von Projekt-Management-Unterstützung für Ethereum-Entwickler Ethereum-Hacker - Von ETHGlobal geführter Discord Chat: Eine Online-Gemeinschaft für Ethereum-Hacker auf der ganzen Welt CryptoDevs - Auf Ethereum Entwicklung fokussierte Discord-Community -EthStaker Discord – Beratung, Bildung, Unterstützung und Ressourcen für bestehende und potenzielle Staker auf Community-Ebene -Ethereum.org Website-Team - Kommen Sie vorbei and schreiben Sie mit dem Team und anderen aus der Gemeinschaft über Ethereum.org Web-Entwicklung und Design +EthStaker Discord – Beratung, Bildung, Unterstützung und Ressourcen für bestehende und potenzielle Staker auf Community-Ebene +Ethereum.org Website-Team - Kommen Sie vorbei and schreiben Sie mit dem Team und anderen aus der Gemeinschaft über Ethereum.org Web-Entwicklung und Design Matos Discord - Web3-Creator-Community, wo sich Entwickler, industrielle Führer, und Ethereum Enthusiasten aufhalten. Wir sind begeistert von Web3-Entwicklung, Design und Kultur. Kommen Sie mit uns bauen. -Solidity-Gitter - Unterhaltungen über Solidity-Entwicklung (Gitter) +Solidity-Gitter - Unterhaltungen über Solidity-Entwicklung (Gitter) Solidity-Matrix - Unterhaltungen über Solidity-Entwicklung (Matrix) -Ethereum Stack Exchange _– Forum für Fragen und Antworten_ -Peeranha _– dezentrales Forum für Fragen und Antworten_ +Ethereum Stack Exchange *– Forum für Fragen und Antworten* +Peeranha *– dezentrales Forum für Fragen und Antworten* ## YouTube und Twitter {#youtube-and-twitter} diff --git a/public/content/translations/de/community/research/index.md b/public/content/translations/de/community/research/index.md index fefdfc6193d..28abf078d3b 100644 --- a/public/content/translations/de/community/research/index.md +++ b/public/content/translations/de/community/research/index.md @@ -124,7 +124,7 @@ Die sicheren und leistungsfähigen Brücken sind ein bestimmter Bereich der Eben - [Einführung in Blockchain-Brücken](/bridges/) - [Vitalik zu Brücken](https://old.reddit.com/r/ethereum/comments/rwojtk/ama_we_are_the_efs_research_team_pt_7_07_january/hrngyk8/) - [Artikel zu Blockchain-Brücken](https://medium.com/1kxnetwork/blockchain-bridges-5db6afac44f8) -- [Der Wert von Brücken]() +- [Der Wert von Brücken](https://dune.com/eliasimos/Bridge-Away-(from-Ethereum)) #### Aktuelle Forschung {#recent-research-3} @@ -156,7 +156,7 @@ Das Sharding war auf der Ethereum-Blockchain lange Teil des Entwicklungs-Fahrpla #### Aktuelle Forschung {#recent-research-5} -- [ecdsa zu FGPAs](https://ethresear.ch/t/does-ecdsa-on-fpga-solve-the-scaling-problem/6738) +- [ecdsa auf FPGAs](https://ethresear.ch/t/does-ecdsa-on-fpga-solve-the-scaling-problem/6738) ## Sicherheit {#security} @@ -346,7 +346,6 @@ Die Tools für Ethereum-Entwickler verbessern sich rasant. In diesem Bereich gib - [Entwickler-Frameworks](/developers/docs/frameworks/) - [Tools-Liste für Entwickler der Konsensebene](https://github.com/ConsenSys/ethereum-developer-tools-list) - [Tokenstandards](/developers/docs/standards/tokens/) -- [Biastek: Tools für Ethereum](https://biastek.com/ethereum-tools/) - [CryptoDevHub: EVM-Tools](https://cryptodevhub.io/wiki/ethereum-virtual-machine-tools) #### Aktuelle Forschung {#recent-research-17} diff --git a/public/content/translations/de/community/support/index.md b/public/content/translations/de/community/support/index.md index 6d1426d2b70..1b2d0b2f056 100644 --- a/public/content/translations/de/community/support/index.md +++ b/public/content/translations/de/community/support/index.md @@ -30,7 +30,7 @@ Haben Sie Probleme mit Ihrer Wallet? Die meisten Wallets haben spezielle Support - [Argent](https://support.argent.xyz/hc/) - [MyEtherWallet](https://help.myetherwallet.com/) -_Das ist keine vollständige Liste. Brauchen Sie Hilfe bei der Suche nach Unterstützung für eine bestimmte Wallet? Treten Sie dem [ethereum.org-Discord](https://discord.gg/ethereum-org) bei, dann versuchen wir, Ihnen zu helfen._ +_Das ist keine vollständige Liste. Brauchen Sie Hilfe bei der Suche nach Unterstützung für eine bestimmte Wallet? Treten Sie dem [ethereum.org-Discord](https://discord.gg/rZz26QWfCg) bei, dann versuchen wir, Ihnen zu helfen._ Suchen Sie eine Ethereum-Wallet? [Sehen Sie sich unsere vollständige Liste der Ethereum-Wallets an](/wallets/find-wallet/). @@ -39,7 +39,7 @@ Suchen Sie eine Ethereum-Wallet? [Sehen Sie sich unsere vollständige Liste der Erstellen kann durchaus schwer sein. Hier finden Sie einige Breiche mit Schwerpunkt auf Entwicklung mit erfahrenen Ethereum-Entwicklern, die Ihnen gerne helfen. - [Alchemy University](https://university.alchemy.com/#starter_code) -- [CryptoDevs-Discord](https://discord.gg/Z9TA39m8Yu) +- [CryptoDevs-Discord](https://discord.com/invite/5W5tVb3) - [Ethereum StackExchange](https://ethereum.stackexchange.com/) - [StackOverflow](https://stackoverflow.com/questions/tagged/web3) - [Web3 University](https://www.web3.university/) @@ -53,7 +53,7 @@ Bezieht sich Ihre Frage auf ein bestimmtes Tool, Projekt oder eine Bibliothek? D Hier sind einige beliebte Beispiele: -- [Solidity](https://gitter.im/ethereum/solidity) +- [Solidity](https://gitter.im/ethereum/solidity/) - [ethers.js](https://discord.gg/6jyGVDK6Jx) - [web3.js](https://discord.gg/GsABYQu4sC) - [Hardhat](https://discord.gg/xtrMGhmbfZ) @@ -65,7 +65,7 @@ Hier sind einige beliebte Beispiele: Wenn Sie einen Knoten oder Validator betreiben, finden Sie hier einige Communitys, die Ihnen den Einstieg erleichtern. -- [EthStaker-Discord](https://discord.io/ethstaker) +- [EthStaker-Discord](https://discord.gg/ethstaker) - [EthStaker-Reddit](https://www.reddit.com/r/ethstaker) Die meisten Teams, die Ethereum-Clients entwickeln, haben auch eigene, öffentlich zugängliche Bereiche, in denen Sie Unterstützung erhalten und Fragen stellen können. diff --git a/public/content/translations/de/decentralized-identity/index.md b/public/content/translations/de/decentralized-identity/index.md index 62e32e4ee06..e4214ec592e 100644 --- a/public/content/translations/de/decentralized-identity/index.md +++ b/public/content/translations/de/decentralized-identity/index.md @@ -161,6 +161,7 @@ Es gibt viele ehrgeizige Projekte, die Ethereum als Grundlage für dezentrale Id - **[Proof of Humanity](https://www.proofofhumanity.id)** - _Proof of Humanity (Beweis des Menschseins) ist ein auf Ethereum basierendes System zur Überprüfung der sozialen Identität._ - **[BrightID](https://www.brightid.org/)**- _Ein dezentralisiertes quelloffenes Netzwerk zur sozialen Identität, das versucht, die Identitätsüberprüfung durch die Schaffung und Analyse eines sozialen Diagramms zu reformieren._ - **[Personennachweis-Passport](https://proofofpersonhood.com/)** - _Ein dezentraler digitaler Identitätsaggregator._ +- **[walt.id](https://walt.id)** — _Open-Source-Infrastruktur für dezentrale Identität und Wallets, die es Entwicklern und Organisationen ermöglicht, selbstbestimmte Identität und NFTs/SBTs zu nutzen._ ## Weiterführende Informationen {#further-reading} @@ -170,6 +171,7 @@ Es gibt viele ehrgeizige Projekte, die Ethereum als Grundlage für dezentrale Id - [Was ist Ethereum ERC725? Eigenständiges Identitätsmanagement in der Blockchain](https://cryptoslate.com/what-is-erc725-self-sovereign-identity-management-on-the-blockchain/) — _Sam-Stadt_ - [Wie die Blockchain das Problem der digitalen Identität lösen könnte](https://time.com/6142810/proof-of-humanity/)— _Andrew R. Chow_ - [Was sind dezentralisierte Identitäten und warum sollten sie Sie interessieren?](https://web3.hashnode.com/what-is-decentralized-identity) — _Emmanuel Awosika_ +- [Einführung in die dezentrale Identität](https://walt.id/white-paper/digital-identity) – _Dominik Beron_ ### Videos {#videos} @@ -177,9 +179,11 @@ Es gibt viele ehrgeizige Projekte, die Ethereum als Grundlage für dezentrale Id - [Anmelden mit Ethereum und dezentralisierter Identität mit Ceramic, IDX, React, und 3ID Connect](https://www.youtube.com/watch?v=t9gWZYJxk7c) — _YouTube-Tutorial zum Aufbau eines Identitätsmanagementsystems zum Erstellen, Lesen und Aktualisieren des Profils von Benutzern mit ihrer Ethereum-Wallet von Nader Dabit_ - [BrightID - Dezentralisierte Identität auf Ethereum](https://www.youtube.com/watch?v=D3DbMFYGRoM) — _Podcast Bankless Episode über BrightID, eine dezentrale Identitätslösung für Ethereum_ - [Das Off-Chain-Internet: Dezentralisierte Identität & Überprüfbare Berechtigungsnachweise](https://www.youtube.com/watch?v=EZ_Bb6j87mg) — EthDenver 2022 Präsentation von Evin McMullen +- [Erklärung zu überprüfbaren Anmeldeinformationen](https://www.youtube.com/watch?v=ce1IdSr-Kig) – YouTube-Erklärvideo mit Demo von Tamino Baumann ### Communities {#communities} - [ERC-725 Allianz auf GitHub](https://github.com/erc725alliance) — _Unterstützer des ERC725-Standards zur Identitätsverwaltung in der Ethereum-Blockchain_ - [SpruceID Discord Server](https://discord.com/invite/Sf9tSFzrnt) — _Community für Enthusiasten und Entwickler, die am Anmelden mit Ethereum arbeiten_ - [Veramo Labs](https://discord.gg/sYBUXpACh4) — _Eine Community von Entwicklern, die zum Aufbau eines Rahmens für überprüfbare Daten für Anwendungen beitragen_ +- [walt.id](https://discord.com/invite/AW8AgqJthZ) – _Eine Gemeinschaft von Entwicklern und Erstellern, die an Anwendungsfällen für dezentrale Identität in verschiedenen Branchen arbeiten_ diff --git a/public/content/translations/de/desci/index.md b/public/content/translations/de/desci/index.md index 1afff22ee61..058bf9280b8 100644 --- a/public/content/translations/de/desci/index.md +++ b/public/content/translations/de/desci/index.md @@ -103,7 +103,7 @@ Erkunden Sie Projekte und werden Sie Teil der DeSci-Gemeinschaft. - [OceanDAO: DAO regelte die Finanzierung der datenbezogenen Wissenschaft](https://oceanprotocol.com/dao) - [OpScientia: offene dezentrale wissenschaftliche Workflows](https://opsci.io/research/) - [LabDAO: Falten eines Proteins in Silizium](https://alphafodl.vercel.app/) -- [Bio.xyz: Erhalten Sie Mittel für Ihr Biotech-DAO oder desci-Projekt](https://www.molecule.to/) +- [Bio.xyz: Erhalten Sie Mittel für Ihr Biotech-DAO oder desci-Projekt](https://www.bio.xyz/) - [ResearchHub: Poste ein wissenschaftliches Ergebnis und führe ein Gespräch mit Partnern](https://www.researchhub.com/) - [VitaDAO: Langfristige Forschung finanziert durch gesponserte Forschungsverträge](https://www.vitadao.com/) - [Flamming-Protokoll: Open-Source-Datenwirtschaft, die die kollaborative biomedizinische Entdeckung fördert](https://medium.com/@FlemingProtocol/a-data-economy-for-patient-driven-biomedical-innovation-9d56bf63d3dd) diff --git a/public/content/translations/de/developers/docs/blocks/index.md b/public/content/translations/de/developers/docs/blocks/index.md index 71c2cbeb275..3b2490d6203 100644 --- a/public/content/translations/de/developers/docs/blocks/index.md +++ b/public/content/translations/de/developers/docs/blocks/index.md @@ -40,7 +40,7 @@ Proof-of-Stake bedeutet Folgendes: Ein Block enthält viele verschiedene Informationen. Auf oberster Ebene enthält ein Block folgende Felder: | Feld | Beschreibung | -| :------------------ | :---------------------------------------------------------- | +|:------------------- |:----------------------------------------------------------- | | `Zeitspanne (Slot)` | Der Slot, zu dem der Block gehört | | `proposer_index` | Die ID des Validators, der den Block vorschlägt | | `parent_root` | Der Hash des vorausgehenden Blocks | @@ -50,7 +50,7 @@ Ein Block enthält viele verschiedene Informationen. Auf oberster Ebene enthält Der `Body` eines Blocks enthält selbst mehrere Felder: | Feld | Beschreibung | -| :------------------- | :------------------------------------------------------------------------------- | +|:-------------------- |:-------------------------------------------------------------------------------- | | `randao_reveal` | Ein Wert, der zur Auswahl des nächsten Block-Vorschlagenden verwendet wird | | `eth1_data` | Informationen zum Einzahlungsvertrag | | `graffiti` | Beliebige Daten, die zum Markieren von Blöcken verwendet werden | @@ -65,7 +65,7 @@ Der `Body` eines Blocks enthält selbst mehrere Felder: Das Feld `attestations` enthält eine Liste aller Attestierungen im Block. Attestierungen haben ihren eigenen Datentyp der mehrere Datenteile enthält. Jede Attestierung enthält: | Feld | Beschreibung | -| :----------------- | :------------------------------------------------------------------------ | +|:------------------ |:------------------------------------------------------------------------- | | `aggregation_bits` | Eine Liste der Validatoren, die an dieser Attestierung teilgenommen haben | | `daten` | Ein Container mit mehreren Unterfeldern | | `signature` | Kollektivsignatur aller bescheinigenden Validatoren | @@ -73,7 +73,7 @@ Das Feld `attestations` enthält eine Liste aller Attestierungen im Block. Attes Das Feld `data` in `attestation` enthält folgende Elemente: | Feld | Beschreibung | -| :------------------ | :---------------------------------------------------------- | +|:------------------- |:----------------------------------------------------------- | | `Zeitspanne (Slot)` | Der Slot, auf den sich die Attestierung bezieht | | `Index` | Indizes für die bescheinigenden Validatoren | | `beacon_block_root` | Der Stamm-Hash des Beacon-Blocks, der dieses Objekt enthält | @@ -85,7 +85,7 @@ Die Ausführung der Transaktionen in der `execution_payload` aktualisiert den gl Der `execution_payload_header` enthält die folgenden Felder: | Feld | Beschreibung | -| :-------------------- | :------------------------------------------------------------------------------------ | +|:--------------------- |:------------------------------------------------------------------------------------- | | `übergeordneter_hash` | Hash des übergeordneten Blocks | | `fee_recipient` | Kontoadresse, an die die Transaktionsgebühren gezahlt werden | | `state_root` | Stamm-Hash für den globalen Zustand nach der Anwendung der Änderungen in diesem Block | @@ -105,7 +105,7 @@ Der `execution_payload_header` enthält die folgenden Felder: Die `execution_payload` selbst enthält Folgendes (das ist identisch zum Header, außer dass es anstatt des Stamm-Hash der Transaktionen die Liste der Transaktions- und Abhebungsinformationen enthält) : | Feld | Beschreibung | -| :-------------------- | :------------------------------------------------------------------------------------ | +|:--------------------- |:------------------------------------------------------------------------------------- | | `übergeordneter_hash` | Hash des übergeordneten Blocks | | `fee_recipient` | Kontoadresse, an die die Transaktionsgebühren gezahlt werden | | `state_root` | Stamm-Hash für den globalen Zustand nach der Anwendung der Änderungen in diesem Block | @@ -125,7 +125,7 @@ Die `execution_payload` selbst enthält Folgendes (das ist identisch zum Header, Die Liste `withdrawals` enthält `withdrawal`-Objekte, die wie folgt strukturiert sind: | Feld | Beschreibung | -| :--------------- | :--------------------------------------------- | +|:---------------- |:---------------------------------------------- | | `address` | Kontoadresse, für die die Abhebung erfolgt ist | | `amount` | Abgehobener Betrag | | `Index` | Abhebungsindexwert | diff --git a/public/content/translations/de/developers/docs/evm/index.md b/public/content/translations/de/developers/docs/evm/index.md index 6204d6d4187..15b14e94051 100644 --- a/public/content/translations/de/developers/docs/evm/index.md +++ b/public/content/translations/de/developers/docs/evm/index.md @@ -10,7 +10,7 @@ Das Ethereum-Protokoll selbst dient ausschließlich dem Zweck, den kontinuierlic ## Voraussetzungen {#prerequisites} -Um den EVM zu verstehen, sind ein paar grundlegende Kenntnisse der gängigen Informatikterminologie wie [Bytes](https://wikipedia.org/wiki/Byte), [Speicher](https://wikipedia.org/wiki/Computer_memory) und [Stack]() notwendig. Es wäre auch hilfreich, wenn Sie sich mit Kryptografie-/Blockchain-Konzepten wie [Hash-Funktionen](https://wikipedia.org/wiki/Cryptographic_hash_function) und dem [Merkle-Baum](https://wikipedia.org/wiki/Merkle_tree) auskennen. +Um den EVM zu verstehen, sind ein paar grundlegende Kenntnisse der gängigen Informatikterminologie wie [Bytes](https://wikipedia.org/wiki/Byte), [Speicher](https://wikipedia.org/wiki/Computer_memory) und [Stack](https://wikipedia.org/wiki/Stack_(abstract_data_type)) notwendig. Es wäre auch hilfreich, wenn Sie sich mit Kryptografie-/Blockchain-Konzepten wie [Hash-Funktionen](https://wikipedia.org/wiki/Cryptographic_hash_function) und dem [Merkle-Baum](https://wikipedia.org/wiki/Merkle_tree) auskennen. ## Vom Ledger zur Zustandsmaschine {#from-ledger-to-state-machine} @@ -46,7 +46,7 @@ Die EVM wird als [Stackmaschine](https://wikipedia.org/wiki/Stack_machine) mit e Während der Ausführung behält die EVM einen transienten _-Speicher_ (als wortadressiertes Byte-Array), der zwischen Transaktionen nicht vorhanden ist. -Verträge enthalten jedoch eine Merkle-Patricia*-Speicher*-Trie (als wortadressierbares Wort-Array), mit der das betreffende Konto und ein Teil des globalen Zustands verbunden sind. +Verträge enthalten jedoch eine Merkle-Patricia_-Speicher_-Trie (als wortadressierbares Wort-Array), mit der das betreffende Konto und ein Teil des globalen Zustands verbunden sind. Kompilierter Smart-Contract-Bytecode wird als eine Anzahl von EVM-[Opcodes ausgeführt](/developers/docs/evm/opcodes), die standardmäßige Stackoperationen wie `XOR`, `UND`, `ADD`, `SUB` etc. ausführen. Die EVM implementiert auch eine Reihe von Blockchain-spezifischen Stack-Operationen, wie `ADDRESS`, `BALANCE`, `BLOCKHASH` usw. @@ -64,6 +64,7 @@ Während der siebenjährigen Geschichte von Ethereum hat die EVM mehrere Revisio - [evmone](https://github.com/ethereum/evmone) - _C++_ - [ethereumjs-vm](https://github.com/ethereumjs/ethereumjs-vm) - _JavaScript_ - [eEVM](https://github.com/microsoft/eevm) - _C++_ +- [revm](https://github.com/bluealloy/revm) - _Rust_ ## Weiterführende Informationen {#further-reading} diff --git a/public/content/translations/de/developers/docs/evm/opcodes/index.md b/public/content/translations/de/developers/docs/evm/opcodes/index.md index f6f6ab2d273..a8ab5e1f52d 100644 --- a/public/content/translations/de/developers/docs/evm/opcodes/index.md +++ b/public/content/translations/de/developers/docs/evm/opcodes/index.md @@ -14,157 +14,157 @@ Für Operationen mit dynamischen Gaskosten, siehe [gas.md](https://github.com/wo 💡 Kurztipp: Um ganze Zeilen einzusehen, verwenden Sie `[shift] + scroll`, um horizontal auf dem Desktop zu scrollen. -| Stack | Name | Gas | Anfangs-Stack | Ergebnis-Stack | Speicher | Anmerkungen | -| :---: | :------------- | :---------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------- | :------------------------------ | :---------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| 00 | STOP | 0 | | | | halt execution | -| 01 | ADD | 3 | `a, b` | `a + b` | | (u)int256 addition modulo 2\*\*256 | -| 02 | MUL | 5 | `a, b` | `a * b` | | (u)int256 multiplication modulo 2\*\*256 | -| 03 | SUB | 3 | `a, b` | `a - b` | | (u)int256 addition modulo 2\*\*256 | -| 04 | DIV | 5 | `a, b` | `a // b` | | uint256 division | -| 05 | SDIV | 5 | `a, b` | `a // b` | | int256 division | -| 06 | MOD | 5 | `a, b` | `a % b` | | uint256 modulus | -| 07 | SMOD | 5 | `a, b` | `a % b` | | int256 modulus | -| 08 | ADDMOD | 8 | `a, b, N` | `(a + b) % N` | | (u)int256 addition modulo N | -| 09 | MULMOD | 8 | `a, b, N` | `(a * b) % N` | | (u)int256 multiplication modulo N | -| 0A | EXP | [A1](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a1-exp) | `a, b` | `a ** b` | | uint256 exponentiation modulo 2\*\*256 | -| 0B | SIGNEXTEND | 5 | `b, x` | `SIGNEXTEND(x, b)` | | [sign extend](https://wikipedia.org/wiki/Sign_extension) `x` from `(b+1)` bytes to 32 bytes | -| 0C-0F | _invalid_ | | | | | | -| 10 | LT | 3 | `a, b` | `a < b` | | uint256 less-than | -| 11 | GT | 3 | `a, b` | `a > b` | | uint256 greater-than | -| 12 | SLT | 3 | `a, b` | `a < b` | | int256 less-than | -| 13 | SGT | 3 | `a, b` | `a > b` | | int256 greater-than | -| 14 | EQ | 3 | `a, b` | `a == b` | | (u)int256 equality | -| 15 | ISZERO | 3 | `a` | `a == 0` | | (u)int256 iszero | -| 16 | AND | 3 | `a, b` | `a && b` | | bitwise AND | -| 17 | OR | 3 | `a, b` | `a \|\| b` | | bitwise OR | -| 18 | XOR | 3 | `a, b` | `a ^ b` | | bitwise XOR | -| 19 | NOT | 3 | `a` | `~a` | | bitwise NOT | -| 1A | BYTE | 3 | `i, x` | `(x >> (248 - i * 8)) && 0xFF` | | `i`th byte of (u)int256 `x`, from the left | -| 1B | SHL | 3 | `shift, val` | `val << shift` | | shift left | -| 1C | SHR | 3 | `shift, val` | `val >> shift` | | logical shift right | -| 1D | SAR | 3 | `shift, val` | `val >> shift` | | arithmetic shift right | -| 1E-1F | _invalid_ | | | | | | -| 20 | KECCAK256 | [A2](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a2-sha3) | `ost, len` | `keccak256(mem[ost:ost+len-1])` | | keccak256 | -| 21-2F | _invalid_ | | | | | | -| 30 | ADDRESS | 2 | `.` | `address(this)` | | address of executing contract | -| 31 | BALANCE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `addr.balance` | | balance, in wei | -| 32 | ORIGIN | 2 | `.` | `tx.origin` | | address that originated the tx | -| 33 | CALLER | 2 | `.` | `msg.sender` | | address of msg sender | -| 34 | CALLVALUE | 2 | `.` | `msg.value` | | msg value, in wei | -| 35 | CALLDATALOAD | 3 | `idx` | `msg.data[idx:idx+32]` | | read word from msg data at index `idx` | -| 36 | CALLDATASIZE | 2 | `.` | `len(msg.data)` | | length of msg data, in bytes | -| 37 | CALLDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | copy msg data | -| 38 | CODESIZE | 2 | `.` | `len(this.code)` | | length of executing contract's code, in bytes | -| 39 | CODECOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | copy executing contract's bytecode | -| 3A | GASPRICE | 2 | `.` | `tx.gasprice` | | gas price of tx, in wei per unit gas [\*\*](https://eips.ethereum.org/EIPS/eip-1559#gasprice) | -| 3B | EXTCODESIZE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `len(addr.code)` | | size of code at addr, in bytes | -| 3C | EXTCODECOPY | [A4](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a4-extcodecopy) | `addr, dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | copy code from `addr` | -| 3D | RETURNDATASIZE | 2 | `.` | `size` | | size of returned data from last external call, in bytes | -| 3E | RETURNDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | copy returned data from last external call | -| 3F | EXTCODEHASH | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `Hash` | | hash = addr.exists ? keccak256(addr.code) : 0 | -| 40 | BLOCKHASH | 20 | `blockNum` | `blockHash(blockNum)` | | | -| 41 | COINBASE | 2 | `.` | `block.coinbase` | | address of miner of current block | -| 42 | TIMESTAMP | 2 | `.` | `block.timestamp` | | timestamp of current block | -| 43 | NUMBER | 2 | `.` | `block.number` | | number of current block | -| 44 | PREVRANDAO | 2 | `.` | `randomness beacon` | | randomness beacon | -| 45 | GASLIMIT | 2 | `.` | `block.gaslimit` | | gas limit of current block | -| 46 | CHAINID | 2 | `.` | `chain_id` | | push current [chain id](https://eips.ethereum.org/EIPS/eip-155) onto stack | -| 47 | SELFBALANCE | 5 | `.` | `address(this).balance` | | balance of executing contract, in wei | -| 48 | BASEFEE | 2 | `.` | `block.basefee` | | base fee of current block | -| 49-4F | _invalid_ | | | | | | -| 50 | POP | 2 | `_anon` | `.` | | remove item from top of stack and discard it | -| 51 | MLOAD | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost` | `mem[ost:ost+32]` | | read word from memory at offset `ost` | -| 52 | MSTORE | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost:ost+32] := val | write a word to memory | -| 53 | MSTORE8 | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost] := val && 0xFF | write a single byte to memory | -| 54 | SLOAD | [A6](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a6-sload) | `key` | `storage[key]` | | read word from storage | -| 55 | SSTORE | [A7](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a7-sstore) | `key, val` | `.` | storage[key] := val | write word to storage | -| 56 | JUMP | 8 | `dst` | `.` | | `$pc := dst` mark that `pc` is only assigned if `dst` is a valid jumpdest | -| 57 | JUMPI | 10 | `dst, condition` | `.` | | `$pc := condition ? dst : $pc + 1` | -| 58 | PC | 2 | `.` | `$pc` | | program counter | -| 59 | MSIZE | 2 | `.` | `len(mem)` | | size of memory in current execution context, in bytes | -| 5A | GAS | 2 | `.` | `gasRemaining` | | | -| 5B | JUMPDEST | 1 | | | mark valid jump destination | a valid jump destination for example a jump destination not inside the push data | -| 5C-5E | _invalid_ | | | | | | -| 5F | PUSH0 | 2 | `.` | `uint8` | | Bringen Sie den konstanten Wert 0 in den Stack ein | -| 60 | PUSH1 | 3 | `.` | `uint8` | | push 1-byte value onto stack | -| 61 | PUSH2 | 3 | `.` | `uint16` | | push 2-byte value onto stack | -| 62 | PUSH3 | 3 | `.` | `uint24` | | push 3-byte value onto stack | -| 63 | PUSH4 | 3 | `.` | `uint32` | | push 4-byte value onto stack | -| 64 | PUSH5 | 3 | `.` | `uint40` | | push 5-byte value onto stack | -| 65 | PUSH6 | 3 | `.` | `uint48` | | push 6-byte value onto stack | -| 66 | PUSH7 | 3 | `.` | `uint56` | | push 7-byte value onto stack | -| 67 | PUSH8 | 3 | `.` | `uint64` | | push 8-byte value onto stack | -| 68 | PUSH9 | 3 | `.` | `uint72` | | push 9-byte value onto stack | -| 69 | PUSH10 | 3 | `.` | `uint80` | | push 10-byte value onto stack | -| 6A | PUSH11 | 3 | `.` | `uint88` | | push 11-byte value onto stack | -| 6B | PUSH12 | 3 | `.` | `uint96` | | push 12-byte value onto stack | -| 6C | PUSH13 | 3 | `.` | `uint104` | | push 13-byte value onto stack | -| 6D | PUSH14 | 3 | `.` | `uint112` | | push 14-byte value onto stack | -| 6E | PUSH15 | 3 | `.` | `uint120` | | push 15-byte value onto stack | -| 6F | PUSH16 | 3 | `.` | `uint128` | | push 16-byte value onto stack | -| 70 | PUSH17 | 3 | `.` | `uint136` | | push 17-byte value onto stack | -| 71 | PUSH18 | 3 | `.` | `uint144` | | push 18-byte value onto stack | -| 72 | PUSH19 | 3 | `.` | `uint152` | | push 19-byte value onto stack | -| 73 | PUSH20 | 3 | `.` | `uint160` | | push 20-byte value onto stack | -| 74 | PUSH21 | 3 | `.` | `uint168` | | push 21-byte value onto stack | -| 75 | PUSH22 | 3 | `.` | `uint176` | | push 22-byte value onto stack | -| 76 | PUSH23 | 3 | `.` | `uint184` | | push 23-byte value onto stack | -| 77 | PUSH24 | 3 | `.` | `uint192` | | push 24-byte value onto stack | -| 78 | PUSH25 | 3 | `.` | `uint200` | | push 25-byte value onto stack | -| 79 | PUSH26 | 3 | `.` | `uint208` | | push 26-byte value onto stack | -| 7A | PUSH27 | 3 | `.` | `uint216` | | push 27-byte value onto stack | -| 7B | PUSH28 | 3 | `.` | `uint224` | | push 28-byte value onto stack | -| 7C | PUSH29 | 3 | `.` | `uint232` | | push 29-byte value onto stack | -| 7D | PUSH30 | 3 | `.` | `uint240` | | push 30-byte value onto stack | -| 7E | PUSH31 | 3 | `.` | `uint248` | | push 31-byte value onto stack | -| 7F | PUSH32 | 3 | `.` | `uint256` | | push 32-byte value onto stack | -| 80 | DUP1 | 3 | `a` | `a, a` | | clone 1st value on stack | -| 81 | DUP2 | 3 | `_, a` | `a, _, a` | | clone 2nd value on stack | -| 82 | DUP3 | 3 | `_, _, a` | `a, _, _, a` | | clone 3rd value on stack | -| 83 | DUP4 | 3 | `_, _, _, a` | `a, _, _, _, a` | | clone 4th value on stack | -| 84 | DUP5 | 3 | `..., a` | `a, ..., a` | | clone 5th value on stack | -| 85 | DUP6 | 3 | `..., a` | `a, ..., a` | | clone 6th value on stack | -| 86 | DUP7 | 3 | `..., a` | `a, ..., a` | | clone 7th value on stack | -| 87 | DUP8 | 3 | `..., a` | `a, ..., a` | | clone 8th value on stack | -| 88 | DUP9 | 3 | `..., a` | `a, ..., a` | | clone 9th value on stack | -| 89 | DUP10 | 3 | `..., a` | `a, ..., a` | | clone 10th value on stack | -| 8A | DUP11 | 3 | `..., a` | `a, ..., a` | | clone 11th value on stack | -| 8B | DUP12 | 3 | `..., a` | `a, ..., a` | | clone 12th value on stack | -| 8C | DUP13 | 3 | `..., a` | `a, ..., a` | | clone 13th value on stack | -| 8D | DUP14 | 3 | `..., a` | `a, ..., a` | | clone 14th value on stack | -| 8E | DUP15 | 3 | `..., a` | `a, ..., a` | | clone 15th value on stack | -| 8F | DUP16 | 3 | `..., a` | `a, ..., a` | | clone 16th value on stack | -| 90 | SWAP1 | 3 | `a, b` | `b, a` | | | -| 91 | SWAP2 | 3 | `a, _, b` | `b, _, a` | | | -| 92 | SWAP3 | 3 | `a, _, _, b` | `b, _, _, a` | | | -| 93 | SWAP4 | 3 | `a, _, _, _, b` | `b, _, _, _, a` | | | -| 94 | SWAP5 | 3 | `a, ..., b` | `b, ..., a` | | | -| 95 | SWAP6 | 3 | `a, ..., b` | `b, ..., a` | | | -| 96 | SWAP7 | 3 | `a, ..., b` | `b, ..., a` | | | -| 97 | SWAP8 | 3 | `a, ..., b` | `b, ..., a` | | | -| 98 | SWAP9 | 3 | `a, ..., b` | `b, ..., a` | | | -| 99 | SWAP10 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9A | SWAP11 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9B | SWAP12 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9C | SWAP13 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9D | SWAP14 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9E | SWAP15 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9F | SWAP16 | 3 | `a, ..., b` | `b, ..., a` | | | -| A0 | LOG0 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len` | `.` | | LOG0(memory[ost:ost+len-1]) | -| A1 | LOG1 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0` | `.` | | LOG1(memory[ost:ost+len-1], topic0) | -| A2 | LOG2 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1) | -| A3 | LOG3 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2) | -| A4 | LOG4 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2, topic3` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2, topic3) | -| A5-EF | _invalid_ | | | | | | -| F0 | CREATE | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len` | `addr` | | addr = keccak256(rlp([address(this), this.nonce])) | -| F1 | CALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | gas, addr, val, argOst, argLen, retOst, retLen | `success` | mem[retOst:retOst+retLen-1] := returndata | | -| F2 | CALLCODE | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, val, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] = returndata | same as DELEGATECALL, but does not propagate original msg.sender and msg.value | -| F3 | RETURN | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | return mem[ost:ost+len-1] | -| F4 | DELEGATECALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | -| F5 | CREATE2 | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len, salt` | `addr` | | addr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] | -| F6-F9 | _invalid_ | | | | | | -| FA | STATICCALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | -| FB-FC | _invalid_ | | | | | | -| FD | REVERT | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | revert(mem[ost:ost+len-1]) | -| FE | INVALID | [AF](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#af-invalid) | | | designated invalid opcode - [EIP-141](https://eips.ethereum.org/EIPS/eip-141) | | -| FF | SELFDESTRUCT | [AB](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#ab-selfdestruct) | `addr` | `.` | | | destroy contract and sends all funds to `addr` | +| Stack | Name | Gas | Anfangs-Stack | Ergebnis-Stack | Speicher | Anmerkungen | +|:-----:|:-------------- |:-----------------------------------------------------------------------------------------------:|:------------------------------------------------ |:-------------------------------------------- |:----------------------------------------------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 00 | STOP | 0 | | | | halt execution | +| 01 | ADD | 3 | `a, b` | `a + b` | | (u)int256 addition modulo 2\*\*256 | +| 02 | MUL | 5 | `a, b` | `a * b` | | (u)int256 multiplication modulo 2\*\*256 | +| 03 | SUB | 3 | `a, b` | `a - b` | | (u)int256 addition modulo 2\*\*256 | +| 04 | DIV | 5 | `a, b` | `a // b` | | uint256 division | +| 05 | SDIV | 5 | `a, b` | `a // b` | | int256 division | +| 06 | MOD | 5 | `a, b` | `a % b` | | uint256 modulus | +| 07 | SMOD | 5 | `a, b` | `a % b` | | int256 modulus | +| 08 | ADDMOD | 8 | `a, b, N` | `(a + b) % N` | | (u)int256 addition modulo N | +| 09 | MULMOD | 8 | `a, b, N` | `(a * b) % N` | | (u)int256 multiplication modulo N | +| 0A | EXP | [A1](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a1-exp) | `a, b` | `a ** b` | | uint256 exponentiation modulo 2\*\*256 | +| 0B | SIGNEXTEND | 5 | `b, x` | `SIGNEXTEND(x, b)` | | [sign extend](https://wikipedia.org/wiki/Sign_extension) `x` from `(b+1)` bytes to 32 bytes | +| 0C-0F | _invalid_ | | | | | | +| 10 | LT | 3 | `a, b` | `a < b` | | uint256 less-than | +| 11 | GT | 3 | `a, b` | `a > b` | | uint256 greater-than | +| 12 | SLT | 3 | `a, b` | `a < b` | | int256 less-than | +| 13 | SGT | 3 | `a, b` | `a > b` | | int256 greater-than | +| 14 | EQ | 3 | `a, b` | `a == b` | | (u)int256 equality | +| 15 | ISZERO | 3 | `a` | `a == 0` | | (u)int256 iszero | +| 16 | AND | 3 | `a, b` | `a && b` | | bitwise AND | +| 17 | OR | 3 | `a, b` | `a \|\| b` | | bitwise OR | +| 18 | XOR | 3 | `a, b` | `a ^ b` | | bitwise XOR | +| 19 | NOT | 3 | `a` | `~a` | | bitwise NOT | +| 1A | BYTE | 3 | `i, x` | `(x >> (248 - i * 8)) && 0xFF` | | `i`th byte of (u)int256 `x`, from the left | +| 1B | SHL | 3 | `shift, val` | `val << shift` | | shift left | +| 1C | SHR | 3 | `shift, val` | `val >> shift` | | logical shift right | +| 1D | SAR | 3 | `shift, val` | `val >> shift` | | arithmetic shift right | +| 1E-1F | _invalid_ | | | | | | +| 20 | KECCAK256 | [A2](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a2-sha3) | `ost, len` | `keccak256(mem[ost:ost+len-1])` | | keccak256 | +| 21-2F | _invalid_ | | | | | | +| 30 | ADDRESS | 2 | `.` | `address(this)` | | address of executing contract | +| 31 | BALANCE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `addr.balance` | | balance, in wei | +| 32 | ORIGIN | 2 | `.` | `tx.origin` | | address that originated the tx | +| 33 | CALLER | 2 | `.` | `msg.sender` | | address of msg sender | +| 34 | CALLVALUE | 2 | `.` | `msg.value` | | msg value, in wei | +| 35 | CALLDATALOAD | 3 | `idx` | `msg.data[idx:idx+32]` | | read word from msg data at index `idx` | +| 36 | CALLDATASIZE | 2 | `.` | `len(msg.data)` | | length of msg data, in bytes | +| 37 | CALLDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | copy msg data | +| 38 | CODESIZE | 2 | `.` | `len(this.code)` | | length of executing contract's code, in bytes | +| 39 | CODECOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | copy executing contract's bytecode | +| 3A | GASPRICE | 2 | `.` | `tx.gasprice` | | gas price of tx, in wei per unit gas [\*\*](https://eips.ethereum.org/EIPS/eip-1559#gasprice) | +| 3B | EXTCODESIZE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `len(addr.code)` | | size of code at addr, in bytes | +| 3C | EXTCODECOPY | [A4](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a4-extcodecopy) | `addr, dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | copy code from `addr` | +| 3D | RETURNDATASIZE | 2 | `.` | `size` | | size of returned data from last external call, in bytes | +| 3E | RETURNDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | copy returned data from last external call | +| 3F | EXTCODEHASH | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `Hash` | | hash = addr.exists ? keccak256(addr.code) : 0 | +| 40 | BLOCKHASH | 20 | `blockNum` | `blockHash(blockNum)` | | | +| 41 | COINBASE | 2 | `.` | `block.coinbase` | | address of miner of current block | +| 42 | TIMESTAMP | 2 | `.` | `block.timestamp` | | timestamp of current block | +| 43 | NUMBER | 2 | `.` | `block.number` | | number of current block | +| 44 | PREVRANDAO | 2 | `.` | `randomness beacon` | | randomness beacon | +| 45 | GASLIMIT | 2 | `.` | `block.gaslimit` | | gas limit of current block | +| 46 | CHAINID | 2 | `.` | `chain_id` | | push current [chain id](https://eips.ethereum.org/EIPS/eip-155) onto stack | +| 47 | SELFBALANCE | 5 | `.` | `address(this).balance` | | balance of executing contract, in wei | +| 48 | BASEFEE | 2 | `.` | `block.basefee` | | base fee of current block | +| 49-4F | _invalid_ | | | | | | +| 50 | POP | 2 | `_anon` | `.` | | remove item from top of stack and discard it | +| 51 | MLOAD | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost` | `mem[ost:ost+32]` | | read word from memory at offset `ost` | +| 52 | MSTORE | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost:ost+32] := val | write a word to memory | +| 53 | MSTORE8 | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost] := val && 0xFF | write a single byte to memory | +| 54 | SLOAD | [A6](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a6-sload) | `key` | `storage[key]` | | read word from storage | +| 55 | SSTORE | [A7](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a7-sstore) | `key, val` | `.` | storage[key] := val | write word to storage | +| 56 | JUMP | 8 | `dst` | `.` | | `$pc := dst` mark that `pc` is only assigned if `dst` is a valid jumpdest | +| 57 | JUMPI | 10 | `dst, condition` | `.` | | `$pc := condition ? dst : $pc + 1` | +| 58 | PC | 2 | `.` | `$pc` | | program counter | +| 59 | MSIZE | 2 | `.` | `len(mem)` | | size of memory in current execution context, in bytes | +| 5A | GAS | 2 | `.` | `gasRemaining` | | | +| 5B | JUMPDEST | 1 | | | mark valid jump destination | a valid jump destination for example a jump destination not inside the push data | +| 5C-5E | _invalid_ | | | | | | +| 5F | PUSH0 | 2 | `.` | `uint8` | | Bringen Sie den konstanten Wert 0 in den Stack ein | +| 60 | PUSH1 | 3 | `.` | `uint8` | | push 1-byte value onto stack | +| 61 | PUSH2 | 3 | `.` | `uint16` | | push 2-byte value onto stack | +| 62 | PUSH3 | 3 | `.` | `uint24` | | push 3-byte value onto stack | +| 63 | PUSH4 | 3 | `.` | `uint32` | | push 4-byte value onto stack | +| 64 | PUSH5 | 3 | `.` | `uint40` | | push 5-byte value onto stack | +| 65 | PUSH6 | 3 | `.` | `uint48` | | push 6-byte value onto stack | +| 66 | PUSH7 | 3 | `.` | `uint56` | | push 7-byte value onto stack | +| 67 | PUSH8 | 3 | `.` | `uint64` | | push 8-byte value onto stack | +| 68 | PUSH9 | 3 | `.` | `uint72` | | push 9-byte value onto stack | +| 69 | PUSH10 | 3 | `.` | `uint80` | | push 10-byte value onto stack | +| 6A | PUSH11 | 3 | `.` | `uint88` | | push 11-byte value onto stack | +| 6B | PUSH12 | 3 | `.` | `uint96` | | push 12-byte value onto stack | +| 6C | PUSH13 | 3 | `.` | `uint104` | | push 13-byte value onto stack | +| 6D | PUSH14 | 3 | `.` | `uint112` | | push 14-byte value onto stack | +| 6E | PUSH15 | 3 | `.` | `uint120` | | push 15-byte value onto stack | +| 6F | PUSH16 | 3 | `.` | `uint128` | | push 16-byte value onto stack | +| 70 | PUSH17 | 3 | `.` | `uint136` | | push 17-byte value onto stack | +| 71 | PUSH18 | 3 | `.` | `uint144` | | push 18-byte value onto stack | +| 72 | PUSH19 | 3 | `.` | `uint152` | | push 19-byte value onto stack | +| 73 | PUSH20 | 3 | `.` | `uint160` | | push 20-byte value onto stack | +| 74 | PUSH21 | 3 | `.` | `uint168` | | push 21-byte value onto stack | +| 75 | PUSH22 | 3 | `.` | `uint176` | | push 22-byte value onto stack | +| 76 | PUSH23 | 3 | `.` | `uint184` | | push 23-byte value onto stack | +| 77 | PUSH24 | 3 | `.` | `uint192` | | push 24-byte value onto stack | +| 78 | PUSH25 | 3 | `.` | `uint200` | | push 25-byte value onto stack | +| 79 | PUSH26 | 3 | `.` | `uint208` | | push 26-byte value onto stack | +| 7A | PUSH27 | 3 | `.` | `uint216` | | push 27-byte value onto stack | +| 7B | PUSH28 | 3 | `.` | `uint224` | | push 28-byte value onto stack | +| 7C | PUSH29 | 3 | `.` | `uint232` | | push 29-byte value onto stack | +| 7D | PUSH30 | 3 | `.` | `uint240` | | push 30-byte value onto stack | +| 7E | PUSH31 | 3 | `.` | `uint248` | | push 31-byte value onto stack | +| 7F | PUSH32 | 3 | `.` | `uint256` | | push 32-byte value onto stack | +| 80 | DUP1 | 3 | `a` | `a, a` | | clone 1st value on stack | +| 81 | DUP2 | 3 | `_, a` | `a, _, a` | | clone 2nd value on stack | +| 82 | DUP3 | 3 | `_, _, a` | `a, _, _, a` | | clone 3rd value on stack | +| 83 | DUP4 | 3 | `_, _, _, a` | `a, _, _, _, a` | | clone 4th value on stack | +| 84 | DUP5 | 3 | `..., a` | `a, ..., a` | | clone 5th value on stack | +| 85 | DUP6 | 3 | `..., a` | `a, ..., a` | | clone 6th value on stack | +| 86 | DUP7 | 3 | `..., a` | `a, ..., a` | | clone 7th value on stack | +| 87 | DUP8 | 3 | `..., a` | `a, ..., a` | | clone 8th value on stack | +| 88 | DUP9 | 3 | `..., a` | `a, ..., a` | | clone 9th value on stack | +| 89 | DUP10 | 3 | `..., a` | `a, ..., a` | | clone 10th value on stack | +| 8A | DUP11 | 3 | `..., a` | `a, ..., a` | | clone 11th value on stack | +| 8B | DUP12 | 3 | `..., a` | `a, ..., a` | | clone 12th value on stack | +| 8C | DUP13 | 3 | `..., a` | `a, ..., a` | | clone 13th value on stack | +| 8D | DUP14 | 3 | `..., a` | `a, ..., a` | | clone 14th value on stack | +| 8E | DUP15 | 3 | `..., a` | `a, ..., a` | | clone 15th value on stack | +| 8F | DUP16 | 3 | `..., a` | `a, ..., a` | | clone 16th value on stack | +| 90 | SWAP1 | 3 | `a, b` | `b, a` | | | +| 91 | SWAP2 | 3 | `a, _, b` | `b, _, a` | | | +| 92 | SWAP3 | 3 | `a, _, _, b` | `b, _, _, a` | | | +| 93 | SWAP4 | 3 | `a, _, _, _, b` | `b, _, _, _, a` | | | +| 94 | SWAP5 | 3 | `a, ..., b` | `b, ..., a` | | | +| 95 | SWAP6 | 3 | `a, ..., b` | `b, ..., a` | | | +| 96 | SWAP7 | 3 | `a, ..., b` | `b, ..., a` | | | +| 97 | SWAP8 | 3 | `a, ..., b` | `b, ..., a` | | | +| 98 | SWAP9 | 3 | `a, ..., b` | `b, ..., a` | | | +| 99 | SWAP10 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9A | SWAP11 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9B | SWAP12 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9C | SWAP13 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9D | SWAP14 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9E | SWAP15 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9F | SWAP16 | 3 | `a, ..., b` | `b, ..., a` | | | +| A0 | LOG0 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len` | `.` | | LOG0(memory[ost:ost+len-1]) | +| A1 | LOG1 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0` | `.` | | LOG1(memory[ost:ost+len-1], topic0) | +| A2 | LOG2 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1) | +| A3 | LOG3 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2) | +| A4 | LOG4 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2, topic3` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2, topic3) | +| A5-EF | _invalid_ | | | | | | +| F0 | CREATE | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len` | `addr` | | addr = keccak256(rlp([address(this), this.nonce])) | +| F1 | CALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | gas, addr, val, argOst, argLen, retOst, retLen | `success` | mem[retOst:retOst+retLen-1] := returndata | | +| F2 | CALLCODE | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, val, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] = returndata | same as DELEGATECALL, but does not propagate original msg.sender and msg.value | +| F3 | RETURN | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | return mem[ost:ost+len-1] | +| F4 | DELEGATECALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | +| F5 | CREATE2 | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len, salt` | `addr` | | addr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] | +| F6-F9 | _invalid_ | | | | | | +| FA | STATICCALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | +| FB-FC | _invalid_ | | | | | | +| FD | REVERT | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | revert(mem[ost:ost+len-1]) | +| FE | INVALID | [AF](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#af-invalid) | | | designated invalid opcode - [EIP-141](https://eips.ethereum.org/EIPS/eip-141) | | +| FF | SELFDESTRUCT | [AB](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#ab-selfdestruct) | `addr` | `.` | | | destroy contract and sends all funds to `addr` | diff --git a/public/content/translations/de/developers/docs/gas/index.md b/public/content/translations/de/developers/docs/gas/index.md index b669b72079d..a368ee37592 100644 --- a/public/content/translations/de/developers/docs/gas/index.md +++ b/public/content/translations/de/developers/docs/gas/index.md @@ -55,7 +55,7 @@ Jeder Block hat seine eigene Basisgebühr, welche als reservierter Preis erschei Die Grundgebühr wird anhand einer Formel berechnet, die die Größe des vorherigen Blocks (die für alle Transaktionen verwendete Gasmenge) mit der Zielgröße vergleicht. Die Grundgebühr erhöht sich um maximal 12,5 % pro Block, wenn die Zielblockgröße überschritten wird. Dieses exponentielle Wachstum macht es wirtschaftlich unrentabel, die Blockgröße unbegrenzt hoch zu halten. | Blocknummer | Enthaltenes Gas | Gebührenerhöhung | Aktuelle Grundgebühr | -| ----------- | --------------: | ---------------: | -------------------: | +| ----------- | ---------------:| ----------------:| --------------------:| | 1 | 15 m | 0 % | 100 gwei | | 2 | 30 m | 0 % | 100 gwei | | 3 | 30 m | 12,5 % | 112,5 gwei | @@ -70,7 +70,7 @@ Der obigen Tabelle folgend: Um eine Transaktion auf Block Nummer 9 zu erstellen, Außerdem ist es unwahrscheinlich, dass es zu längeren Zeiträumen mit vollen Blöcken kommt, da die Grundgebühr vor einem vollen Block schnell ansteigt. | Blocknummer | Enthaltenes Gas | Gebührenerhöhung | Aktuelle Grundgebühr | -| ----------- | --------------: | ---------------: | -------------------: | +| ----------- | ---------------:| ----------------:| --------------------:| | 30 | 30 m | 12,5 % | 2705,6 gwei | | ... | ... | 12,5 % | ... | | 50 | 30 m | 12,5 % | 28531,3 gwei | diff --git a/public/content/translations/de/developers/docs/networks/index.md b/public/content/translations/de/developers/docs/networks/index.md index 4a32ec80066..0131cc16499 100644 --- a/public/content/translations/de/developers/docs/networks/index.md +++ b/public/content/translations/de/developers/docs/networks/index.md @@ -56,12 +56,11 @@ Die beiden öffentlichen Testnets, die die Client-Entwickler derzeit betreiben, - [QuickNode Sepolia Faucet](https://faucet.quicknode.com/drip) - [Grabteeth](https://grabteeth.xyz/) - [PoW-Faucet](https://sepolia-faucet.pk910.de/) -- [Sepolia-Faucet](https://faucet.sepolia.dev/) -- [FaucETH](https://fauceth.komputing.org) -- [Coinbase Wallet Faucet | Sepolia](https://coinbase.com/faucets/ethereum-sepolia-faucet) -- [Alchemy Sepolia-Faucet](https://sepoliafaucet.com/) -- [Infura Sepolia-Faucet](https://www.infura.io/faucet) -- [Chainstack Sepolia-Faucet](https://faucet.chainstack.com/sepolia-faucet) +- [Faucet für Coinbase-Wallet | Sepolia](https://coinbase.com/faucets/ethereum-sepolia-faucet) +- [Faucet für Alchemy Sepolia](https://sepoliafaucet.com/) +- [Faucet für Infura Sepolia](https://www.infura.io/faucet) +- [Faucet für Chainstack Sepolia](https://faucet.chainstack.com/sepolia-faucet) +- [Testnetz-Faucet | Sepolia](https://testnet-faucet.com/sepolia/) #### Goerli _(Langzeit-Support)_ {#goerli} @@ -113,9 +112,17 @@ Ein Testnet für [Optimism](https://www.optimism.io/). - [Paradigm-Faucet](https://faucet.paradigm.xyz/) - [Coinbase Wallet Faucet | Optimism Goerli](https://coinbase.com/faucets/optimism-goerli-faucet) +#### Starknet Goerli {#starknet-goerli} + +Ein Testnetz für [Starknet](https://www.starknet.io). + +##### Faucets + +- [Starknet-Faucet](https://faucet.goerli.starknet.io) + ## Private Netzwerke {#private-networks} -Ein Ethereum-Netzwerk ist ein privates Netzwerk, wenn seine Knoten nicht mit einem öffentlichen Netzwerk verbunden sind (d. h. Mainnet oder ein Testnet). In diesem Zusammenhang bedeutet privat nur reserviert oder isoliert statt geschützt oder sicher. +Ein Ethereum-Netzwerk ist ein privates Netzwerk, wenn seine Knoten nicht mit einem öffentlichen Netzwerk verbunden sind (z. B. mit Mainnet oder einem Testnet). In diesem Zusammenhang bedeutet privat nur reserviert oder isoliert statt geschützt oder sicher. ### Entwicklungsnetzwerke {#development-networks} @@ -125,7 +132,7 @@ Es gibt Projekte und Tools, die dabei hilfreich sind. Erfahren Sie mehr über [E ### Konsortium-Netzwerke {#consortium-networks} -Der Konsensprozess wird von einer vordefinierten Gruppe von Knoten gesteuert, die vertrauenswürdig sind. Zum Beispiel ein privates Netzwerk bekannter akademischer Institutionen, die jeweils einen einzelnen Knoten stellen, wodurch Blöcke mit einer Schwelle von Unterzeichnern innerhalb des Netzwerks validiert werden. +Der Konsensprozess wird von einer vordefinierten Gruppe von Nodes gesteuert, die vertrauenswürdig sind. Beispielsweise ein privates Netzwerk bekannter akademischer Institutionen, die jeweils eine einzelne Node stellen, sowie Blöcke werden mithilfe einer Schwelle von Unterzeichnern innerhalb des Netzwerks validiert. Wenn ein öffentliches Ethereum-Netzwerk wie das öffentliche Internet ist, dann ist ein Konsortialnetzwerk wie ein privates Intranet. @@ -137,4 +144,4 @@ Wenn ein öffentliches Ethereum-Netzwerk wie das öffentliche Internet ist, dann ## Weiterführende Informationen {#further-reading} - [Vorschlag: vorhersehbarer Ethereum-Testnet-Lebenszyklus](https://ethereum-magicians.org/t/proposal-predictable-ethereum-testnet-lifecycle/11575/17) -- [Die Evolution der Ethereum-Testnets](https://etherworld.co/2022/08/19/the-evolution-of-ethereum-testnet/) +- [Die Entwicklung der Ethereum-Testnets](https://etherworld.co/2022/08/19/the-evolution-of-ethereum-testnet/) diff --git a/public/content/translations/de/developers/docs/nodes-and-clients/archive-nodes/index.md b/public/content/translations/de/developers/docs/nodes-and-clients/archive-nodes/index.md index 49f6b56c0f0..2a1bab7cc38 100644 --- a/public/content/translations/de/developers/docs/nodes-and-clients/archive-nodes/index.md +++ b/public/content/translations/de/developers/docs/nodes-and-clients/archive-nodes/index.md @@ -56,7 +56,7 @@ Bevor Sie ihren eigenen Archivierungsknoten starten, sollten Sie die Unterschied ## Empfohlene Verfahren -Neben den generellen [Empfehlungen zum Betreiben eines Knotens](/developers/docs/nodes-and-clients/run-a-node/) kann ein Archivierungsknoten höhere Anforderungen an Hardware und Wartung stellen. In Anbetracht von Erigons [Schlüsselfunktionen](https://github.com/ledgerwatch/erigon#key-features) ist der praktischste Ansatz, die [Erigon](/developers/docs/nodes-and-clients/#erigon)-Client-Implementation zu verwenden. +Abgesehen von den generellen [Empfehlungen zum Betreiben einer Node](/developers/docs/nodes-and-clients/run-a-node/) kann eine Archivierungs-Node höhere Anforderungen an Hardware und Wartung stellen. In Anbetracht von Erigons [Schlüsselfunktionen](https://github.com/ledgerwatch/erigon#key-features) ist der praktischste Ansatz, die [Erigon](/developers/docs/nodes-and-clients/#erigon)-Client-Implementation zu verwenden. ### Hardware diff --git a/public/content/translations/de/developers/docs/nodes-and-clients/client-diversity/index.md b/public/content/translations/de/developers/docs/nodes-and-clients/client-diversity/index.md index 38bb734b15e..9dd6b3ba85b 100644 --- a/public/content/translations/de/developers/docs/nodes-and-clients/client-diversity/index.md +++ b/public/content/translations/de/developers/docs/nodes-and-clients/client-diversity/index.md @@ -31,7 +31,7 @@ Die Client-Vielfalt bietet auch eine gewisse Widerstandsfähigkeit gegen Angriff Ein Fehler in einem Konsensclient mit mehr als 33 % der Ethereum-Knoten könnte verhindern, dass die Konsensebene finalisieren kann. Das bedeutet, dass die Nutzer nicht darauf vertrauen können, dass Transaktionen nicht irgendwann rückgängig gemacht oder geändert werden. Dies wäre für viele der auf Ethereum aufbauenden Anwendungen, insbesondere DeFi, sehr problematisch. - Schlimmer noch, ein kritischer Fehler in einem Client mit einer Zweidrittelmehrheit könnte dazu führen, dass die Chain nicht korrekt geteilt und finalisiert wird. Dies wiederum würde dazu führen, dass eine große Anzahl von Validatoren auf einer ungültigen Chain stecken bleibt. Wenn sie sich der korrekten Chain wieder anschließen möchten, müssen diese Validatoren mit Slashing oder einem langsamen und teuren freiwilligen Rückzug und Reaktivierung rechnen. Das Ausmaß eines Slashings skaliert mit der Anzahl der schuldigen Knoten, wobei maximal eine Zweidrittelmehrheit geslashed werden kann (32 ETH). + Schlimmer noch, ein kritischer Fehler in einem Client mit einer Zweidrittelmehrheit könnte dazu führen, dass die Chain nicht korrekt geteilt und finalisiert wird. Dies wiederum würde dazu führen, dass eine große Anzahl von Validatoren auf einer ungültigen Chain stecken bleibt. Wenn sie sich der korrekten Chain wieder anschließen möchten, müssen diese Validatoren mit Slashing oder einem langsamen und teuren freiwilligen Rückzug und Reaktivierung rechnen. Das Ausmaß eines Slashings skaliert mit der Anzahl der schuldigen Knoten, wobei maximal eine Zweidrittelmehrheit geslashed werden kann (32 ETH). Obwohl dies unwahrscheinliche Szenarien sind, kann das Ethereum-Ökosystem das Risiko mindern, indem es die Verteilung der Clients auf die aktiven Knoten ausgleicht. Im Idealfall würde kein Konsensclient jemals einen Anteil von 33 % an der Gesamtzahl der Nodes erreichen. diff --git a/public/content/translations/de/developers/docs/nodes-and-clients/index.md b/public/content/translations/de/developers/docs/nodes-and-clients/index.md index 9a268da2f34..b9ba9692b62 100644 --- a/public/content/translations/de/developers/docs/nodes-and-clients/index.md +++ b/public/content/translations/de/developers/docs/nodes-and-clients/index.md @@ -136,6 +136,7 @@ Diese Tabelle gibt einen Überblick über die verschiedenen Clients. Sie alle be | [Nethermind](http://nethermind.io/) | C#, .NET | Linux, Windows, MacOS | Mainnet, Sepolia, Goerli und weitere | Snap (ohne Serving), Fast, Full | Archive, Pruned | | [Besu](https://besu.hyperledger.org/en/stable/) | Java | Linux, Windows, MacOS | Mainnet, Sepolia, Goerli und weitere | Snap, Fast, Full | Archive, Pruned | | [Erigon](https://github.com/ledgerwatch/erigon) | Go | Linux, Windows, MacOS | Mainnet, Sepolia, Goerli und weitere | Full | Archive, Pruned | +| [Reth](https://github.com/paradigmxyz/reth) | Rust | Linux, Windows, MacOS | Mainnet, Sepolia, Goerli und weitere | Full | Archiv, Reduziert | Weitere Informationen zu unterstützten Netzwerken finden Sie unter [Ethereum-Netzwerke](/developers/docs/networks/). diff --git a/public/content/translations/de/developers/docs/nodes-and-clients/light-clients/index.md b/public/content/translations/de/developers/docs/nodes-and-clients/light-clients/index.md index c29b90a4adc..e2cc50bf1ce 100644 --- a/public/content/translations/de/developers/docs/nodes-and-clients/light-clients/index.md +++ b/public/content/translations/de/developers/docs/nodes-and-clients/light-clients/index.md @@ -1,5 +1,5 @@ --- -title: Light Clients +title: Leichte Clients description: Einführung zu leichten Clients von Ethereum. lang: de --- diff --git a/public/content/translations/de/developers/docs/nodes-and-clients/node-architecture/index.md b/public/content/translations/de/developers/docs/nodes-and-clients/node-architecture/index.md index 1522866987d..e532eb3ee45 100644 --- a/public/content/translations/de/developers/docs/nodes-and-clients/node-architecture/index.md +++ b/public/content/translations/de/developers/docs/nodes-and-clients/node-architecture/index.md @@ -1,5 +1,5 @@ --- -title: Node-Architektur +title: Knotenarchitektur description: Einleitung zum Aufbau von Ethereum-Knoten. lang: de --- @@ -55,5 +55,5 @@ Knotenbetreiber können Validatoren zu ihren Konsensclients hinzufügen, indem s ## Weiterführende Informationen {#further-reading} - [Proof-of-Stake](/developers/docs/consensus-mechanisms/pos) -- [Blockvorschlag](/developers/docs/consensus-mechanisms/pos/block-proposal) +- [Block-Vorschlag](/developers/docs/consensus-mechanisms/pos/block-proposal) - [Prämien und Strafen für Validatoren](/developers/docs/consensus-mechanisms/pos/rewards-and-penalties) diff --git a/public/content/translations/de/developers/docs/nodes-and-clients/run-a-node/index.md b/public/content/translations/de/developers/docs/nodes-and-clients/run-a-node/index.md index e41f72495f8..2d3dfba12d8 100644 --- a/public/content/translations/de/developers/docs/nodes-and-clients/run-a-node/index.md +++ b/public/content/translations/de/developers/docs/nodes-and-clients/run-a-node/index.md @@ -151,7 +151,7 @@ Dort finden Sie die Versionsseiten der Clients, auf denen Sie die vorgefertigten ##### Clients auf Ausführungsebene - [Besu](https://github.com/hyperledger/besu/releases) -- [Erigon](https://github.com/ledgerwatch/erigon#usage) (Bietet keine vorgefertigte Binärdatei, muss kompiliert werden) +- [Erigon](https://github.com/ledgerwatch/erigon/releases) - [Geth](https://geth.ethereum.org/downloads/) - [Nethermind](https://downloads.nethermind.io/) diff --git a/public/content/translations/de/guides/how-to-create-an-ethereum-account/index.md b/public/content/translations/de/guides/how-to-create-an-ethereum-account/index.md index b547c07f2c6..80a7886110f 100644 --- a/public/content/translations/de/guides/how-to-create-an-ethereum-account/index.md +++ b/public/content/translations/de/guides/how-to-create-an-ethereum-account/index.md @@ -4,37 +4,39 @@ description: Eine Schritt-für-Schritt-Anleitung für die Erstellung eines Ether lang: de --- -# So "registrieren" Sie ein Ethereum-Konto +# So erstellen Sie ein Ethereum-Konto -Jeder kann ein Ethereum-Konto kostenlos erstellen mit einer speziellen Art App, allgemein als „Wallet" bezeichnet. Wallets erstellen und sichern die Schlüssel die ein Halten, Senden und Empfangen von Kryptowährungen ermöglichen. Außerdem kann man sich mit Projekten auf Ethereum verbinden, um beispielsweise NFTs oder Token zu handeln, wie auch den Zugang zu Spielen zu öffnen, und noch viel mehr. +Jeder kann zu jeder Zeit ein kostenloses Ethereum-Konto einrichten. Es gibt mehrere Möglichkeiten, aber die einfachste und gebräuchlichste ist die Verwendung einer App, die als Wallet bekannt ist. Wallets erstellen und sichern den Schlüssel, mit dem Sie Ethereum nutzen können. Mit Ihrer Wallet können Sie Transaktionen senden, Ihren Token-Saldo überprüfen und sich mit Anwendungen verbinden, die auf Ethereum aufgebaut sind, wie zum Beispiel Token-Börsen, Spiele, NFT-Marktplätze und mehr. Einige "web2"-Anwendungen erlauben es nun auch, sich mit Ethereum anzumelden. -Im Gegensatz zur Eröffnung eines neuen Kontos bei einer Firma erfolgt die Erstellung eines Ethereum Kontos frei, privat und ohne gesonderte Erlaubnis. Die Konten werden durch Schlüssel kontrolliert, die Sie mit Hilfe Ihrer Wallet-Software erstellen. Sie werden weder von einer dritten Partei ausgestellt noch in einem zentralen Register gespeichert. +Im Gegensatz zur Eröffnung eines neuen Kontos bei einem Unternehmen erfolgt die Einrichtung eines Ethereum-Kontos freiwillig, privat und ohne Genehmigungspflicht. Die Konten werden durch Schlüssel kontrolliert, die Sie mit Hilfe Ihrer Wallet-Software erstellen. Sie werden weder von einer dritten Partei ausgestellt noch in einem zentralen Register gespeichert. -## Schritt 1: Durchsuchen Sie unsere Liste der Wallets (Geldbörsen) +## Schritt 1: Eine Wallet auswählen -Eine Wallet ist wie ein Online-Bankkonto für Ethereum. Es gibt Dutzende von verschiedenen Wallets (Geldbörsen) zur Auswahl - für das Handy, für den Desktop oder sogar für Browser-Erweiterungen. Unsere Liste mit vertrauenswürdigen Geldbörsen ist ein guter Anfang. +Eine Wallet ist eine App, mit der Sie Ihr Ethereum-Konto verwalten können. Die App verwendet Ihre Schlüssel, um Transaktionen zu senden oder entgegenzunehmen und sich bei Anwendungen anzumelden. Es gibt Dutzende von verschiedenen Wallets (Geldbörsen) zur Auswahl - für das Handy, für den Desktop oder sogar für Browser-Erweiterungen. Finden Sie eine Wallet -## Schritt 2: Wählen Sie eine Wallet, die Ihren Anforderungen entspricht +Wenn Sie noch keine Erfahrung mit Kryptowährungen haben, können Sie den Filter "New to Crypto" (Neu im Bereich Kryptowährungen) auf der Seite "Find a Wallet" (Geldbörse finden) auswählen, um die Wallets zu finden, die alle notwendigen Funktionen für Einsteiger enthalten. -Wenn Sie neu sind, können Sie den Filter „New to crypto" aktivieren, um nur die Wallets zu sehen, die alle notwendigen Funktionen enthalten, von denen wir glauben, dass sie für Anfänger besonders geeignet sind. Es gibt auch andere Profilfilter, die auf Ihre Bedürfnisse abgestimmt sind. +![Filterauswahl auf der Seite „Wallet finden“](./wallet-box.png) -## Schritt 3: Laden Sie Ihre Wallet-App herunter und installieren Sie sie. +Es gibt auch andere Profilfilter, die auf Ihre Bedürfnisse abgestimmt sind. Das sind Beispiele für gängige Wallets – Sie sollten jedoch selbst recherchieren, bevor Sie einer Software vertrauen. + +## Schritt 2: Wallet-App herunterladen und installieren Wenn Sie sich für eine bestimmte Wallet entschieden haben, besuchen Sie die offizielle Website oder den App-Store, laden Sie es herunter und installieren Sie es. Sie alle sollten kostenlos sein. -## Schritt 4: Öffnen Sie die App und erstellen oder importieren Sie Ihr Ethereum-Konto +## Schritt 3: App öffnen und ein Ethereum-Konto erstellen oder importieren Wenn Sie Ihre neue Wallet zum ersten Mal öffnen, werden Sie möglicherweise gefragt, ob Sie ein neues Konto anlegen oder ein bestehendes importieren möchten. Klicken Sie auf neues Konto erstellen. -## Schritt 5: Speichern Sie Ihren Wiederherstellungssatz +## Schritt 4: Wiederherstellungssatz speichern -Einige Anwendungen fordern Sie auf, einen geheimen Wiederherstellungssatz zu speichern. Es ist extrem wichtig, diesen geheimen Wiederherstellungssatz sicher aufzubewahren! Jede Person, die diesen geheimen Wiederherstellungssatz kennt, kann die Kontrolle über alle Ihre Konten übernehmen, die mit diesen Wörtern erstellt wurden. Geben Sie diese niemals weiter. Dieser Satz sollte 12 bis 24 zufällig generierte Wörter enthalten (die Reihenfolge der Wörter ist wichtig). +Einige Anwendungen fordern Sie auf, eine geheime "Seed-Phrase" zu speichern (diese wird auch als "Recovery-Phrase" oder "Mnemonic" bezeichnet). Es ist extrem wichtig, diese "Seed-Phrase " sicher aufzubewahren! Die Seed-Phrase wird verwendet, um einen geheimen Schlüssel für ein Konto zu generieren, der zum Signieren und Senden von Transaktionen verwendet werden kann. Jede Person, die die Seed-Phrase kennt, kann alle Konten kontrollieren, die damit erstellt wurden. Teilen Sie die Seed-Phrase niemals mit anderen. Die Seed-Phrase sollte 12 bis 24 zufällig generierte Wörter enthalten (die Reihenfolge der Wörter ist wichtig). -Sobald Sie Ihren Wiederherstellungssatz gespeichert haben, sollten Sie das Dashboard Ihrer Brieftasche mit Ihrem Guthaben sehen. Schauen Sie sich unsere Anleitung an: [Wie verwenden Sie ein Wallet.](/guides/how-to-use-a-wallet) +Sobald Sie Ihre Seed-Phrase gespeichert haben, sollten Sie Ihr Wallet-Dashboard mit Ihrem Guthaben sehen können. Schauen Sie sich unsere Anleitung an: [Wie verwenden Sie ein Wallet.](/guides/how-to-use-a-wallet)
@@ -49,20 +51,22 @@ Sobald Sie Ihren Wiederherstellungssatz gespeichert haben, sollten Sie das Dashb ### Ist meine Wallet auch mein Ethereum-Konto? -Nein, genau wie beim Online-Banking auch kann man mehrere unterschiedliche Konten besitzen, die in einer Wallet-Anwendung gespeichert sind. Die 1aus 24 bzw. 24 Wörtern bestehende Phrase sichert sie alle: Man kann sie mit dem Samen eines großen Baumes vergleichen (weshalb sie stets sicher verwahrt werden muss). Jeder Ast des Baumes enthält einen Schlüssel, und jeder Schlüssel ist einer Ihrer Konten. Wenn Sie den Zugang zu Ihrer Wallet verlieren (also der Baum gefällt wird), können Sie jederzeit alle verschiedenen Konten durch andere Software und den gleichen Seed wiederherstellen (es wächst immer der gleiche Baum daraus). +Nein. Die Wallet ist ein Verwaltungsinstrument, mit dem Sie Ihre Konten verwalten können. Eine einzige Wallet kann Zugang zu mehreren Konten gewähren, und ein einziges Konto kann von mehreren Wallets genutzt werden. Die Seed-Phrase wird verwendet, um Konten zu erstellen, die dann von der Wallet verwaltet werden. + +Sie können sich die Konten als Blätter an einem Baum vorstellen, die alle aus einer einzigen Seed-Phrase "erwachsen". Jedes einzelne "Seed" bringt einen völlig anderen Konto-Baum hervor. ### Kann ich Bitcoin an eine Ethereum-Adresse senden oder Ether an eine Bitcoin-Adresse? -Nein, das können Sie nicht. Bitcoin und Ether befinden sich auf zwei separaten Netzwerken (also unterschiedlichen Blockchains) mit jeweils eigenen Modellen der Buchführung und des Formats der Adresse. Es gab verschiedene Versuche, eine Brücke zwischen den Netzwerken zu bauen, von welchen der Aktivste derzeit [Wrapped bitcoin bzw. WBTC](https://www.bitcoin.com/get-started/what-is-wbtc/) ist. Dies ist keine Unterstützung, da WBTC eine treuhänderische Lösung ist (was bedeutet, dass eine einzelne Personengruppe bestimmte kritische Funktionen kontrolliert) und wird hier nur zu Informationszwecken bereitgestellt. +Nein, das ist nicht möglich. Bitcoin und Ether befinden sich auf zwei separaten Netzwerken (also unterschiedlichen Blockchains) mit jeweils eigenen Modellen der Buchführung und des Formats der Adresse. Es gab verschiedene Versuche, eine Brücke zwischen den Netzwerken zu bauen, von welchen der Aktivste derzeit [Wrapped bitcoin bzw. WBTC](https://www.bitcoin.com/get-started/what-is-wbtc/) ist. Dies ist keine Unterstützung, da WBTC eine treuhänderische Lösung ist (was bedeutet, dass eine einzelne Personengruppe bestimmte kritische Funktionen kontrolliert) und wird hier nur zu Informationszwecken bereitgestellt. ### Wenn ich eine ETH-Adresse besitze, besitze ich dann die gleiche Adresse auf anderen Blockchains? -Sie können dieselbe Adresse auf allen EVM-kompatiblen Blockchains verwenden (wenn Sie eine Wallet mit einem Wiederherstellungssatz haben). Diese [Liste](https://chainlist.org/) zeigt Ihnen, welche Blockchains Sie mit der gleichen Adresse verwenden können. Einige Blockchains, wie z. B. Bitcoin, implementieren einen komplett separaten Satz von Netzwerkregeln und Sie benötigen eine andere Adresse mit einem anderen Format. Wenn Sie eine Smart Contract Wallet haben, sollten Sie auf der Produktwebsite nachsehen, welche Blockchains unterstützt werden. +Sie können dieselbe Adresse auf allen Blockchains verwenden, die eine ähnliche zugrunde liegende Software wie Ethereum verwenden (bekannt als "EVM-kompatibel"). Diese [Liste](https://chainlist.org/) zeigt Ihnen, welche Blockchains Sie mit der gleichen Adresse verwenden können. Einige Blockchains, wie z. B. Bitcoin, implementieren einen komplett separaten Satz von Netzwerkregeln und Sie benötigen eine andere Adresse mit einem anderen Format. Wenn Sie eine Smart Contract Wallet haben, sollten Sie auf der Produktwebsite nachsehen, welche Blockchains unterstützt werden. ### Ist eine eigene Wallet sicherer als die Beträge auf einer Börse zu halten? -Ja, das ist eine viel sicherere Option, da niemand sonst Zugriff auf Ihre Gelder haben wird. Leider gibt es viele Beispiele für gescheiterte Börsen, die Konkurs angemeldet haben, was dazu führte, dass die Nutzer ihre verwahrten Ersparnisse verloren. Hacks, eingefrorene Konten oder blockierte Auszahlungen sind weitere häufige Risiken. Der Besitz einer Wallet (mit einem Wiederherstellungssatz) ist der beste Weg, um Ihr Vermögen zu schützen. Ein schlecht gesicherter Wiederherstellungssatz birgt jedoch potenziell mehr Risiken als die Verwaltung Ihrer Schlüssel durch eine Börse. Bewahren Sie Ihren Wiederherstellungssatz an einem sicheren Ort auf. +Eine eigene Wallet zu besitzen bedeutet, dass Sie die Verantwortung für die Sicherheit Ihrer Vermögenswerte übernehmen. Leider gibt es viele Beispiele für gescheiterte Börsen, die das Geld ihrer Kunden verloren haben. Wenn Sie eine Wallet besitzen (mit einer Seed-Phrase), ist es nicht erforderlich, dass Sie Ihr Vermögen einem anderen Unternehmen anvertrauen. Allerdings müssen Sie Ihre eigenen Schlüssel sichern und Phishing-Betrug, die versehentliche Genehmigung von Transaktionen oder die Preisgabe von Schlüsseln, die Interaktion mit gefälschten Websites und andere Risiken bei der Selbstverwahrung vermeiden. Risiken und Nutzen sind unterschiedlich. ### Wenn ich mein/e Telefon/Hardware-Wallet verliere, muss ich dann dieselbe Wallet-App erneut verwenden, um das verlorene Geld wiederzuerlangen? -Nein, Sie können nahezu jede Wallet verwenden, da der Wiederherstellungsprozess weitestgehend standardisiert ist. Das bedeutet, dass die Eingabe des gleichen Satzes aus 12 bzw. 24 Wörtern in den meisten Wallets zur Wiederherstellung desselben Kontos genutzt werden kann. Seien Sie vorsichtig, falls Sie dies einmal tun müssen: Stellen Sie am besten sicher, dass Sie während der Wiederherstellung Ihrer Wallet nicht mit dem Internet verbunden sind, um ein versehentliches Durchsickern Ihres Wiederherstellungscodes zu vermeiden. Es ist meist unmöglich, verlorene Guthaben ohne den Wiederherstellungssatz wiederzuerlangen. +Nein, es ist möglich, eine andere Wallet zu verwenden. Solange Sie die Seed-Phrase haben, können Sie diese in den meisten Wallets eingeben. Die Wallet stellt dann Ihr Konto wieder her. Seien Sie vorsichtig, wenn das einmal erforderlich werden sollte: Stellen Sie sicher, dass Sie bei der Wiederherstellung Ihrer Wallet nicht mit dem Internet verbunden sind, damit Ihre Seed-Phrase nicht versehentlich veröffentlicht wird. Meist ist es nicht möglich, verlorene Gelder ohne die Seed-Phrase wiederzuerlangen. diff --git a/public/content/translations/de/guides/how-to-id-scam-tokens/index.md b/public/content/translations/de/guides/how-to-id-scam-tokens/index.md new file mode 100644 index 00000000000..947a5773e95 --- /dev/null +++ b/public/content/translations/de/guides/how-to-id-scam-tokens/index.md @@ -0,0 +1,97 @@ +--- +title: So erkennen Sie betrügerische Token +description: Erkennen von betrügerischen Token, wie sie sich legitim erscheinen lassen und wie sie sich vermeiden lassen. +lang: de +--- + +# So erkennen Sie betrügerische Token {#identify-scam-tokens} + +Eine der häufigsten Verwendungen von Ethereum ist die Schaffung eines handelbaren Tokens durch eine Gruppe, gewissermaßen ihre eigene Währung. Diese Token folgen in der Regel dem Standard, [ERC-20](/developers/docs/standards/tokens/erc-20/). Jedoch gibt es überall, wo es legitime wertschöpfende Anwendungsmöglichkeiten gibt, auch Kriminelle, die diese Werte stehlen möchten. + +Die beiden folgenden Täuschungsversuche sind dabei gängig: + +- **Verkaufen eines betrügerischen Tokens**, der im Aussehen einem legitimen Token ähnelt und den Sie kaufen möchten, jedoch von einem Betrüger erstellt wurde und keinen Wert hat. +- **Sie werden dazu verleitet, unzulässige Transaktionen zu unterzeichnen**, indem Sie für gewöhnlich auf die Benutzeroberfläche der Betrüger geleitet wird. Sie könnten versuchen, Sie dazu zu bringen, ihren Verträgen einen Freibetrag für Ihre ERC-20-Token zu gewähren, sensible Informationen preiszugeben, über die sie Zugang zu Ihren Vermögenswerten erhalten usw. Solche Benutzeroberflächen können nahezu perfekte Klone von legitimen Websites sein, jedoch mit versteckten Tricks. + +Um zu veranschaulichen, was Betrugs-Token sind und wie man sie erkennt, sehen wir uns ein Beispiel an: [`wARB`](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82). Dieser Token immitiert das Aussehen eines legitimen [`ARB`](https://etherscan.io/address/0xb50721bcf8d664c30412cfbc6cf7a15145234ad1) -Tokens. + + + +Arbitrum ist eine Organisation zur Entwicklung und Verwaltung von optimistischen Rollups. Ursprünglich war Arbitrum als gewinnorientiertes Unternehmen organisiert, unternahm dann aber Schritte zur Dezentralisierung. Im Rahmen dieses Prozesses wurde ein handelbarer Governance-Token ausgegeben. + + + + + +In Ethereum gibt es eine Konvention: Wird ein Asset erstellt, das nicht ERC-20-kompatibel ist, wird eine " Wrapped"-Version erstellt wird, deren Name mit "w" beginnt. So gibt es beispielsweise wBTC für Bitcoin und wETH für Ether. + +Es ergibt keinen Sinn, eine Wrapped-Version eines ERC-20-Tokens zu erstellen, der bereits auf Ethereum vorhanden ist, aber Betrüger verlassen sich eher auf den Anschein von Legitimität als auf die zugrunde liegende Realität. + + + +## Wie funktionieren betrügerische Token? {#how-do-scam-tokens-work} + +Dezentralisierung ist das zentrale Element von Ethereum. Das bedeutet, dass es keine zentrale Autorität gibt, die Ihre Anlagen konfiszieren oder Sie daran hindern könnte, einen Smart Contract bereitzustellen. Doch das bedeutet auch, dass Betrüger jeden beliebigen Smart Contract bereitstellen können. + + + +Smart Contracts sind die Programme, die auf der Ethereum-Blockchain laufen. Jeder ERC-20 Token ist beispielsweise als Smart Contract implementiert. + + + +Insbesondere Arbitrum setzt so einen Contract ein, der das Symbol `ARB` nutzt. Doch das hält andere Menschen nicht davon ab, ebenfalls einen Contract einzusetzen, der dasselbe oder ein ähnliches Symbol nutzt. Wer den Contract schreibt, kann bestimmen, wofür er verwendet wird. + +## Legitimes Erscheinungsbild {#appearing-legitimate} + +Es gibt einige Tricks, die die Ersteller von betrügerischen Tokens nutzen, um ein legitimes Erscheinungsbild zu imitieren. + +- **Legitimer Name und legitimes Symbol**. Wie bereits beschrieben, können ERC-20-Contracts dasselbe Symbol und denselben Namen wie andere ERC-20-Contracts aufweisen. Es ist nicht möglich, darüber auf die Sicherheit der Token zu schließen. + +- **Legitime Besitzer**. Betrügerische Token senden oft signifikante Beträge an Adressen, die als legitime Besitzer des echten Tokens angenommen werden. + + Kommen wir nochmals auf `wARB` zurück. [Ungefähr 16 % der Token](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82?a=0x1c8db745abe3c8162119b9ef2c13864cd1fdd72f) werden von einer Adresse verwaltet, deren öffentlicher Tag ["Arbitrum Foundation: Deployer"](https://etherscan.io/address/0x1c8db745abe3c8162119b9ef2c13864cd1fdd72f) ist. Das ist _keine_ falsche Adresse, es ist vielmehr die Adresse, die [den echten ARB-Contract auf dem Ethereum-Mainnet](https://etherscan.io/tx/0x242b50ab4fe9896cb0439cfe6e2321d23feede7eeceb31aa2dbb46fc06ed2670) eingesetzt hat. + + Da das ERC-20-Guthaben einer Adresse Teil des ERC-20-Vertragsspeichers ist, kann dafür festgelegt werden, was sich der Entwickler wünscht. Es ist für einen Contract auch möglich, Transfers zu verbieten, sodass der legitime Nutzer keine Chance hat, die betrügerischen Token zu entfernen. + +- **Legitime Transfers**. _Legitime Besitzer würden nicht dafür bezahlen, einen betrügerischen Token auf andere zu übertragen. Daher muss der Token, sofern er Transfers ausführt, legitim sein, oder?_ **Falsch**. `Transfer`-Ereignisse werden auch durch den ERC-20-Contract produziert. Ein Betrüger kann einfach den Contract so schreiben, dass er diese Aktionen produziert. + +## Betrügerische Websites {#websites} + +Betrüger können auch sehr überzeugende Websites produzieren, manchmal sogar präzise Klone von authentischen Seiten mit einer identischen Benutzeroberfläche, aber mit subtilen Tricks. Beispiele könnten externe links sein, die legitim aussehen, jedoch den Nutzer zu einer externen betrügerischen Seite senden. Es könnten auch falsche Anweisungen sein, die den Nutzer dazu bringen, seine Schlüssel freizugeben oder dem Angreifer Gelder zu senden. + +Die beste Art das zu vermeiden, ist es, die URL vorsichtig auf von Ihnen besuchte Seiten zu überprüfen. Dafür können Sie authentische Seiten in ihren Lesezeichen speichern. Dann können Sie die Seiten über Ihre Lesezeichen aufrufen, ohne versehentlich Rechtschreibfehler zu machen oder sich auf externe Links verlassen zu müssen. + +## Wie können Sie sich schützen? {#protect-yourself} + +1. **Überprüfen der Contract-Adresse**. Legitime Token stammen von legitimen Organisationen und Sie können die Contract-Adressen auf der Website dieser Organisation nachschauen. Zum Beispiel können Sie[ die legitimen Adressen für `ARB` hier nachsehen](https://docs.arbitrum.foundation/deployment-addresses#token). + +2. **Echte Token weisen Liquidität auf**. Eine weitere Option ist, sich die Liquidität-Poolgröße auf [Uniswap](https://uniswap.org/) anzuschauen – eines der gängigsten Token-Tauschprotokolle. Dieses Protokoll funktioniert, indem es Liquiditätspools nutzt, in die ihre Token investieren, in der Hoffnung, mit Handelsgebühren Gewinne zu machen. + +Betrügerische Tokens habe, wenn überhaupt, klassischerweise kleine Liquiditätspools, da die Betrüger keine echten Anlagen riskieren wollen. Der `ARB`/`ETH` Uniswap Pool hält beispielsweise ungefähr eine halbe Millionen Dollar ([schlagen Sie hier den aktuellen Wert nach](https://info.uniswap.org/#/pools/0x755e5a186f0469583bd2e80d1216e02ab88ec6ca)) und das Kaufen oder Verkaufen einer kleinen Menge wird den Preis nicht beeinflussen: + +![Einen legitimen Token kaufen](./uniswap-real.png) + +Doch wenn Sie versuchen würden, den betrügerischen `wARB`-Token zu kaufen, könnte sogar eine kleine Investition den Preis um über 90 % steigern: + +![Einen betrügerischen Token kaufen](./uniswap-scam.png) + +Das ist ein weiterer Beweis, der uns zeigt, dass `wARB` wahrscheinlich kein legitimer Token ist. + +3. **Sehen Sie auf Etherscan nach**. Viele betrügerische Token wurden bereits identifiziert und von der Community gemeldet. Solche Token werden in [Etherscan gekennzeichnet](https://info.etherscan.com/etherscan-token-reputation/). Während Etherscan keine unfehlbare Quelle ist (es ist normal für dezentralisierte Netzwerke, dass es so etwas nicht gibt), sind Token, die von Etherscan als Betrug gekennzeichnet wurden, wahrscheinlich betrügerisch. + + ![Betrügerische Token in Etherscan](./etherscan-scam.png) + +## Fazit {#conclusion} + +Solange es Werte in der Welt gibt, wird es immer Betrüger geben, die diese stehlen wollen. In einer dezentralisierten Welt gibt es niemanden, der Sie beschützt, außer Sie selbst. Hoffentlich helfen Ihnen diese Informationen dabei, betrügerische und legitime Token auseinanderzuhalten: + +- Betrügerische Token kopieren legitime Token, sie können denselben Namen, dasselbe Symbol etc. verwenden. +- Betrügerische Token _können nicht_ dieselbe Contract-Adresse verwenden. +- Die beste Quelle für die Adresse des legitimen Tokens ist die Organisation, um deren Token es sich handelt. +- Sie können zudem sichere Anwendungen wie [Uniswap](https://app.uniswap.org/#/swap) und [Etherscan](https://etherscan.io/) nutzen. diff --git a/public/content/translations/de/guides/how-to-swap-tokens/index.md b/public/content/translations/de/guides/how-to-swap-tokens/index.md index 0ded6458ae4..4c6b5e92f9d 100644 --- a/public/content/translations/de/guides/how-to-swap-tokens/index.md +++ b/public/content/translations/de/guides/how-to-swap-tokens/index.md @@ -12,7 +12,7 @@ Ein Token-Swap beinhaltet den Austausch von zwei verschiedenen Assets im Ethereu **Voraussetzung:** -- Haben Sie eine Krypto-Wallet. Sie können diesem Tutorium folgen: [Wie man ein Ethereum-Konto anmelden kann](/guides/how-to-create-an-ethereum-account/) +- Haben Sie eine Krypto-Wallet, können Sie sich dieses Tutorium ansehen: [So "registrieren" Sie ein Ethereum-Konto](/guides/how-to-create-an-ethereum-account/) - Laden Sie Ihre Krypto-Wallet auf ## 1. Verbinden Sie Ihre Krypto-Wallet mit einem Exchange (DEX) Ihrer Wahl diff --git a/public/content/translations/de/guides/how-to-use-a-bridge/index.md b/public/content/translations/de/guides/how-to-use-a-bridge/index.md index bb61f69da67..f04b434aba7 100644 --- a/public/content/translations/de/guides/how-to-use-a-bridge/index.md +++ b/public/content/translations/de/guides/how-to-use-a-bridge/index.md @@ -10,7 +10,7 @@ Wenn eine hohe Auslastung auf Ethereum herrscht, kann es teuer werden. Eine Lös **Voraussetzung:** -- Haben Sie eine Krypto-Wallet. Sie können diesem Tutorium folgen: [Wie man ein Ethereum-Konto anmelden kann](/guides/how-to-create-an-ethereum-account/) +- Haben Sie eine Krypto-Wallet, können Sie sich dieses Tutorium ansehen: [So "registrieren" Sie ein Ethereum-Konto](/guides/how-to-create-an-ethereum-account/) - Laden Sie Ihre Krypto-Wallet auf ## 1. Bestimmen Sie, welches Layer-2-Netzwerk Sie verwenden möchten diff --git a/public/content/translations/de/guides/how-to-use-a-wallet/index.md b/public/content/translations/de/guides/how-to-use-a-wallet/index.md index b69035ee381..d671c8fc6bb 100644 --- a/public/content/translations/de/guides/how-to-use-a-wallet/index.md +++ b/public/content/translations/de/guides/how-to-use-a-wallet/index.md @@ -6,7 +6,7 @@ lang: de # So verwenden Sie eine Wallet -Lernen Sie die grundlegenden Funktionen einer Krypto-Wallet kennen. Falls Sie noch keine besitzen, schauen Sie sich mal die Seite [Wie erstelle ich einen Ethereum "Account"](/guides/how-to-create-an-ethereum-account/) an. +Lernen Sie die grundlegenden Funktionen einer Krypto-Wallet kennen. Wenn Sie noch keine haben, werfen Sie einen blick auf unseren [Leitfaden zur Erstellung eines Ethereum-Kontos](/guides/how-to-create-an-ethereum-account/) an. ## Öffnen Sie Ihre Wallet @@ -18,7 +18,7 @@ Möchten Sie Kryptowährungen in ihrer Wallet empfangen? Jedes Ethereum Account hat seine eigene Empfangsadresse, welche eine einzigartige Abfolge von Zahlen und Buchstaben enthält. Die Adresse funktioniert wie eine Bankkontonummer. Ethereum-Adressen beginnen immer mit „0x“. Sie können diese Adresse mit jedem teilen: Es besteht kein Sicherheitsrisiko. -Ihre Adresse (die auch als „public key" bezeichnet wird) ist wie Ihre Wohnanschrift: Sie müssen sie den Leuten mitteilen, damit sie Sie finden können. Es besteht keine Gefahr, dies zu tun, weil Sie immer noch Ihre Haustür mit einem anderen Schlüssel, den Sie kontrollieren, abschließen können, sodass keiner hereinkommen kann, auch wenn sie wissen, wo Sie wohnen. +Mit Ihrer Adresse verhält es sich wie mit Ihrer Privatadresse: Sie müssen diese angeben, damit man Sie finden kann. Es besteht keine Gefahr, dies zu tun, weil Sie immer noch Ihre Haustür mit einem anderen Schlüssel, den Sie kontrollieren, abschließen können, sodass keiner hereinkommen kann, auch wenn sie wissen, wo Sie wohnen. Sie müssen jedem, der Ihnen Geld schicken möchten, Ihre öffentliche Adresse zur Verfügung stellen. Viele Wallet-Apps lassen Sie zur vereinfachten Handhabung Ihre Adresse kopieren oder zeigen einen QR-Code an, der gescannt werden kann. Vermeiden Sie die manuelle Eingabe einer Ethereum-Adresse. Dies kann leichtfertig zu Schreibfehlern und damit zum Verlust Ihres Vermögens führen. @@ -51,7 +51,7 @@ Ihre Adresse wird auf allen Ethereum Projekten dieselbe sein. Sie brauchen sich 1. Besuchen Sie die Webseite eines Projekts. 2. Wenn die Zielseite des Projekts nur eine statische Beschreibung des Projekts ist, sollten Sie in der Lage sein, auf eine Schaltfläche „App öffnen" im Menü zu klicken, die Sie zur eigentlichen Web-App navigiert. -3. Sobald Sie sich in der App befinden, klicken Sie auf „Verbinden" +3. Sobald Sie in der App sind, klicken Sie auf "Verbinden". ![Schaltfläche zum Verbinden mit einer Wallet](./connect1.png) @@ -77,7 +77,7 @@ Sie können dieselbe Adresse auf allen EVM-kompatiblen Blockchains verwenden (we ### Kann ich dieselbe Adresse auf mehreren Geräten verwenden? -Ja, Sie können dieselbe Adresse auf mehreren Geräten verwenden. Wallets sind technisch gesehen nur eine Schnittstelle, um Ihnen Ihr Guthaben zu zeigen und Transaktionen zu tätigen, Ihr Konto ist nicht in der Wallet gespeichert, sondern auf der Blockchain. +Ja, Sie können die gleiche Adresse auf mehreren Geräten verwenden. Wallets sind technisch gesehen nur eine Schnittstelle, um Ihnen Ihr Guthaben zu zeigen und Transaktionen zu tätigen, Ihr Konto ist nicht in der Wallet gespeichert, sondern auf der Blockchain. ### Ich habe kein Krypto erhalten, wo kann ich den Status einer Transaktion überprüfen? diff --git a/public/content/translations/de/guides/index.md b/public/content/translations/de/guides/index.md index 31c7d634305..b43574d37b3 100644 --- a/public/content/translations/de/guides/index.md +++ b/public/content/translations/de/guides/index.md @@ -6,7 +6,7 @@ lang: de # Ethereum Leitfäden -Wollen Sie Ihre Ethereum Reise starten? Ethereum ist kein Unternehmen mit einem Skript-gebundenen Helpdesk, aber diese praktischen Anleitungen helfen Ihnen zu lernen, wie Sie anfangen können. +Möchten Sie Ihre Ethereum Reise starten? Unsere praktischen Leitfäden führen Sie Schritt für Schritt durch den Einstieg und erleichtern Ihnen den Umgang mit dieser neuen Technologie. ## Erste Schritte @@ -16,14 +16,12 @@ Wollen Sie Ihre Ethereum Reise starten? Ethereum ist kein Unternehmen mit einem ## Grundlagen zur Sicherheit -1. [Wie man einen Smart-Contract-Zugriff widerrufen kann](/guides/how-to-revoke-token-access/) - Falls Sie plötzlich eine Transaktion in ihrer Wallet sehen, welche sie nicht initiiert haben, wird Ihnen diese Anleitung erklären, wie Sie das in Zukunft verhindern können. +1. [Wie man einen Smart-Contract-Zugriff widerrufen kann](/guides/how-to-revoke-token-access/) – Falls Sie plötzlich eine Transaktion in Ihrer Wallet sehen, die Sie nicht initiiert haben, finden Sie in diesem Leitfaden eine Anleitung, wie sich das in Zukunft verhinden lässt. + +2. [Wie man betrügerische Token (Scam-Token) erkennt](/guides/how-to-id-scam-tokens/) – Was scams sind, welche Taktiken dabei eingesetzt werden und wie man sie erkennen kann, um sich zu schützen und nicht betrogen zu werden. ## Ethereum verwenden 1. [Wie man Token in Layer 2 überführt](/guides/how-to-use-a-bridge/) - Sind Ethereum-Transaktionen zu teuer? Betrachten Sie den Wechsel auf sogenannte Layer-2 Skalierungslösungen. 2. [Wie man Token tauscht](/guides/how-to-swap-tokens/) - Wollen Sie Ihre Token gegen andere austauschen? Dieser simple Leitfaden zeigt Ihnen, wie Sie das machen. - -## Dezentralisierte Denkfähigkeiten - -Sobald Sie eine Wallet haben und einige der Features genutzt haben, verstehen Sie mehr über Ethereum, indem Sie sich fragen: "_Warum_ ist das eigentlich so wichtig?" Was macht Geld so wertvoll, wenn es niemand kontrolliert? Was ist Vertrauen? Trägt das zur Freiheit bei? Welche Arten von neuen Governance- und Organisationsstrukturen ermöglicht Ethereum? Diese und weitere Fragen werden offen in Gemeinschaften wie [Kernel](https://www.kernel.community/) diskutiert. diff --git a/public/content/translations/de/refi/index.md b/public/content/translations/de/refi/index.md index 7fa127d3f34..44bb7506994 100644 --- a/public/content/translations/de/refi/index.md +++ b/public/content/translations/de/refi/index.md @@ -18,7 +18,7 @@ summaryPoint3: Ein Instrument zur drastischen Skalierung von Gütern für ökolo Stattdessen zielt ReFi darauf ab, ökologische, kommunale oder soziale Probleme zu lösen, indem es regenerative Kreisläufe schafft. Diese Systeme schaffen Werte für die Teilnehmer und kommen gleichzeitig den Ökosystemen und Gemeinschaften zugute. -Eine der Grundlagen von ReFi ist das Konzept der regenerativen Wirtschaft, das von John Fullerton vom [Capital Institute](https://capitalinstitute.org) erdacht wurde. Er schlug acht miteinander verknüpfte Grundsätze vor, die der systemischen Gesundheit zugrunde liegen: +Eine der Grundlagen von ReFi ist das Konzept der regenerativen Wirtschaft, das von John Fullerton vom Capital Institute erdacht wurde. Er schlug [acht miteinander verknüpfte Grundsätze](https://capitalinstitute.org/8-principles-regenerative-economy/) vor, die der systemischen Gesundheit zugrunde liegen: ![Acht miteinander verknüpfte Grundsätze](./refi-regenerative-economy-diagram.png) diff --git a/public/content/translations/de/roadmap/account-abstraction/index.md b/public/content/translations/de/roadmap/account-abstraction/index.md index b85eabcf00e..f2ade84be2b 100644 --- a/public/content/translations/de/roadmap/account-abstraction/index.md +++ b/public/content/translations/de/roadmap/account-abstraction/index.md @@ -47,8 +47,8 @@ Zum Beispiel können Backup-Schlüssel zu einer Wallet hinzugefügt werden, soda - **Multisig-Autorisierung**: Sie können Autorisierungsdaten über mehrere vertrauenswürdige Personen oder Geräte verteilen. Dann kann der Vertrag so konfiguriert werden, dass Transaktionen über einem bestimmten vordefinierten Wert die Autorisierung von einem bestimmten Anteil (z.B. 3/5) der vertrauenswürdigen Parteien erfordern. Zum Beispiel könnten Transaktionen mit hohem Wert die Zustimmung sowohl von einem mobilen Gerät als auch von einer Hardware-Wallet erfordern, oder Signaturen von Konten, die an vertrauenswürdige Familienmitglieder verteilt wurden. - **Kontosperrung**: Wenn ein Gerät verloren geht oder kompromittiert wird, kann das Konto von einem anderen autorisierten Gerät aus gesperrt werden, um die Vermögenswerte des Benutzers zu schützen. - **Kontowiederherstellung**: Haben Sie ein Gerät verloren oder ein Passwort vergessen? Im aktuellen Paradigma könnte dies bedeuten, dass Ihre Vermögenswerte für immer eingefroren werden könnten. Mit einer Smart-Contract-Wallet können Sie einige vorab genehmigte Konten festlegen, die neue Geräte autorisieren und den Zugriff zurücksetzen können. -- **Transaktionslimits festlegen**: Legen Sie tägliche Grenzwerte fest, wie viel Wert innerhalb eines Tages/einer Woche/eines Monats vom Konto übertragen werden kann. Das bedeutet, wenn ein Angreifer Zugang zu Ihrem Konto erlangt, kann er nicht alles auf einmal abziehen und Sie haben die Möglichkeit, den Zugang zu sperren und zurückzusetzen. -- **Erstellen Sie Whitelists**: Erlauben Sie Transaktionen nur zu bestimmten Adressen, die Sie als sicher einstufen. Das bedeutet, dass _selbst wenn_ Ihr privater Schlüssel gestohlen wurde, der Angreifer keine Mittel an nicht-whitelistete Zielkonten senden könnte. Diese Whitelists würden mehrere Unterschriften zur Änderung erfordern, sodass ein Angreifer seine eigene Adresse nicht zur Liste hinzufügen könnte, es sei denn, er hätte Zugang zu mehreren Ihrer Backup-Schlüssel. +- **Transaktionslimits festlegen**: Legen Sie tägliche Obergrenzen dafür fest, wie viel Wert innerhalb eines Tages/einer Woche/eines Monats von dem Konto überwiesen werden kann. Das bedeutet, wenn ein Angreifer Zugang zu Ihrem Konto erlangt, kann er nicht alles auf einmal abziehen und Sie haben die Möglichkeit, den Zugang zu sperren und zurückzusetzen. +- **Whitelists erstellen**: Erlauben Sie Transaktionen nur zu bestimmten Adressen, von denen Sie wissen, dass sie sicher sind. Das bedeutet, dass _selbst wenn_ Ihr privater Schlüssel gestohlen wurde, der Angreifer keine Mittel an nicht-whitelistete Zielkonten senden könnte. Diese Whitelists würden mehrere Unterschriften zur Änderung erfordern, sodass ein Angreifer seine eigene Adresse nicht zur Liste hinzufügen könnte, es sei denn, er hätte Zugang zu mehreren Ihrer Backup-Schlüssel. ## Bessere Nutzererfahrung {#better-user-experience} diff --git a/public/content/translations/de/roadmap/index.md b/public/content/translations/de/roadmap/index.md index c172f67d16e..beb3fceb6ea 100644 --- a/public/content/translations/de/roadmap/index.md +++ b/public/content/translations/de/roadmap/index.md @@ -3,13 +3,15 @@ title: Ethereum-Roadmap description: Der Weg zu mehr Skalierbarkeit, Sicherheit und Nachhaltigkeit für Ethereum. lang: de template: roadmap -image: /roadmap/roadmap-main.png +image: /heroes/roadmap-hub-hero.jpg alt: "Ethereum-Roadmap" summaryPoints: buttons: - - label: Weitere Upgrades + - + label: Weitere Upgrades toId: welche-veränderungen-kommen-werden - - label: Bisherige Upgrades + - + label: Bisherige Upgrades to: /history/ variant: Übersicht --- @@ -59,7 +61,7 @@ Ethereum erhält regelmäßig Upgrades, die seine Skalierbarkeit, Sicherheit ode -Die Roadmap ist vor allem das Ergebnis jahrelanger Arbeit von Forschern und Entwicklern - da das Protokoll sehr technisch ist - aber jede motivierte Person kann sich daran beteiligen. Die Ideen beginnen in der Regel als Diskussionen in einem Forum wie [ethresear.ch](https://ethresear.ch/), [Ethereum magicians](https://www.figma.com/exit?url=https%3A%2F%2Fethereum-magicians.org%2F) oder dem Eth R&D Discord Server. Dabei kann es sich um Reaktionen auf neu entdeckte Schwachstellen handeln, um Vorschläge von Organisationen, die auf der Anwendungsebene arbeiten (z. B. Dapps und Börsen), oder um bekannte Schwierigkeiten für Endnutzer (z. B. Kosten oder Transaktionsgeschwindigkeit). Wenn diese Ideen ausgereift sind, können sie als [Ethereum Improvement Proposals](https://eips.ethereum.org/) vorgeschlagen werden. Dies alles geschieht öffentlich, so dass sich jeder aus der Community jederzeit einbringen kann. +Die Roadmap ist vor allem das Ergebnis jahrelanger Arbeit von Forschern und Entwicklern - da das Protokoll sehr technisch ist - aber jede motivierte Person kann sich daran beteiligen. Ideen beginnen in der Regel als Diskussionen in einem Forum wie [ethresear.ch](https://ethresear.ch/), [Ethereum Magicians](https://ethereum-magicians.org/) oder dem Eth R&D-Discord-Server. Dabei kann es sich um Reaktionen auf neu entdeckte Schwachstellen handeln, um Vorschläge von Organisationen, die auf der Anwendungsebene arbeiten (z. B. Dapps und Börsen), oder um bekannte Schwierigkeiten für Endnutzer (z. B. Kosten oder Transaktionsgeschwindigkeit). Wenn diese Ideen ausgereift sind, können sie als [Ethereum Improvement Proposals](https://eips.ethereum.org/) vorgeschlagen werden. Dies alles geschieht öffentlich, so dass sich jeder aus der Community jederzeit einbringen kann. [Mehr über Ethereum-Governance](/governance/) @@ -114,4 +116,4 @@ Beim Sharding wird die Ethereum-Blockchain so aufgeteilt, dass Untergruppen von - [Secret leader election](/roadmap/secret-leader-election) - Durch geschickte Kryptographie kann sichergestellt werden, dass die Identität des aktuellen Blockantragstellers nicht bekannt gegeben wird, wodurch er vor bestimmten Arten von Angriffen geschützt ist. - [Account abstraction](/roadmap/account-abstraction)- Die Kontoabstraktion ist eine Klasse von Upgrades, die Smart-Contract-Wallets direkt auf Ethereum unterstützen, anstatt komplexe Middleware zu verwenden. - [Verkle trees](/roadmap/verkle-trees) - Verkle-Bäume sind eine Datenstruktur, die verwendet werden kann, um zustandslose Clients auf Ethereum zu ermöglichen. Diese "zustandslosen" Clients benötigen nur wenig Speicherplatz, sind aber dennoch in der Lage, neue Blöcke zu verifizieren. -- [Statelessness](/roadmap/statelessness) - zustandslose Clients können neue Blöcke verifizieren, ohne große Datenmengen speichern zu müssen. Dies bietet alle Vorteile des Betriebs einer Node mit nur einem kleinen Bruchteil der heutigen Kosten. +- [Statuslosigkeit](/roadmap/statelessness) – Statuslose Clients werden in der Lage sein, neue Blöcke zu überprüfen, ohne große Mengen an Daten speichern zu müssen. Dies bietet alle Vorteile des Betriebs einer Node mit nur einem kleinen Bruchteil der heutigen Kosten. diff --git a/public/content/translations/de/roadmap/merge/index.md b/public/content/translations/de/roadmap/merge/index.md index 334d178eae9..4a3e3794535 100644 --- a/public/content/translations/de/roadmap/merge/index.md +++ b/public/content/translations/de/roadmap/merge/index.md @@ -4,7 +4,6 @@ description: Erfahren Sie mehr über die Zusammenführung, als Mainnet Ethereum lang: de template: upgrade image: /upgrades/merge.png -alt: summaryPoint1: Ethereum Mainnet verwendet Proof-of-Stake, aber das war nicht immer der Fall. summaryPoint2: Der Wechsel vom ursprünglichen Proof-of-Work Mechanismus zu Proof-of-Stake wurde Zusammenführung genannt. summaryPoint3: Die Zusammenführung bezieht sich auf das ursprüngliche Ethereum Mainnet, welches mit einer separaten Proof-of-Stake-Blockchain namens Beacon Chain vereinigt wurde, und somit nun beide als eine Blockchain existieren. @@ -179,18 +178,18 @@ Dadurch wird ein Massenexodus der für Staking eingesetzten Mittel verhindert. D Der effektive Jahreszins ist auch bewusst dynamisch, damit ein Markt von Stakern abwägen kann, wie viel sie bereit sind, für die Sicherung des Netzwerks zu zahlen. Wenn die Rate zu niedrig ist, werden die Validatoren mit einer durch das Protokoll begrenzten Rate aussteigen. Nach und nach wird dadurch die APR für alle erhöht, die bleiben und wieder neue oder wiederkehrende Staker anziehen. -## Was ist mit "Eth2" passiert? {#eth2} +## Was ist mit „Eth2“ passiert? {#eth2} Der Begriff "Eth2" ist veraltet. Nach der Zusammenführung von "Eth1" und "Eth2" in eine einzelne Chain gibt es keinen Grund mehr zwischen zwei Ethereum Netzwerken zu unterscheiden. Es gibt nur Ethereum. Um Unklarheiten zu minimieren, hat die Community diese Begriffe aktualisiert: -- „Eth1“ ist nun der „Ausführungslayer“, der Transaktionen verarbeitet und ausführt. -- „Eth2“ ist nun der „Konsenslayer“, der den Proof-of-Stake-Konsens regelt. +- „Eth1“ ist nun die „Ausführungsebene“, die Transaktionen und Ausführungen verarbeitet. +- „Eth2“ ist nun die „Konsensebene“, die den Proof-of-Stake-Konsens regelt. -Diese aktualisierte Terminologie ändert lediglich die Benennungskonventionen. Die Ziele von Ethereum oder die Roadmap ändern sich dadurch nicht. +Diese aktualisierte Terminologie ändert lediglich die Benennungskonventionen. Die Ziele und der Fahrplan von Ethereum ändern sich dadurch nicht. -[Mehr erfahren über die „Eth2“-Umbenennung](https://blog.ethereum.org/2022/01/24/the-great-eth2-renaming/) +[Mehr über die „Eth2“-Umbenennung erfahren](https://blog.ethereum.org/2022/01/24/the-great-eth2-renaming/) ## Beziehung zwischen den Upgrades {#relationship-between-upgrades} diff --git a/public/content/translations/de/roadmap/merge/issuance/index.md b/public/content/translations/de/roadmap/merge/issuance/index.md index 01dd5dcfa82..cc2c4c36ba2 100644 --- a/public/content/translations/de/roadmap/merge/issuance/index.md +++ b/public/content/translations/de/roadmap/merge/issuance/index.md @@ -44,7 +44,7 @@ Gesamt ETH Angebot: **~120,520,000 ETH** (zum Zeitpunkt von The Merge im Septemb **Ausgabe in der Ausführungsschicht:** -- Wurde auf 2,08 ETH pro 13,3 Sekunden\* geschätzt: **~4,930,000** ETH wurden in einem Jahr ausgegeben +- Wurde auf 2,08 ETH pro 13,3 Sekunden* geschätzt: **~4,930,000** ETH wurden in einem Jahr ausgegeben - Führte zu einer Inflationsrate von **etwa 4.09%** (4,93 Mio. pro Jahr / 120,5 Mio. Gesamt) - \*Dies beinhaltet die 2 ETH pro kanonischem Block, plus durchschnittlich 0,08 ETH über die Zeit von Ommer-Blöcken. Es verwendet auch 13,3 Sekunden, die Zielzeit für den Baseline-Block ohne jeglichen Einfluss durch eine ["Difficulty Bomb"](/glossary/#difficulty-bomb). ([Siehe Quelle](https://bitinfocharts.com/ethereum/)) diff --git a/public/content/translations/de/roadmap/single-slot-finality/index.md b/public/content/translations/de/roadmap/single-slot-finality/index.md index da54f9301a0..97b109ac4ae 100644 --- a/public/content/translations/de/roadmap/single-slot-finality/index.md +++ b/public/content/translations/de/roadmap/single-slot-finality/index.md @@ -37,7 +37,7 @@ Mit dem derzeitigen Aufbau des Mechanismus müssen, um die Zeit zur Endlichkeit Der derzeitige Konsensmechanismus verbindet Attestierungen mehrerer Validatoren, welche Komitees genannt werden, um die Anzahl an Nachrichten, die jeder Validator in einem Block verarbeiten muss, um jenen zu validieren, zu verringern. Jeder Validator hat in jeder Epoche (32 Plätze) die Möglichkeit zur Attestierung. In jedem Platz haben jedoch nur eine Untergruppe von Validatoren, bekannt als Komitee-Attestierung diese Möglichkeit. Das machen sie, indem sie in Unternetzwerke unterteilt werden, in denen wenige Validatoren als "Aggregatoren" ausgewählt werden. Diese Aggregatoren verbinden alle die Unterschriften, welche sie von anderen Validatoren bekommen in, in ihrem Netzwerk zu einer einzelnen aggregierten Unterschrift. Der Aggregator, welcher die größte Anzahl an einzelnen Teilnahmen beinhaltet, gibt dann die aggregierte Unterschrift an den Blockantragsteller (Block Proposer) weiter, welcher sie dann in seinem Block mit den aggregierten Unterschriften anderer Komitees einschließt. -Dieser Prozess gibt für jeden Validatoren ausreichende Kapazität, in jeder Epoche abzustimmen, da 32 Plätze _ 64 Komitees _ 256 Validator pro Komitee 524 288 Validatoren pro Epoche ergeben. Zum Zeitpunkt der Erstellung dieses Artikels (Februar 2023) gibt es ~513 000 aktive Validatoren. +Dieser Prozess gibt für jeden Validatoren ausreichende Kapazität, in jeder Epoche abzustimmen, da 32 Plätze * 64 Komitees * 256 Validator pro Komitee 524 288 Validatoren pro Epoche ergeben. Zum Zeitpunkt der Erstellung dieses Artikels (Februar 2023) gibt es ~513 000 aktive Validatoren. In diesem Schema ist es für jeden Validatoren möglich für einen Block abzustimmen, indem er seine Attestierungen über die gesamte Epoche verteilen. Jedoch gibt es potentielle Wege diesen Mechanismus zu verbessern, sodass _jeder Validator die Chance hat in jedem Platz zu attestieren_. diff --git a/public/content/translations/de/roadmap/statelessness/index.md b/public/content/translations/de/roadmap/statelessness/index.md index 49b4454e2ca..4c751c46b65 100644 --- a/public/content/translations/de/roadmap/statelessness/index.md +++ b/public/content/translations/de/roadmap/statelessness/index.md @@ -66,7 +66,7 @@ Schwache Zustandslosigkeit beinhaltet Änderungen dazu, wie Ethereum Nodes Zusta **Bei der schwachen Zustandslosigkeit brauchen Blöcke Zugriff auf die vollen Zustandsdaten, jedoch benötigt das Verifizieren von Blöcken keine Zustandsdaten** -Damit dies passieren kann, müssten [Verkle Bäume](/roadmap/verkle-trees/) bereits in Ethereum Clients implementiert sein. Verkle-Bäume sind eine Datenersetzungsstruktur um Ethereums Zustandsdaten zu speichern. Sie erlauben kleine "Zeugen" fester Größe, die dazu da sind Daten zwischen Peers zu vermitteln und Blöcke direkt, anstatt gegen lokale Datenbanken zu verifizieren. [Proposer-Builder Separation](/roadmap/pbs/) wird zudem benötigt, da es Blockerzeugern erlaubt spezialisierte Nodes mit leistungsfähigerer Hardware zu sein und da sie es sind, die Zugriff auf die vollen Zustandsdaten brauchen. +Damit dies passieren kann, müssen [Verkle Trees](/roadmap/verkle-trees/) bereits in Ethereum Clients implementiert sein. Verkle-Bäume sind eine Datenersetzungsstruktur um Ethereums Zustandsdaten zu speichern. Sie erlauben kleine "Zeugen" fester Größe, die dazu da sind Daten zwischen Peers zu vermitteln und Blöcke direkt, anstatt gegen lokale Datenbanken zu verifizieren. [Proposer-Builder Separation](/roadmap/pbs/) wird zudem benötigt, da es Blockerzeugern erlaubt spezialisierte Nodes mit leistungsfähigerer Hardware zu sein und da sie es sind, die Zugriff auf die vollen Zustandsdaten brauchen. @@ -81,7 +81,7 @@ Schwache Zustandslosigkeit ist in einem fortgeschrittenem Forschungsstand, aber ### Starke Zustandslosigkeit {#strong-statelessness} -Starke Zustandslosigkeit entfernt jegliche Notwendigkeit für irgendeinen Node die Zustandsdaten zu speichern. Stattdessen werden Transaktionen mit Zeugen, welche von Blockerzeugern aggregiert werden können, versendet. Die Blockerzeuger sind dann verantwortlich, nur den für die Generierung von Zeugen für relevante Accounts gebrauchten Zustand zu speichern. Die Verantwortung für den Zustand ist fast komplett an den Nutzer verschoben, da diese Zeugen senden und 'Listen aufrufen' um zu erklären, mit welchen Account- und Speicherschlüsseln sie interagieren. +Starke Zustandslosigkeit entfernt jegliche Notwendigkeit für irgendeinen Node die Zustandsdaten zu speichern. Stattdessen werden Transaktionen mit Zeugen, welche von Blockerzeugern aggregiert werden können, versendet. Die Blockerzeuger sind dann verantwortlich, nur den für die Generierung von Zeugen für relevante Accounts gebrauchten Zustand zu speichern. Die Verantwortung für den Zustand ist fast komplett an den Nutzer verschoben, da diese Zeugen senden und 'Listen aufrufen' um zu erklären, mit welchen Account- und Speicherschlüsseln sie interagieren. Dies würde extrem leichte Nodes ermöglichen, aber es gibt auch Nachteile, einschließlich der Erschwerung von Transaktionen mit Smart Contracts. Starke Zustandslosigkeit wurde von Forschern untersucht, wird aber wahrscheinlich kein Teil der Ethereum Roadmap sein - es ist wahrscheinlicher, dass die schwache Zustandslosigkeit für Ethereums Skalierungsbedürfnisse ausreicht. diff --git a/public/content/translations/de/staking/pools/index.md b/public/content/translations/de/staking/pools/index.md index 3a14c6acf00..8cfcd9f10ba 100644 --- a/public/content/translations/de/staking/pools/index.md +++ b/public/content/translations/de/staking/pools/index.md @@ -26,7 +26,7 @@ Zusätzlich zu den Vorteilen, die wir in unserer [Einführung zum Staking](/stak - + @@ -53,14 +53,14 @@ Es gibt eine Vielzahl von Optionen, die Ihnen bei der Einrichtung helfen. Anhand -Hinweis: Es ist wichtig, einen Dienst zu wählen, der [Client-Diversität](/developers/docs/nodes-and-clients/client-diversity/) ernst nimmt, da das die Sicherheit des Netzwerks verbessert und Ihr Risiko begrenzt. Dienste, die nachweislich die Nutzung von Mehrheits-Clients einschränken, sind gekennzeichnet mit "Vielfalt der Ausführungskunden" and "Vielfalt der Konsenskunden". +Hinweis: Es ist wichtig, einen Dienst zu wählen, der [Client-Diversität](/developers/docs/nodes-and-clients/client-diversity/) ernst nimmt, da das die Sicherheit des Netzwerks verbessert und Ihr Risiko begrenzt. Dienste, die nachweislich die Nutzung von Mehrheits-Clients einschränken, sind gekennzeichnet mit "Vielfalt der Ausführungs-Clients" and "Vielfalt der Konsens-Clients". Haben Sie einen Vorschlag für einen Staking-Tool, der noch fehlt? Machen Sie sich mit unserer [Richtlinie zum Aufführen von Produkten](/contributing/adding-staking-products/) vertraut, um beurteilen zu können, ob Ihr Vorschlag geeignet ist. Senden Sie ihn uns dann zur Prüfung zu. ## Häufig gestellte Fragen {#faq} -Typischerweise werden ERC-20 Staking-Token an Staker ausgegeben, die den Wert ihrer eingesetzten ETH plus Belohnungen darstellen. Denken Sie daran, dass Staking-Belohnungen grundsätzlich etabliert sind, verschiedene Pools Staking-Belohnungen allerdings nach leicht unterschiedlichen Methoden an ihre Benutzer verteilen. +Typischerweise werden ERC-20-Staking-Token an die Staker ausgegeben und repräsentieren den Wert ihres eingesetzten ETH sowie Belohnungen. Denken Sie daran, dass Staking-Belohnungen grundsätzlich etabliert sind, verschiedene Pools Staking-Belohnungen allerdings nach leicht unterschiedlichen Methoden an ihre Benutzer verteilen. @@ -81,5 +81,6 @@ Einige Pooling-Optionen sind im Hinblick auf die Nodes, die sie unterstützen, s ## Weiterführende Informationen {#further-reading} +- [Das Ethereum-Staking-Verzeichnis](https://www.staking.directory/) - _Eridian und Spacesider_ - [Staking mit Rocket Pool – Staking-Übersicht](https://docs.rocketpool.net/guides/staking/overview.html) – _RocketPool-Dokumentation_ - [Staking von Ethereum mit Lido](https://help.lido.fi/en/collections/2947324-staking-ethereum-with-lido) - _Lido Hilfedokumente_ diff --git a/public/content/translations/de/staking/saas/index.md b/public/content/translations/de/staking/saas/index.md index 24c0a75e96b..3bc772cdcf9 100644 --- a/public/content/translations/de/staking/saas/index.md +++ b/public/content/translations/de/staking/saas/index.md @@ -47,7 +47,7 @@ Nachfolgend finden Sie einige verfügbare SaaS-Anbieter. Verwenden Sie die obige -Hinweis: Es ist wichtig, dass sie die [Client-Diversität](/developers/docs/nodes-and-clients/client-diversity/) unterstützen, denn das erhöht die Netzsicherheit und begrenzt Ihre Risiken. Dienste, die nachweislich die Nutzung von Mehrheits-Clients einschränken, sind gekennzeichnet mit "Vielfalt der Ausführungskunden" and "Vielfalt der Konsenskunden". +Hinweis: Es ist wichtig, dass sie die [Client-Diversität](/developers/docs/nodes-and-clients/client-diversity/) unterstützen, denn das erhöht die Netzsicherheit und begrenzt Ihre Risiken. Dienste, die nachweislich die Nutzung von Mehrheits-Clients einschränken, sind gekennzeichnet mit "Vielfalt der Ausführungs-Clients" and "Vielfalt der Konsens-Clients". ### Schlüssel-Generatoren @@ -91,4 +91,5 @@ Für weitere Informationen zu Garantien oder Versicherungsoptionen sowie zur Anl ## Weiterführende Informationen {#further-reading} +- [Das Ethereum-Staking-Verzeichnis](https://www.staking.directory/) - _Eridian und Spacesider_ - [Bewertung von Staking-Diensten](https://www.attestant.io/posts/evaluating-staking-services/) – _Jim McDonald 2020_ diff --git a/public/content/translations/de/staking/solo/index.md b/public/content/translations/de/staking/solo/index.md index 9cb0960f8f9..9d8d1d7906a 100644 --- a/public/content/translations/de/staking/solo/index.md +++ b/public/content/translations/de/staking/solo/index.md @@ -109,7 +109,7 @@ Es gibt eine Vielzahl von Optionen, die Ihnen bei der Einrichtung helfen. Verwen -Bitte beachten Sie, wie wichtig es ist, einen [Minderheits-Client](/developers/docs/nodes-and-clients/client-diversity/) zu wählen, da er die Sicherheit des Netzwerks verbessert und Ihr Risiko begrenzt. Tools, mit denen Sie einen Minderheit-Client einrichten können, werden als „Multi-Client" bezeichnet. +Bitte beachten Sie, wie wichtig es ist, einen [Minderheits-Client](/developers/docs/nodes-and-clients/client-diversity/) zu wählen, da er die Sicherheit des Netzwerks verbessert und Ihr Risiko begrenzt. Tools, mit denen Sie einen Minderheits-Client einrichten können, werden als „Multi-Client" bezeichnet. ### Schlüssel-Generatoren @@ -195,6 +195,7 @@ Um Ihr gesamtes Guthaben zu entsperren und zu erhalten, müssen Sie auch den Pro ## Weiterführende Informationen {#further-reading} +- [Das Ethereum-Staking-Verzeichnis](https://www.staking.directory/) - _Eridian und Spacesider_ - [Ethereums Client-Diversitätsproblem](https://hackernoon.com/Ethereums-Client-Diversitätsproblem) – _@emmanuelawosika 2022_ - [Client-Diversität fördern](https://www.attestant.io/Posts/Client-Diversität-fördern/) – _Jim McDonald 2022_ - [Client-Diversität auf der Konsensebene von Ethereum](https://mirror.xyz/jmcook.eth/S7ONEka_0RgtKTZ3-dakPmAHQNPvuj15nh0YGKPFriA) – _jmcook.eth 2022_ diff --git a/public/content/translations/de/staking/withdrawals/index.md b/public/content/translations/de/staking/withdrawals/index.md index 7c017a5be48..df9e0425e6c 100644 --- a/public/content/translations/de/staking/withdrawals/index.md +++ b/public/content/translations/de/staking/withdrawals/index.md @@ -114,12 +114,12 @@ Indem wir diese Berechnung erweitern, können wir die Zeit abschätzen, die ben | Anzahl der Auszahlungen | Zeit bis zum Abschluss | -| :---------------------: | :--------------------: | -| 400,000 | 3,5 Tage | -| 500,000 | 4,3 Tage | -| 600,000 | 5,2 Tage | -| 700,000 | 6,1 Tage | -| 800,000 | 7,0 Tage | +| :-------------------: | :--------------: | +| 400,000 | 3,5 Tage | +| 500,000 | 4,3 Tage | +| 600,000 | 5,2 Tage | +| 700,000 | 6,1 Tage | +| 800,000 | 7,0 Tage | @@ -194,7 +194,7 @@ eventCategory="FAQ" eventAction="I operate a validator. Where can I find more information on enabling withdrawals?" eventName="read more"> -Es wird empfohlen, dass Validatoren die Seite Staking Launchpad Withdrawals besuchen, auf der Sie weitere Details dazu finden, wie Sie Ihren Validator auf Auszahlungen vorbereiten können. Vorbereitung, Zeitpunkt der Ereignisse und weitere Details darüber, wie Auszahlungen funktionieren. +Validator-Betreibern wird empfohlen, die Seite Startplattform für Staking-Auszahlungen zu besuchen. Dort können sie mehr Details darüber erfahren, wie Sie Ihren Validator auf Auszahlungen vorbereiten, sowie Informationen zum Zeitpunkt der Ereignisse und zur Funktionsweise von Auszahlungen erhalten. Um Ihre Einrichtung zunächst auf einem Testnetz auszuprobieren, können Sie mit dem Goerli Testnet Staking Launchpad beginnen. @@ -214,5 +214,5 @@ Nein. Sobald ein Validator ausgetreten ist und sein gesamtes Guthaben abgehoben - [EIP-4895: Beacon-Kette implementiert Abhebungen als Operationen](https://eips.ethereum.org/EIPS/eip-4895) - [Ethereum Cat Herders - Shanghai](https://www.ethereumcatherders.com/shanghai_upgrade/index.html) - [PEEPanEIP #94: Auszahlung von gestaktem ETH (Testing) mit Potuz & Hsiao-Wei Wang](https://www.youtube.com/watch?v=G8UstwmGtyE) -- [PEEPanEIP#68: EIP-4895: Beacon-Kette implementiert Abhebungen als Operationen mit Alex Stokes](https://www.youtube.com/watch?v=CcL9RJBljUs) +- [PEEPanEIP#68: EIP-4895: Auszahlungen per Beacon Chain Push als Operationen mit Alex Stokes](https://www.youtube.com/watch?v=CcL9RJBljUs) - [Verständnis der effektiven Bilanz des Validators](https://www.attestant.io/posts/understanding-validator-effective-balance/) diff --git a/public/content/translations/fr/web3/index.md b/public/content/translations/fr/web3/index.md index 07b996fc003..88a8fdce02e 100644 --- a/public/content/translations/fr/web3/index.md +++ b/public/content/translations/fr/web3/index.md @@ -64,7 +64,7 @@ Web3 permet la propriété directe via les [jetons non-fongibles (NFT)](/nft/).
En savoir plus sur les NFT
- Plus d'infos sur les NTF + Plus d'infos sur les NFT
diff --git a/public/content/translations/ja/developers/docs/bridges/index.md b/public/content/translations/ja/developers/docs/bridges/index.md index 5869c8e9a05..f5c8777ef55 100644 --- a/public/content/translations/ja/developers/docs/bridges/index.md +++ b/public/content/translations/ja/developers/docs/bridges/index.md @@ -4,7 +4,7 @@ description: デベロッパー向けのブリッジ概要 lang: ja --- -L1 のブロックチェーンおよび L2 の[スケーリング](/developers/docs/scaling/)ソリューションが一般化し、ますます多くの分散型アプリケーションがクロスチェーンで運用されつつある現在、複数のチェーン間における通信および資産移動を実現する機能がネットワークインフラにおける不可欠な要素となっています。 この機能を提供するために、さまざまな種類のブリッジが開発されています。 +L1のブロックチェーンおよびL2の[スケーリング](/developers/docs/scaling/)ソリューションが一般化し、ますます多くの分散型アプリケーションがクロスチェーンで運用されつつある現在、複数のチェーン間における通信および資産移動を実現する機能がネットワークインフラにおける不可欠な要素となっています。 この機能を提供するために、さまざまな種類のブリッジが開発されています。 ## ブリッジがなぜ必要か? {#need-for-bridges} @@ -23,14 +23,14 @@ L1 のブロックチェーンおよび L2 の[スケーリング](/developers/d デベロッパーは、ブリッジを通して以下を実現できます: - あらゆる種類のデータ、情報、および資産をチェーンを超えて転送できる。 -- ブリッジが個別のプロトコルで提供可能な機能の設計範囲を拡張するため、新たな機能やユースケースが可能になる。 例えば、当初イーサリアムメインネットでデプロイされたイールドファーミング用のプロトコルは、EVM 互換のすべてのチェーンに流動性プールを提供できる。 -- 様々なブロックチェーンが持つ独自の強みを活用できる機会を提供する。 例えば、複数のロールアップやサイドチェーン上で Dapp をデプロイし、ユーザーがそれらをまたいで利用できるようにすることで、様々な L2 ソリューションが提供する安価な手数料を提供できる。 +- ブリッジが個別のプロトコルで提供可能な機能の設計範囲を拡張するため、新たな機能やユースケースが可能になる。 例えば、当初イーサリアムメインネットでデプロイされたイールドファーミング用のプロトコルは、EVM互換のすべてのチェーンに流動性プールを提供できる。 +- 様々なブロックチェーンが持つ独自の強みを活用できる機会を提供する。 例えば、複数のロールアップやサイドチェーン上でDappをデプロイし、ユーザーがそれらをまたいで利用できるようにすることで、様々なL2ソリューションが提供する安価な手数料を提供できる。 - 様々なブロックチェーンエコシステムに関与しているデベロッパーが連携して、新たなプロダクトを構築できる。 -- 様々なエコシステムから、自社 Dapp にユーザーやコミュニティを呼び込むことができる。 +- 様々なエコシステムから、自社Dappにユーザーやコミュニティを呼び込むことができる。 ## ブリッジはどのように機能するのか? {#how-do-bridges-work} -[ブリッジの設計](https://blog.li.fi/what-are-blockchain-bridges-and-how-can-we-classify-them-560dc6ec05fa)には多くの種類がありますが、特に、クロスチェーンで資産を移転する以下の 3 つの方法が重要です: +[ブリッジの設計](https://li.fi/knowledge-hub/blockchain-bridges-and-classification/)には多くの種類がありますが、特に、クロスチェーンで資産を移転する以下の3つの方法が重要です。 - **ロックとミント** - ソースチェーン上のアセットをロックした上で、宛先チェーン上でアセットをミントする方式。 - **バーンとミント** - ソースチェーン上のトークンをバーンした上で、宛先チェーン上で新たにトークンをミントする方式。 @@ -40,10 +40,10 @@ L1 のブロックチェーンおよび L2 の[スケーリング](/developers/d ブリッジは通常、以下のカテゴリーに分類されます: -- **ネイティブブリッジ** - 通常、特定のブロックチェーンにおいて流動性を自動供給するための構築されたブリッジであり、当該エコシステムに対する資金の転送を容易にするものです。 例えば、[Arbitrum ブリッジ](https://bridge.arbitrum.io/)は、イーサリアムから Arbitrum への資金転送を容易にするために開発されたブリッジです。 この種類のブリッジとしては、Polygon PoS ブリッジや[Optimism ゲートウェイ](https://app.optimism.io/bridge)等があります。 -- **バリデータ/オラクルベースのブリッジ** - クロスチェーン間の転送につき、外部のバリデータ群またはオラクルによる検証に依存するブリッジです。 Multichain や Across が含まれます。 -- **一般的なメッセージの受け渡しを伴うブリッジ** - チェーン間の資産転送につき、メッセージおよび任意のデータと共に実行するもの。 Nomad や LayerZero が含まれます。 -- **流動性ネットワーク** - 主に、アトミック・スワップによるチェーン間の資産転送に焦点をあてたブリッジです。 通常、この種類のブリッジはチェーン間のメッセージの受け渡しには対応しません。 Conext や Hop が含まれます。 +- **ネイティブブリッジ** - 通常、特定のブロックチェーンにおいて流動性を自動供給するための構築されたブリッジであり、当該エコシステムに対する資金の転送を容易にするものです。 例えば、[ Arbitrumブリッジ](https://bridge.arbitrum.io/)は、イーサリアムからArbitrumへの資金転送を容易にするために開発されたブリッジです。 この種類のブリッジとしては、Polygon PoSブリッジや[Optimismゲートウェイ](https://app.optimism.io/bridge)等があります。 +- **バリデータ/オラクルベースのブリッジ** - クロスチェーン間の転送につき、外部のバリデータ群またはオラクルによる検証に依存するブリッジです。 MultichainやAcrossが含まれます。 +- **一般的なメッセージの受け渡しを伴うブリッジ** - チェーン間の資産転送につき、メッセージおよび任意のデータと共に実行するもの。 NomadやLayerZeroが含まれます。 +- **流動性ネットワーク** - 主に、アトミック・スワップによるチェーン間の資産転送に焦点をあてたブリッジです。 通常、この種類のブリッジはチェーン間のメッセージの受け渡しには対応しません。 ConextやHopが含まれます。 ## 考慮すべきトレードオフ {#trade-offs} @@ -51,11 +51,11 @@ L1 のブロックチェーンおよび L2 の[スケーリング](/developers/d - **セキュリティ** - システムの検証を誰が担うか? 一般に、外部のバリデータによりセキュリティを保証するブリッジは、当該ブロックチェーンのバリデータがローカル/ネイティブにセキュリティを保証する場合よりもセキュリティが低くなります。 - **利便性** - トランザクションの実行にかかる時間と、ユーザーが署名する必要があるトランザクションの数はどの程度か? デベロッパーにとっては、ブリッジを組み込むプロセスの時間や複雑さを検討する必要があります。 -- **接続性** - 様々な宛先チェーン(ロールアップ、サイドチェーン、他の L1 ブロックチェーン等)にどれだけ接続でき、新規ブロックチェーンとの統合がどの程度難しいかについて検討が必要です。 +- **接続性** - 様々な宛先チェーン(ロールアップ、サイドチェーン、他のL1ブロックチェーン等)にどれだけ接続でき、新規ブロックチェーンとの統合がどの程度難しいかについて検討が必要です。 - **複雑なデータの伝達能力** - チェーン間におけるメッセージやより複雑な任意データの転送が可能か、あるいは、チェーン間の資産移転のみに対応しているかが問題になります。 - **コスト効率** - ブリッジによるチェーン間の資産転送において、どの程度コストが発生するかです。 ブリッジは一般に、固定の手数料またはガス代および特定の転送レートの流動性に基づく変動料金を請求します。 さらに、セキュリティを確保するのにどれだけの手数料が必要になるかに基づき、特定のブリッジにおけるコスト効率を評価することが非常に重要です。 -より大まかに見れば、ブリッジはトラステッドとトラストレスの 2 種類に分類できます。 +より大まかに見れば、ブリッジはトラステッドとトラストレスの2種類に分類できます。 - **トラステッド** - トラステッドのブリッジとは、外部による検証に依存するブリッジです。 つまり、チェーン間のデータ送信につき、外部の検証者セット(マルチシグによるフェデレーション、マルチパーティの計算システム、オラクルネットワーク)が介在するブリッジを指します。 これにより、接続性に優れ、完全に汎用化されたメッセージをチェーン間でやりとりすることができます。 さらに、速度やコスト効率の面からも優れている場合が多いです。 ただし、ユーザーはブリッジ自体のセキュリティに依存するため、セキュリティが損なわれる可能性があります。 - **トラストレス** - これらのブリッジは、接続するブロックチェーンならびに転送するメッセージやトークンに対するバリデータに依存しています。 これらのブリッジが「トラストレス」と呼ばれるのは、(ブロックチェーン自体で想定するものを除き)、新たな信頼想定を追加しないためです。 これにより、トラステッドのブリッジと比較してセキュリティが高いと評価されます。 @@ -67,53 +67,53 @@ L1 のブロックチェーンおよび L2 の[スケーリング](/developers/d ## ブリッジに伴うリスク {#risk-with-bridges} -ブリッジは、[DeFi における最悪のハッキング事例](https://rekt.news/leaderboard/)上位 3 位における原因となっており、現在も開発途上の技術です。 ブリッジの利用は、以下のようなリスクを伴います: +ブリッジは、[DeFiにおける最悪のハッキング事例](https://rekt.news/leaderboard/)上位3位における原因となっており、現在も開発途上の技術です。 ブリッジの利用は、以下のようなリスクを伴います: -- **スマートコントラクトのリスク** - 多くのブリッジは監査に合格しているものの、スマートコントラクトに欠陥がひとつでも含まれていれば、資産に対するハッキング攻撃が可能になります(例: [Solana のワームホールブリッジ](https://rekt.news/wormhole-rekt/))。 +- **スマートコントラクトのリスク** - 多くのブリッジは監査に合格しているものの、スマートコントラクトに欠陥がひとつでも含まれていれば、資産に対するハッキング攻撃が可能になります(例: [Solanaのワームホールブリッジ](https://rekt.news/wormhole-rekt/))。 - **システミックな財務リスク** - 多くのブリッジでは、原資産の正規バージョンを新規チェーンでミントするためにラップ資産を用います。 ラップされたトークンが悪用された事例はすでに発生しており、エコシステム全体にシステミックリスクをもたらします。 - **カウンターパーティリスク** - 一部のブリッジでは、複数のバリデータが共謀してユーザーの資金を奪い取ろうと考えることはないという信頼の想定をユーザーに要求する、信頼ベースの設計を採用しています。 ユーザーは、これらのサードパーティアクターを信頼しなければならないため、ラグプル、検閲、およびその他の悪意の行為が発生するリスクにさらされています。 - **未解決の問題** - 現在でもブリッジは開発の初期段階にあるため、様々な市場環境(ネットワーク混雑時や、ネットワーク全体への攻撃やステートのロールバックといった予見できないイベントの発生時)においてブリッジがどのように機能するかについては、未確認の事項が多く残っています。 この不確実性は様々なリスクをもたらすものですが、その影響の度合いはまだ不明です。 -## Dapp でブリッジを利用する方法 {#how-can-dapps-use-bridges} +## Dappでブリッジを利用する方法 {#how-can-dapps-use-bridges} -以下では、デベロッパがブリッジを活用して Dapp のクロスチェーン化を検討する際の実践的な応用例について紹介します: +以下では、デベロッパがブリッジを活用してDappのクロスチェーン化を検討する際の実践的な応用例について紹介します: ### ブリッジとの統合 {#integrating-bridges} -開発中の Dapp をブリッジに対応させるには、多くの方法が存在します: +開発中のDappをブリッジに対応させるには、多くの方法が存在します: 1. **独自のブリッジを構築する** - 安全で信頼性が高いブリッジの開発は、特にトラストレスのアプローチを採用した場合、容易ではありません。 さらに、スケーラビリティや相互運用性に関する豊富な経験や技術的な知識が必要です。 また、ブリッジを管理し、実務上要求される十分な流動性を維持するためには常駐チームが必要です。 -2. **ユーザーが様々なブリッジから選択できるようにする** - 多くの[Dapp](/developers/docs/dapps/)では、ユーザーに対してネイティブトークンでのやりとりを要求しています。 ユーザーが所有するトークンを利用できるようにするために、Dapp のウェブサイトでは様々なブリッジのオプションを提供しています。 しかしこの方法は、自社の Dapp のインターフェイスだけでプロセスを完結できず、他の Dapp やブリッジとのやりとりが必要になるため、その場しのぎの対策と言わざるを得ません。 また、ユーザーのオンボーディングが複雑になり、ミスが発生する可能性も高まります。 +2. **ユーザーが様々なブリッジから選択できるようにする** - 多くの[Dapp](/developers/docs/dapps/)では、ユーザーに対してネイティブトークンでのやりとりを要求しています。 ユーザーが所有するトークンを利用できるようにするために、Dappのウェブサイトでは様々なブリッジのオプションを提供しています。 しかしこの方法は、自社のDappのインターフェイスだけでプロセスを完結できず、他のDappやブリッジとのやりとりが必要になるため、その場しのぎの対策と言わざるを得ません。 また、ユーザーのオンボーディングが複雑になり、ミスが発生する可能性も高まります。 -3. **Dapp 内にブリッジを組み込む** - このアプローチでは、ユーザーは外部のブリッジや DEX インターフェイスとやりとりする必要がなくなります。 このため、ユーザーのオンボーディング体験が向上します。 しかし、このアプローチにも以下のような制限があります: +3. **Dapp内にブリッジを組み込む** - このアプローチでは、ユーザーは外部のブリッジやDEXインターフェイスとやりとりする必要がなくなります。 このため、ユーザーのオンボーディング体験が向上します。 しかし、このアプローチにも以下のような制限があります: - ブリッジに対する評価やメンテナンスは、手間や時間がかかる。 - ひとつのブリッジを選択することで、単一障害点や依存関係が発生する。 - - 当該ブリッジの機能により、Dapp のサービスが制限される。 - - ブリッジだけでは対応できない機能が必要になる場合がある。 チェーン間のスワップなどの機能を追加するには、DEX を含める必要があるかもしれない。 + - 当該ブリッジの機能により、Dappのサービスが制限される。 + - ブリッジだけでは対応できない機能が必要になる場合がある。 チェーン間のスワップなどの機能を追加するには、DEXを含める必要がある場合がある。 4. **複数のブリッジを組み込む** - このアプローチは、ひとつのブリッジを統合する場合の多くの問題を解消できます。 一方で、複数のブリッジとの統合は多くのリソースを消費し、暗号資産の分野において最も希少性が高いリソースであるデベロッパーにとって、技術面およびコミュニケーション面での負担が増加してしまいます。 -5. **ブリッジアグリゲーターを導入する** - 複数のブリッジにアクセスできる、ブリッジアグリゲーションを活用するのもひとつの方法です。 ブリッジアグリゲーターはすべてのブリッジの強みを継承するため、各ブリッジが提供する機能のみに制限されなくなります。 特に、通常はブリッジアグリゲーターが Dapp とブリッジとの統合を管理するため、Dapp のデベロッパー側はブリッジとの統合における技術的/運用的な側面を管理する作業から解放されます。 +5. **ブリッジアグリゲーターを導入する** - 複数のブリッジにアクセスできる、ブリッジアグリゲーションを活用するのもひとつの方法です。 ブリッジアグリゲーターはすべてのブリッジの強みを継承するため、各ブリッジが提供する機能のみに制限されなくなります。 特に、通常はブリッジアグリゲーターがDappとブリッジとの統合を管理するため、Dappのデベロッパー側はブリッジとの統合における技術的/運用的な側面を管理する作業から解放されます。 ブリッジアグリゲーターは、このような利点を持つ一方で、欠点もあります。 例えば、より多くのブリッジを活用するオプションを提供することは事実ですが、特定のアグリゲーターのプラットフォームが提供するブリッジよりもさらに多くのブリッジが市場で提供されています。 さらに、ブリッジの場合と同じように、ブリッジアグリゲーターもスマートコントラクトやテクノロジーに由来するリスクにさらされています(対応するコントラクトが多くなれば、リスクも拡大します)。 -Dapp にブリッジやブリッジアグリゲーターを組み込む場合、統合の度合いに応じて様々なオプションが考えられます。 例えば、ユーザーにおけるオンボーディング体験の向上を目的とするフロントエンドのみの統合では、ウィジェットを搭載すればよいでしょう。 しかし、ステーキングやイールドファーミング等のより複雑なチェーン間のやりとりを実現するには、SDK や API を統合する必要があります。 +Dappにブリッジやブリッジアグリゲーターを組み込む場合、統合の度合いに応じて様々なオプションが考えられます。 例えば、ユーザーにおけるオンボーディング体験の向上を目的とするフロントエンドのみの統合では、ウィジェットを搭載すればよいでしょう。 しかし、ステーキングやイールドファーミング等のより複雑なチェーン間のやりとりを実現するには、SDKやAPIを統合する必要があります。 -### 複数のチェーン上で Dapp をデプロイする {#deploying-a-dapp-on-multiple-chains} +### 複数のチェーン上でDappをデプロイする {#deploying-a-dapp-on-multiple-chains} -複数のブロックチェーン上で Dapp をデプロイするには、[Alchemy](https://www.alchemy.com/)、[Hardhat](https://hardhat.org/)、あるいは[Truffle](https://trufflesuite.com/), [Moralis](https://moralis.io/)などの開発プラットフォームを利用することができます。 一般にこれらのプラットフォームには、Dapp のクロスチェーン化を実現するコンポーザブルなプラグインが含まれています。 例えば、 [hardhat-deploy plugin](https://github.com/wighawag/hardhat-deploy)で提供される決定論的なデプロイ用プロキシを活用することができます。 +複数のブロックチェーン上でDappをデプロイするには、[Alchemy](https://www.alchemy.com/)、[Hardhat](https://hardhat.org/)、あるいは[Truffle](https://trufflesuite.com/), [Moralis](https://moralis.io/)などの開発プラットフォームを利用することができます。 一般にこれらのプラットフォームには、Dappのクロスチェーン化を実現するコンポーザブルなプラグインが含まれています。 例えば、 [hardhat-deploy plugin](https://github.com/wighawag/hardhat-deploy)で提供される決定論的なデプロイ用プロキシを活用することができます。 #### 例: -- [クロスチェーン対応の Dapp を開発する方法](https://moralis.io/how-to-build-cross-chain-dapps/) -- [クロスチェーン対応の NFT マーケットプレイスを開発する方法](https://youtu.be/WZWCzsB1xUE) -- [Moralis: クロスチェーン対応の DApps を開発する](https://www.youtube.com/watch?v=ehv70kE1QYo) +- [クロスチェーン対応のDappを開発する方法](https://moralis.io/how-to-build-cross-chain-dapps/) +- [クロスチェーン対応のNFTマーケットプレイスを開発する方法](https://youtu.be/WZWCzsB1xUE) +- [Moralis: クロスチェーン対応のDAppsを開発する](https://www.youtube.com/watch?v=ehv70kE1QYo) ### コントラクトにおけるチェーン間のやりとりを監視する {#monitoring-contract-activity-across-chains} -コントラクトにおけるチェーン間のやりとりを監視するには、サブグラフや、Tenderly 等の開発プラットフォームを用いて、スマートコントラクトの状態をリアルタイムで観察することができます。 これらのプラットフォームにはさらに、[コントラクトが発行したイベント](https://docs.soliditylang.org/en/v0.8.14/contracts.html?highlight=events#events)をチェックするなど、チェーン間のやりとりを対象としてより充実したデータ監視機能を実現できるツールが含まれています。 +コントラクトにおけるチェーン間のやりとりを監視するには、サブグラフや、Tenderly等の開発プラットフォームを用いて、スマートコントラクトの状態をリアルタイムで観察することができます。 これらのプラットフォームにはさらに、[コントラクトが発行したイベント](https://docs.soliditylang.org/en/v0.8.14/contracts.html?highlight=events#events)をチェックするなど、チェーン間のやりとりを対象としてより充実したデータ監視機能を実現できるツールが含まれています。 #### ツール @@ -123,10 +123,10 @@ Dapp にブリッジやブリッジアグリゲーターを組み込む場合、 ## さらに学びたい方へ {#further-reading} - [ブロックチェーンにおけるブリッジ](/bridges/) - ethereum.org -- [ブロックチェーンにおけるブリッジ: クリプトネットワークのネットワーク構築](https://medium.com/1kxnetwork/blockchain-bridges-5db6afac44f8) 2021 年 9 月 8 日、ドミトリー・ベレンゾン作成。 -- [相互運用性のトリレンマ](https://blog.connext.network/the-interoperability-trilemma-657c2cf69f17) 2021 年 10 月 1 日、アルジュン・ブプタニ作成。 -- [クラスタ: 信頼ベースおよび信頼最小化のブリッジは、マルチチェーン環境をどのように変化させるか](https://blog.celestia.org/clusters/) 2021 年 10 月 4 日、ムスタファ・アル=バッサム作成。 -- [LI.FI: ブリッジの信頼依存度は様々に異なる](https://blog.li.fi/li-fi-with-bridges-trust-is-a-spectrum-354cd5a1a6d8) 2022 年 4 月 28 日 、アルジュン・チャンド作成。 +- [ブロックチェーンにおけるブリッジ: クリプトネットワークのネットワーク構築](https://medium.com/1kxnetwork/blockchain-bridges-5db6afac44f8) 2021年9月8日、ドミトリー・ベレンゾン作成。 +- [相互運用性のトリレンマ](https://blog.connext.network/the-interoperability-trilemma-657c2cf69f17) 2021年10月1日、アルジュン・ブプタニ作成。 +- [クラスタ: 信頼ベースおよび信頼最小化のブリッジは、マルチチェーン環境をどのように変化させるか](https://blog.celestia.org/clusters/) 2021年10月4日、ムスタファ・アル=バッサム作成。 +- [LI.FI: ブリッジの信頼依存度は様々に異なる](https://blog.li.fi/li-fi-with-bridges-trust-is-a-spectrum-354cd5a1a6d8) 2022年4月28日 、アルジュン・チャンド作成。 ブリッジについてさらに理解を深めたい方は、 [ジェイムズ・プレストウィッチ](https://twitter.com/_prestwich)による洞察溢れる講演をご覧ください: diff --git a/public/content/translations/ja/developers/docs/data-availability/index.md b/public/content/translations/ja/developers/docs/data-availability/index.md index 3c6a5f19d09..6fd0f527182 100644 --- a/public/content/translations/ja/developers/docs/data-availability/index.md +++ b/public/content/translations/ja/developers/docs/data-availability/index.md @@ -1,167 +1,83 @@ --- title: データ可用性 -description: イーサリアムにおけるデータの可用性に関する問題および解決策の概要 +description: イーサリアムにおけるデータ可用性に関する問題および解決策の概要 lang: ja --- -トラストレスであることは、パブリックブロックチェーンにおける大前提であると言えます(「信頼せず、検証せよ」)。 イーサリアムにおいて信頼性の前提を引き下げる方法のひとつに、データの可用性に関するルールの強制的な適用があります。 ブロックを生成するユーザーは各ブロックのデータを公開しなければならず、これをイーサリアムのコンセンサスに参加するノードがローカルで保存するのです。 +「信頼するな、検証せよ」は、イーサリアムでよく使われる格言です。 この考え方は、あなたのノードで独自に検証できることを指しています。情報が正しいのかどうかをピアから受け取ったブロックのトランザクションを全て実行することで、提案された変更がノードによって個別に計算された変更と正確に一致することを保証することが可能です。 これにより、ノードがブロックの送信者が正直であると信頼する必要がないことを意味します。 データが欠落している場合は、信頼することができまません。 -イーサリアムネットワーク上のすべてのノードは、他のノードから受け取ったブロック内のトランザクションを実行することで、ブロック生成者が提案した変更が、各ノードにおいて独立して計算されたものと正確に一致することを確認することができます。 これにより各ノードは、ブロック生成者の誠実性を信頼する必要を伴わずに、新たな情報が正当なものであることを確認できます。 この確認は、データが欠落していると実行できません。 - -ブロックチェーンにおいてデータの可用性が重要な理由は、参照可能なデータで再現できない物は存在しないと見なされるためです。 検証するノードは、ブロックデータにアクセスすることで、各ノードにおけるイーサリアムのワールドステートを用いてトラストレスにトランザクションを再生し、各ブロックの正確性を独立して検証することができます。 +**データ可用性**は、ユーザーがブロックを検証するために必要なデータがすべてのネットワーク参加者で実際に利用可能であるという確実性を指しています。 イーサリアムのレイヤー1にあるフルノードの場合は比較的シンプルです。 フルノードは、各ブロック内のすべてのデータのコピーをダウンロードします。ダウンロードが可能であるには、 データが入手可能であることが_必要_です。 データが欠落しているブロックは、ブロックチェーンに加えられることはなく、破棄されます。 これは「オンチェーンにおけるデータ可用性」であり、モノリシックブロックチェーンの機能です。 フルノードでは、すべてのトランザクションを自分でダウンロードして実行するため、だまされて無効なトランザクションを受け入れることはありません。 ただし、モジュラー型のブロックチェーン、レイヤー2ロールアップ、ライトノードの場合では、データ可用性の状勢がより複雑になり、より高度な検証手順が必要になります。 ## 前提知識 {#prerequisites} [ブロックチェーンの基礎](/developers/docs/intro-to-ethereum/)、特に[コンセンサス・メカニズム](/developers/docs/consensus-mechanisms/)をよく理解している必要があります。 さらに、[ブロック](/developers/docs/blocks/)、[トランザクション](/developers/docs/transactions/)、[ノード](/developers/docs/nodes-and-clients/)、[スケーリングソリューション](/developers/docs/scaling/)、およびその他の関連トピックについての知識が必要です。 -## データの可用性とは何か? {#what-is-data-availability} - -データの可用性とは、ブロック提案者が当該ブロックに関するすべてのトランザクションデータを公開し、このトランザクションデータをネットワークの他の参加者も利用可能であることを保証することです。 イーサリアムのトランザクションは、[ブロック](/developers/docs/blocks/)で処理されます。 複数のブロックをチェーンでつなぐことで、「ブロックチェーン」が作られます。 - -各ブロックは、主に以下の 2 つのパーツで構成されます: - -- **ブロックヘッダー**:タイムスタンプ、ブロックハッシュ、ブロック番号など、ブロックに関する一般的な情報(メタデータ)を含む部分です。 -- **ブロックボディ**:当該ブロックの一部として処理された実際のトランザクションを含む部分です。 - -ブロック生成者が新しいブロックを提案する場合、(ブロックボディ内の)トランザクションデータを含むブロック全体を公開しなければなりません。 コンセンサスに参加している各ノードは、それを受けて、このブロックのデータをダウンロードし、トランザクションを再実行することで、新規ブロックの正当性を確認します。 トランザクションを検証する他のノードが存在しなければ、ブロック提案者がブロックに悪意のトランザクションを紛れ込ませることが可能になります。 - -### データの可用性に関する問題点 {#the-data-availability-problem} - -データの可用性に関する問題は、「新たに生成されたデータの参照可能性をどのように検証できるか」という問いに要約できます。 イーサリアムでは、フルノードがブロックデータにアクセスできるという前提によりセキュリティを確保しているため、データが参照可能であることが死活的に重要です。 - -ブロックの生成者がすべてのデータを提供せずにブロックを提案する場合、このブロックは無効なトランザクションを含んだままでファイナリティに達してしまうかもしれません。 仮に適切なブロックであったとしても、検証に必要なデータがすべて参照できない場合、イーサリアムネットワークのユーザーおよび機能に対して悪影響を及ぼします。 - -データの可用性に関する問題は同時に、ロールアップをはじめとする[スケーリング・ソリューション](/developers/docs/scaling/)に関する議論においても重要です。 スケーリングのためのプロトコルは、イーサリアムメインネット以外でトランザクションを実行することで、スループットを増大させます。 しかし、これらのプロトコルがイーサリアムを通じてセキュリティを確保するためには、トランザクションデータをメインネットに送信して、メインチェーン以外で実行された処理の正確性を誰もが検証できるようにしなければなりません。 - -#### データの可用性とライトクライアント - -データの可用性に関する従来の考え方では、検証を行うノードにおけるトランザクションデータの可視性について議論を進めてきましたが、最近は、ライトクライアントにおけるデータの可用性を検証する方法に焦点を当てる傾向が強まっています。 ライトクライアントにおけるデータの可用性の問題は、ブロック全体をダウンロードせずにブロックの可用性を検証できるか、という点にあります。 - -イーサリアムにおけるライトクライアントとは、最新のブロックヘッダーのみに同期し、フルノードに対して他の情報をリクエストするノードです。 ライトクライアントは、ブロック全体をダウンロードしないため、トランザクションを検証したり、イーサリアムのセキュリティ向上に貢献することはできません。 - -しかし、ライトクライアントがブロックをダウンロードしないでもデータの可用性を証明できる方法についての研究が進められています。 ライトクライアントがブロックの可用性を検証できるようになれば、可用性がないブロックについて他のノードに警告を発することで、イーサリアム全体のセキュリティ向上に貢献することができます。 - -これに関連して、ステートレスのイーサリアムにおいてデータの可用性を検証可能にするためのメカニズムについても研究が進められています。 [ステートレス・クライアント・コンセプト](https://ethresear.ch/t/the-stateless-client-concept/172) は、提案中のイーサリアムのバージョンであり、検証を行うノードはブロックを検証する前に状態データを保存する必要がなくなります。 - -ステートレス性により、イーサリアムのセキュリティ、スケーラビリティ、および長期的なサステナビリティが向上できると期待されています。 ノードを検証するためのハードウェア要件を引き下げることで、より多くのバリデータがネットワークに参加できるようになるため、悪意のアクターからネットワークを保護できるようになります。 - -### データの可用性と取り出し可能性の違いとは? {#data-availability-vs-data-retrievability} - -データの可用性は、データの取り出し可能性とは異なる概念です。 データの可用性とは、チェーンに追加するために処理中であるブロックのトランザクションデータを、ノードがダウンロードできる機能を指します。 つまり、データの可用性が問題になるのは、コンセンサスに達していないブロックを対象とする場合です。 - -一方、データの取り出し可能性とは、ブロックチェーンにおける*過去の情報*をノードが取り出すことができる機能を指します。 ブロックチェーンの履歴は、過去のブロックおよび、過去のイベントに関する情報が保存されているレシートにより構成されます。 過去のブロックチェーンデータは、アーカイブ化のために必要となる場合がありますが、各ノードは、この履歴なしでブロックチェーンを検証し、トランザクションを処理することができます。 - -イーサリアムのコアプロトコルでは、主に、データの取り出し可能性についてではなく、可用性について取り上げています。 イーサリアムでは、処理済みのすべてのトランザクションを永遠に保存することはありません。そうすると、フルノードにおけるストレージ要件が厳格化され、イーサリアムの分散化にとって有害だからです。 - -幸いなことに、データの取り出し可能性は、データの可用性よりもはるかに解決しやすい問題です。 過去のブロックチェーンデータを取り出すためには、履歴情報を保存している正直なノードがひとつ存在すればよいからです。 さらに、ブロックチェーン・エクスプローラーなどの組織は、アーカイブデータを保存して、他のユーザーからのリクエストに基づいて提供するというインセンティブを持っています。 - -[データの取り出し可能性に関するソリューションの詳細](https://notes.ethereum.org/@vbuterin/data_sharding_roadmap#Who-would-store-historical-data-under-sharding) - -## データの可用性が重要である理由 {#why-is-data-availability-important} - -### ブロックチェーンのセキュリティ {#blockchain-security} +## データ可用性問題 {#the-data-availability-problem} -データの可用性は、ブロックチェーンのセキュリティを維持する上で死活的に重要であり、可用性が存在しなければ、「データ秘匿による攻撃」が一般化してしまうでしょう。 データ隠し持ち攻撃とは、ブロックの生成者が、当該ブロックを構築するために用いたトランザクションデータを共有せずにブロックを公開するものです。 +データ可用性問題とは、すべてのノードがすべてのデータをダウンロードすることなく、有効なトランザクションのセットを表すブロックチェーンが追加されたことを要約された形式のいくつかのトランザクションデータからネットワーク全体を証明する必要があることを指します。 ブロックを個別に検証するには完全なトランザクションデータが必要になりますが、すべてのノードがすべてのトランザクションデータをダウンロードする必要があると、スケーリングの障壁になります。 データ可用性問題に対する解決策としては、自分自身でデータをダウンロードして保存しないネットワーク参加者に対して、完全なトランザクションデータが検証のために利用可能であることを十分に保証する状態を目指すことです。 -データ隠し持ち攻撃が発生した場合、フルノードは、イーサリアムのワールドステートに対するアップデートが適切であるかを検証することが不可能になります。 これにより、悪意のブロック提案者は、プロトコルのルールをかいくぐり、イーサリアムネットワークにおいて無効な状態遷移を実行させることができます。 +ネットワーク参加者が強力なデータ可用性保証を必要としているものの、自分自身でダウンロードやトランザクションデータを処理することができない重要な例としては、[ライトノード](/developers/docs/nodes-and-clients/light-clients)や[レイヤー2ロールアップ](/developers/docs/scaling)があります。 トランザクションデータのダウンロードを避けることでライトノードは軽量になり、ロールアップは効果的なスケーリングソリューションになることができます。 -フルノードにおけるブロックデータの可視性が重要なのは、ライトクライアントをはじめとする他のネットワーク参加者におけるネットワーク状態の検証がフルノードに依存しているためです。 ライトクライアントは、フルノードとは異なり、ブロックヘッダーのみを確認し、ブロックボディはダウンロードしません。 このため、データ可用性に関するルールは、フルノードがブロックを検証可能であり、チェーンの不正利用を防止できることを保証するのです。 +データ可用性は、ブロックを検証するために状態データをダウンロードして保存する必要のない今後の[「ステートレス」](/roadmap/statelessness)イーサリアムクライアントにとっても重要な課題事項になっています。 ステートレスクライアントでは、データが_どこか_で入手可能であることおよびデータが正しく処理されていることを依然として確認する必要があります。 -### 分散型のスケーラビリティ {#decentralized-scalability} - -[イーサリアムでは、分散化とセキュリティを犠牲にすることなく、処理能力のスケーラビリティを実現することを目標としています。](/roadmap/vision/) ブロックチェーンのアーキテクチャにおけるモノリシックな限界により、分散型のスケーラビリティを実現するにはデータの可用性が非常に重要になります。 - -#### データの可用性と L2 のスケーリング {#data-availability-and-layer-2-scaling} - -[ロールアップ](/glossary/#rollups)などの[L2 のスケーリング・ソリューション](/layer-2/)は、イーサリアムのメイン実行レイヤー以外でトランザクションを処理することで、ネットワークのスループットおよびレイテンシーにおけるスケーラビリティを実現します。 オフチェーンのトランザクションは、圧縮されたデータがバッチでイーサリアムに投稿されるため、オフチェーンで数千件のトランザクションが実行される場合でも、イーサリアムは提出された各バッチに関連した*1 件*のトランザクションをオンチェーンで処理すればよいのです。 これにより、ベースレイヤーにおける処理の混雑を軽減し、ユーザーの手数料を引き下げられると同時に、トランザクションの処理速度を高めることができます。 - -しかし、イーサリアムがロールアップのセキュリティを保証するには、オフチェーンで実行されるトランザクションの正当性を検証するメカニズムが必要になります。 ここで、データの可用性が重要になってきます。 - -[オプティミスティック・ロールアップ](/developers/docs/scaling/optimistic-rollups/)の場合、圧縮されたトランザクションデータは`calldata`としてイーサリアムに送信されます。 これにより、すべてのユーザーがロールアップの状態を検証でき、トランザクションの正当性を保証することができます。 トランザクションが無効である場合、検証者は、参照できるトランザクションデータを用いて<[不正証明](/glossary/#fraud-proof)を構築し、異議を申し立てることができます。 - -[ゼロ知識 (ZK) ロールアップ](/developers/docs/scaling/zk-rollups)では、[ゼロ知識有効性証明](/glossary/#zk-proof)を用いて状態遷移の正当性を保証できるため、トランザクションデータを投稿する必要はありません。 ただし、状態データにアクセスできない場合、ゼロ知識ロールアップの機能(またはロールアップとのやりとり)を保証することはできません。 - -具体的には、オペレーターがロールアップの状態に関する詳細を公開しない場合、ユーザーは自分の残高を確認できません。 さらに、新たに追加されたブロックに含まれる情報を用いて、状態アップデートを実行することもできません。 - -## ブロックチェーンにおけるデータ可用性システムの種類 {#types-of-data-availability-systems-in-blockchains} - -### オンチェーンにおけるデータの可用性 {#on-chain-data-availability} - -データの可用性に関する問題に対する標準的な解決策は、ブロック生成者に対し、すべてのトランザクションデータをオンチェーンで公開させ、検証するノードにこのデータをダウンロードさせるという方法です。 オンチェーンにおけるデータの可用性は、データの可用性、トランザクションの実行、およびコンセンサスを 1 つのレイヤーで管理するという「モノリシックなブロックチェーン」の特徴だと言えます。 イーサリアムのプロトコルでは、ネットワーク全体において冗長的に状態データを保存することで、各ノードは、トランザクションを再現し、状態アップデートを検証し、無効な状態遷移をフラッグするために必要なデータにアクセスすることができます。 - -しかし、オンチェーンにおけるデータの可用性を維持する場合、スケーラビリティのボトルネックが発生します。 モノリシックなブロックチェーンでは、各ノードがすべてのブロックをダウンロードし、同じトランザクションを再生する必要があるため、処理速度が低下する場合が多いためです。 さらに、フルノードに対して常に増化する状態の保存を要求するため、分散化という目標に反したトレンドとも言えます。 イーサリアムの状態が加速度的に増化する場合、検証者はより高性能のマシンに投資しなければならず、最終的には検証ノードを実行するユーザーの数が減少するでしょう。 - -### オフチェーンにおけるデータの可用性 {#off-chain-data-availability} - -オフチェーンのデータ可用性システムは、データの保存場所をブロックチェーン外に移動させます。ブロックの生成者は、トランザクションデータをオンチェーンで公開するのではなく、当該データの可用性を証明する暗号化されたコミットメントを提供します。 これは、 [モジュラー型ブロックチェーン](https://celestia.org/learn/basics-of-modular-blockchains/modular-and-monolithic-blockchains/)で用いられている方法であり、ブロックチェーンは、トランザクションの実行やコンセンサスといった一部のタスクを管理する一方で、その他のタスク(データの可用性など)は他のレイヤーで処理させます。 - -スケーリングを実現する多くのソリューションでは、データの可用性をコンセンサスや実行と分離するというモジュラー型のアプローチを採用しており、ノードの要件を強化することなくブロックチェーンのスケーラビリティを実現する上で最適の方法だと考えられています。 例えば、[バリディウム](/developers/docs/scaling/validium/)や[プラズマ](/developers/docs/scaling/plasma/)では、オフチェーンのストレージを使用してオンチェーンで投稿されるデータの量を軽減しています。 - -オフチェーンにおけるデータの可用性は、効率性の向上をもたらすものの、分散化、セキュリティ、およびトラストレス性といった事項に対しては悪影響を及ぼします。 例えば、バリディウムやプラズマにおける参加者は、ブロックの生成者が提案したブロックに無効なトランザクションを含めていないことを信頼する必要があります。 ブロックの生成者は悪意の行為(つまり、無効な状態遷移)を行う可能性があり、状態データを秘匿することで、悪意のトランザクションに対する異議申立の試みを無効化しようとすることができます。 - -オフチェーンのデータストレージに伴う様々な問題により、一部のスケーリング・ソリューションでは、イーサリアムのような親ブロックチェーン上でトランザクションデータを保存しています。 例えば、オプティミスティック・ロールアップやゼロ知識ロールアップでは、トランザクションデータを保存せず、イーサリアムメインネットをデータ可用性レイヤーとして使用します。 - -## データ可用性の問題点を解決するソリューションには、どのようなものがあるか? {#solutions-to-data-availability-problem} - -すでに述べたように、データの可用性に関する問題とは、新たに提案されたブロックにおけるトランザクションデータが検証可能かという点に関わっています。 この問題に対する解決策は、データの可用性を保証するためのメカニズムを提供するものです。 +## データ可用性ソリューション {#data-availability-solutions} ### データ可用性サンプリング(DAS) {#data-availability-sampling} -データ可用性サンプリング(DAS)とは、暗号化メカニズムを使ってデータの可用性を保証するものです。 Das により、ブロックチェーンの各ノードは、ブロック全体をダウンロードせずに提案されたブロックのデータ可用性を検証することができます。 - -DAS システムでは、各ノードが対象ブロックから小規模なチャンクを複数回サンプリングしてデータの可用性を検証します。 対象ブロックの異なる部分を多くのノードが同時にサンプリングすることで、統計的に高い確実性に基づいて可用性を検証することができます。 - -DAS は、イーサリアムをはじめとするブロックチェーンに適用した場合、ライトクライアントもチェーンのセキュリティおよび機能性を保証するために貢献できるようになります。 ライトクライアントも高価なハードウェアを導入せずに検証を実行できるため、イーサリアムネットワーク上のあらゆるユーザーが検証作業に参加することができます。 +データ可用性サンプリング (DAS) は、各ノードに過度な負担をかけずに、ネットワークでデータが取得可能であることを確認する方法です。 各ノード (非ステーキングノードを含む) は、すべてのデータからランダムに選択された小さなサブセットをダウンロードします。 サンプルのダウンロードが成功することで、すべてのデータが取得可能であることを高い信頼性をもって確認できます。 これは、データイレイジャーディングコーディングに依存しています。データイレイジャーコーディングとは、指定された冗長な情報を展開します (_多項式_として知られる関数をデータに当てはめ、追加の点において、その多項式を評価する方法をとります) 。 これにより、必要に応じて冗長データから元のデータを復元できます。 このデータ作成の結果、元のデータの_いずれか_が取得できない場合、 展開されたデータの_半分_が行方不明になります! 各ノードによってダウンロードされるデータサンプリングの量が、実際に取得可能なデータの半分未満である_場合_では、各クライアントからサンプリングされた少なくとも1つのデータフラグメントが欠落している可能性が_極めて_高くなるように調整されています。 -[データ可用性サンプリングに関する詳細。](https://hackmd.io/@vbuterin/sharding_proposal#ELI5-data-availability-sampling) +DASは、[EIP-4844](/roadmap/danksharding)が実装された後、ロールアップオペレータがトランザクションデータを取得できることを確実にするために使われます。 イーサリアムノードでは、上述した冗長性スキームを使い、ブロブで提供されるトランザクションデータをランダムにサンプリングし、すべてのデータが存在することを確認します。 同じ手法を採用することで、ブロック生成者がすべてのデータをライトノードへ使用可能にしていることを保証できます。 同様に、[プロポーザー/ビルダーセパレーション(PBS)](/roadmap/pbs)では、ブロックビルダーはブロック全体を処理することのみが求められ、他のバリデータはデータ可用性サンプリングを用いて検証します。 -#### データ可用性証明 {#data-availability-proofs} +### データ可用性委員会(DAC) {#data-availability-committees} -データ可用性サンプリングを通じて、対象ブロックの可用性を統計的に保証することができるものの、悪意のノードがデータを秘匿する可能性を完全に消し去ることはできません。 DAS のテクニックは、当該ブロックにおける大部分のデータの可用性を証明するだけであり、ブロック全体の可用性を保証しません。 そして、ブロックの生成者がトランザクションデータのごく一部を秘匿するだけでも、多くの被害が発生しうるのです。 +データ可用性委員会 (DAC) は、データ可用性を提供もしくは証明する信頼できる当事者です。 DACは、DASの代わりに使うことができたり、DASと[組み合わせること](https://hackmd.io/@vbuterin/sharding_proposal#Why-not-use-just-committees-and-not-DAS)ができます。 この委員会が持つ安全性の保証は、具体的な設定によって異なります。 例えばイーサリアムでは、ランダムにサンプリングされたバリデータのサブセットを使い、ライトノードのデータ可用性を証明します。 -私たちはこの問題を解決するために、データ可用性サンプリングと[イレイジャーコード](https://en.wikipedia.org/wiki/Erasure_code)を組み合わせることで、「データ可用性証明」というプロセスを開発しました。 イレイジャーコーディングとは、ブロックに冗長な部分を追加することで、データセットを二重化する技術です。 これにより、本来のデータセットが失われた場合も、イレイジャーコードを用いて元々のデータを再構築することができます。 +DACは一部のバリディアムでも使われています。 DACは、データのコピーをオフラインに保存する信頼できるノードの集合です。 紛争が発生した場合、データを取得可能にすることがDACに求めらます。 DACのメンバーはさらに、当該データが実際に提供可能であることを証明するために、オンチェーン上で誓約を公開します。 一部のバリディアムでは、DACの代わりに、プルーフ・オブ・ステーク(PoS)のバリデータシステムを導入しています。 このシステムでは、すべてのユーザーがバリデータとなり、オフチェーンでデータを保存することが可能になります。 ただし、バリデータとなるためには、スマートコントラクトに対して担保となる「ボンド」を預け入れる必要があります。 バリデータがデータを秘匿するなどの悪意の行為が発生した場合、預け入れられたボンドを没収することができます。 プルーフ・オブ・ステークのデータ可用性委員会は、正直な行動に直接インセンティブが働くため、通常のDACよりもさらに安全になっています。 -ブロックチェーンにイレイジャーコードを実装することで、データセット全体のごく一部のみを用いてブロックに含まれるトランザクション全体を再構築することができるため、データの可用性を向上させることができます。 このシステムでは、悪意のブロック生成者がデータ隠し持ち攻撃を実行するには、ブロック全体の 50%以上を隠し持つ必要があります。 イレイジャーコードを実装しない場合、ブロック生成者は全体のうちわずか 1%のデータを秘匿するだけで悪意の行動が可能でした。 +## データ可用性とライトノード {#data-availability-and-light-nodes} -イレイジャーコーディングを実行したブロックの場合、ライトクライアントは、ブロック全体のデータがネットワーク上で公開済みであるという統計的な確証を得ることができます。 さらに、ライトクライアントは、フルノードに依存せずに、ブロックが可用性を持たないという警告を受け取ることができます。 +[ライトノード](/developers/docs/nodes-and-clients/light-clients)では、ブロックデータをダウンロードせずに、受信したブロックヘッダーの正確性を検証しなければなりません。 この軽量であることの代償として、フルノードのようにローカルでトランザクションを再実行してブロックヘッダーを独自に検証できないことがあります。 -[データ可用性証明の詳細。](https://github.com/ethereum/research/wiki/A-note-on-data-availability-and-erasure-coding) +イーサリアムのライトノードでは、_同期委員会_に割り当てられたバリデータのランダムなセットである512台を信頼します。 同期委員会は、暗号署名を使用してヘッダー内のデータが正しいことをライトノードに通知するデータ可用性員会(DAC)として振る舞います。 同期委員会は毎日更新されます。 同期委員会は、暗号署名を使用してヘッダー内のデータが正しいことをライトノードに通知するデータ可用性員会(DAC)として振る舞います。 -### データ可用性委員会(DAC) {#data-availability-committees} +しかし、攻撃者が何らかの方法で悪意のあるブロックヘッダーをライトノードに渡し、それが正直な同期委員会によって承認されたブロックヘッダーであると信じ込ませることが_できた_場合に何が起こるでしょうか? このケースでは、攻撃者は無効なトランザクションを含め、ライトクライアントはブロック ヘッダーに要約されているすべての状態変更を個別にチェックしないため、それらを盲目的に受け入れてしまう可能性があります。 これを防ぐために、ライトノードでは、不正証明を使うことができます。 -ピュア・バリディアムでは、ブロックの生成者はトランザクションデータをオフチェーンで保存するため、ブロックチェーンはある程度一元化されます。 これにより、ブロックの生成者は無効なトランザクションを公開でき、トランザクションデータを秘匿することでロールアップの真の状態を隠すことができるため、ブロックチェーンの分散性やセキュリティが低下します。 +この不正証明は、次のように機能します。ネットワーク上でゴシップされている無効な状態遷移を認識したフルノードは、提案された状態遷移が特定のトランザクションのセットにおいて発生する可能性がありえないことを明示した小さなデータを素早く生成し、データをピアにブロードキャストします。 ライトノードでは、これらの不正証明を取得して無効なブロックヘッダーを破棄するために使用します。これにより、フルノードと同じ正直なチェーン上に確実に存在することができます。 -一部のバリディアムでは、ブロック生成者に対して、トランザクションデータを信頼できるユーザーで構成されたデータ可用性委員会(DAC)で保存するように指示することで、この問題を解決しようと試みています。 この DAC は、オフチェーンのデータのコピーをオフラインで保存した上で、紛争が発生した場合にはこのデータを提供することが義務付けられています。 DAC のメンバーはさらに、当該データが実際に提供可能であることを証明するために、オンチェーン上で誓約を公開します。 +これは、完全なトランザクションデータにアクセスできるフルノードに依存しています。 無向なブロックヘッダーをブロードキャストし、そのトランザクションデータ使用させることに失敗した攻撃者は、フルノードが不正証明を生成することを阻止する可能性もありえます。 フルノードは無効なブロックに対して警告を出せるかもしれませんが、証明を生成するためのデータが使用可能になっていないため、その警告を証明で裏付けることができません! -[データ可用性委員会(DAC)の詳細。](https://medium.com/starkware/data-availability-e5564c416424) +このデータ可用性問題の解決策がDASです。 ライトノードは、すべての状態データに対する非常に少量なチャンクをランダムにダウンロードして、そのサンプルを検証することで全てのデータセットが使用可能であることを確認します。 N個のチャンクをランダムにダウンロードした後にフルデータの可用性を誤って推測してしまう実際の可能性を計算できます ([100個のチャンクでは、確率は10のマイナス30乗](https://dankradfeist.de/ethereum/2019/12/20/data-availability-checks.html)であり、非常に低い確率です) 。 -### プルーフ・オブ・ステークを用いたデータ可用性委員会 {#proof-of-stake-data-availability-committees} +このシナリオでさえも、ほんの数バイトを保留する攻撃において、ランダムにデータリクエストを行うクライアントでは、気付くことが出来ない可能性があります。 イレイジャーコーディングでは、提案された状態変化をチェックするために使用するデータの小さな欠落を再構築することで解決します。 その後、再構築されたデータを使い不正証明を構築し、ライトノードが不正なヘッダーを受け入れるのを防ぎます。 -データ可用性委員会(DAC)は、バリディウムの従来のアプローチよりも優れていますが、信頼を前提にするという問題点は解消されていません。 つまり、DAC がブロック生成者と結託してトランザクションデータを秘匿しようとした場合には、問題が解決できません。 多くの場合 DAC の構成メンバーは少数であるため、共謀のリスクや、外部アクターが DAC を乗っ取る可能性が高まります。 +**注意:** DASと不正証明は、プルーフ・オブ・ステークにおけるイーサリアムのライトクライアントでは未実装ですが、ロードマップには含まれています。これは、ZK- SNARKベースの証明形式をとる可能性が最も高くなっています。 現在のライトクライアントでは、DAC形式に依存しています。このDAC形式では、同期委員会のIDを検証し、受信した署名付きブロックヘッダーを信頼します。 -一部のバリディアムでは、DAC の代わりに、プルーフ・オブ・ステーク(PoS)のバリデータシステムを導入しています。 このシステムでは、すべてのユーザーがバリデータとなり、オフチェーンでデータを保存することが可能になります。 ただし、バリデータとなるためには、スマートコントラクトに対して担保となる「ボンド」を預け入れる必要があります。 バリデータがデータを秘匿するなどの悪意の行為が発生した場合、預け入れられたボンドを没収することができます。 +## データ可用性とレイヤー2ロールアップ {#data-availability-and-layer-2-rollups} -プルーフ・オブ・ステークを用いた DAC は、通常の DAC よりもセキュリティが大幅に強化されます。 この方法は、許可なし、信頼なしであるだけでなく、正直な行動を促すためのインセンティブがうまく設計されています。 +[ロールアップ](/glossary/#rollups)などの[レイヤー2スケーリングソリューション](/layer-2/)では、トランザクションコストを削減したり、トランザクションをオフチェーンで処理することによりイーサリアムのスループットを向上させています。 ロールアップトランザクションは圧縮され、イーサリアムへバッチでポストされます。 バッチは、イーサリアム上の一つのトランザクション内にある数千の個々のオフチェーントランザクションに相当します。 この圧縮により、ベースレイヤーの混雑状態が軽減され、ユーザーの料金が削減されます。 -[プルーフ・オブ・ステークを用いた DAC の詳細。](https://blog.matter-labs.io/zkporter-a-breakthrough-in-l2-scaling-ed5e48842fbf) +ただし、イーサリアムにポストされた「要約」トランザクションを信頼できるのは、提案された状態変更を自律的に検証することができ、すべての個別のオフチェーントランザクションを適用した結果を確認できる場合においてのみです。 ロールアップオペレータがこの検証に対してトランザクションデータを入手可能にしていなければ、ロールアップオペレータは、不正なデータを送信することができます。 -## イーサリアムと今後のデータ可用性 {#ethereum-and-the-future-of-data-availability} +[オプティミスティックロールアップ](/developers/docs/scaling/optimistic-rollups/)では、圧縮されたトランザクションデータをイーサリアムにポストし、独立した検証者がデータをチェックできるよう一定期間 (通常は7日間) 待機します。 検証者が問題を特定した場合、不正証明を生成し、それを使用してロールアップに対して異議申立ができます。 これにより、チェーンがロールバックされ、無効なブロックが除外されます。 これは、データが入手可能でないとできません。 現状のデータは、オンチェーンに永続的に存在する `CALLDATA`として永続的に入手可能になっています。 しかし、EIP-4844によって、ロールアップがトランザクションデータをCALLDATAの代わりに安価なBLOBストレージにポストできるようになる予定です。 これは永続ストレージではありません。 独立した検証者では、データがイーサリアムレイヤー1から削除される前の約1~3か月以内にBLOBへクエリを実行し、異議申立を提起しなければなりません。 データ可用性は、イーサリアムプロトコルによって、その短い一定の窓口期間内においてのみ保証されます。 それ以降は、イーサリアムエコシステム内の他のエンティティの責任になります。 どのノードでもDASを使い (すなわち、ブロブデータのランダムなサンプルをダウンロードすることによって) データ可用性を検証することができます。 -ロールアップでは、オフチェーンでの処理を通じてスループットの規模を拡大することができますが、この規模は、基盤となるブロックチェーンのデータスループットにより制限されます。 イーサリアムをデータ可用性レイヤーとして使用してロールアップを行うには、イーサリアムにおけるデータストレージおよび処理の能力を強化する必要があります。 +[ゼロ知識 (ZK) ロールアップ](/developers/docs/scaling/zk-rollups)では、[ゼロ知識有効性証明](/glossary/#zk-proof)を用いて状態遷移の正当性を保証できるため、トランザクションデータを投稿する必要はありません。 ただし、データ可用性に対して依然として問題があります。なぜなら、状態データにアクセスできない場合、ゼロ知識ロールアップの機能(またはロールアップとのやりとり)を保証することができないからです。 具体的には、オペレータがロールアップの状態に関する詳細を公開しない場合、ユーザーは自分の残高を確認できません。 さらに、新たに追加されたブロックに含まれる情報を用いて、状態アップデートを実行することもできません。 -[シャーディング](/upgrades/shard-chains/)は、イーサリアムの実行レイヤーにおいてデータのスループットを向上させるために提案されている方法です。 シャーディングでは、イーサリアムのネットワークを一定数のサブチェーンに分割し、各サブチェーンごとに専用のバリデータを割り振ります。 +## データ可用性と取り出し可能性の違いとは? {#data-availability-vs-data-retrievability} -バリデータは、割り当てられたシャードに対してのみフルノードを実行する必要があり、他のシャードについては軽量クライアントとして実行すればよくなります。 シャーディングでは、データを保存するジョブが異なるシャードに分割されるため、ロールアップに使用できるデータ領域を拡大することができます。 +データ可用性は、データの取り出し可能性とは異なる概念です。 フルノードが特定のブロックに関連付けられたトランザクションの完全なセットにアクセスし、検証できることを保証するのがデータ可用性です。 データが永久にアクセス可能である必要はありません。 -しかし、このようなデータのシャーディングは同時に、「特定のシャードを担当するバリデータたちが悪意を持ち、無効な状態遷移を処理しはじめたらどうなるのか」という新たな問題を生み出します。 このような問題が発生しうるのは、現在とは異なり、特定のトランザクションデータにフルノードがアクセスするのが不可能になるためです。 データのシャーディングを実装するには、各ノードが、ブロックをダウンロードすることなく、他のシャードにおけるデータの可用性を検証できるシステムを構築する必要があり、これを実現できなければシャーディングの目的を達成することはできません。 +一方、データの取り出し可能性とは、ブロックチェーンにおける_過去の情報_をノードが取り出すことができる機能を指します。 この履歴データは、新しいブロックの検証には不要です。ジェネシスブロックからフルノードを同期する場合、または特定の履歴に対するリクエストを処理する場合にのみ必要になります。 -この問題を解決するために、イーサリアムでは[ダンクシャーディング](https://notes.ethereum.org/@vbuterin/proto_danksharding_faq)などの新たなスケーリングソリューションが提案されています。これは、データ可用性をサンプリングすることで、ブログのコンテンツ全体をネットワークが確認したことを検証するというアプローチです。 このシステムでは、各ノードにおいてすべてのコンテンツを直接ダウンロードし、検証するという負荷を軽減することができます。 +イーサリアムのコアプロトコルでは、主に、データの取り出し可能性についてではなく、可用性について取り上げています。 データ取り出し可能性については、サードパーティが運用する少数のアーカイブノードによって提供したり、[ポータルネットワーク](https://www.ethportal.net/)等の分散ファイルストレージを使ってネットワーク全体に分配することができます。 ## 参考文献 {#further-reading} -- [データの可用性とは一体何ですか?](https://medium.com/blockchain-capital-blog/wtf-is-data-availability-80c2c95ded0f) +- [データ可用性とは一体何ですか?](https://medium.com/blockchain-capital-blog/wtf-is-data-availability-80c2c95ded0f) - [データ可用性とは?](https://coinmarketcap.com/alexandria/article/what-is-data-availability) -- [データ可用性プラットフォーム](https://blog.polygon.technology/the-data-availability-problem-6b74b619ffcc/) - [イーサリアムにおけるオフチェーンのデータ可用性に関する現況](https://blog.celestia.org/ethereum-off-chain-data-availability-landscape/) - [データ可用性チェックの入門](https://dankradfeist.de/ethereum/2019/12/20/data-availability-checks.html) -- [シャーディング+ DAS 提案とは何か?](https://hackmd.io/@vbuterin/sharding_proposal#ELI5-data-availability-sampling) +- [シャーディング+ DAS提案とは何か?](https://hackmd.io/@vbuterin/sharding_proposal#ELI5-data-availability-sampling) +- [データ可用性とイレイジャーコードディングの注意事項](https://github.com/ethereum/research/wiki/A-note-on-data-availability-and-erasure-coding#can-an-attacker-not-circumvent-this-scheme-by-releasing-a-full-unavailable-block-but-then-only-releasing-individual-bits-of-data-as-clients-query-for-them) +- [データ可用性委員会(DAC)](https://medium.com/starkware/data-availability-e5564c416424) +- [プルーフ・オブ・ステークを用いたデータ可用性委員会.](https://blog.matter-labs.io/zkporter-a-breakthrough-in-l2-scaling-ed5e48842fbf) +- [データの取り出し可能性問題の解決策](https://notes.ethereum.org/@vbuterin/data_sharding_roadmap#Who-would-store-historical-data-under-sharding) diff --git a/public/content/translations/ja/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md b/public/content/translations/ja/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md index 678ca3a386c..bc4d7b2ce01 100644 --- a/public/content/translations/ja/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md +++ b/public/content/translations/ja/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md @@ -7,7 +7,7 @@ sidebarDepth: 2 マークル・パトリシア・ツリー(Patricia Merkle Trie)は、暗号的に認証されたデータ構造を提供し、すべての `(key, value)`バインディングを保存するために使用できます。 -マークル・パトリシア・ツリーは完全に決定的です。つまり、同じ `(key, value)` バインディングを持つツリーは、最後のバイトまで必ず同一です。 それらが同じルートハッシュを持ち、挿入、検索、削除において`O(log(n))`という優れた効率を発揮します。 さらに、レッド・ブラック・ツリーのような比較に基づく複雑な代替案よりも、理解やコーディングが簡単です。 +マークル・パトリシア・ツリーは、完全に決定的な構造であり、同じ`(key, value)`バインディングを持つツリーは、最後のバイトまで必ず同一になります。 それらが同じルートハッシュを持ち、挿入、検索、削除において`O(log(n))`という優れた効率を発揮します。 さらに、レッド・ブラック・ツリーのような比較に基づく複雑な代替案よりも、理解やコーディングが簡単です。 ## 前提知識 {#prerequisites} @@ -21,11 +21,11 @@ sidebarDepth: 2 [i_0, i_1 ... i_n, value] ``` -`i_0 ... i_n`は、アルファベットの記号列(通常は 2 進数または 16 進数)を表し、`value`はノードの最終値、スロット `i_0, i_1 ... i_n`の値は、`NULL`または他のノードへのポインタ(イーサリアムの場合はハッシュ値)です。 これにより、基本的な`(key, value)`型ストアが形成されます。 +`i_0 ... i_n`は、アルファベットの記号列(通常は2進数または16進数)を表し、`value`はノードの最終値、スロット `i_0, i_1 ... i_n`の値は、`NULL`または他のノードへのポインタ(イーサリアムの場合はハッシュ値)です。 これにより、基本的な`(key, value)`型ストアが形成されます。 -キーバリューセットに対する順序を永続化するために、基数ツリーのデータ構造を使用するとします。 ツリーで現在`dog`に対応する値を知るには、最初に`dog`のアルファベットの文字を変換します(`64 6f 67`)。次に、値が見つかるまで 64 6f 67 のパスをたどってツリーを下ります。 つまり、ツリーのルートノードを見つけるために、フラットなキーバリュー DB のルートハッシュを調べることから始めます。 これは、他のノードを指すキーの配列として表現されます。 インデックス`6`の値をキーとして使用し、フラットなキーバリュー DB で検索し、ノードを 1 レベル下げます。 次にインデックス`4`を選択して次の値を検索し、次にインデックス`6`を選択します。 `root -> 6 -> 4 -> 6 -> 15 -> 6 -> 7`のパスをたどり、ノードの値を参照して結果を返します。 +キーバリューセットに対する順序を永続化するために、基数ツリーのデータ構造を使用するとします。 ツリーで現在`dog`に対応する値を知るには、最初に`dog`のアルファベットの文字を変換します(`64 6f 67`)。次に、値が見つかるまで64 6f 67のパスをたどってツリーを下ります。 つまり、ツリーのルートノードを見つけるために、フラットなキーバリューDBのルートハッシュを調べることから始めます。 これは、他のノードを指すキーの配列として表現されます。 インデックス`6`の値をキーとして使用し、フラットなキーバリューDBで検索し、ノードを1レベル下げます。 次にインデックス`4`を選択して次の値を検索し、次にインデックス`6`を選択します。 `root -> 6 -> 4 -> 6 -> 15 -> 6 -> 7`のパスをたどり、ノードの値を参照して結果を返します。 -「ツリー」で何かを検索することと、下層のフラットなキーバリュー型「データベース」で検索することには、違いがあります。 どちらもキーバリューの配列を定義しますが、下層のデータベースは従来の 1 ステップのキー検索が実行できます。 ツリーでキーを検索するには、複数のデータベースを検索して上記の最終値を得る必要があります。 あいまいさをなくすために、後者を`path`としましょう。 +「ツリー」で何かを検索することと、下層のフラットなキーバリュー型「データベース」で検索することには、違いがあります。 どちらもキーバリューの配列を定義しますが、下層のデータベースは従来の1ステップのキー検索が実行できます。 ツリーでキーを検索するには、複数のデータベースを検索して上記の最終値を得る必要があります。 あいまいさをなくすために、後者を`path`としましょう。 基数ツリーの更新操作と削除操作は、次のように定義できます。 @@ -62,26 +62,26 @@ sidebarDepth: 2 return hash(newnode) ``` -「マークル」基数ツリーは、決定論的に生成された暗号ハッシュダイジェストを使用してノードをリンクすることによって構築されます。 このコンテンツアドレッシング(キーバリュー DB で `key == keccak256(rlp(value))`)は、格納されたデータの暗号認証を提供します。 特定のツリーのルートハッシュが公に知られている場合、特定の値をツリールートに結合する各ノードのハッシュ値を提供することにより、特定のパスに特定の値がツリーに含まれていることを証明できます。 +「マークル」基数ツリーは、決定論的に生成された暗号ハッシュダイジェストを使用してノードをリンクすることによって構築されます。 このコンテンツアドレッシング(キーバリューDBで`key == keccak256(rlp(value))`)は、格納されたデータの暗号完全性保証を提供します。 特定のツリーのルートハッシュが公に知られている場合、特定の値をツリールートに結合する各ノードのハッシュ値を提供することで、ツリーの内部にあるリーフデータにアクセスして、特定のパスに特定の値が存在していることを証明できます。 -攻撃者は、存在しない `(path, value)` のペアの証明を提供することは不可能です。これはルートハッシュは、結局のところその下のにあるすべてのハッシュ値に基づいているためです。 下層の変更はルートハッシュを変更します。 +攻撃者は、存在しない`(path, value)`のペアの証明を提供することは不可能です。これはルートハッシュは、結局のところその下のにあるすべてのハッシュ値に基づいているためです。 下層の変更はルートハッシュを変更します。 ハッシュについては、データの構造情報を圧縮して表現し、ハッシュ関数の事前イメージによって保護されていると考えることができます。 -基数ツリーの最小単位 (1 つの 16 進数文字、すなわち 4 ビットの 2 進数) を「ニブル」と呼びます。 上記のように一度に 1 つのニブルでパスを横断している間、ノードは最大で 16 の子を参照することができますが`value`要素を含んでいます。 このため、それらを長さのある配列として表します。 これらの 17 要素配列を「ブランチノード」と呼びます。 +基数ツリーの最小単位(1つの16 進数文字、すなわち4ビットの2進数)を「ニブル」と呼びます。 上記のように一度に1つのニブルでパスを横断している間、ノードは最大で16の子を参照することができますが`value`要素を含んでいます。 そのため、ノードは長さ17の配列として表されます。 これらの17要素配列を「ブランチノード」と呼びます。 ## マークル・パトリシア・ツリー {#merkle-patricia-trees} -基数ツリーには、1 つの大きな制限があります。それは、非効率的であることです。 イーサリアムのようにパスが 64 文字長 (`bytes32`単位のニブル数)の 1 つの`(path, value)`のバインディングを格納する場合、1 文字を格納する 1 レベルに、1 キロバイト以上のスペースが必要となり、また、それぞれの検索または削除には、64 ステップが必要です。 次に紹介するパトリシア・ツリーは、この問題を解決します。 +基数ツリーには、1つの大きな制限があります。それは、非効率的であることです。 イーサリアムのようにパスが64文字長 (`bytes32`単位のニブル数)の1つの`(path, value)`のバインディングを格納する場合、1文字を格納する1レベルに、1キロバイト以上のスペースが必要となり、また、それぞれの検索または削除には、64ステップが必要です。 次に紹介するパトリシア・ツリーは、この問題を解決します。 ### 最適化 {#optimization} マークル・パトリシア・ツリーのノードは、以下のいずれかです。 1. `NULL` (空文字列を表す) -2. `branch` 17 アイテムのノード `[ v0 ... v15, vt ]` -3. `leaf` 2 アイテムのノード `[ encodedPath, value ]` -4. `extension` 2 アイテムのノード `[ encodedPath, key ]` +2. `branch` 17アイテムのノード `[ v0 ... v15, vt ]` +3. `leaf` 2アイテムのノード `[ encodedPath, value ]` +4. `extension` 2アイテムのノード `[ encodedPath, key ]` -64 文字のパスでは、ツリーの最初のいくつかのレイヤーを横断した後、少なくとも下方の一部に分岐パスが存在しないノードに到達することは避けらません。 パスに沿って最大 15 の`NULL`のスパースノードを作成する必要性を回避するために、`[ encodedPath, key ]`フォームの`extension`ノードを設定することで下りへショートカットをします。この`encodedPath`は、次へスキップするための「部分パス」を含みます(後述のコンパクトエンコーディングを使用)。そして、`key` は、次の DB ルックアップ用です。 +64文字のパスでは、ツリーの最初のいくつかのレイヤーを横断した後、少なくとも下方の一部に分岐パスが存在しないノードに到達することは避けらません。 パスに沿って最大15の`NULL`のスパースノードを作成する必要性を回避するために、`[ encodedPath, key ]`フォームの`extension`ノードを設定することで下りへショートカットをします。この`encodedPath`は、次へスキップするための「部分パス」を含みます(後述のコンパクトエンコーディングを使用)。そして、`key` は、次のDBルックアップ用です。 `leaf`ノードは、`encodedPath`の最初のニブルのフラグでマークできます。パスは、前のノードのすべてのパスのフラグメントをエンコードし、`value`を直接調べることができます。 @@ -89,9 +89,9 @@ sidebarDepth: 2 パスをニブルで横断する場合、すべてのデータが`bytes`形式で格納されているため、ニブルの数が奇数になる場合があります。 例えば、ニブル`1`とニブル`01`を区別することはできません(両方とも`<01>`として格納される必要があります)。 奇数の長さを指定するには、部分パスの前にフラグをつけます。 -### 仕様: オプショナルターミネーターを使用した 16 進数シーケンスのコンパクトエンコーディング {#specification} +### 仕様: オプショナルターミネーターを使用した16進数シーケンスのコンパクトエンコーディング {#specification} -上記の*残りの部分パス長が偶数または奇数*かと、*リーフまたは拡張ノード*かを表すフラグは両方、あらゆる「2 アイテムのノード」の部分パスの最初のニブルにあります。 結果は、次の通りになります。 +上記の_残りの部分パス長が偶数または奇数_かと、_リーフまたは拡張ノード_かを表すフラグは両方、あらゆる「2アイテムのノード」の部分パスの最初のニブルにあります。 結果は、次の通りになります。 hex char bits | node type partial path length ---------------------------------------------------------- @@ -160,9 +160,9 @@ sidebarDepth: 2 ### ツリーの例 {#example-trie} -次の 4 つのパスバリューのペアを含むツリーが必要だとします。 `('do', 'verb')`、`('dog', 'puppy')`、`('doge', 'coin')`、`('horse', 'stallion')` +次の4つのパスバリューのペアを含むツリーが必要だとします。 `('do', 'verb')`、`('dog', 'puppy')`、`('doge', 'coin')`、`('horse', 'stallion')` -まず、パスと値(バリュー)の両方を`bytes`に変換します。 以下では、*paths*を実際のバイト表現 `<>`によって表示しています。しかし、 *values*は、分かりやすいように文字列として`''`で表示しています(実際は`bytes`) 。 +まず、パスと値(バリュー)の両方を`bytes`に変換します。 以下では、_paths_を実際のバイト表現 `<>`によって表示しています。しかし、 _values_は、分かりやすいように文字列として`''`で表示しています(実際は`bytes`) 。 ``` <64 6f> : 'verb' @@ -181,27 +181,27 @@ sidebarDepth: 2 hashE: [ <17>, [ <>, <>, <>, <>, <>, <>, [ <35>, 'coin' ], <>, <>, <>, <>, <>, <>, <>, <>, <>, 'puppy' ] ] ``` -1 つのノードが内部の別のノードから参照されるとき、含まれているのは、`H(rlp.encode(x))`であり、`H(x) = keccak256(x) if len(x) >= 32 else x`と`rlp.encode`は、[RLP](/developers/docs/data-structures-and-encoding/rlp)エンコーディング関数です。 +1つのノードが内部の別のノードから参照されるとき、含まれているのは、`H(rlp.encode(x))`であり、`H(x) = keccak256(x) if len(x) >= 32 else x`と`rlp.encode`は、[RLP](/developers/docs/data-structures-and-encoding/rlp)エンコーディング関数です。 -ツリーを更新するとき、新しく作成されたノードの長さが 32 以上の*場合*、キーバリューのペア`(keccak256(x), x)`を永続的なルックアップテーブルに格納する必要があることに注意してください。 ただし、ノードがそれよりも短い場合、関数 function f(x) = x は可逆であるため、何も格納する必要はありません。 +ツリーを更新するとき、新しく作成されたノードの長さが32以上の_場合_、キーバリューのペア`(keccak256(x), x)`を永続的なルックアップテーブルに格納する必要があることに注意してください。 ただし、ノードがそれよりも短い場合、関数 function f(x) = x は可逆であるため、何も格納する必要はありません。 ## イーサリアムのツリー {#tries-in-ethereum} イーサリアムの実行レイヤーのすべてのマークルツリーは、マークル・パトリシア・ツリーを使用しています。 -ブロックヘッダーに、これらのツリーの 3 つから、3 つのルートがあります。 +ブロックヘッダーに、これらのツリーの3つから、3つのルートがあります。 1. stateRoot (ステートルート) 2. transactionsRoot (トランザクションルート) 3. receiptsRoot (レシートルート) -### ステート(状態)ツリー {#state-trie} +### ステート(状態)ツリー {#state-trie} -グローバルの状態ツリーが 1 つあり、クライアントがブロックを処理するたびに更新されます。 その中では、 `path`は常に`keccak256(ethereumAddress)`であり、`value`は常に`rlp(ethereumAccount)`です。 より具体的には、イーサリアムの`account`は、4 つのアイテムの配列`[nonce,balance,storageRoot,codeHash]`です。 この点において、この`storageRoot`が、もう一つのパトリシア・ツリーであることは非常に重要です。 +グローバルの状態ツリーが1つあり、クライアントがブロックを処理するたびに更新されます。 その中では、 `path`は常に`keccak256(ethereumAddress)`であり、`value`は常に`rlp(ethereumAccount)`です。 より具体的には、イーサリアムの`account`は、4つのアイテムの配列`[nonce,balance,storageRoot,codeHash]`です。 この点において、この`storageRoot`が、もう一つのパトリシア・ツリーであることは非常に重要です。 ### ストレージツリー {#storage-trie} -ストレージツリーは、 *すべて*のコントラクトデータが存在する場所です。 アカウントごとに個別のストレージツリーがあります。 与えられたアドレスにある、特定のストレージポジションの値を取得するには、ストレージアドレスであるストレージに格納されたデータの整数のポジションと、ブロック ID が必要です。 これらは、JSON-RPC API で定義されている`eth_getStorageAt`に引数として渡すことができます。アドレス`0x295a70b2de5e3953354a6a8344e616ed314d7251`ストレージスロット 0 のデータを取得する例は、次のようになります。 +ストレージツリーは、 _すべて_のコントラクトデータが存在する場所です。 アカウントごとに個別のストレージツリーがあります。 与えられたアドレスにある、特定のストレージポジションの値を取得するには、ストレージアドレスであるストレージに格納されたデータの整数のポジションと、ブロックIDが必要です。 これらは、JSON-RPC APIで定義されている`eth_getStorageAt`に引数として渡すことができます。アドレス`0x295a70b2de5e3953354a6a8344e616ed314d7251`ストレージスロット0のデータを取得する例は、次のようになります。 ``` curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"], "id": 1}' localhost:8545 @@ -210,13 +210,13 @@ curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": [ ``` -ストレージの他の要素を取得するのは、ストレージツリーのポジションを最初に計算する必要があるため、より複雑になります。 ポジションは、アドレスとストレージポジションの`keccak256`ハッシュとして計算され、両方とも長さ 32 バイト長になるように左からゼロが足されます。 例えば、アドレス `0x391694e7e0b0cce554cb130d723a9d27458f9298`のストレージスロット 1 のデータの位置は、次のようになります。 +ストレージの他の要素を取得するのは、ストレージツリーのポジションを最初に計算する必要があるため、より複雑になります。 ポジションは、アドレスとストレージポジションの`keccak256`ハッシュとして計算され、両方とも長さ32バイト長になるように左からゼロが足されます。 例えば、アドレス `0x391694e7e0b0cce554cb130d723a9d27458f9298`のストレージスロット1のデータの位置は、次のようになります。 ``` keccak256(decodeHex("000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001")) ``` -Geth コンソールでは、これは次のように計算できます。 +Gethコンソールでは、これは次のように計算できます。 ``` > var key = "000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001" @@ -233,6 +233,8 @@ curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": [ {"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000162e"} ``` +注: イーサリアムアカウントの`storageRoot`は、コントラクトアカウントでなければ、デフォルトで空になります。 + ### トランザクションツリー {#transaction-trie} ブロックごとに個別のトランザクションツリーがあり、ここでも`(key, value)`ペアが格納されます。 パスは、ここでは`rlp(transactionIndex)`で、以下によって決定される値に対応するキーを表します。 @@ -248,7 +250,7 @@ else: ### レシートツリー {#receipts-trie} -すべてのブロックは、それぞれのレシートツリーを持っています。 ここでの`path`は、`rlp(transactionIndex)`です。 `transactionIndex`は、マイニングされたブロックのインデックスです。 レシートツリーは更新されることはありません。 トランザクションと同様に、現在のレシートとレガシーのレシートがあります。 レシートツリーで特定のレシートをクエリーするには、ブロックのトランザクションのインデックス、レシートのペイロード、トランザクションタイプが必要となります。 返されるレシートは、`transaction type`と`transaction payload`の集まったものとして定義される`Receipt`タイプまたは、`rlp([status, cumulativeGasUsed, logsBloom, logs])`として定義される`LegacyReceipt`タイプとなります。 +すべてのブロックは、それぞれのレシートツリーを持っています。 ここでの`path`は、`rlp(transactionIndex)`です。 `transactionIndex`は、マイニングされたブロックのインデックスです。 レシートツリーは更新されることはありません。 トランザクションと同様に、現在のレシートとレガシーのレシートがあります。 レシートツリーで特定のレシートをクエリーするには、ブロックのトランザクションのインデックス、レシートのペイロード、トランザクションタイプが必要となります。 返されるレシートは、`TransactionType`と`ReceiptPayload`の集まったものとして定義される`Receipt`タイプまたは、`rlp([status, cumulativeGasUsed, logsBloom, logs])`として定義される`LegacyReceipt`タイプとなります。 詳細については、[EIP 2718](https://eips.ethereum.org/EIPS/eip-2718)のドキュメントを参照してください。 diff --git a/public/content/translations/ja/developers/docs/data-structures-and-encoding/rlp/index.md b/public/content/translations/ja/developers/docs/data-structures-and-encoding/rlp/index.md index 76f5161320f..3f8c550c4b7 100644 --- a/public/content/translations/ja/developers/docs/data-structures-and-encoding/rlp/index.md +++ b/public/content/translations/ja/developers/docs/data-structures-and-encoding/rlp/index.md @@ -5,18 +5,18 @@ lang: ja sidebarDepth: 2 --- -再帰的な長さのプレフィックス(RLP)シリアライゼーションは、イーサリアムの実行クライアントで広く使われています。 RLP はスペース効率に優れたフォーマットで、ノード間のデータ転送を標準化します。 RLP の目的は、任意のネストされたバイナリデータの配列をエンコード(符号化)することです。また、RLP はイーサリアムの実行レイヤーのオブジェクトのシリアライズに用いられる主要なエンコーディング方式です。 RLP の唯一の目的は、構造をエンコードすることです。特定のデータ型(例: 文字列型、浮動小数点型など)のエンコーディングは、上位のプロトコルが行いますが、正の RLP 整数は、先頭にゼロのないビッグエンディアン・バイナリ形式で表されます(そのため、整数値ゼロは空のバイト配列となります) 。 先頭がゼロのデシリアル化された正の整数は、無効として扱われます。 文字列長の整数表現は、ペイロード内の整数と同様にこの方法でエンコードする必要があります。 +再帰的な長さのプレフィックス(RLP)シリアライゼーションは、イーサリアムの実行クライアントで広く使われています。 RLPはスペース効率に優れたフォーマットで、ノード間のデータ転送を標準化します。 RLPの目的は、任意のネストされたバイナリデータの配列をエンコード(符号化)することです。また、RLPはイーサリアムの実行レイヤーのオブジェクトのシリアライズに用いられる主要なエンコーディング方式です。 RLPの唯一の目的は、構造をエンコードすることです。特定のデータ型(例: 文字列型、浮動小数点型など)のエンコーディングは、上位のプロトコルが行いますが、正のRLP整数は、先頭にゼロのないビッグエンディアン・バイナリ形式で表されます(そのため、整数値ゼロは空のバイト配列となります) 。 先頭がゼロのデシリアル化された正の整数は、無効として扱われます。 文字列長の整数表現は、ペイロード内の整数と同様にこの方法でエンコードする必要があります。 -詳細については、[イーサリアムイエローペーパー (付録 B)](https://ethereum.github.io/yellowpaper/paper.pdf#page=19)を参照してください。 +詳細については、[イーサリアムイエローペーパー (付録B)](https://ethereum.github.io/yellowpaper/paper.pdf#page=19)を参照してください。 -RLP を使用して辞書をエンコードするのに、次の 2 つの正規の方法があります。 +RLPを使用して辞書をエンコードするのに、次の2つの正規の方法があります。 - `[[k1,v1],[k2,v2]...]`のように辞書順にキーを並べて使用する - イーサリアムのように上位レベルのパトリシア・ツリー・エンコーディングを使用する ## 定義 {#definition} -RLP エンコーディング関数は、アイテムを取ります。 アイテムは次のように定義されます。 +RLPエンコーディング関数は、アイテムを取ります。 アイテムは次のように定義されます。 - 文字列型(すなわちバイト配列) はアイテム - アイテムのリストはアイテム @@ -30,58 +30,58 @@ RLP エンコーディング関数は、アイテムを取ります。 アイテ 本ページのこれ以降では、「文字列」は「あるバイト数のバイナリデータ」を意味することに注意してください。特別なエンコーディングは使用されておらず、文字列が何を指すのかの知識は必要ありません。 -RLP エンコーディングは以下のように定義されます。 +RLPエンコーディングは以下のように定義されます。 -- `[0x00, 0x7f]`(10 進数`[0, 127]`)の範囲にある 1 バイトは、そのバイト自体が RLP エンコーディングとなる。 -- その他、文字列が 0 ~ 55 バイトの場合、RLP エンコーディングは値が**0x80**(10 進数 128)に、文字列の長さを足した 1 バイト、続いて文字列で構成される。 したがって、最初の 1 バイトの範囲は`[0x80, 0xb7]`(10 進数`[128, 183]`)となる。 -- 文字列の長さが 55 バイトを超える場合、RLP エンコーディングは、**0xb7**(10 進数 183)にバイナリ形式の文字列長をバイト数を加えた 1 バイト、続けて文字列の長さ、次に文字列で構成される。 例えば、1024 バイトの長さの文字列は、`\xb9\x04\x00` (10 進数`185, 4, 0`)にエンコードされ、その後文字列となる。 ここでは、最初の 1 バイトとして`0xb9` (183 + 2 = 185)、次に実際の文字列の長さを示す 2 バイトの`0x0400` (10 進数 1024)が続く。 したがって、最初の 1 バイトの範囲は、`[0xb8, 0xbf]` (10 進数`[184, 191]`)となる。 -- リストの全ペイロード(RLP エンコードされるすべてのアイテムを合わせた長さ)が、0 ~ 55 バイトである場合、RLP エンコーディングは、**0xc0**にリストの長さを加えた 1 バイト、続けてアイテムを RLP エンコーディングして続けたもので構成される。 したがって、最初のバイトの範囲は`[0xc0, 0xf7]` (10 進数`[192, 247]`)となる。 -- リストの全ペイロードが、55 バイトを超える場合、RLP エンコーディングは、**0xf7**にバイナリ形式のペイロードの長さのバイト数を加えた 1 バイト、次にペイロードの長さ、アイテムの RLP エンコーディングしたものを続けたもので構成される。 したがって、最初のバイトの範囲は、`[0xf8, 0xff]` (10 進数`[248, 255]`)となる 。 +- `[0x00, 0x7f]`(10進数`[0, 127]`)の範囲にある1バイトは、そのバイト自体がRLPエンコーディングとなる。 +- その他、文字列が0~55バイトの場合、RLPエンコーディングは値が**0x80**(10進数128)に、文字列の長さを足した1バイト、続いて文字列で構成される。 したがって、最初の1バイトの範囲は`[0x80, 0xb7]`(10進数`[128, 183]`)となる。 +- 文字列の長さが55バイトを超える場合、RLPエンコーディングは、**0xb7**(10進数 183)にバイナリ形式の文字列長をバイト数を加えた1バイト、続けて文字列の長さ、次に文字列で構成される。 例えば、1024バイトの長さの文字列は、`\xb9\x04\x00` (10進数`185, 4, 0`)にエンコードされ、その後文字列となる。 ここでは、最初の1バイトとして`0xb9` (183 + 2 = 185)、次に実際の文字列の長さを示す2バイトの`0x0400` (10進数1024)が続く。 したがって、最初の1バイトの範囲は、`[0xb8, 0xbf]` (10進数`[184, 191]`)となる。 +- リストの全ペイロード(例えば、RLPエンコードされるすべてのアイテムを合わせた長さ)が0~55バイトである場合、RLPエンコーディングは、**0xc0**にペイロードの長さを加えた1バイト、続けてアイテムをRLPエンコーディングして続けたもので構成される。 したがって、最初のバイトの範囲は`[0xc0, 0xf7]` (10進数`[192, 247]`)となる。 +- リストの全ペイロードが、55バイトを超える場合、RLPエンコーディングは、**0xf7**にバイナリ形式のペイロードの長さのバイト数を加えた1バイト、次にペイロードの長さ、アイテムのRLPエンコーディングしたものを続けたもので構成される。 したがって、最初のバイトの範囲は、`[0xf8, 0xff]` (10進数`[248, 255]`)となる 。 コードでは、これは次のようになります。 ```python def rlp_encode(input): if isinstance(input,str): - if len(input) == 1 and ord(input) < 0x80: return input - else: return encode_length(len(input), 0x80) + input - elif isinstance(input,list): + if len(input) == 1 and ord(input) < 0x80: + return input + return encode_length(len(input), 0x80) + input + elif isinstance(input, list): output = '' - for item in input: output += rlp_encode(item) + for item in input: + output += rlp_encode(item) return encode_length(len(output), 0xc0) + output -def encode_length(L,offset): +def encode_length(L, offset): if L < 56: return chr(L + offset) elif L < 256**8: BL = to_binary(L) return chr(len(BL) + offset + 55) + BL - else: - raise Exception("input too long") + raise Exception("input too long") def to_binary(x): if x == 0: return '' - else: - return to_binary(int(x / 256)) + chr(x % 256) + return to_binary(int(x / 256)) + chr(x % 256) ``` ## いくつかの例 {#examples} - 文字列「dog」= [ 0x83, 'd', 'o', 'g' ] -- リスト [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` +- リスト [ "cat", "dog" ] = `[ 0xc8, 0x83, 'c', 'a', 't', 0x83, 'd', 'o', 'g' ]` - 空文字列 ('null') = `[ 0x80 ]` - 空リスト = `[ 0xc0 ]` -- 整数 0 = `[ 0x80 ]` -- 整数 0 ('\\x00')のエンコード = `[ 0x00 ]` -- 整数 15 ('\\x0f')エンコード = `[ 0x0f ]` -- 整数 1024 ('\\x04\\x00')のエンコード = `[ 0x82, 0x04, 0x00 ]` -- 3 の[集合論的表現](http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` +- 整数0 = `[ 0x80 ]` +- 整数0 ('\\x00')のエンコード = `[ 0x00 ]` +- 整数15 ('\\x0f')エンコード = `[ 0x0f ]` +- 整数1024 ('\\x04\\x00')のエンコード = `[ 0x82, 0x04, 0x00 ]` +- 3の[集合論的表現](http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0 ]` - 文字列「Lorem ipsum dolor sit amet, consectetur adipisicing elit」= `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` -## RLP デコードディング {#rlp-decoding} +## RLPデコーディング {#rlp-decoding} -RLP エンコーディング規則とプロセスに従って、RLP デコードの入力は、バイナリデータ配列とみなされます。 RLP のデコーディングプロセスは、次のようになります。 +RLPエンコーディング規則とプロセスに従って、RLPデコードの入力は、バイナリデータ配列とみなされます。 RLPのデコーディングプロセスは、次のようになります。 1. 入力データの最初のバイト(プレフィックス) とデコーディングするデータ型に従った実際のデータ長とオフセット @@ -91,15 +91,15 @@ RLP エンコーディング規則とプロセスに従って、RLP デコード その中で、データ型とオフセットのデコード規則は次のようになります。 -1. 最初の 1 バイト(プレフィックス)の範囲が [0x00, 0x7f]の場合は、データは文字列型で、文字列はそのバイトそのもの。 +1. 最初の1バイト(プレフィックス)の範囲が [0x00, 0x7f]の場合は、データは文字列型で、文字列はそのバイトそのもの。 -2. 最初の 1 バイトの範囲が[0x80, 0xb7]の場合、データは文字列型。最初の 1 バイト、続いて最初の 1 バイトから 0x80 を引いた長さの文字列となる。 +2. 最初の1バイトの範囲が[0x80, 0xb7]の場合、データは文字列型。最初の1バイト、続いて最初の1バイトから 0x80 を引いた長さの文字列となる。 -3. 最初の 1 バイトの範囲が[0xb8, 0xbf]の場合は、データは文字列型。最初の 1 バイト、続いて最初の 1 バイトから 0xb7 を引いた文字列長(バイトで表す)、最後に文字列となる。 +3. 最初の1バイトの範囲が[0xb8, 0xbf]の場合は、データは文字列型。最初の1バイト、続いて最初の1バイトから0xb7を引いた文字列長(バイトで表す)、最後に文字列となる。 -4. 最初の 1 バイトの範囲が[0xc0, 0xf7]の場合は、データはリスト型。最初の 1 バイト、続いて全ペイロードが最初のバイトから 0xc0 を引いたものに等しい、リストの全アイテムを RLP エンコーディングして続けたものとなる。 +4. 最初の1バイトの範囲が[0xc0, 0xf7]の場合は、データはリスト型。最初の1バイト、続いて全ペイロードが最初のバイトから0xc0を引いたものに等しい、リストの全アイテムをRLPエンコーディングして続けたものとなる。 -5. 最初の 1 バイトの範囲が[0xf8, 0xff]の場合は、データはリスト型。最初の 1 バイト、続いてリストの長さが最初の 1 バイトから 0xf7 を引いたリストの全ペイロード、最後にリストのすべてのアイテムを RLP エンコーディングして続けたものとなる。 +5. 最初の1バイトの範囲が[0xf8, 0xff]の場合は、データはリスト型。最初の1バイト、続いてリストの長さが最初の1バイトから0xf7を引いたリストの全ペイロード、最後にリストのすべてのアイテムをRLPエンコーディングして続けたものとなる。 コードでは、これは次のようになります。 @@ -113,7 +113,7 @@ def rlp_decode(input): output = instantiate_str(substr(input, offset, dataLen)) elif type is list: output = instantiate_list(substr(input, offset, dataLen)) - output + rlp_decode(substr(input, offset + dataLen)) + output += rlp_decode(substr(input, offset + dataLen)) return output def decode_length(input): @@ -137,8 +137,7 @@ def decode_length(input): lenOfListLen = prefix - 0xf7 listLen = to_integer(substr(input, 1, lenOfListLen)) return (1 + lenOfListLen, listLen, list) - else: - raise Exception("input does not conform to RLP encoding form") + raise Exception("input does not conform to RLP encoding form") def to_integer(b): length = len(b) @@ -146,15 +145,14 @@ def to_integer(b): raise Exception("input is null") elif length == 1: return ord(b[0]) - else: - return ord(substr(b, -1)) + to_integer(substr(b, 0, -1)) * 256 + return ord(substr(b, -1)) + to_integer(substr(b, 0, -1)) * 256 ``` ## 参考文献 {#further-reading} -- [イーサリアムの RLP](https://medium.com/coinmonks/data-structure-in-ethereum-episode-1-recursive-length-prefix-rlp-encoding-decoding-d1016832f919) +- [イーサリアムのRLP](https://medium.com/coinmonks/data-structure-in-ethereum-episode-1-recursive-length-prefix-rlp-encoding-decoding-d1016832f919) - [イーサリアムの内部: RLP](https://medium.com/coinmonks/ethereum-under-the-hood-part-3-rlp-decoding-df236dc13e58) -- [Coglio, A. (2020). ACL2 のイーサリアムの再帰的な長さのプレフィックス arXiv preprint arXiv:2009.13769.](https://arxiv.org/abs/2009.13769) +- [Coglio, A. (2020). ACL2のイーサリアムの再帰的な長さのプレフィックス arXiv preprint arXiv:2009.13769.](https://arxiv.org/abs/2009.13769) ## 関連トピック {#related-topics} diff --git a/public/content/translations/ja/developers/docs/data-structures-and-encoding/ssz/index.md b/public/content/translations/ja/developers/docs/data-structures-and-encoding/ssz/index.md index 530622ae987..78f09c33af8 100644 --- a/public/content/translations/ja/developers/docs/data-structures-and-encoding/ssz/index.md +++ b/public/content/translations/ja/developers/docs/data-structures-and-encoding/ssz/index.md @@ -5,13 +5,13 @@ lang: ja sidebarDepth: 2 --- -**シンプル・シリアライゼーション(SSZ)**とは、ビーコンチェーンで使用されているシリアライゼーション方法です。 これは、ピア検出プロトコルを除くコンセンサスレイヤー全体の実行レイヤーで使われた RLP シリアライゼーションに取って代わるものです。 SSZ は決定的であり、効率的にマークル化するように設計されています。 SSZ には、次の 2 つのコンポーネントがあると見なすことができます。シリアライゼーション・スキームと、シリアル化されたデータ構造を効率的に処理するように設計されたマークライゼーション・スキームです。 +**シンプル・シリアライゼーション(SSZ)**とは、ビーコンチェーンで使用されているシリアライゼーション方法です。 これは、ピア検出プロトコルを除くコンセンサスレイヤー全体の実行レイヤーで使われたRLPシリアライゼーションに取って代わるものです。 SSZは決定的であり、効率的にマークル化するように設計されています。 SSZには、次の2つのコンポーネントがあると見なすことができます。シリアライゼーション・スキームと、シリアル化されたデータ構造を効率的に処理するように設計されたマークライゼーション・スキームです。 ## シンプル・シリアライゼーション(SSZ) {#how-does-ssz-work} ### シリアライゼーション {#serialization} -シンプル・シリアライゼーション(SSZ)は自己記述型ではなく、むしろ事前に知らされているスキーマに依存するシリアライゼーション・スキームです。 SSZ シリアル化の目的は、任意の複雑なオブジェクトをバイト列で表すことです。 「基本型」の場合は、非常に簡単な処理です。 エレメントは、単に 16 進数のバイトに変換されます。 基本型には、次のものがあります。 +シンプル・シリアライゼーション(SSZ)は自己記述型ではなく、むしろ事前に知らされているスキーマに依存するシリアライゼーション・スキームです。 SSZシリアル化の目的は、任意の複雑なオブジェクトをバイト列で表すことです。 「基本型」の場合は、非常に簡単な処理です。 エレメントは、単に16進数のバイトに変換されます。 基本型には、次のものがあります。 - 符号なし整数型 - ブール型 @@ -44,7 +44,7 @@ sidebarDepth: 2 ``` -`serialized`は、次のような構造になります。 ここでは、4 ビットにしていますが、実際は 32 ビットに付け足されます。また、分かりやすくするために `int`(整数型)で表しています。 +`serialized`は、次のような構造になります。 ここでは、4ビットにしていますが、実際は32ビットに付け足されます。また、分かりやすくするために `int`(整数型)で表しています。 ``` [37, 0, 0, 0, 55, 0, 0, 0, 16, 0, 0, 0, 22, 0, 0, 0, 1, 2, 3, 4] @@ -81,17 +81,17 @@ sidebarDepth: 2 可変長型の実際の値は、シリアル化されたオブジェクトの末尾にあるヒープに格納され、オフセット値はフィールドの順序付けられたリストの正しい位置に格納されます。 -また、特別な対応が必要となる特殊ケースもあります。例えば、`BitList`型のように、シリアル化時に長さの上限を追加し、デシリアル化時に削除する必要があるような型です。 詳細については、[SSZ の仕様](https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md)を参照してください。 +また、特別な対応が必要となる特殊ケースもあります。例えば、`BitList`型のように、シリアル化時に長さの上限を追加し、デシリアル化時に削除する必要があるような型です。 詳細については、[SSZの仕様](https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md)を参照してください。 ### デシリアライゼーション {#deserialization} このオブジェクトをデシリアライズするには、スキーマが必要になります。 スキーマに、シリアル化されたデータの正確なレイアウトを定義することで、特定の各要素をバイトのブロブ(blob)から適切な型、値、サイズ、位置を持つ意味のあるオブジェクトにデシリアル化できるようにします。 どれがオフセット値でどれが実際の値であるか伝えるのは、デシリアライザーです。 全フィールド名は、オブジェクトがシリアル化されたときに消えますが、スキーマによりデシリアライゼーション時に再インスタンス化されます。 -SSZ に関するインタラクティブな説明については、[ssz.dev](https://www.ssz.dev/overview)を参照してください。 +SSZに関するインタラクティブな説明については、[ssz.dev](https://www.ssz.dev/overview)を参照してください。 ## マークライゼーション(Merkleization) {#merkleization} -この SSZ でシリアル化されたオブジェクトは、次にマークル化でき、つまり同データをマークルツリー表現に変換できます。 最初に、シリアル化されたオブジェクトの 32 バイトのチャンク数が決定されます。 これらは、ツリー (木) の「リーフ (葉) 」です。 リーフの合計数が、2 の冪乗でなければなりません。これにより、リーフをまとめてハッシュ化すると、最終的に単一のハッシュ・ツリー・ルートが生成されます。 2 の冪乗にならない場合は、32 バイトのゼロを持つリーフが追加されます。 図式化すると次のようになります。 +このSSZでシリアル化されたオブジェクトは、次にマークル化でき、つまり同データをマークルツリー表現に変換できます。 最初に、シリアル化されたオブジェクトの32バイトのチャンク数が決定されます。 これらは、ツリー (木) の「リーフ (葉) 」です。 リーフの合計数が、2の冪乗でなければなりません。これにより、リーフをまとめてハッシュ化すると、最終的に単一のハッシュ・ツリー・ルートが生成されます。 2の冪乗にならない場合は、32バイトのゼロを持つリーフが追加されます。 図式化すると次のようになります。 ``` hash tree root @@ -107,9 +107,9 @@ SSZ に関するインタラクティブな説明については、[ssz.dev](htt leaf1 leaf2 leaf3 leaf4 ``` -また、上の例のように自然にツリーのリーフが均等とならない場合があります。 例えば、リーフ 4 (leaf4)が複数の要素を持ちマークルツリーに「深さ」を追加する必要があるコンテナだとすると、不均一なツリーになる場合があります。 +また、上の例のように自然にツリーのリーフが均等とならない場合があります。 例えば、リーフ4 (leaf4)が複数の要素を持ちマークルツリーに「深さ」を追加する必要があるコンテナだとすると、不均一なツリーになる場合があります。 -これらのツリーの要素をリーフ X (leaf X)やノード X (node X)などと呼ぶ代わりに、ルートを 1 (root=1) として開始し、左から右へ各レベルごとにカウントする一般化インデックスを付与することができます。 先で述べたインデックスが、この一般化インデックスです。 シリアル化されたリストの各要素は、`2**depth + idx`に等しい一般化インデックスを持ちます。ここで、idx は、シリアル化されたオブジェクトのゼロインデックスの位置です。深さはマークルツリーのレベル数で、要素 (リーフ) の数の平方根として決定することができます。 +これらのツリーの要素をリーフX(leaf X)やノードX(node X)などと呼ぶ代わりに、ルートを1(root=1)として開始し、左から右へ各レベルごとにカウントする一般化インデックスを付与することができます。 先で述べたインデックスが、この一般化インデックスです。 シリアル化されたリストの各要素は、`2**depth + idx`に等しい一般化インデックスを持ちます。ここで、idxは、シリアル化されたオブジェクトのゼロインデックスの位置です。深さはマークルツリーのレベル数で、要素(リーフ)の数である2を底とする対数として決定することができます。 ## 一般化インデックス {#generalized-indices} @@ -128,7 +128,7 @@ SSZ に関するインタラクティブな説明については、[ssz.dev](htt 特定の要素を表す一般化インデックスのリストを提供することで、ハッシュ・ツリー・ルートに対して検証することができます。 このルートは、受け入れられた真実のバージョンです。 提供されたすべてのデータは、(一般化インデックスによって決定された)マークルツリー内の適切な場所に挿入し、ルートが一定のままであることを確認することで、真実性に対して検証することができます。 [こちら](https://github.com/ethereum/consensus-specs/blob/dev/ssz/merkle-proofs.md#merkle-multiproofs)の仕様書に、一般化インデックスの特定のセットの内容を検証するために必要なノードの最小セットを計算する方法として、関数が示されています。 -例えば、下記のツリーのインデックス 9 のデータを検証する場合、インデックス 8、9、5、3、1 のデータのハッシュが必要です。 (8,9)のハッシュは、(4)のハッシュと等しい必要があり、これは 5 とハッシュして 2 を生成し、3 とハッシュしてツリールート 1 を生成します。 もし、9 に誤ったデータが提供された場合、ルートが変更されることになります。これを検知し、ブランチの検証が失敗します。 +例えば、下記のツリーのインデックス9のデータを検証する場合、インデックス8、9、5、3、1のデータのハッシュが必要です。 (8,9)のハッシュは、(4)のハッシュと等しい必要があり、これは5とハッシュして2を生成し、3とハッシュしてツリールート1を生成します。 もし、9に誤ったデータが提供された場合、ルートが変更されることになります。これを検知し、ブランチの検証が失敗します。 ``` * = data required to generate proof @@ -144,6 +144,6 @@ SSZ に関するインタラクティブな説明については、[ssz.dev](htt - [イーサリアムのアップグレード: SSZ](https://eth2book.info/altair/part2/building_blocks/ssz) - [イーサリアムのアップグレード: マークライゼーション](https://eth2book.info/altair/part2/building_blocks/merkleization) -- [SSZ の実装](https://github.com/ethereum/consensus-specs/issues/2138) -- [SSZ 計算器](https://simpleserialize.com/) +- [SSZの実装](https://github.com/ethereum/consensus-specs/issues/2138) +- [SSZ計算器](https://simpleserialize.com/) - [SSZ.dev](https://www.ssz.dev/) diff --git a/public/content/translations/ja/developers/docs/data-structures-and-encoding/web3-secret-storage-definition/index.md b/public/content/translations/ja/developers/docs/data-structures-and-encoding/web3-secret-storage-definition/index.md index 790f13cd823..d96a9f05263 100644 --- a/public/content/translations/ja/developers/docs/data-structures-and-encoding/web3-secret-storage-definition/index.md +++ b/public/content/translations/ja/developers/docs/data-structures-and-encoding/web3-secret-storage-definition/index.md @@ -5,7 +5,7 @@ lang: ja sidebarDepth: 2 --- -アプリをイーサリアムで動作させるために、web3.js ライブラリが提供する Web3 オブジェクトを使用できます。 これは、内部で RPC 呼び出しを介してローカルノードと通信します。 [Web3](https://github.com/ethereum/web3.js/)は、RPC レイヤーを公開しているイーサリアムノードと連携します。 +アプリをイーサリアムで動作させるために、web3.jsライブラリが提供するWeb3オブジェクトを使用できます。 これは、内部でRPC呼び出しを介してローカルノードと通信します。 [Web3](https://github.com/ethereum/web3.js/)は、RPCレイヤーを公開しているイーサリアムノードと連携します。 `web3`には、`eth`オブジェクト「web3.eth」が含まれています。 @@ -25,28 +25,28 @@ fs.readFile("keyfile.json", (err, data) => { */ ``` -このドキュメントは、**バージョン 3**の Web3 シークレットストレージの定義です。 +このドキュメントは、**バージョン3**のWeb3シークレットストレージの定義です。 ## 定義 {#definition} -ファイルのエンコードとデコードは、暗号化アルゴリズムが AES-128-CBC に固定されなくなったことを除いて(AES-128-CTR が最小要件になりました)、実際にはバージョン 1 からほとんど変更されていません 。 ほとんどの意味またはアルゴリズムは、バージョン 1 と似ていますが、`mac`を除きます。これは、完全な`ciphertext`と共に導出鍵の左から 2 番目の 16 バイトを連結した SHA3 (keccak-256) として指定されます。 +ファイルのエンコードとデコードは、暗号化アルゴリズムがAES-128-CBCに固定されなくなったことを除いて(AES-128-CTR が最小要件になりました)、実際にはバージョン1からほとんど変更されていません 。 ほとんどの意味またはアルゴリズムは、バージョン1と似ていますが、`mac`を除きます。これは、完全な`ciphertext`と共に導出鍵の左から2番目の16バイトを連結したSHA3 (keccak-256) として指定されます。 -秘密鍵ファイルは、`~/.web3/keystore` (Unix のようなシステム環境)と `~/AppData/Web3/keystore` (Windows 環境)に直接保存されます。 任意の名前を付けることができますが、適切な規則としては`.json`とすることが望ましいです。ここで、``は、秘密鍵(秘密鍵のアドレスのプライバシーを保護するプロキシ)に付与された 128 ビットの UUID です。 +秘密鍵ファイルは、`~/.web3/keystore` (Unixのようなシステム環境)と `~/AppData/Web3/keystore` (Windows環境)に直接保存されます。 任意の名前を付けることができますが、適切な規則としては`.json`とすることが望ましいです。ここで、``は、秘密鍵(秘密鍵のアドレスのプライバシーを保護するプロキシ)に付与された128ビットのUUIDです。 -これらのファイルはすべて、関連付けられたパスワードを持っています。 ある`.json`ファイルの秘密鍵を導出するには、まずファイルの暗号化鍵を導出します。これはファイルのパスワードを取得し、それを`kdf`鍵で記述された鍵導出関数に渡すことによって行われます。 KDF 関数への KDF 依存の静的パラメータおよび動的パラメータは、`kdfparams`鍵に記述されています。 +これらのファイルはすべて、関連付けられたパスワードを持っています。 ある`.json`ファイルの秘密鍵を導出するには、まずファイルの暗号化鍵を導出します。これはファイルのパスワードを取得し、それを`kdf`鍵で記述された鍵導出関数に渡すことによって行われます。 KDF関数へのKDF依存の静的パラメータおよび動的パラメータは、`kdfparams`鍵に記述されています。 -次に示される PBKDF2 は、最小限に準拠したすべての実装でサポートされている必要があります。 +次に示されるPBKDF2は、最小限に準拠したすべての実装でサポートされている必要があります。 - `kdf`: `pbkdf2` -PBKDF2 の場合、kdfparams は次を含みます。 +PBKDF2の場合、kdfparamsは次を含みます。 - `prf`: `hmac-sha256`でなければならない(将来的には拡張される場合ががある) - `c`: 反復回数 -- `salt`: PBKDF に渡されるソルト -- `dklen`: 導出鍵の長さ (32 以上でなければならない) +- `salt`: PBKDFに渡されるソルト +- `dklen`: 導出鍵の長さ (32以上でなければならない) -ファイルの鍵が導出されたら、MAC の導出によってそれを検証する必要があります。 MAC は、`ciphertext`鍵の内容を持つ導出鍵の左から 2 番目の 16 バイトの連結として形成されたバイト配列の SHA3 (keccak-256) ハッシュとして計算されるべきです。 すなわち次のようになります。 +ファイルの鍵が導出されたら、MACの導出によってそれを検証する必要があります。 MACは、`ciphertext`鍵の内容を持つ導出鍵の左から2番目の16バイトの連結として形成されたバイト配列のSHA3 (keccak-256) ハッシュとして計算されるべきです。 すなわち次のようになります。 ```js KECCAK(DK[16..31] ++ ) @@ -58,15 +58,15 @@ KECCAK(DK[16..31] ++ ) ファイルの鍵が検証された後、暗号テキスト(ファイル内の `ciphertext`鍵)は、`cipher`キーで指定された対称暗号アルゴリズムを使用して復号化され、`cipherparams`鍵によってパラメータ化されます。 導出鍵のサイズとアルゴリズムの鍵のサイズが一致しない場合、ゼロが付け足され、導出鍵の右端のバイトをアルゴリズムのキーとして使用する必要があります。 -最小限の準拠をしたすべての実装は、次に示される AES-128-CTR アルゴリズムをサポートする必要があります。 +最小限の準拠をしたすべての実装は、次に示されるAES-128-CTRアルゴリズムをサポートする必要があります。 - `cipher: aes-128-ctr` -この暗号は、cipherparams 鍵への鍵として与えられる次のパラメーターを取ります。 +この暗号は、cipherparams鍵への鍵として与えられる次のパラメーターを取ります。 -- `iv`: 暗号の 128 ビット初期化ベクトル。 +- `iv`: 暗号の128ビット初期化ベクトル。 -暗号鍵は、導出鍵の左端の 16 バイト、つまり`DK[0..15]`です。 +暗号鍵は、導出鍵の左端の16バイト、つまり`DK[0..15]`です。 秘密鍵の作成/暗号化は、本質的にはこれらの命令の逆であるべきです。 `uuid`、`salt`、`iv`が実際にランダムであることを確認してください。 @@ -116,25 +116,25 @@ KECCAK(DK[16..31] ++ ) ### スクリプト {#scrypt} -AES-128-CTR とスクリプトを使用したテストベクトル +AES-128-CTRとスクリプトを使用したテストベクトル ```json { "crypto": { "cipher": "aes-128-ctr", "cipherparams": { - "iv": "83dbcc02d8ccb40e466191a123791e0e" + "iv": "740770fce12ce862af21264dab25f1da" }, - "ciphertext": "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", + "ciphertext": "dd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2", "kdf": "scrypt", "kdfparams": { "dklen": 32, "n": 262144, - "p": 8, - "r": 1, - "salt": "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" + "p": 1, + "r": 8, + "salt": "25710c2ccd7c610b24d068af83b959b7a0e5f40641f0c82daeb1345766191034" }, - "mac": "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" + "mac": "337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c" }, "id": "3198bc9c-6672-5ab3-d995-4942343ae5b6", "version": 3 @@ -143,16 +143,16 @@ AES-128-CTR とスクリプトを使用したテストベクトル **中間体**: -`Derived key`: `fac192ceb5fd772906bea3e118a69e8bbb5cc24229e20d8766fd298291bba6bd` `MAC Body`: `bb5cc24229e20d8766fd298291bba6bdd172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c` `MAC`: `2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097` `Cipher key`: `fac192ceb5fd772906bea3e118a69e8b` +`Derived key`: `7446f59ecc301d2d79bc3302650d8a5cedc185ccbb4bf3ca1ebd2c163eaa6c2d` `MAC Body`: `edc185ccbb4bf3ca1ebd2c163eaa6c2ddd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2` `MAC`: `337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c` `Cipher key`: `7446f59ecc301d2d79bc3302650d8a5c` -## バージョン 1 からの変更点 {#alterations-from-v2} +## バージョン1からの変更点 {#alterations-from-v2} -このバージョンでは、[こちら](https://github.com/ethereum/homestead-guide/blob/master/old-docs-for-reference/go-ethereum-wiki.rst/Passphrase-protected-key-store-spec.rst)に公開されているバージョン 1 のいくつかの矛盾点が解消されています。 簡単には次のとおりです。 +このバージョンでは、[こちら](https://github.com/ethereum/homestead-guide/blob/master/old-docs-for-reference/go-ethereum-wiki.rst/Passphrase-protected-key-store-spec.rst)に公開されているバージョン1のいくつかの矛盾点が解消されています。 簡単には次のとおりです。 -- 大文字の使用が正当化されていなく、一貫性がない(scrypt の小文字、Kdf の大文字と小文字の混合、MAC の大文字) 。 +- 大文字の使用が正当化されていなく、一貫性がない(scryptの小文字、Kdfの大文字と小文字の混合、MACの大文字) 。 - 不必要な対処とプライバシーの侵害。 - `Salt`は、本質的に鍵導出関数のパラメーターであり、一般的な暗号ではなく、鍵導出関数のパラメーターに関連付ける方がふさわしい。 -- *SaltLen*が不要(Salt から導出) 。 +- _SaltLen_が不要(Saltから導出) 。 - 鍵導出関数が与えられているが、暗号アルゴリズムは厳密に指定されている。 - `Version`は、本質的には数値であるものの文字列(構造化されたバージョン管理は、文字列でできるが、ほとんど変更されない構成ファイル形式の範囲外と考えられる) 。 - `KDF`と `cipher`は、概念的には兄弟であるが、構造は異なる。 @@ -184,6 +184,6 @@ AES-128-CTR とスクリプトを使用したテストベクトル } ``` -## バージョン 2 からの変更点 {#alterations-from-v2} +## バージョン2からの変更点 {#alterations-from-v2} -バージョン 2 は、初期の C++実装で多くのバグがありました。 すべての必須機能は、バージョン 2 から変更ありません。 +バージョン2は、初期のC++実装で多くのバグがありました。 すべての必須機能は、バージョン2から変更ありません。 diff --git a/public/content/translations/ja/developers/docs/design-and-ux/index.md b/public/content/translations/ja/developers/docs/design-and-ux/index.md new file mode 100644 index 00000000000..0cd9f239de0 --- /dev/null +++ b/public/content/translations/ja/developers/docs/design-and-ux/index.md @@ -0,0 +1,86 @@ +--- +title: Web3のデザインとUX +description: Web3におけるUXデザインおよびリサーチの紹介とイーサリアム +lang: ja +--- + +イーサリアムを使ったデザインは初めてでしょうか? そうならば、ここはあなたに適した場所です。 イーサリアムコミュニティでは、Web3のデザインとリサーチの基礎を紹介するためのリソースを作っています。 ここでは、あなたがよく知っている他のアプリのデザインとは異なる可能性があるコア・コンセプトについて学びます。 + +それより前に、Web3の基礎を理解したいでしょうか? でしたら[**学習ハブ**](/learn/)を参照ください。 + +## ユーザーリサーチを始める {#start-with-user-research} + +効果的なデザインは、視覚的に魅力的なユーザーインターフェイスを作成するだけにとどまりません。 ユーザーのニーズ、目的、推進要因などを深く理解することが伴います。 そのため、すべてのデザイナーが[**ダイヤモンドプロセス**](https://en.wikipedia.org/wiki/Double_Diamond_(design_process_model))などのデザインプロセスを採用することをお勧めします。これは、仕事が意図的であることを確実にします。 + +- [Web3では、より多くのUXリサーチャーとデザイナーが必要](https://akasha.org/blog/2022/10/11/akasha-conversation-09-web3-ux-researchers-and-designers) - 現在のデザイン成熟度の概要 +- [web3におけるUXリサーチの簡単なガイド](https://uxplanet.org/a-complete-guide-to-ux-research-for-web-3-0-products-d6bead20ebb1) - リサーチ方法の簡単なガイド +- [Web3におけるUXデザインのアプローチ方法](https://archive.devcon.org/archive/watch/6/data-empathy-how-to-approach-ux-decisions-in-web3/) - 定量的リサーチと定性的リサーチの概要とその2つの違い (6分間のビデオ) +- [Web3のUXリサーチャーになること](https://medium.com/@georgia.rakusen/what-its-like-being-a-user-researcher-in-web3-6a4bcc096849) - Web3のUXリサーチャーがどのようなものかついての個人的な見解 + +## Web3の調査研究 {#research-in-web3} + +ここにあるのは、Web3の分野で行われたユーザー調査についての収集したリストです。デザインや製品の決定に役立てることができます。もしくは、独自調査におけるインスピレーションとして役立ちます。 + +| フォーカス分野 | 名前 | +|:---------------------------------------------------- |:-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 暗号通過へのオンボーディング | [CRADL: クリプトの研究開発ラボ](https://project-cradl.notion.site/Crypto-Research-and-Design-Lab-50a7127f34ed4c88ad95c7cedf7fbe36) | +| 暗号通過へのオンボーディング | [CRADL: 暗号通貨のUX](https://docs.google.com/presentation/d/1s2OPSH5sMJzxRYaJSSRTe8W2iIoZx0PseIV-WeZWD1s/edit?usp=sharing) | +| 暗号通過へのオンボーディング | [CRADL: 暗号通貨の勉強会](https://docs.google.com/presentation/d/1R9nFuzA-R6SxaGCKhoMbE4Vxe0JxQSTiHXind3LVq_w/edit?usp=sharing) | +| 暗号通過へのオンボーディング | [ビットコインUXレポート](https://github.com/patestevao/BitcoinUX-report/blob/master/report.md) | +| 暗号通過へのオンボーディング | [ConSensys: 2023年の世界におけるWeb3への認識に関する状態](https://consensys.io/insight-report/web3-and-crypto-global-survey-2023) | +| ステーキング | [ステーキング: 主要なトレンド、要点、予測 - ETHステーカー](https://lookerstudio.google.com/u/0/reporting/cafcee00-e1af-4148-bae8-442a88ac75fa/page/p_ja2srdhh2c?s=hmbTWDh9hJo) | +| ステーキング | [複数のアプリのステーキング](https://github.com/threshold-network/UX-User-Research/blob/main/Multi-App%20Staking%20(MAS)/iterative-user-study/MAS%20Iterative%20User%20Study.pdf) | +| 自律分散型組織 | [2022年DAOリサーチのアップデート: DAOビルダーが必要なことは何か?](https://blog.aragon.org/2022-dao-research-update/) | +| 分散型金融(DeFi) | [2023年のDefiの状態](https://stateofdefi.org/) | +| 分散型金融(DeFi) | [カバレッジプール](https://github.com/threshold-network/UX-User-Research/tree/main/Keep%20Coverage%20Pool) | +| 分散型金融(DeFi) | [ConSensys: 2022年DeFiユーザーリサーチレポート](https://cdn2.hubspot.net/hubfs/4795067/ConsenSys%20Codefi-Defi%20User%20ResearchReport.pdf) | +| Metaverse | [メタバース: ユーザーリサーチレポート](https://www.politico.com/f/?id=00000187-7685-d820-a7e7-7e85d1420000) | +| Metaverse | [Going on Safari: メタバースでのユーザリサーチ](https://archive.devcon.org/archive/watch/6/going-on-safari-researching-users-in-the-metaverse/?tab=YouTube) (27分間のビデオ) | +| Ethereum.org UXの状況 | [ユーザビリティとユーザ満足度調査ダッシュボード - Ethereum.org](https://lookerstudio.google.com/reporting/0a189a7c-a890-40db-a5c6-009db52c81c9) | + +## Web3のデザイン {#design-for-web3} + +- [Web3デザイン原則](https://medium.com/@lyricalpolymath/web3-design-principles-f21db2f240c1) - ブロックチェーンベースのDappsにおけるUXルールのフレームワーク +- [ブロックチェーンデザイン原則](https://medium.com/design-ibm/blockchain-design-principles-599c5c067b6e) - IBMのブロックチェーン設計チームが学んだ教訓 +- [Web3 UXの特徴](https://uxdesign.cc/the-levels-of-web3-user-experience-4f2ad113e37d) - Web3 UXの異なるレイヤーとその課題の分析 +- [Web3デザインパターン](https://www.web3designpatterns.io/)- 実際のWeb3製品から収集されたデザインパターンのライブラリ +- [W3design.io](https://w3design.io/) - エコシステム内のさまざまなプロジェクトのUIフローを収集したライブラリ +- [Neueux.com](https://neueux.com/apps) - 多様なフィルタリングオプションを備えたユーザーフローのUIライブラリ + +## Web3デザインのケーススタディ {#design-case-studies} + +- [Web3エラーメッセージの適切な記述方法](https://medium.com/@JonCrabb/how-to-design-better-web3-error-messages-bd96e12fa582) +- [Defiデザインのヒント](https://medium.com/@JonCrabb/defi-design-tips-vol-12-8600f4374714) +- [Deep Work Studio](https://deepwork.studio/case-studies/) +- [Crypto UXハンドブック](https://www.cryptouxhandbook.com/) +- [OpenSeaでのNFT販売方法](https://builtformars.com/case-studies/opensea) +- [ウォレットのUX分析: ウォレットをどのように展開させるべきか](https://www.youtube.com/watch?v=oTpuxYj8JWI&ab_channel=ETHDenver) (20分間のビデオ) + +## デザイン報奨金 {#bounties} + +- [Dework](https://app.dework.xyz/bounties) +- [Gitcoin](https://bounties.gitcoin.co/explorer) +- [Buildboxハッカソン](https://gitcoin.co/hackathons) +- [ETHGlobal](https://ethglobal.com/) + +## DAOとコミュニティのデザイン {#design-daos-and-communities} + +プロフェッショナルによるコミュニティ主導の組織に参加したり、デザイングループに参加して、他のメンバーとデザインについて話し合ったり、関連するトピックやトレンドについて研究したりしましょう。 + +- [Vectordao.com](https://vectordao.com/) +- [Deepwork.studio](https://www.deepwork.studio/) +- [Designer-dao.xyz](https://www.designer-dao.xyz/) +- [We3.co](https://we3.co/) +- [Openux.xyz](https://openux.xyz/about) +- [web3trends.org](https://web3trends.org/) +- [オープンソースWeb3デザイン](https://www.web3designers.org/) + +## デザインシステム {#design-systems} + +- [オプティミズムデザイン](https://www.figma.com/@oplabs) (Figma) +- [Ethereum.orgデザインシステム](https://www.figma.com/@ethdotorg) (Figma) +- [Finity: ポリゴンによるWeb3デザインシステム](https://finity.polygon.technology/) (Figma) +- [ENSデザインシステム](https://thorin.ens.domains/) +- [Mirrorデザインシステム](https://degen-xyz.vercel.app/) + +**このページに掲載されている記事の内容やプロジェクトを公式に推薦しているわけではありません**。情報提供のみを目的としています。 [掲載ポリシー](/contributing/design/adding-design-resources)の基準に基づいて、このページにリンクを追加しています。 このページへプロジェクトや記事を追加したい場合は、 [GitHub](https://github.com/ethereum/ethereum-org-website/blob/dev/src/content/developers/docs/design-and-ux/index.md)にあるこのページを編集してください。 diff --git a/public/content/translations/ja/developers/docs/mev/index.md b/public/content/translations/ja/developers/docs/mev/index.md index ea260897d61..d55f801a720 100644 --- a/public/content/translations/ja/developers/docs/mev/index.md +++ b/public/content/translations/ja/developers/docs/mev/index.md @@ -8,214 +8,214 @@ lang: ja ## 採掘可能価値(MEV) {#miner-extractable-value} -最大抽出可能価値(MEV)は、 [プルーフ・オブ・ワーク](/developers/docs/consensus-mechanisms/pow/)に基づき導入された概念であり、当初は「採掘可能価値(MEV)」と呼ばれていました。 プルーフ・オブ・ワークでは、トランザクションの追加、削除、および順序決定をマイナーが管理していたためです。 しかし、[マージ](/upgrades/merge)によるプルーフ・オブ・ステークへの移行後、バリデータがこれらの役割を担うようになり、マイニングはイーサリアムのプロトコルから削除されました。 しかし、価値採掘のための手段は依然として存在するため、現在は「最大抽出可能価値」という用語を用います。 +最大抽出可能価値(MEV)は、 [プルーフ・オブ・ワーク](/developers/docs/consensus-mechanisms/pow/)に基づき導入された概念であり、当初は「採掘可能価値(MEV)」と呼ばれていました。 プルーフ・オブ・ワークでは、トランザクションの追加、削除、および順序決定をマイナーが管理していたためです。 しかし、[マージ](/roadmap/merge)によるプルーフ・オブ・ステークへの移行後、バリデータがこれらの役割を担うようになり、マイニングはイーサリアムのプロトコルから削除されました。 しかし、価値採掘のための手段は依然として存在するため、現在は「最大抽出可能価値」という用語を用います。 ## 前提知識 {#prerequisites} -[トランザクション](/developers/docs/transactions/)、[ブロック](/developers/docs/blocks/)、[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos)、および[ガス](/developers/docs/gas/)について理解している必要があります。 また、[分散アプリケーション(Dapp)](/dapps/)や[分散型金融(DeFi)](/defi/)の知識も有用です。 +[トランザクション](/developers/docs/transactions/) 、[ブロック](/developers/docs/blocks/)、[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos)、および[ガス](/developers/docs/gas/)について理解している必要があります。 また、[分散アプリケーション(Dapp)](/dapps/)や[分散型金融(DeFi)](/defi/)の知識も有用です。 -## MEV の抽出 {#mev-extraction} +## MEVの抽出 {#mev-extraction} -理論的に言えば、利益を伴う MEV の抽出の実行を保証できるのはバリデータのみであるため、MEV が蓄積するのはバリデータにおいてのみです。 しかし実際には、抽出される MEV の大部分は「サーチャー」と呼ばれる独立したネットワーク参加者が獲得しています。 サーチャーは、ブロックチェーンのデータに対して複雑なアルゴリズムを実行して利益を伴う MEV の抽出機会を検出し、ボットを利用してこれらの利益を伴うトランザクションをネットワークに自動的に送信します。 +理論的に言えば、利益を伴うMEVの抽出の実行を保証できるのはバリデータのみであるため、MEVが蓄積するのはバリデータにおいてのみです。 しかし実際には、抽出されるMEVの大部分は「サーチャー」と呼ばれる独立したネットワーク参加者が獲得しています。 サーチャーは、ブロックチェーンのデータに対して複雑なアルゴリズムを実行して利益を伴うMEVの抽出機会を検出し、ボットを利用してこれらの利益を伴うトランザクションをネットワークに自動的に送信します。 -サーチャーは、高額のガス代を(バリデータに)支払ってでも、発見した利益が期待できるトランザクションがブロックに追加される可能性を高めたいと考えるため、バリデータは発生した MEV 全体からその一部を獲得することができます。 サーチャーが経済的に合理的に行動すると仮定した場合、サーチャーが支払いたいと考えるガス代は、サーチャーが獲得できる MEV の 100%までになります(ガス代が MEV の 100%を越えれば、サーチャーは赤字になるため)。 +サーチャーは、高額のガス代を(バリデータに)支払ってでも、発見した利益が期待できるトランザクションがブロックに追加される可能性を高めたいと考えるため、バリデータは発生したMEV全体からその一部を獲得することができます。 サーチャーが経済的に合理的に行動すると仮定した場合、サーチャーが支払いたいと考えるガス代は、サーチャーが獲得できるMEVの100%までになります(ガス代がMEVの100%を越えれば、サーチャーは赤字になるため)。 -ただし、[分散型取引所(DEX)の裁定取引](#mev-examples-dex-arbitrage)のように競争が激しい MEV の抽出機会の場合、非常に多くのユーザーが利益を伴う裁定取引を実行したいと考えるため、サーチャーは、この MEV における全収益の 90%あるいはそれ以上をバリデータに支払う必要がある場合があります。 裁定取引が実行できる唯一の保証は、最も高いガス代を持つトランザクションを送信することだからです。 +ただし、[分散型取引所(DEX)の裁定取引](#mev-examples-dex-arbitrage)のように競争が激しいMEVの抽出機会の場合、非常に多くのユーザーが利益を伴う裁定取引を実行したいと考えるため、サーチャーは、このMEVにおける全収益の90%あるいはそれ以上をバリデータに支払う必要がある場合があります。 裁定取引が実行できる唯一の保証は、最も高いガス代を持つトランザクションを送信することだからです。 ### ガス・ゴルフ {#mev-extraction-gas-golfing} -上記の力学に基づき、「ガス・ゴルフ(gas golfing)」(ガス代が最も安価になるようにトランザクションをプログラミングすること)の能力が競合上の優位性として確立されています。ガス・ゴルフにより、サーチャーはより高価なガス代を設定しつつ、ガス代の合計額を一定に抑えられるためです(ガス代=ガス価格 ÷ 使用ガス量)。 +上記の力学に基づき、「ガス・ゴルフ(gas golfing)」(ガス代が最も安価になるようにトランザクションをプログラミングすること)の能力が競合上の優位性として確立されています。ガス・ゴルフにより、サーチャーはより高価なガス代を設定しつつ、ガス代の合計額を一定に抑えられるためです(ガス代=ガス価格÷使用ガス量)。 -よく知られているガス・ゴルフのテクニックとしては、以下があります:多くのゼロを持つ文字列で始まるアドレス (例: [0x0000000000C521824EaFf97Eac7B73B084ef9306](https://etherscan.io/address/0x0000000000c521824eaff97eac7b73b084ef9306)) を使う方法では、保存スペースが小さくなるためガス代も低くなります。あるいは、少額の[ERC-20](/developers/docs/standards/tokens/erc-20/) トークン残高をコントラクトに残しておく方法もありますが、これは(残高が 0 の場合に)ストレージスロットを初期化すると、 ストレージスロットを更新する場合よりも多くのガスが消費される点を利用したものです。 サーチャーのコミュニティでは、ガスの使用量を減らすためのテクニックが活発に研究されています。 +よく知られているガス・ゴルフのテクニックとしては、以下があります:多くのゼロを持つ文字列で始まるアドレス (例: [0x0000000000C521824EaFf97Eac7B73B084ef9306](https://etherscan.io/address/0x0000000000c521824eaff97eac7b73b084ef9306)) を使う方法では、保存スペースが小さくなるためガス代も低くなります。あるいは、少額の[ERC-20](/developers/docs/standards/tokens/erc-20/) トークン残高をコントラクトに残しておく方法もありますが、これは(残高が0の場合に)ストレージスロットを初期化すると、 ストレージスロットを更新する場合よりも多くのガスが消費される点を利用したものです。 サーチャーのコミュニティでは、ガスの使用量を減らすためのテクニックが活発に研究されています。 ### 汎用フロントランナー {#mev-extraction-generalized-frontrunners} -一部のサーチャーは、利益を伴う MEV 機会を検出するために複雑なアルゴリズムを開発する代わりに、汎用的なフロントランナーを実行します。 汎用フロントランナーとは、利益を伴うトランザクションを検出するためにメモリプールを監視するボットです。 汎用フロントランナーは、潜在的に利益を伴うトランザクションのコードをコピーし、フロントランナーのアドレスで置き換えた上でトランザクションをローカルで実行することで、修正後のトランザクションがフロントランナーのアドレスに収益をもたらすことをダブルチェックします。 このトランザクションが実際に利益をもたらすことが確認できれば、フロントランナーはアドレスを置き換えた修正後のトランザクションをより高いガス代と共に送信し、本来のトランザクションよりも「優位に立つ」ことで、本来のサーチャーが得ようとした MEV を獲得することができるのです。 +一部のサーチャーは、利益を伴うMEV機会を検出するために複雑なアルゴリズムを開発する代わりに、汎用的なフロントランナーを実行します。 汎用フロントランナーとは、利益を伴うトランザクションを検出するためにメモリプールを監視するボットです。 汎用フロントランナーは、潜在的に利益を伴うトランザクションのコードをコピーし、フロントランナーのアドレスで置き換えた上でトランザクションをローカルで実行することで、修正後のトランザクションがフロントランナーのアドレスに収益をもたらすことをダブルチェックします。 このトランザクションが実際に利益をもたらすことが確認できれば、フロントランナーはアドレスを置き換えた修正後のトランザクションをより高いガス代と共に送信し、本来のトランザクションよりも「優位に立つ」ことで、本来のサーチャーが得ようとしたMEVを獲得することができるのです。 ### フラッシュボット {#mev-extraction-flashbots} -フラッシュボットは、実行クライアントを拡張する独立したプロジェクトであり、サーチャーに対して、パブリックのメモリプールに公開することなく、MEV トランザクションをバリデータに送信できるサービスを提供します。 このサービスを使用すれば、汎用フロントランナーを用いたトランザクションに実行を先回りされることを防ぐことができます。 +フラッシュボットは、実行クライアントを拡張する独立したプロジェクトであり、サーチャーに対して、パブリックのメモリプールに公開することなく、MEVトランザクションをバリデータに送信できるサービスを提供します。 このサービスを使用すれば、汎用フロントランナーを用いたトランザクションに実行を先回りされることを防ぐことができます。 -## MEV の実例 {#mev-examples} +## MEVの実例 {#mev-examples} -ブロックチェーンにおいて MEV が発生するケースは、いくつかの種類があります。 +ブロックチェーンにおいてMEVが発生するケースは、いくつかの種類があります。 -### DEX における裁定取引 {#mev-examples-dex-arbitrage} +### DEXにおける裁定取引 {#mev-examples-dex-arbitrage} -[分散型取引所 (DEX)](/glossary/#dex)における裁定取引は、最もシンプルでよく知られている MEV の機会です。 このため、ユーザー間の競争も最も激しくなっています。 +[分散型取引所 (DEX) ](/glossary/#dex)における裁定取引は、最もシンプルでよく知られているMEVの機会です。 このため、ユーザー間の競争も最も激しくなっています。 -具体的には、以下のように発生します:2 カ所の DEX が同じトークンを異なる価格で提供している場合、より安価に設定した DEX でトークンを購入し、より高価に設定した DEX で売却すれば、1 回の不可分な取引で利益を得ることができます。 ブロックチェーンの仕組みにより、全くリスクを伴わない裁定取引が可能になります。 +具体的には、以下のように発生します:2カ所のDEXが同じトークンを異なる価格で提供している場合、より安価に設定したDEXでトークンを購入し、より高価に設定したDEXで売却すれば、1回の不可分な取引で利益を得ることができます。 ブロックチェーンの仕組みにより、全くリスクを伴わない裁定取引が可能になります。 -[これは](https://etherscan.io/tx/0x5e1657ef0e9be9bc72efefe59a2528d0d730d478cfc9e6cdd09af9f997bb3ef4)、Uniswap および Sushiswap における ETH/DAI ペアの価格差を利用して、サーチャーが 1,000ETH を 1,045ETH に変換して収益を得た裁定取引の例です。 +[これは](https://etherscan.io/tx/0x5e1657ef0e9be9bc72efefe59a2528d0d730d478cfc9e6cdd09af9f997bb3ef4)、UniswapおよびSushiswapにおけるETH/DAIペアの価格差を利用して、サーチャーが1,000ETHを1,045ETHに変換して収益を得た裁定取引の例です。 ### 清算 {#mev-examples-liquidations} -貸出プロトコルによる精算も、よく知られた MEV 獲得機会のひとつです。 +貸出プロトコルによる精算も、よく知られたMEV獲得機会のひとつです。 -Maker や Aave のような貸出プロトコルでは、ユーザーは何らかの担保(例: ETH)を預入しなければなりません。 預け入れられた担保は、他のユーザーに貸し出されます。 +MakerやAaveのような貸出プロトコルでは、ユーザーは何らかの担保(例: ETH)を預入しなければなりません。 預け入れられた担保は、他のユーザーに貸し出されます。 -ユーザーは、この仕組みを活用して、預け入れた担保に対する一定の上限額まで、自らの必要に応じて他のユーザーから資産やトークンを借り入れることができます(例: MakerDAO のガバナンス提案に投票するために、MKR を借り入れる場合)。 例えば、借入可能額が預け入れた担保の 30%までの場合、プロトコルに 100 DAI を預け入れれば、30 DAI の価値を持つ他の資産を借り入れることができます。 貸出プロトコルは、具体的な借入能力(担保に対する割合)を決定します。 +ユーザーは、この仕組みを活用して、預け入れた担保に対する一定の上限額まで、自らの必要に応じて他のユーザーから資産やトークンを借り入れることができます(例: MakerDAOのガバナンス提案に投票するために、MKRを借り入れる場合)。 例えば、借入可能額が預け入れた担保の30%までの場合、プロトコルに100 DAIを預け入れれば、30 DAIの価値を持つ他の資産を借り入れることができます。 貸出プロトコルは、具体的な借入能力(担保に対する割合)を決定します。 -借り手の担保価値が変動すれば、借入能力も上下します。 具体的には、市場の変動により借入資産の価値が担保価値の(例えば)30%を越えた場合(上述したように、実際の借入可能な割合は貸出プロトコルが決定します)、貸出プロトコルは通常、あらゆるユーザーに対してこの担保を精算し、瞬時に貸し手に払い戻すことを許可します(これは、伝統的な金融市場における[マージンコール](https://www.investopedia.com/terms/m/margincall.asp)の仕組みと同様です)。 一般に、担保が精算される場合に借り手は高額の精算手数料を支払う必要があり、この手数料の一部は清算人に支払われるため、MEV を獲得する機会が発生するのです。 +借り手の担保価値が変動すれば、借入能力も上下します。 具体的には、市場の変動により借入資産の価値が担保価値の(例えば)30%を越えた場合(上述したように、実際の借入可能な割合は貸出プロトコルが決定します)、貸出プロトコルは通常、あらゆるユーザーに対してこの担保を精算し、瞬時に貸し手に払い戻すことを許可します(これは、伝統的な金融市場における[マージンコール](https://www.investopedia.com/terms/m/margincall.asp)の仕組みと同様です)。 一般に、担保が精算される場合に借り手は高額の精算手数料を支払う必要があり、この手数料の一部は清算人に支払われるため、MEVを獲得する機会が発生するのです。 サーチャーは、可能なかぎり高速にブロックチェーンのデータを分析することで、精算の対象となりうる借り手を特定し、精算トランザクションを他に先がけて送信し、精算手数料を回収するための競争を行っています。 ### サンドイッチ取引 {#mev-examples-sandwich-trading} -サンドイッチ取引もまた、一般的な MEV 抽出の方法です。 +サンドイッチ取引もまた、一般的なMEV抽出の方法です。 -サーチャーは、サンドイッチ取引を念頭に置いて DEX における大型取引のメモリプールを監視します。 例えば、あるユーザーが Uniswap で、DAI を使って 10000 UNI を購入したい場合を考えてみましょう。 これほど大きな取引は、UNI/DAI ペアの為替レートに有意な影響を与えるものであり、対 DAI の UNI 価格を大きく上昇させる可能性があります。 +サーチャーは、サンドイッチ取引を念頭に置いてDEXにおける大型取引のメモリプールを監視します。 例えば、あるユーザーがUniswapで、DAIを使って10000 UNIを購入したい場合を考えてみましょう。 これほど大きな取引は、UNI/DAIペアの為替レートに有意な影響を与えるものであり、対DAIのUNI価格を大きく上昇させる可能性があります。 -サーチャーは、この大口取引による UNI/DAI ペアに対する大まかな価格効果を計算し、大口取引の*直前に*最適な買い注文を実行して UNI を安価で購入した上で、大口取引の*直後に* 売り注文を実行し、大口注文により値上がりした価格で売却することができます。 +サーチャーは、この大口取引によるUNI/DAIペアに対する大まかな価格効果を計算し、大口取引の_直前に_最適な買い注文を実行してUNIを安価で購入した上で、大口取引の_直後に_ 売り注文を実行し、大口注文により値上がりした価格で売却することができます。 -しかし、サンドイッチ取引は 1 回で完結できない取引であるため(この点が、上述の DEX における裁定取引とは異なります)よりリスクが大きく、[サルモネラ攻撃](https://github.com/Defi-Cartel/salmonella)の対象となりやすい欠点を持ちます。 +しかし、サンドイッチ取引は1回で完結できない取引であるため(この点が、上述のDEXにおける裁定取引とは異なります)よりリスクが大きく、[サルモネラ攻撃](https://github.com/Defi-Cartel/salmonella)の対象となりやすい欠点を持ちます。 -### NFT を利用した MEV {#mev-examples-nfts} +### NFTを利用したMEV {#mev-examples-nfts} -NFT を用いた MEV の抽出は、最近発生しつつある現象であり、必ずしも利益を伴う取引ではありません。 +NFTを用いたMEVの抽出は、最近発生しつつある現象であり、必ずしも利益を伴う取引ではありません。 -しかし、NFT のトランザクションは、その他すべてのイーサリアムのトランザクションと同一のブロックチェーン上で実行されるため、サーチャーは上記で紹介した従来の MEV 獲得のためのテクニックを NFT 市場でも応用することができます。 +しかし、NFTのトランザクションは、その他すべてのイーサリアムのトランザクションと同一のブロックチェーン上で実行されるため、サーチャーは上記で紹介した従来のMEV獲得のためのテクニックをNFT市場でも応用することができます。 -例えば、人気が高い NFT ドロップが実行され、サーチャーが特定の NFT あるいは複数の NFT を持つセットを獲得したい場合、この NFT の購入リストの先頭になるようにトランザクションをプログラミングしたり、1 回のトランザクションで当該 NFT のセット全体を購入したりすることができます。 また、NFT が [ミスにより低価格で出品](https://www.theblockcrypto.com/post/113546/mistake-sees-69000-cryptopunk-sold-for-less-than-a-cent)されている場合、サーチャーは他の購入者を先回りして取引を実行し、安価で手に入れることができます。 +例えば、人気が高いNFTドロップが実行され、サーチャーが特定のNFTあるいは複数のNFTを持つセットを獲得したい場合、このNFTの購入リストの先頭になるようにトランザクションをプログラミングしたり、1回のトランザクションで当該NFTのセット全体を購入したりすることができます。 また、NFTが [ミスにより低価格で出品](https://www.theblockcrypto.com/post/113546/mistake-sees-69000-cryptopunk-sold-for-less-than-a-cent)されている場合、サーチャーは他の購入者を先回りして取引を実行し、安価で手に入れることができます。 -NFT を使った MEV 抽出の顕著な事例としては、あるサーチャーが 700 万ドルを投じて、Cryptopunk を底値ですべて[購入した](https://etherscan.io/address/0x650dCdEB6ecF05aE3CAF30A70966E2F395d5E9E5)ケースがあります。 この事例については、買い手が MEV プロバイダーと連携してどのようにこの購入を秘匿したかについて、あるブロックチェーン研究者が[ツイッター](https://twitter.com/IvanBogatyy/status/1422232184493121538)上で説明しています。 +NFTを使ったMEV抽出の顕著な事例としては、あるサーチャーが700万ドルを投じて、Cryptopunkを底値ですべて[購入した](https://etherscan.io/address/0x650dCdEB6ecF05aE3CAF30A70966E2F395d5E9E5)ケースがあります。 この事例については、買い手がMEVプロバイダーと連携してどのようにこの購入を秘匿したかについて、あるブロックチェーン研究者が[ツイッター](https://twitter.com/IvanBogatyy/status/1422232184493121538)上で説明しています。 ### ロングテール {#mev-examples-long-tail} -DEX における裁定取引、精算、およびサンドイッチ取引はいずれも、よく知られた MEV の獲得機会であり、新規参入のサーチャーが利益を得られる可能性は低いです。 しかし、数は少ないものの、まだ一般的でない MEV の獲得機会も存在します(NFT による MEV 獲得も、そのひとつだと言えるかもしれません)。 +DEXにおける裁定取引、精算、およびサンドイッチ取引はいずれも、よく知られたMEVの獲得機会であり、新規参入のサーチャーが利益を得られる可能性は低いです。 しかし、数は少ないものの、まだ一般的でないMEVの獲得機会も存在します(NFTによるMEV獲得も、そのひとつだと言えるかもしれません)。 -サーチャーの分野に新たに参入したい方は、このロングテールの部分に焦点を当てることで、MEV を獲得できる可能性が高まるかもしれません。 フラッシュボットの[MEV 求人板](https://github.com/flashbots/mev-job-board)には、最近発生しつつある新たな MEV 獲得機会が掲載されています。 +サーチャーの分野に新たに参入したい方は、このロングテールの部分に焦点を当てることで、MEVを獲得できる可能性が高まるかもしれません。 フラッシュボットの[MEV求人板](https://github.com/flashbots/mev-job-board)には、最近発生しつつある新たなMEV獲得機会が掲載されています。 -## MEV の影響 {#effects-of-mev} +## MEVの影響 {#effects-of-mev} -MEV は必ずしも絶対悪ではなく、イーサリアムにとってはよい影響と悪い影響の両方を持ちます。 +MEVは必ずしも絶対悪ではなく、イーサリアムにとってはよい影響と悪い影響の両方を持ちます。 ### よい影響 {#effects-of-mev-the-good} -多くの分散型金融(DeFi)プロジェクトは、プロトコルの有用性と安定性を確保するために、経済的合理性に基づいて行動するユーザーに依存しています。 DEX における裁定取引は、ユーザーが各自のトークンに対して最善かつ最も適切な価格を得られることを保証するメカニズムであり、貸出プロトコルは、借入可能な比率を超過した借り手にただちに精算を迫ることで、貸し手に対する返済を保証しています。 +多くの分散型金融(DeFi)プロジェクトは、プロトコルの有用性と安定性を確保するために、経済的合理性に基づいて行動するユーザーに依存しています。 DEXにおける裁定取引は、ユーザーが各自のトークンに対して最善かつ最も適切な価格を得られることを保証するメカニズムであり、貸出プロトコルは、借入可能な比率を超過した借り手にただちに精算を迫ることで、貸し手に対する返済を保証しています。 -経済合理性に基づき行動するサーチャーが、経済的な非効率性を発見し、それを修正することで、当該プロトコルにおける経済的なインセンティブを獲得することができなければ、DeFi のプロトコルや Dapp は現在実現されている強じん性を維持できないでしょう。 +経済合理性に基づき行動するサーチャーが、経済的な非効率性を発見し、それを修正することで、当該プロトコルにおける経済的なインセンティブを獲得することができなければ、DeFiのプロトコルやDappは現在実現されている強じん性を維持できないでしょう。 ### 悪い影響 {#effects-of-mev-the-bad} -アプリケーションレイヤーにおいては、サンドイッチ取引をはじめとする一部の MEV 獲得方法はユーザーの利用体験を明らかに低下させます。 サンドイッチ取引に巻き込まれたユーザーは、スリッページの被害を受け、取引条件が悪化するでしょう。 +アプリケーションレイヤーにおいては、サンドイッチ取引をはじめとする一部のMEV獲得方法はユーザーの利用体験を明らかに低下させます。 サンドイッチ取引に巻き込まれたユーザーは、スリッページの被害を受け、取引条件が悪化するでしょう。 ネットワークレイヤーにおいては、汎用フロントランナーやガス価格のオークションが頻繁に用いられるため(複数のフロントランナーが、次のブロックに追加されるトランザクションのガス代を吊り上げる競争を行う場合)、ネットワークの混雑が悪化するだけでなく、通常のトランザクションを実行したい他のすべてのユーザーにとってもガス代が上昇してしまいます。 -MEV は、ブロック *内部における影響に加えて、複数のブロック*間においても悪影響をもたらす場合があります。 特定のブロック内において獲得できる MEV が標準的なブロック報酬を大きく上回る場合、バリデータにとっては、ブロックを再編成し、バリデータ自身が MEV を獲得しようというインセンティブが発生しうるため、ブロックチェーンの再編成を促し、コンセンサスの安定性が損なわれる可能性があります。 +MEVは、ブロック _内部__における影響に加えて、複数のブロック_間_においても悪影響をもたらす場合があります。 特定のブロック内において獲得できるMEVが標準的なブロック報酬を大きく上回る場合、バリデータにとっては、ブロックを再編成し、バリデータ自身がMEVを獲得しようというインセンティブが発生しうるため、ブロックチェーンの再編成を促し、コンセンサスの安定性が損なわれる可能性があります。 -このブロックチェーンが再編成される可能性は、 [すでにビットコインのブロックチェーンにおいて発生しています](https://dl.acm.org/doi/10.1145/2976749.2978408)。 ビットコインのブロック報酬が半減し、ブロック報酬においてトランザクション手数料が占める割合がますます大きくなると、マイナーにとっては、次のブロックで得られる報酬よりも、より高額な手数料が期待できる過去のブロックを再採掘する方が経済的に合理的である状況が発生します。 MEV の抽出が一般化した場合、イーサリアムにおいても類似の状況が発生し、イーサリアム・ブロックチェーンの健全性が損なわれる可能性があります。 +このブロックチェーンが再編成される可能性は、 [すでにビットコインのブロックチェーンにおいて発生しています](https://dl.acm.org/doi/10.1145/2976749.2978408)。 ビットコインのブロック報酬が半減し、ブロック報酬においてトランザクション手数料が占める割合がますます大きくなると、マイナーにとっては、次のブロックで得られる報酬よりも、より高額な手数料が期待できる過去のブロックを再採掘する方が経済的に合理的である状況が発生します。 MEVの抽出が一般化した場合、イーサリアムにおいても類似の状況が発生し、イーサリアム・ブロックチェーンの健全性が損なわれる可能性があります。 -## MEV の現況 {#state-of-mev} +## MEVの現況 {#state-of-mev} -MEV の抽出は、2021 年初頭から爆発的に増加し、同年 1 月から数ヶ月にわたりガス価格が大きく高騰しました。 しかし、フラッシュボットの MEV リレーが登場した結果、汎用フロントランナーの効果が薄れ、ガス代のオークションがオフチェーンで実行されるようになったため、通常のユーザーが支払うガス価格は低下しました。 +MEVの抽出は、2021年初頭から爆発的に増加し、同年1月から数ヶ月にわたりガス価格が大きく高騰しました。 しかし、フラッシュボットのMEVリレーが登場した結果、汎用フロントランナーの効果が薄れ、ガス代のオークションがオフチェーンで実行されるようになったため、通常のユーザーが支払うガス価格は低下しました。 -現在も多くのサーチャーが MEV により充分な利益を得ているものの、MEV の抽出機会に対する認知度が高まり、同じ機会により多くのサーチャーが参加するようになるにつれ、MEV の総収益のうちバリデータの利益が占める割合はますます大きくなるでしょう(と言うのも、上記で説明したガス代のオークションと同様の状況は、非公開の取引を通じてフラッシュボットでも発生するため、その結果発生するガス収益はバリデータが獲得するためです)。 また、MEV が発生するのはイーサリアムに限りません。イーサリアムにおける MEV の獲得機会に対する競争が激化するにつれ、サーチャーは、同じような機会が存在し、より競争相手が少ないバイナンス・スマートチェーンなどの他のブロックチェーンに移行する傾向を強めています。 +現在も多くのサーチャーがMEVにより充分な利益を得ているものの、MEVの抽出機会に対する認知度が高まり、同じ機会により多くのサーチャーが参加するようになるにつれ、MEVの総収益のうちバリデータの利益が占める割合はますます大きくなるでしょう(と言うのも、上記で説明したガス代のオークションと同様の状況は、非公開の取引を通じてフラッシュボットでも発生するため、その結果発生するガス収益はバリデータが獲得するためです)。 また、MEVが発生するのはイーサリアムに限りません。イーサリアムにおけるMEVの獲得機会に対する競争が激化するにつれ、サーチャーは、同じような機会が存在し、より競争相手が少ないバイナンス・スマートチェーンなどの他のブロックチェーンに移行する傾向を強めています。 -一方、プルーフ・オブ・ワークからプルーフ・オブ・ステークへの移行や、ロールアップならびにシャーディングを活用してイーサリアムのスケーリングを実現するための継続的な取り組みなどはいずれも、MEV を取り巻く環境を一変させるものですが、それらがどのような影響を及ぼすかは現時点では明確ではありません。 プルーフ・オブ・ワークの確率論的モデルとの比較において、保証済みのブロック提案者に対してやや事前に通知することが MEV 抽出の力学をどのように変化させるのか、あるいは、[1 名のシークレットリーダー選挙](https://ethresear.ch/t/secret-non-single-leader-election/11789)および[分散型バリデータ技術](https://github.com/ethereum/distributed-validator-specs)が実装された場合に、この環境がどのような影響を被るのかは、現在のところはっきりしていません。 同様に、大部分のユーザーアクティビティがイーサリアムの外部に移行し、L2 におけるロールアップやシャードで実行される場合、どのような MEV の抽出機会が残存するのかも不明です。 +一方、プルーフ・オブ・ワークからプルーフ・オブ・ステークへの移行や、ロールアップを活用してイーサリアムのスケーリングを実現するための継続的な取り組みなどはいずれも、MEVを取り巻く環境を一変させるものですが、それらがどのような影響を及ぼすかは現時点では明確ではありません。 プルーフ・オブ・ワークの確率論的モデルとの比較において、保証済みのブロック提案者に対してやや事前に通知することがMEV抽出の力学をどのように変化させるのか、あるいは、[1名のシークレットリーダー選挙](https://ethresear.ch/t/secret-non-single-leader-election/11789)および[分散型バリデータ技術](/staking/dvt/)が実装された場合に、この環境がどのような影響を被るのかは、現在のところはっきりしていません。 同様に、大部分のユーザーアクティビティがイーサリアムの外部に移行し、L2におけるロールアップやシャードで実行される場合、どのようなMEVの抽出機会が残存するのかも不明です。 -## イーサリアムのプルーフ・オブ・ステーク(PoS)における MEV {#mev-in-ethereum-proof-of-stake} +## イーサリアムのプルーフ・オブ・ステーク(PoS)におけるMEV {#mev-in-ethereum-proof-of-stake} -上述したように、MEV は全般的なユーザー体験やコンセンサスレイヤーのセキュリティに悪影響を及ぼします。 しかし、イーサリアムにおけるプルーフ・オブ・ステークへの移行(「マージ」と呼ぶ)に伴い、MEV に関連して以下のような新たなリスクが発生する可能性があります: +上述したように、MEVは全般的なユーザー体験やコンセンサスレイヤーのセキュリティに悪影響を及ぼします。 しかし、イーサリアムにおけるプルーフ・オブ・ステークへの移行(「マージ」と呼ぶ)に伴い、MEVに関連して以下のような新たなリスクが発生する可能性があります: ### バリデータの集中 {#validator-centralization} -マージ後のイーサリアムにおいては、バリデータ(32 ETH のセキュリティ・デポジットを行ったユーザー)は、ビーコンチェーンに追加されたブロックの検証に対するコンセンサスに参加します。 多くのユーザーにとっては、32 ETH の負担は大きすぎるため、[ステーキングプールへの参加](/staking/pools/)がより現実的なオプションとなるかもしれません。 しかし、特定のユーザーのみにバリデータが集中することを回避し、イーサリアムのセキュリティを向上させるには、[ソロステーカー](/staking/solo/)の割合を健全に保つことが望ましいと言えます。 +マージ後のイーサリアムにおいては、バリデータ(32 ETHのセキュリティ・デポジットを行ったユーザー)は、ビーコンチェーンに追加されたブロックの検証に対するコンセンサスに参加します。 多くのユーザーにとっては、32 ETHの負担は大きすぎるため、[ステーキングプールへの参加](/staking/pools/)がより現実的なオプションとなるかもしれません。 しかし、特定のユーザーのみにバリデータが集中することを回避し、イーサリアムのセキュリティを向上させるには、[ソロステーカー](/staking/solo/)の割合を健全に保つことが望ましいと言えます。 -しかし、MEV の抽出機会により、特定のユーザーのみがバリデータとなる傾向が強まると考えられています。 この原因のひとつとして、現在のところ、バリデータはマイナーと比較すると[ブロックの提案により得られる収入が少ない](/upgrades/merge/issuance/#how-the-merge-impacts-ETH-supply)ため、MEV の抽出がマージ後における[バリデータの収益](https://github.com/flashbots/eth2-research/blob/main/notebooks/mev-in-eth2/eth2-mev-calc.ipynb)に対して大きな影響を与えると予想されるためです。 +しかし、MEVの抽出機会により、特定のユーザーのみがバリデータとなる傾向が強まると考えられています。 この原因のひとつとして、現在のところ、バリデータはマイナーと比較すると[ブロックの提案により得られる収入が少ない](/roadmap/merge/issuance/#how-the-merge-impacts-ETH-supply)ため、MEVの抽出がマージ後における[バリデータの収益](https://github.com/flashbots/eth2-research/blob/main/notebooks/mev-in-eth2/eth2-mev-calc.ipynb)に対して大きな影響を与えると予想されるためです。 -ステーキングプールの規模が大きくなればなるほど、MEV の抽出機会を活用するために必要な最適化に対してより多くのリソースを投じる傾向が高まるでしょう。 これらのプールから抽出できる MEV が大きくなればなるほど、バリデータは MEV の抽出能力を向上させるためにより多くのリソースを投じ、(さらに全体的な収益増を実現する)ことになるため、結果的に[規模の経済](https://www.investopedia.com/terms/e/economiesofscale.asp#)が実現されます。 +ステーキングプールの規模が大きくなればなるほど、MEVの抽出機会を活用するために必要な最適化に対してより多くのリソースを投じる傾向が高まるでしょう。 これらのプールから抽出できるMEVが大きくなればなるほど、バリデータはMEVの抽出能力を向上させるためにより多くのリソースを投じ、(さらに全体的な収益増を実現する)ことになるため、結果的に[規模の経済](https://www.investopedia.com/terms/e/economiesofscale.asp#)が実現されます。 -ソロステーカーは、利用できるリソースが少ないために、MEV の機会から利益を得られなくなるかもしれません。 これにより、独立系のバリデータが収益を高めるために大規模なステーキングプールに参加する傾向が強まり、イーサリアムにおける分散化が損なわれる可能性があります。 +ソロステーカーは、利用できるリソースが少ないために、MEVの機会から利益を得られなくなるかもしれません。 これにより、独立系のバリデータが収益を高めるために大規模なステーキングプールに参加する傾向が強まり、イーサリアムにおける分散化が損なわれる可能性があります。 ### 許可済みのメモリプール {#permissioned-mempools} -サンドイッチ取引やフロントランナー攻撃に対処するため、取引を行うユーザーは、トランザクションのプライバシーを維持するためにバリデータを伴う取引をオフチェーンで実行するようになるかもしれません。 MEV 抽出の可能性があるトランザクションを公開メモリプールに送信するのではなく、バリデータにトランザクションを直接送信する方法では、ブロックへの追加を担うバリデータと利益を共有することができます。 +サンドイッチ取引やフロントランナー攻撃に対処するため、取引を行うユーザーは、トランザクションのプライバシーを維持するためにバリデータを伴う取引をオフチェーンで実行するようになるかもしれません。 MEV抽出の可能性があるトランザクションを公開メモリプールに送信するのではなく、バリデータにトランザクションを直接送信する方法では、ブロックへの追加を担うバリデータと利益を共有することができます。 このような取り決めをより大規模にしたものが「ダークプール」であり、一定の手数料を支払う意思があるユーザーのみが参加する、許可済みでアクセスのみ可能なメモリプールとして機能します。 このようなメモリプールを活用する傾向が強まれば、イーサリアムにおけるパーミッションレス、トラストレスの特性が失われ、ブロックチェーンが最高額入札者にとって有利な「ペイ・トゥ・プレイ」のメカニズムに変質してしまう可能性があります。 -さらに、許可済みのメモリプールは、上述したようにユーザーの集中化というリスクを強めます。 複数のバリデータが大規模なプールを実行する場合、取引者およびユーザーにとってはトランザクションのプライバシーを維持できるという利益が発生するため、MEV の収益が増加するでしょう。 +さらに、許可済みのメモリプールは、上述したようにユーザーの集中化というリスクを強めます。 複数のバリデータが大規模なプールを実行する場合、取引者およびユーザーにとってはトランザクションのプライバシーを維持できるという利益が発生するため、MEVの収益が増加するでしょう。 -マージ後のイーサリアムにおいては、これらの MEV 関連の問題にどう対処するかがリサーチコミュニティにおける核心的な課題となっています。 現在のところ、マージ後のイーサリアムにおいて MEV が及ぼす分散化およびセキュリティへの悪影響を軽減するためのソリューションとしては、**提案者と作成者の分離(PBS)**および**ビルダー API**が提案されています。 +マージ後のイーサリアムにおいては、これらのMEV関連の問題にどう対処するかがリサーチコミュニティにおける核心的な課題となっています。 現在のところ、マージ後のイーサリアムにおいてMEVが及ぼす分散化およびセキュリティへの悪影響を軽減するためのソリューションとしては、**提案者と作成者の分離(PBS)**および**ビルダーAPI**が提案されています。 ### ブロックにおける提案者と作成者の分離(PBS) {#proposer-builder-separation} プルーフ・オブ・ワークであれプルーフ・オブ・ステークであれ、ブロックを作成するノードは、作成したブロックをチェーンに追加することをコンセンサスに参加する他のノードに提案します。 新しいブロックは、他のマイナーがさらにその上にブロックを構築した場合(プルーフ・オブ・ワーク)、あるいは過半数のバリデータからアテステーションを受け取った場合(プルーフ・オブ・ステーク)に、正規のブロックチェーンに追加されます。 -この記事で紹介した MEV に関する問題点の多くは、ブロックの作成者と提案者の役割が分離されていないことに由来しています。 例えば、コンセンサスに参加しているノードは、MEV による収益を最大化するために、タイムバンディット攻撃を使ってチェーンの再編成をトリガーするインセンティブを持っています。 +この記事で紹介したMEVに関する問題点の多くは、ブロックの作成者と提案者の役割が分離されていないことに由来しています。 例えば、コンセンサスに参加しているノードは、MEVによる収益を最大化するために、タイムバンディット攻撃を使ってチェーンの再編成をトリガーするインセンティブを持っています。 -[提案者と作成者の分離(PBS)](https://ethresear.ch/t/proposer-block-builder-separation-friendly-fee-market-designs/9725) は、特にコンセンサスレイヤーにおける MEV の影響を軽減するように設計されています。 PBS の主な機能は、ブロックの作成者と提案者に対するルールを分離することです。 バリデータがブロックの提案と投票に責任を負う点は変わりませんが、**ブロックビルダー**と呼ばれる専門の新たなエンティティ・クラスが導入され、トランザクションの順番付けと構築を担当することになります。 +[提案者と作成者の分離(PBS)](https://ethresear.ch/t/proposer-block-builder-separation-friendly-fee-market-designs/9725) は、特にコンセンサスレイヤーにおけるMEVの影響を軽減するように設計されています。 PBSの主な機能は、ブロックの作成者と提案者に対するルールを分離することです。 バリデータがブロックの提案と投票に責任を負う点は変わりませんが、**ブロックビルダー**と呼ばれる専門の新たなエンティティ・クラスが導入され、トランザクションの順番付けと構築を担当することになります。 -PBS では、ブロックビルダーがトランザクションバンドルを作成し、ビーコンチェーン・ブロックへの追加に対して(「実行ペイロード」として)入札を行います。 次のブロック提案者として選択されたバリデータは、これを受けて、様々な入札をチェックし、最も高額な手数料のバンドルを選択します。 つまり PBS は、ブロックスペースの販売価格についてビルダーとバリデーターが交渉するオークション市場を構築するものです。 +PBSでは、ブロックビルダーがトランザクションバンドルを作成し、ビーコンチェーン・ブロックへの追加に対して(「実行ペイロード」として)入札を行います。 次のブロック提案者として選択されたバリデータは、これを受けて、様々な入札をチェックし、最も高額な手数料のバンドルを選択します。 つまりPBSは、ブロックスペースの販売価格についてビルダーとバリデーターが交渉するオークション市場を構築するものです。 -現在の PBS の設計では、ブロックビルダーは入札において、当該ブロックのコンテンツ(ブロックヘッダー)に対する暗号コミットメントのみを公開する[コミットメント=公開スキーム](https://gitcoin.co/blog/commit-reveal-scheme-on-ethereum/)が採用されています。 提案者は、最高額の入札を受け入れた上で、ブロックヘッダーを含む署名済みのブロック提案を作成します。 ブロックビルダーは、署名済みのブロック提案を確認した後にブロック全体を公開すると想定されており、ブロック提案が最終決定される前に、バリデータから充分な数の[アテステーション](/glossary/#attestation)を得なければなりません。 +現在のPBSの設計では、ブロックビルダーは入札において、当該ブロックのコンテンツ(ブロックヘッダー)に対する暗号コミットメントのみを公開する[コミットメント=公開スキーム](https://gitcoin.co/blog/commit-reveal-scheme-on-ethereum/)が採用されています。 提案者は、最高額の入札を受け入れた上で、ブロックヘッダーを含む署名済みのブロック提案を作成します。 ブロックビルダーは、署名済みのブロック提案を確認した後にブロック全体を公開すると想定されており、ブロック提案が最終決定される前に、バリデータから充分な数の[アテステーション](/glossary/#attestation)を得なければなりません。 -#### 提案者と作成者の分離は、MEV の悪影響をどの程度緩和するか? {#how-does-pbs-curb-mev-impact} +#### 提案者と作成者の分離は、MEVの悪影響をどの程度緩和するか? {#how-does-pbs-curb-mev-impact} -プロトコルにおいて提案者と作成者を分離することで、MEV の抽出がバリデータの作業範囲に含まれなくなるため、コンセンサスに対する MEV の影響を軽減することができます。 これにより、今後は専用のハードウェアを稼働させているブロックビルダーが MEV の抽出機会を得ることになります。 +プロトコルにおいて提案者と作成者を分離することで、MEVの抽出がバリデータの作業範囲に含まれなくなるため、コンセンサスに対するMEVの影響を軽減することができます。 これにより、今後は専用のハードウェアを稼働させているブロックビルダーがMEVの抽出機会を得ることになります。 -ただし、ブロックビルダーはバリデータによる承認を得るために入札額を高くしなければならないため、バリデータにとっても MEV に伴う収益がまったくゼロになるわけではありません。 しかし、バリデータは MEV による収益増を直接的な目標として行動しなくなるため、タイムバンディット攻撃の脅威を低下させることができます。 +ただし、ブロックビルダーはバリデータによる承認を得るために入札額を高くしなければならないため、バリデータにとってもMEVに伴う収益がまったくゼロになるわけではありません。 しかし、バリデータはMEVによる収益増を直接的な目標として行動しなくなるため、タイムバンディット攻撃の脅威を低下させることができます。 -PBS はさらに、MEV による集中化のリスクを引き下げます。 例えば、コミット=公開スキームにより、ブロックビルダーは、バリデータが MEV の抽出機会を奪い取ったり、他の構築者に公開することを行わないユーザーである信頼する必要がなくなります。 これにより、ソロステーカーが MEV 抽出による利益を得る上での障壁が低くなります。そうでなければ、ブロックビルダーはオフチェーンでの評判が高い大規模なプールを選好し、オフチェーンでの取引が増加するトレンドが発生するでしょう。 +PBSはさらに、MEVによる集中化のリスクを引き下げます。 例えば、コミット=公開スキームにより、ブロックビルダーは、バリデータがMEVの抽出機会を奪い取ったり、他の構築者に公開することを行わないユーザーである信頼する必要がなくなります。 これにより、ソロステーカーがMEV抽出による利益を得る上での障壁が低くなります。そうでなければ、ブロックビルダーはオフチェーンでの評判が高い大規模なプールを選好し、オフチェーンでの取引が増加するトレンドが発生するでしょう。 -同じように、バリデータの側も、支払いが必須であるため、ブロックビルダーがブロックボディを秘匿したり、無効なブロックを公開しないユーザーである信頼する必要がなくなります。 つまり、提案されたブロックが参照できない場合や、他のバリデータにより無効と宣言された場合でも、当初のバリデータの手数料は処理されるのです。 他のバリデータが無効と宣言した場合、当該ブロックは単に破棄され、ブロックビルダーはすべての取引手数料および MEV 収益を失うことになります。 +同じように、バリデータの側も、支払いが必須であるため、ブロックビルダーがブロックボディを秘匿したり、無効なブロックを公開しないユーザーである信頼する必要がなくなります。 つまり、提案されたブロックが参照できない場合や、他のバリデータにより無効と宣言された場合でも、当初のバリデータの手数料は処理されるのです。 他のバリデータが無効と宣言した場合、当該ブロックは単に破棄され、ブロックビルダーはすべての取引手数料およびMEV収益を失うことになります。 -### ビルダー API {#builder-api} +### ビルダーAPI {#builder-api} -PBS(提案者と作成者の分離)は、MEV の抽出に伴う悪影響を減らす効果が期待される一方で、実装にはコンセンサス・プロトコルの変更が必要です。 具体的には、ビーコンチェーンにおける[分岐の選択](/developers/docs/consensus-mechanisms/pos/#fork-choice)ルールを変更する必要があります。 [ビルダー API](https://github.com/ethereum/builder-specs)は、信頼性の前提がより高くなるものの、提案者と作成者を実務的に分離するための一時的なソリューションです。 +PBS(提案者と作成者の分離)は、MEVの抽出に伴う悪影響を減らす効果が期待される一方で、実装にはコンセンサス・プロトコルの変更が必要です。 具体的には、ビーコンチェーンにおける[分岐の選択](/developers/docs/consensus-mechanisms/pos/#fork-choice)ルールを変更する必要があります。 [ビルダーAPI](https://github.com/ethereum/builder-specs)は、信頼性の前提がより高くなるものの、提案者と作成者を実務的に分離するための一時的なソリューションです。 -ビルダー API は、コンセンサスレイヤーのクライアントが実行レイヤーのクライアントに対して実行ペイロードを請求する際に用いられる[エンジン API](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md)の修正バージョンです。 [正直なバリデータの仕様](https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/validator.md)に概要が記述されている通り、ブロック提案に関する職責のために選択されたバリデータは、接続された実行クライアントにトランザクションバンドルを要求し、そのバンドルを提案されたビーコンチェーンのブロックに追加します。 +ビルダーAPIは、コンセンサスレイヤーのクライアントが実行レイヤーのクライアントに対して実行ペイロードを請求する際に用いられる[エンジンAPI](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md)の修正バージョンです。 [正直なバリデータの仕様](https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/validator.md)に概要が記述されている通り、ブロック提案に関する職責のために選択されたバリデータは、接続された実行クライアントにトランザクションバンドルを要求し、そのバンドルを提案されたビーコンチェーンのブロックに追加します。 -ビルダー API はさらに、バリデータと実行レイヤーのクライアントとの間のミドルウェアとして機能します。ただし、ビーコンチェーン上のバリデータが外部エンティティからブロックを調達できる(実行クライアントを用いてローカルでブロックを構築するのではない)点が異なります。 +ビルダーAPIはさらに、バリデータと実行レイヤーのクライアントとの間のミドルウェアとして機能します。ただし、ビーコンチェーン上のバリデータが外部エンティティからブロックを調達できる(実行クライアントを用いてローカルでブロックを構築するのではない)点が異なります。 -以下に、ビルダー API の仕組みについて簡単に説明します: +以下に、ビルダーAPIの仕組みについて簡単に説明します: -1. ビルダー API により、バリデータは、実行レイヤーのクライアントを実行しているブロックビルダーのネットワークに接続されます。 PBS の場合と同様に、ビルダーは、リソース集約型のブロック構築への投資に特化し、MEV や優先度チップを通じた収益最大化のために様々な戦略を用いるユーザーで構成されます。 +1. ビルダーAPIにより、バリデータは、実行レイヤーのクライアントを実行しているブロックビルダーのネットワークに接続されます。 PBSの場合と同様に、ビルダーは、リソース集約型のブロック構築への投資に特化し、MEVや優先度チップを通じた収益最大化のために様々な戦略を用いるユーザーで構成されます。 2. (コンセンサスレイヤーのクライアントを実行中である)バリデータは、ビルダーのネットワークからの入札と同時に、実行ペイロードを要求します。 ビルダーからの入札には、実行ペイロードヘッダー(ペイロードのコンテンツに対する暗号コミットメント)と、バリデータに支払う手数料が含まれています。 -3. バリデータは、送信された入札をレビューした上で、最も手数料が高い実行ペイロードを選択します。 バリデータは、ビルダー API を用いて、各自の署名と実行ペイロードヘッダーのみが含まれている「ブラインド」のビーコン用ブロック提案を作成し、ビルダーに送り返します。 +3. バリデータは、送信された入札をレビューした上で、最も手数料が高い実行ペイロードを選択します。 バリデータは、ビルダーAPIを用いて、各自の署名と実行ペイロードヘッダーのみが含まれている「ブラインド」のビーコン用ブロック提案を作成し、ビルダーに送り返します。 -4. ビルダー API を実行しているビルダーは、ブラインドのブロック提案を確認した上で、完全な実行ペイロードで対応すると想定されています。 これにより、バリデータは「署名済み」のビーコンブロックを作成し、ネットワークに拡散することができます。 +4. ビルダーAPIを実行しているビルダーは、ブラインドのブロック提案を確認した上で、完全な実行ペイロードで対応すると想定されています。 これにより、バリデータは「署名済み」のビーコンブロックを作成し、ネットワークに拡散することができます。 -5. ビルダー API を使用するバリデータの場合でも、ブロックビルダーが迅速に対応しない場合にブロック提案に伴う報酬が受け取れない場合を避けるために、ローカルでブロックを構築する必要があります。 しかしバリデータは、この時点で公開されたトランザクションあるいは他のセットを用いて別のブロックを作成することはできません。これは*曖昧化*(同じスロット内の 2 つのブロックに署名すること)を発生させるため、スラッシングの対象である違反行為です。 +5. ビルダーAPIを使用するバリデータの場合でも、ブロックビルダーが迅速に対応しない場合にブロック提案に伴う報酬が受け取れない場合を避けるために、ローカルでブロックを構築する必要があります。 しかしバリデータは、この時点で公開されたトランザクションあるいは他のセットを用いて別のブロックを作成することはできません。これは_曖昧化_(同じスロット内の2つのブロックに署名すること)を発生させるため、スラッシングの対象である違反行為です。 -ビルダー API の実装例としては、イーサリアムに対する MEV の悪影響を軽減するように[フラッシュボットのオークション機能](https://docs.flashbots.net/Flashbots-auction/overview/)を改善した[MEV Boost](https://github.com/flashbots/mev-boost)があります。 フラッシュボットのオークションでは、プルーフ・オブ・ワークを行うマイナーに対し、利益を伴うブロックを作成する作業を**サーチャー**と呼ばれる専門のユーザーに外注することが認められています。 +ビルダーAPIの実装例としては、イーサリアムに対するMEVの悪影響を軽減するように[フラッシュボットのオークション機能](https://docs.flashbots.net/Flashbots-auction/overview/)を改善した[MEV Boost](https://github.com/flashbots/mev-boost)があります。 フラッシュボットのオークションでは、プルーフ・オブ・ワークを行うマイナーに対し、利益を伴うブロックを作成する作業を**サーチャー**と呼ばれる専門のユーザーに外注することが認められています。 -サーチャーは、利益性が高い MEV の機会を発見するために、マイナーに対して[非公開の入札価格](https://en.wikipedia.org/wiki/First-price_sealed-bid_auction)と共にトランザクションバンドルを送信してブロックへの追加を求めます。 Go-Ethereum(Geth)クライアントの分岐後のバージョンである mev-geth を実行しているマイナーは、最も収益が大きいバンドルを選択し、それを新たなブロックの一部としてマイニングすればよいのです。 マイナーからスパムや無効のトランザクションから保護するため、トランザクションバンドルは、マイナーが受信する前に、**リレイヤー**による検証が行われます。 +サーチャーは、利益性が高いMEVの機会を発見するために、マイナーに対して[非公開の入札価格](https://en.wikipedia.org/wiki/First-price_sealed-bid_auction)と共にトランザクションバンドルを送信してブロックへの追加を求めます。 Go-Ethereum(Geth)クライアントの分岐後のバージョンであるmev-gethを実行しているマイナーは、最も収益が大きいバンドルを選択し、それを新たなブロックの一部としてマイニングすればよいのです。 マイナーからスパムや無効のトランザクションから保護するため、トランザクションバンドルは、マイナーが受信する前に、**リレイヤー**による検証が行われます。 -MEV Boost は、フラッシュボットにおける従来のオークションと同一の仕組みを採用していますが、イーサリアムにおけるプルーフ・オブ・ステークへの移行に対応した新機能が追加されています。 サーチャーが利益を伴う MEV トランザクションをブロックに追加しようとする点は同じですが、**ビルダー**と呼ばれる新たな専門ユーザーがトランザクションおよびバンドルをブロックにまとめる役割を担います。 ビルダーは、サーチャーから送信された非公開の入札価格を受け入れ、最適化を実行することで最も利益性が高い注文を決定します。 +MEV Boostは、フラッシュボットにおける従来のオークションと同一の仕組みを採用していますが、イーサリアムにおけるプルーフ・オブ・ステークへの移行に対応した新機能が追加されています。 サーチャーが利益を伴うMEVトランザクションをブロックに追加しようとする点は同じですが、**ビルダー**と呼ばれる新たな専門ユーザーがトランザクションおよびバンドルをブロックにまとめる役割を担います。 ビルダーは、サーチャーから送信された非公開の入札価格を受け入れ、最適化を実行することで最も利益性が高い注文を決定します。 -ここでもリレイヤーは、提案者に送信する事前にトランザクションを検証する責任を負う点は変わりません。 しかし MEV Boost では、ビルダーから送信されたブロックボディおよびバリデータから送信されたブロックヘッダーを保存することで、[データの可用性](/developers/docs/data-availability/)を提供する仕組みである**エスクロー**が導入されています。 エスクローでは、リレーに接続されたバリデータが利用可能な実行ペイロードを要求し、MEV Boost の注文アルゴリズムを用いて、入札価格および MEV チップが最も高いペイロードヘッダーを選択します。 +ここでもリレイヤーは、提案者に送信する事前にトランザクションを検証する責任を負う点は変わりません。 しかしMEV Boostでは、ビルダーから送信されたブロックボディおよびバリデータから送信されたブロックヘッダーを保存することで、[データの可用性](/developers/docs/data-availability/)を提供する仕組みである**エスクロー**が導入されています。 エスクローでは、リレーに接続されたバリデータが利用可能な実行ペイロードを要求し、MEV Boostの注文アルゴリズムを用いて、入札価格およびMEVチップが最も高いペイロードヘッダーを選択します。 -#### ビルダー API は、どのように MEV の悪影響を軽減するのか? {#how-does-builder-api-curb-mev-impact} +#### ビルダーAPIは、どのようにMEVの悪影響を軽減するのか? {#how-does-builder-api-curb-mev-impact} -ビルダー API がもたらす利点の核心は、MEV の抽出機会を利用できるユーザー層を民主化しうるという点にあります。 コミット=公開スキームを採用することで、信頼性の前提が必要なくなり、MEV から利益を得たいと考えるバリデータにおける参入障壁が低くなります。 このため、ソロステーカーが MEV による収益増を目指す場合に、大規模なステーキングプールに参入しなければならないという圧力が少なくなるでしょう。 +ビルダーAPIがもたらす利点の核心は、MEVの抽出機会を利用できるユーザー層を民主化しうるという点にあります。 コミット=公開スキームを採用することで、信頼性の前提が必要なくなり、MEVから利益を得たいと考えるバリデータにおける参入障壁が低くなります。 このため、ソロステーカーがMEVによる収益増を目指す場合に、大規模なステーキングプールに参入しなければならないという圧力が少なくなるでしょう。 -ビルダー API の実装が一般化すれば、ブロックビルダー間の競争が促進され、検閲耐性が高まるでしょう。 バリデータは、複数のビルダーからの入札をレビューするようになるため、1 件または複数のユーザートランザクションを検閲したいと考えるビルダーは、検閲の意図を持たないその他すべてのビルダーよりも高値を提示しなければならなくなります。 これにより、ユーザーを検閲するコストが劇的に上昇するため、検閲できるユーザーが減ると予想されます。 +ビルダーAPIの実装が一般化すれば、ブロックビルダー間の競争が促進され、検閲耐性が高まるでしょう。 バリデータは、複数のビルダーからの入札をレビューするようになるため、1件または複数のユーザートランザクションを検閲したいと考えるビルダーは、検閲の意図を持たないその他すべてのビルダーよりも高値を提示しなければならなくなります。 これにより、ユーザーを検閲するコストが劇的に上昇するため、検閲できるユーザーが減ると予想されます。 -MEV Boost をはじめとするいくつかのプロジェクトでは、フロントランニングやサンドイッチ取引などを開始したいトレーダーなど、特定のユーザーにトランザクションのプライバシーを提供するという全般的な構造設計の一環としてビルダー API を採用しています。 これは、ユーザーとブロックビルダー間に非公開のコミュニケーションチャネルを提供することで達成されます。 上述の許可済みメモリプールの場合とは異なり、このアプローチは以下の点で有益だと言えます: +MEV Boostをはじめとするいくつかのプロジェクトでは、フロントランニングやサンドイッチ取引などを開始したいトレーダーなど、特定のユーザーにトランザクションのプライバシーを提供するという全般的な構造設計の一環としてビルダーAPIを採用しています。 これは、ユーザーとブロックビルダー間に非公開のコミュニケーションチャネルを提供することで達成されます。 上述の許可済みメモリプールの場合とは異なり、このアプローチは以下の点で有益だと言えます: 1. 複数のビルダーが市場で共存することで、実務上検閲の意味がなくなるため、ユーザーにとって有益です。 反対に、集中型で信頼ベースのダークプールが存在する場合、数名のブロックビルダーに権力が集中し、検閲が発生する可能性が高まります。 -2. ビルダー API のソフトウェアはオープンソースであるため、どのユーザーでもブロックビルダー関連のサービスを提供できます。 これにより、ユーザーは特定のブロックビルダーの使用を強制されることがないため、イーサリアムの中立性やパーミッションレス性が向上します。 さらい、MEV の獲得を目指すトレーダーが、非公開のトランザクションチャネルを利用することで意図せずに集中化を促進してしまうことがなくなります。 +2. ビルダーAPIのソフトウェアはオープンソースであるため、どのユーザーでもブロックビルダー関連のサービスを提供できます。 これにより、ユーザーは特定のブロックビルダーの使用を強制されることがないため、イーサリアムの中立性やパーミッションレス性が向上します。 さらに、MEVの獲得を目指すトレーダーが、非公開のトランザクションチャネルを利用することで意図せずに集中化を促進してしまうことがなくなります。 ## 関連リソース {#related-resources} - [フラッシュボット関連文書](https://docs.flashbots.net/) -- [フラッシュボットの GitHub](https://github.com/flashbots/pm) -- [MEV-Explore](https://explore.flashbots.net/) - _MEV のトランザクションを対象とするダッシュボードおよび同時検索プログラム_ -- [mevboost.org](https://www.mevboost.org/) - _MEV-Boost リレーとブロックビルダーに関するリアルタイムの統計を提供するトラッカー_ +- [フラッシュボットのGitHub](https://github.com/flashbots/pm) +- [MEV-Explore](https://explore.flashbots.net/) - _MEVのトランザクションを対象とするダッシュボードおよび同時検索プログラム_ +- [mevboost.org](https://www.mevboost.org/) - _MEV-Boostリレーとブロックビルダーに関するリアルタイムの統計を提供するトラッカー_ ## 参考文献 {#further-reading} - [採掘可能価値(MEV)とは何か?](https://blog.chain.link/what-is-miner-extractable-value-mev/) -- [MEV と私](https://research.paradigm.xyz/MEV) +- [MEVと私](https://www.paradigm.xyz/2021/02/mev-and-me) - [イーサリアムはダークな森である](https://www.paradigm.xyz/2020/08/ethereum-is-a-dark-forest/) - [ダークな森から抜け出すには](https://samczsun.com/escaping-the-dark-forest/) -- [フラッシュボッツ: MEV 危機をフロントランニングするには](https://medium.com/flashbots/frontrunning-the-mev-crisis-40629a613752) -- [@bertcmiller の MEV 関連スレッド](https://twitter.com/bertcmiller/status/1402665992422047747) -- [MEV-Boost: マージに対応した Flashbots のアーキテクチャ](https://ethresear.ch/t/mev-boost-merge-ready-flashbots-architecture/11177) -- [MEV Boost とは](https://www.alchemy.com/overviews/mev-boost) -- [mev-boost を実行する理由](https://writings.flashbots.net/writings/why-run-mevboost/) +- [フラッシュボッツ: MEV危機をフロントランニングするには](https://medium.com/flashbots/frontrunning-the-mev-crisis-40629a613752) +- [@bertcmillerのMEV関連スレッド](https://twitter.com/bertcmiller/status/1402665992422047747) +- [MEV-Boost: マージに対応したFlashbotsのアーキテクチャ](https://ethresear.ch/t/mev-boost-merge-ready-flashbots-architecture/11177) +- [MEV Boostとは](https://www.alchemy.com/overviews/mev-boost) +- [mev-boostを実行する理由](https://writings.flashbots.net/writings/why-run-mevboost/) - [イーサリアムへのヒッチハイク・ガイド](https://members.delphidigital.io/reports/the-hitchhikers-guide-to-ethereum) diff --git a/public/content/translations/ja/developers/docs/networking-layer/index.md b/public/content/translations/ja/developers/docs/networking-layer/index.md index 2e0de61d9b4..04c4127b861 100644 --- a/public/content/translations/ja/developers/docs/networking-layer/index.md +++ b/public/content/translations/ja/developers/docs/networking-layer/index.md @@ -5,11 +5,11 @@ lang: ja sidebarDepth: 2 --- -イーサリアムは、何千ものノードからなるピアツーピアネットワークですが、標準プロトコルを使用して、複数のノード間で直接的に相互に通信できる必要があります。 「ネットワークレイヤー」とは、これらのノードが互いを見つけて情報を交換可能とする為のプロトコルが集まったものです。 イーサリアムのネットワークレイヤーには、特定のノード間でのリクエストとレスポンスの交換(1 対 1 の通信)だけでなく、ネットワーク上での情報の「ゴシップ」(1 対多の通信)も含まれます。 各ノードは、正しい情報を送受信するために、特定のネットワークルールを遵守する必要があります。 +イーサリアムは、何千ものノードからなるピアツーピアネットワークですが、標準プロトコルを使用して、複数のノード間で直接的に相互に通信できる必要があります。 「ネットワークレイヤー」とは、これらのノードが互いを見つけて情報を交換可能とする為のプロトコルが集まったものです。 イーサリアムのネットワークレイヤーには、特定のノード間でのリクエストとレスポンスの交換(1対1の通信)だけでなく、ネットワーク上での情報の「ゴシップ」(1対多の通信)も含まれます。 各ノードは、正しい情報を送受信するために、特定のネットワークルールを遵守する必要があります。 -クライアントソフトウェアには 2 つの部分(実行クライアントとコンセンサスクライアント)があり、それぞれ独自のネットワークスタックを備えています。 他のイーサリアムノードと通信するだけでなく、実行クライアントとコンセンサスクライアントは互いに通信する必要があります。 このページでは、初心者向けに、この通信を可能にするプロトコルを説明をします。 +クライアントソフトウェアには2つの部分(実行クライアントとコンセンサスクライアント)があり、それぞれ独自のネットワークスタックを備えています。 他のイーサリアムノードと通信するだけでなく、実行クライアントとコンセンサスクライアントは互いに通信する必要があります。 このページでは、初心者向けに、この通信を可能にするプロトコルを説明をします。 -実行クライアントは、実行レイヤーのピアツーピアネットワーク上でトランザクションをゴシップします。 これには、認証されたピア同士の暗号化通信が必要です。 ブロックを提案するバリデータが選ばれると、そのノードのローカルトランザクションプールからトランザクションがローカル RPC 接続を介してコンセンサスクライアントに渡され、ビーコンブロックにパッケージ化されます。 コンセンサスクライアントはその後、ピアツーピアネットワーク上でビーコンブロックをゴシップします。 これは 2 つの別々のピアツーピアネットワークを必要とします。1 つはトランザクションゴシップのための実行クライアントを接続するもので、もう 1 つはブロックゴシップのためのコンセンサスクライアントを接続するものです。 +実行クライアントは、実行レイヤーのピアツーピアネットワーク上でトランザクションをゴシップします。 これには、認証されたピア同士の暗号化通信が必要です。 ブロックを提案するバリデータが選ばれると、そのノードのローカルトランザクションプールからトランザクションがローカルRPC接続を介してコンセンサスクライアントに渡され、ビーコンブロックにパッケージ化されます。 コンセンサスクライアントはその後、ピアツーピアネットワーク上でビーコンブロックをゴシップします。 これは2つの別々のピアツーピアネットワークを必要とします。1つはトランザクションゴシップのための実行クライアントを接続するもので、もう1つはブロックゴシップのためのコンセンサスクライアントを接続するものです。 ## 前提知識 {#prerequisites} @@ -17,25 +17,25 @@ sidebarDepth: 2 ## 実行レイヤー {#execution-layer} -実行レイヤーのネットワークプロトコルは、2 つのスタックに分割されています: +実行レイヤーのネットワークプロトコルは、2つのスタックに分割されています: -- ディスカバリースタック: UDP 上に構築され、新しいノードがピアに接続できるようにする +- ディスカバリースタック: UDP上に構築され、新しいノードがピアに接続できるようにする -- DevP2P スタック:TCP 上に構築され、ノードが情報交換できるようにする +- DevP2Pスタック:TCP上に構築され、ノードが情報交換できるようにする -両スタックは、並列的に動作します。 ディスカバリースタックは新しいネットワーク参加者をネットワークに送り込み、DevP2P スタックによって相互通信が可能になります。 +両スタックは、並列的に動作します。 ディスカバリースタックは新しいネットワーク参加者をネットワークに送り込み、DevP2Pスタックによって相互通信が可能になります。 ### ディスカバリー(Discovery) {#discovery} ディスカバリーとは、ネットワークの他のノードを見つけるプロセスです。 これは、小規模なブートノード(クライアントをすぐに見つけピアに接続できるように、アドレスがクライアントに [ハードコードされている](https://github.com/ethereum/go-ethereum/blob/master/params/bootnodes.go)ノード)を使用してブートストラップされています。 これらのブートノードは、新しいノードをピアのセットに追加するためにのみ存在します。これが唯一の目的で、チェーンの同期などの通常のクライアントタスクには参加せず、クライアントが初回起動した時にのみ使用されます。 -ノードとブートノードとのやり取りに使用されるプロトコルは、[Kademlia](https://medium.com/coinmonks/a-brief-overview-of-kademlia-and-its-use-in-various-decentralized-platforms-da08a7f72b8f)が修正された形式です。これは、[分散ハッシュテーブル](https://en.wikipedia.org/wiki/Distributed_hash_table)を使用してノードのリストを共有します。 各ノードには、最も近いピアに接続するために必要な情報を含む、分散ハッシュテーブルのバージョンがあります。 この「近さ」とは地理的なものではありません。ここでの距離はノードの ID の類似性によって定義されるものです。 各ノードのテーブルは、セキュリティ機能として定期的に更新されます。 例えば、 [Discv5](https://github.com/ethereum/devp2p/tree/master/discv5)では、ディスカバリープロトコルのノードは、クライアントがサポートするサブプロトコルを表示する「広告」を送信することもでき、ピアは両者が通信に使用できるプロトコルについて取り決めることができます。 +ノードとブートノードとのやり取りに使用されるプロトコルは、[Kademlia](https://medium.com/coinmonks/a-brief-overview-of-kademlia-and-its-use-in-various-decentralized-platforms-da08a7f72b8f)が修正された形式です。これは、[分散ハッシュテーブル](https://en.wikipedia.org/wiki/Distributed_hash_table)を使用してノードのリストを共有します。 各ノードには、最も近いピアに接続するために必要な情報を含む、分散ハッシュテーブルのバージョンがあります。 この「近さ」とは地理的なものではありません。ここでの距離はノードのIDの類似性によって定義されるものです。 各ノードのテーブルは、セキュリティ機能として定期的に更新されます。 例えば、 [Discv5](https://github.com/ethereum/devp2p/tree/master/discv5)では、ディスカバリープロトコルのノードは、クライアントがサポートするサブプロトコルを表示する「広告」を送信することもでき、ピアは両者が通信に使用できるプロトコルについて取り決めることができます。 -ディスカバリーは、PING-PONG から始まります。 ピンポンが成功すると、新しいノードはブートノードに「結合」されます。 ネットワークに入る新しいノードの存在をブートノードに通知する最初のメッセージは `PING` です。 この`PING`には、新しいノード、ブートノード、および期限切れのタイムスタンプに関するハッシュ化された情報が含まれています。 ブートノードは`PING`を受信し、 `PING` のハッシュを含む`PONG`を返します。 `PING`と`PONG`のハッシュが一致すると、新しいノードとブートノードの接続が確認され、「結合」されたと言うことになります。 +ディスカバリーは、PING-PONGから始まります。 ピンポンが成功すると、新しいノードはブートノードに「結合」されます。 ネットワークに入る新しいノードの存在をブートノードに通知する最初のメッセージは `PING` です。 この`PING`には、新しいノード、ブートノード、および期限切れのタイムスタンプに関するハッシュ化された情報が含まれています。 ブートノードは`PING`を受信し、 `PING` のハッシュを含む`PONG`を返します。 `PING`と`PONG`のハッシュが一致すると、新しいノードとブートノードの接続が確認され、「結合」されたと言うことになります。 一度結合されると、新しいノードはブートノードに`FIND-NEIGHBOURS`リクエストを送信できるようになります。 ブートノードから返されるデータには、新しいノードが接続できるピアのリストが含まれています。 ノードが結合されていない場合、`FIND-NEIGHBOURS`リクエストは失敗となるため、新しいノードはネットワークに入ることができません。 -新しいノードは、ブートノードから近隣ノードのリストを受け取ると、それぞれのノードと PING-PONG を開始します。 PING-PONG が成功すると、新しいノードとその隣接ノードが結合され、メッセージの交換が可能になります。 +新しいノードは、ブートノードから近隣ノードのリストを受け取ると、それぞれのノードとPING-PONGを開始します。 PING-PONGが成功すると、新しいノードとその隣接ノードが結合され、メッセージの交換が可能になります。 ``` start client --> connect to bootnode --> bond to bootnode --> find neighbours --> bond to neighbours @@ -45,39 +45,39 @@ start client --> connect to bootnode --> bond to bootnode --> find neighbours -- #### ENR: イーサリアムノードレコード(Ethereum Node Record) {#enr} -[イーサリアムノードレコード (ENR)](/developers/docs/networking-layer/network-addresses/) とは、署名(合意された 認証スキームに従って作成されたレコード内容のハッシュ)、レコードへの変更を追跡するシーケンス番号、およびキーと値のペアの任意のリストという 3 つの基本要素を含むオブジェクトのことです。 これは、新しいピア間で識別情報の交換を容易にする、将来性のあるフォーマットで、イーサリアムノードの[ネットワークアドレス](/developers/docs/networking-layer/network-addresses)の優先フォーマットです。 +[イーサリアムノードレコード (ENR)](/developers/docs/networking-layer/network-addresses/) とは、署名(合意された 認証スキームに従って作成されたレコード内容のハッシュ)、レコードへの変更を追跡するシーケンス番号、およびキーと値のペアの任意のリストという3つの基本要素を含むオブジェクトのことです。 これは、新しいピア間で識別情報の交換を容易にする、将来性のあるフォーマットで、イーサリアムノードの[ネットワークアドレス](/developers/docs/networking-layer/network-addresses)の優先フォーマットです。 -#### ディスカバリーが UDP で構築されている理由 {#why-udp} +#### ディスカバリーがUDPで構築されている理由 {#why-udp} -UDP はエラーチェック、失敗したパケットの再送、接続の動的な開閉をサポートしません。UDP は、受信に成功したかどうかにかかわらず、単にターゲットに対して連続的な情報ストリームを送信するだけです。 こうした最小限の機能により、オーバーヘッドも最小限に抑えられ、接続は非常に高速になります。 ノードが単に自分の存在を知らせ、相手との正式な接続を確立するためのディスカバリーにとっては、UDP で十分に要件を満たすことができます。 しかし、ディスカバリー以外の残りのネットワークスタックにとっては、UDP では目的を満たすことはできません。 ノード間の情報交換は非常に複雑であるため、再送信やエラーチェックなどに対応できる、より高機能なプロトコルが必要です。 TCP に付随する追加のオーバーヘッドは、まさにこうした追加機能として必要な要件を満たしています。 したがって、P2P スタックの大部分は TCP で動作することになります。 +UDPはエラーチェック、失敗したパケットの再送、接続の動的な開閉をサポートしません。UDPは、受信に成功したかどうかにかかわらず、単にターゲットに対して連続的な情報ストリームを送信するだけです。 こうした最小限の機能により、オーバーヘッドも最小限に抑えられ、接続は非常に高速になります。 ノードが単に自分の存在を知らせ、相手との正式な接続を確立するためのディスカバリーにとっては、UDPで十分に要件を満たすことができます。 しかし、ディスカバリー以外の残りのネットワークスタックにとっては、UDPでは目的を満たすことはできません。 ノード間の情報交換は非常に複雑であるため、再送信やエラーチェックなどに対応できる、より高機能なプロトコルが必要です。 TCPに付随する追加のオーバーヘッドは、まさにこうした追加機能として必要な要件を満たしています。 したがって、P2Pスタックの大部分はTCPで動作することになります。 ### DevP2P {#devp2p} -DevP2P は、それ自体がピアツーピアネットワークの確立と維持するためにイーサリアムが実装しているプロトコルのスタックをすべてを包括しています。 新しいノードがネットワークに参加した後、その相互通信は[DevP2P](https://github.com/ethereum/devp2p)スタックのプロトコルによって制御されます。 これらはすべて TCP 上にあり、RLPx トランスポートプロトコル、ワイヤプロトコル、およびいくつかのサブプロトコルが含まれています。 [RLPx](https://github.com/ethereum/devp2p/blob/master/rlpx.md)は、ノード間のセッションを開始、認証、維持するためのプロトコルです。 RLPx はデータをノード間で送信するための最小限の構造にエンコードする非常にスペース効率の良い RLP (再帰的な長さのプレフィックス)を使ってメッセージをエンコードします。 +DevP2Pは、それ自体がピアツーピアネットワークの確立と維持するためにイーサリアムが実装しているプロトコルのスタックをすべてを包括しています。 新しいノードがネットワークに参加した後、その相互通信は[DevP2P](https://github.com/ethereum/devp2p)スタックのプロトコルによって制御されます。 これらはすべてTCP上にあり、RLPxトランスポートプロトコル、ワイヤプロトコル、およびいくつかのサブプロトコルが含まれています。 [RLPx](https://github.com/ethereum/devp2p/blob/master/rlpx.md)は、ノード間のセッションを開始、認証、維持するためのプロトコルです。 RLPxはデータをノード間で送信するための最小限の構造にエンコードする非常にスペース効率の良いRLP (再帰的な長さのプレフィックス)を使ってメッセージをエンコードします。 -2 つのノード間の RLPx セッションは、最初の暗号化ハンドシェイクで始まります。 このプロセスには、ノードが auth メッセージを送信し、ピアによって検証されることが含まれます。 検証に成功すると、ピアは auth-acknowledgement メッセージを生成し、イニシエーター・ノードに返します。 これは、ノードが非公開で安全に通信できるようにするための鍵交換プロセスです。 暗号化ハンドシェイクが成功すると、両ノードに「Hello」メッセージを互いに「ワイヤ上」で送信するようにトリガーします。 Hello メッセージの交換に成功すると、ワイヤプロトコルが開始されます。 +2つのノード間のRLPxセッションは、最初の暗号化ハンドシェイクで始まります。 このプロセスには、ノードがauthメッセージを送信し、ピアによって検証されることが含まれます。 検証に成功すると、ピアはauth-acknowledgementメッセージを生成し、イニシエーター・ノードに返します。 これは、ノードが非公開で安全に通信できるようにするための鍵交換プロセスです。 暗号化ハンドシェイクが成功すると、両ノードに「Hello」メッセージを互いに「ワイヤ上」で送信するようにトリガーします。 Helloメッセージの交換に成功すると、ワイヤプロトコルが開始されます。 -Hello メッセージには以下が含まれます。 +Helloメッセージには以下が含まれます。 - プロトコルバージョン -- クライアント ID +- クライアントID - ポート -- ノード ID +- ノードID - サポートされるサブプロトコルのリスト これらは両ノード間で相互作用を成功させるために、共有される機能を定義し、通信を構成するのに必要な情報です。 各ノードがサポートするサブプロトコルのリストを比較し、両ノードに共通するものをセッションで使用できるようにするサブプロトコルネゴシエーションというプロセスがあります。 -ワイヤプロトコルは、Hello メッセージとともに、接続が終了することを相手に警告する「切断」メッセージも送信することができます。 ワイヤプロトコルは、セッションを開いたままにするために定期的に送信される PING と PONG メッセージも含んでいます。 したがって、RLPx とワイヤプロトコルの交換は、ノード間の通信の基礎を確立し、特定のサブプロトコルに従って交換される有用な情報のための土台を提供します。 +ワイヤプロトコルは、Helloメッセージとともに、接続が終了することを相手に警告する「切断」メッセージも送信することができます。 ワイヤプロトコルは、セッションを開いたままにするために定期的に送信されるPINGとPONGメッセージも含んでいます。 したがって、RLPxとワイヤプロトコルの交換は、ノード間の通信の基礎を確立し、特定のサブプロトコルに従って交換される有用な情報のための土台を提供します。 ### サブプロトコル {#sub-protocols} #### ワイヤプロトコル {#wire-protocol} -ピアが接続され、RLPx セッションが開始されると、ワイヤプロトコルはピアがどのように通信するかを定義します。 当初、ワイヤプロトコルは、チェーンの同期、ブロックの伝搬、トランザクションの交換という 3 つの主要なタスクを定義していました。 しかし、イーサリアムがプルーフ・オブ・ステーク(PoS)に移行すると、ブロック伝搬とチェーン同期はコンセンサスレイヤーの一部となりました。 トランザクションの交換は、依然として実行クライアントの範疇にあります。 トランザクションの交換とは、保留中のトランザクションをノード間で交換し、マイナーがその一部を次のブロックに含めるために選択できるようにすることです。 これらのタスクの詳細については、[こちら](https://github.com/ethereum/devp2p/blob/master/caps/eth.md)をご覧ください。 これらのサブプロトコルをサポートするクライアントは、[JSON-RPC](/developers/docs/apis/json-rpc/)を介してそれらを公開します。 +ピアが接続され、RLPxセッションが開始されると、ワイヤプロトコルはピアがどのように通信するかを定義します。 当初、ワイヤプロトコルは、チェーンの同期、ブロックの伝搬、トランザクションの交換という3つの主要なタスクを定義していました。 しかし、イーサリアムがプルーフ・オブ・ステーク(PoS)に移行すると、ブロック伝搬とチェーン同期はコンセンサスレイヤーの一部となりました。 トランザクションの交換は、依然として実行クライアントの範疇にあります。 トランザクションの交換とは、保留中のトランザクションをノード間で交換し、マイナーがその一部を次のブロックに含めるために選択できるようにすることです。 これらのタスクの詳細については、[こちら](https://github.com/ethereum/devp2p/blob/master/caps/eth.md)をご覧ください。 これらのサブプロトコルをサポートするクライアントは、[JSON-RPC](/developers/docs/apis/json-rpc/)を介してそれらを公開します。 #### ライト・イーサリアム・サブプロトコル(les) {#les} -これは、ライトクライアントの同期用の最小限のプロトコルです。 フルノードはインセンティブなしにライトクライアントにデータを提供する必要があるため、従来このプロトコルはほとんど使用されてきませんでした。 実行クライアントのデフォルトの動作は、les でライトクライアントのデータを提供しないようになっています。 詳細については、les [仕様](https://github.com/ethereum/devp2p/blob/master/caps/les.md)をご確認ください。 +これは、ライトクライアントの同期用の最小限のプロトコルです。 フルノードはインセンティブなしにライトクライアントにデータを提供する必要があるため、従来このプロトコルはほとんど使用されてきませんでした。 実行クライアントのデフォルトの動作は、lesでライトクライアントのデータを提供しないようになっています。 詳細については、les [仕様](https://github.com/ethereum/devp2p/blob/master/caps/les.md)をご確認ください。 #### スナップ(Snap) {#snap} @@ -89,7 +89,7 @@ Hello メッセージには以下が含まれます。 #### ウィスパー(Whisper) {#whisper} -ウィスパーは、ブロックチェーンに情報を書き込むことなくピア間で安全なメッセージングを提供することを目的としたプロトコルです。 DevP2P ワイヤープロトコルの一部でしたが、現在は非推奨となっています。 他にも同様の目的を持つ[関連プロジェクト](https://wakunetwork.com/)があります。 +ウィスパーは、ブロックチェーンに情報を書き込むことなくピア間で安全なメッセージングを提供することを目的としたプロトコルです。 DevP2Pワイヤープロトコルの一部でしたが、現在は非推奨となっています。 他にも同様の目的を持つ[関連プロジェクト](https://wakunetwork.com/)があります。 ## コンセンサスレイヤー(consensus layer) {#consensus-layer} @@ -97,52 +97,52 @@ Hello メッセージには以下が含まれます。 ### ディスカバリ {#consensus-discovery} -実行クライアントと同様に、コンセンサスクライアントもピアを見つけるために UDP 上の [discv5](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-discovery-domain-discv5) を使用します。 コンセンサスレイヤーの discv5 の実装は、discv5 を[libP2P](https://libp2p.io/)スタックに接続するアダプターを含んでおり、DevP2P を非推奨としている点のみ、実行クライアントの実装と異なります。 実行レイヤーの RLPx セッションは廃止され、libP2P のノイズセキュアチャネル・ハンドシェイクが採用されています。 +実行クライアントと同様に、コンセンサスクライアントもピアを見つけるためにUDP上の [discv5](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-discovery-domain-discv5) を使用します。 コンセンサスレイヤーのdiscv5の実装は、discv5を[libP2P](https://libp2p.io/)スタックに接続するアダプターを含んでおり、DevP2Pを非推奨としている点のみ、実行クライアントの実装と異なります。 実行レイヤーのRLPxセッションは廃止され、libP2Pのノイズセキュアチャネル・ハンドシェイクが採用されています。 ### ENR {#consensus-enr} -コンセンサスノードの ENR には、ノードの公開鍵、IP アドレス、UDP および TCP ポート、コンセンサス特有の 2 つのフィールド(認証サブネットビットフィールドと`eth2`)が含まれます。 前者は、ノードが特定の認証ゴシップ・サブネットワークに参加しているピアを見つけやすくします。 `eth2`キーには、ノードが使用しているイーサリアムフォークのバージョンに関する情報が含まれており、ピアが正しいイーサリアムに接続していることを確認できます。 +コンセンサスノードのENRには、ノードの公開鍵、IPアドレス、UDPおよび TCP ポート、コンセンサス特有の2つのフィールド(認証サブネットビットフィールドと`eth2`)が含まれます。 前者は、ノードが特定の認証ゴシップ・サブネットワークに参加しているピアを見つけやすくします。 `eth2`キーには、ノードが使用しているイーサリアムフォークのバージョンに関する情報が含まれており、ピアが正しいイーサリアムに接続していることを確認できます。 ### libP2P {#libp2p} -libP2P スタックは、ディスカバリー後のすべての通信をサポートします。 クライアントは、ENR で定義された IPv4 および/または IPv6 でダイヤルおよびリッスンできます。 libP2P レイヤーのプロトコルは、ゴシップとリクエスト/レスポンスのドメインに細分化されます。 +libP2Pスタックは、ディスカバリー後のすべての通信をサポートします。 クライアントは、ENRで定義されたIPv4および/またはIPv6でダイヤルおよびリッスンできます。 libP2Pレイヤーのプロトコルは、ゴシップとリクエスト/レスポンスのドメインに細分化されます。 ### ゴシップ(Gossip) {#gossip} -ゴシップドメインは、ネットワーク全体に直ぐに広まる必要のあるすべての情報を含みます。 これには、ビーコンブロック、証明、アテステーション、イグジット、スラッシングが含まれます。 これは libP2P ゴシップサブ v1 を使って送信され、受信・送信するゴシップペイロードの最大サイズなどの各ノードにローカルに保存されている様々なメタデータに依存します。 ゴシップドメインに関する詳細な情報は、[こちら](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub)をご覧ください。 +ゴシップドメインは、ネットワーク全体に直ぐに広まる必要のあるすべての情報を含みます。 これには、ビーコンブロック、証明、アテステーション、イグジット、スラッシングが含まれます。 これはlibP2Pゴシップサブ v1を使って送信され、受信・送信するゴシップペイロードの最大サイズなどの各ノードにローカルに保存されている様々なメタデータに依存します。 ゴシップドメインに関する詳細な情報は、[こちら](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub)をご覧ください。 ### リクエスト/レスポンス(Request-response) {#request-response} -リクエスト/レスポンス・ドメインには、クライアントがピアに特定の情報を要求するためのプロトコルが含まれます。 例えば、あるルートハッシュに一致する特定のビーコンブロックや、スロット範囲内のビーコンブロックのリクエストなどがあります。 レスポンスは常に snappy(圧縮アルゴリズムの一つ)圧縮された SSZ エンコードバイトとして返されます。 +リクエスト/レスポンス・ドメインには、クライアントがピアに特定の情報を要求するためのプロトコルが含まれます。 例えば、あるルートハッシュに一致する特定のビーコンブロックや、スロット範囲内のビーコンブロックのリクエストなどがあります。 レスポンスは常にsnappy(圧縮アルゴリズムの一つ)圧縮されたSSZエンコードバイトとして返されます。 -## コンセンサスクライアントで RLP より SSZ が好まれる理由 {#ssz-vs-rlp} +## コンセンサスクライアントでRLPよりSSZが好まれる理由 {#ssz-vs-rlp} -SSZ は、シンプル・シリアライゼーションの略です。 SSZ は、固定オフセットを使うことで、構造全体をデコードすることなく、エンコードされたメッセージの個々の部分を簡単にデコードすることができます。これは、エンコードされたメッセージから特定の情報を効率的に取得できるため、コンセンサスクライアントにとって非常に便利な機能です。 また、マークルプロトコルと統合するように特別に設計されており、マークル化に関連した効率化も得られます。 コンセンサスレイヤーのハッシュはすべてマークルルートであるため、これは大きな改善となります。 また、SSZ は値の一意性も保証します。 +SSZは、シンプル・シリアライゼーションの略です。 SSZは、固定オフセットを使うことで、構造全体をデコードすることなく、エンコードされたメッセージの個々の部分を簡単にデコードすることができます。これは、エンコードされたメッセージから特定の情報を効率的に取得できるため、コンセンサスクライアントにとって非常に便利な機能です。 また、マークルプロトコルと統合するように特別に設計されており、マークル化に関連した効率化も得られます。 コンセンサスレイヤーのハッシュはすべてマークルルートであるため、これは大きな改善となります。 また、SSZは値の一意性も保証します。 ## 実行クライアントとコンセンサスクライアントの接続 {#connecting-clients} -コンセンサスクライアントと実行クライアントは、並列に動作します。 コンセンサスクライアントが実行クライアントに指示を出し、実行クライアントがコンセンサスクライアントにトランザクション・バンドルを渡してビーコンブロックに含めることができるように、両者は接続されている必要があります。 両クライアント間の通信は、ローカル RPC 接続を使用して実現することができます。 [「エンジン API」](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md) と呼ばれる API が、両クライアント間で送信される命令を定義します。 両クライアントは単一のネットワーク ID の背後に位置するため、各クライアントの個別のキー(eth1 キーと eth2 キー)を含む ENR(イーサリアムノードレコード)を共有します。 +コンセンサスクライアントと実行クライアントは、並列に動作します。 コンセンサスクライアントが実行クライアントに指示を出し、実行クライアントがコンセンサスクライアントにトランザクション・バンドルを渡してビーコンブロックに含めることができるように、両者は接続されている必要があります。 両クライアント間の通信は、ローカルRPC接続を使用して実現することができます。 [「エンジンAPI」](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md) と呼ばれるAPIが、両クライアント間で送信される命令を定義します。 両クライアントは単一のネットワークIDの背後に位置するため、各クライアントの個別のキー(eth1キーとeth2キー)を含むENR(イーサリアムノードレコード)を共有します。 制御フローの概要を以下に示します。括弧内は関連するネットワークスタックです。 ### コンセンサスクライアントがブロック生成者でない場合: -- コンセンサスクライアントがブロック・ゴシップ・プロトコル(コンセンサス p2p)を介してブロックを受信する +- コンセンサスクライアントがブロック・ゴシップ・プロトコル(コンセンサスp2p)を介してブロックを受信する - コンセンサスクライアントはブロックを事前に検証し、確正しいメタデータを持つ有効な送信者からのものであることを確実にする -- ブロックのトランザクションが実行ペイロードとして実行レイヤーに送信される(ローカル RPC 接続) +- ブロックのトランザクションが実行ペイロードとして実行レイヤーに送信される(ローカルRPC接続) - 実行レイヤーはトランザクションを実行し、ブロックヘッダーの状態を検証する(ハッシュ値の一致をチェックする) -- 実行レイヤーは検証データをコンセンサスレイヤーに返し、ブロックは検証済みとみなされる(ローカル RPC 接続) -- コンセンサスレイヤーはブロックを自分のブロックチェーンの先頭に追加して証明し、そのアテステーション(証明)をネットワーク上にブロードキャストする(コンセンサス p2p) +- 実行レイヤーは検証データをコンセンサスレイヤーに返し、ブロックは検証済みとみなされる(ローカルRPC接続) +- コンセンサスレイヤーはブロックを自分のブロックチェーンの先頭に追加して証明し、そのアテステーション(証明)をネットワーク上にブロードキャストする(コンセンサスp2p) ### コンセンサスクライアントがブロック生成者の場合: - コンセンサスクライアントが次のブロック生成者であることを通知される(consensus p2p) -- コンセンサスレイヤーが実行クライアントの`create block`メソッドを呼び出す(ローカル RPC) -- 実行レイヤーは、トランザクション・ゴシップ・プロトコルによって生成されたトランザクション・メンプールにアクセスする(実行 p2p) +- コンセンサスレイヤーが実行クライアントの`create block`メソッドを呼び出す(ローカルRPC) +- 実行レイヤーは、トランザクション・ゴシップ・プロトコルによって生成されたトランザクション・メンプールにアクセスする(実行p2p) - 実行クライアントはトランザクションをブロックにまとめ、トランザクションを実行し、ブロックハッシュを生成する -- コンセンサスクライアントは実行クライアントからトランザクションとブロックハッシュを取得し、ビーコンブロックに追加する(ローカル RPC) -- コンセンサスクライアントは、ブロック・ゴシップ・プロトコルでブロックをブロードキャストする(コンセンサス p2p) -- 他のクライアントが、ブロック・ゴシップ・プロトコルで提案されたブロックを受信し、上記のように検証する(コンセンサス p2p) +- コンセンサスクライアントは実行クライアントからトランザクションとブロックハッシュを取得し、ビーコンブロックに追加する(ローカルRPC) +- コンセンサスクライアントは、ブロック・ゴシップ・プロトコルでブロックをブロードキャストする(コンセンサスp2p) +- 他のクライアントが、ブロック・ゴシップ・プロトコルで提案されたブロックを受信し、上記のように検証する(コンセンサスp2p) 十分な数のバリデータによってブロックが認証されると、チェーンの先頭に追加され、正当性が確認された後、最終的に確定(ファイナライズ)される。 @@ -152,4 +152,4 @@ SSZ は、シンプル・シリアライゼーションの略です。 SSZ は ## 参考文献 {#further-reading} -[DevP2P](https://github.com/ethereum/devp2p) [LibP2p](https://github.com/libp2p/specs) [コンセンサスレイヤーネットワークの仕様](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#enr-structure) カデムリアから discv5[discv5](https://vac.dev/kademlia-to-discv5) [カデムリアペーパー](https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf) [Ethereum ピアツーピア入門](https://p2p.paris/en/talks/intro-ethereum-networking/) [eth1eth2 の関係](http://ethresear.ch/t/eth1-eth2-client-relationship/7248) [マージと eth2 クライアントの詳細に関するビデオ](https://www.youtube.com/watch?v=zNIrIninMgg) +[DevP2P](https://github.com/ethereum/devp2p) [LibP2p](https://github.com/libp2p/specs) [コンセンサスレイヤーネットワークの仕様](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#enr-structure) カデムリアからdiscv5[discv5](https://vac.dev/kademlia-to-discv5) [カデムリアペーパー](https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf) [Ethereumピアツーピア入門](https://p2p.paris/en/talks/intro-ethereum-networking/) [eth1eth2の関係](http://ethresear.ch/t/eth1-eth2-client-relationship/7248) [マージとeth2クライアントの詳細に関するビデオ](https://www.youtube.com/watch?v=zNIrIninMgg) diff --git a/public/content/translations/ja/developers/docs/networking-layer/network-addresses/index.md b/public/content/translations/ja/developers/docs/networking-layer/network-addresses/index.md index 987bb67327d..8f73d42338a 100644 --- a/public/content/translations/ja/developers/docs/networking-layer/network-addresses/index.md +++ b/public/content/translations/ja/developers/docs/networking-layer/network-addresses/index.md @@ -5,7 +5,7 @@ lang: ja sidebarDepth: 2 --- -イーサリアムノードがピアに接続するには、いくつかの基本情報で自分自身を識別する必要があります。 潜在的なピアがこの情報を解釈できるようにするため、イーサリアムノードが理解できる 3 つの標準化されたフォーマット(multiaddr、enode、イーサリアム・ノード・レコード(ENR))のいずれかで伝えられます。 なお、イーサリアム・ノード・レコード(ENR)はイーサリアム・ネットワークアドレスの現在の標準です。 +イーサリアムノードがピアに接続するには、いくつかの基本情報で自分自身を識別する必要があります。 潜在的なピアがこの情報を解釈できるようにするため、イーサリアムノードが理解できる3つの標準化されたフォーマット(multiaddr、enode、イーサリアム・ノード・レコード(ENR))のいずれかで伝えられます。 なお、イーサリアム・ノード・レコード(ENR)はイーサリアム・ネットワークアドレスの現在の標準です。 ## 前提知識 {#prerequisites} @@ -13,25 +13,25 @@ sidebarDepth: 2 ## マルチアドレス(Multiaddr) {#multiaddr} -元々、イーサリアムノードのアドレス形式は「multiaddr」(マルチアドレスの略)でした。 Multiaddr は、ピアツーピアネットワーク用に設計された汎用フォーマットです。 アドレスは、キーと値をスラッシュで区切った key-value のペアで表現されます。 例えば、IPv4 アドレス`192.168.22.27`で TCP ポート`33000`をリッスンしているノードの multiaddr は、次のようになります。 +元々、イーサリアムノードのアドレス形式は「multiaddr」(マルチアドレスの略)でした。 Multiaddrは、ピアツーピアネットワーク用に設計された汎用フォーマットです。 アドレスは、キーと値をスラッシュで区切ったkey-valueのペアで表現されます。 例えば、IPv4アドレス`192.168.22.27`でTCPポート`33000`をリッスンしているノードのmultiaddrは、次のようになります。 `/ip4/192.168.22.27/tcp/33000` -イーサリアムノードの場合、multiaddr にノード ID(公開鍵のハッシュ値)が含まれます。 +イーサリアムノードの場合、multiaddrにノードID(公開鍵のハッシュ値)が含まれます。 `/ip4/192.168.22.27/tcp/33000/p2p/5t7Nv7dG2d6ffbvAiewVsEwWweU3LdebSqX2y1bPrW8br` ## enode {#enode} -enode とは、URL アドレス形式を用いたイーサリアムノードの識別方法です。 16 進数のノード ID は、URL のユーザーネーム部分がエンコードされ、@記号を用いてホストと区切られます。 ホスト名には IP アドレスのみを指定することができ、DNS 名は指定できません。 ホスト名セクションのポートは、TCP リスニングポートです。 TCP ポートと UDP(ディスカバリー)ポートが異なる場合は、UDP ポートをクエリパラメータ 「discport 」で指定します。 +enodeとは、URLアドレス形式を用いたイーサリアムノードの識別方法です。 16進数のノードIDは、URLのユーザーネーム部分がエンコードされ、@記号を用いてホストと区切られます。 ホスト名にはIPアドレスのみを指定することができ、DNS名は指定できません。 ホスト名セクションのポートは、TCPリスニングポートです。 TCPポートとUDP(ディスカバリー)ポートが異なる場合は、UDPポートをクエリパラメータ 「discport 」で指定します。 -次の例では、ノード URL は IP アドレス`10.3.58.6`、TCP ポート`30303`、UDP ディスカバリーポート `30301`のノードを記述しています。 +次の例では、ノードURLはIPアドレス`10.3.58.6`、TCPポート`30303`、UDPディスカバリーポート `30301`のノードを記述しています。 `enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301` ## イーサリアム・ノード・レコード(ENR) {#enr} -イーサリアム・ノード・レコード(ENR) は、イーサリアム 上のネットワークアドレス用に標準化されたフォーマットです。 ENR は、multiaddr と enode に取って代わるものです。 ENR はノード間でより大きな情報交換を可能にするため、特に有用です。 ENR には署名、シーケンス番号、および署名の生成と検証に使用される ID スキームの詳細を示すフィールドが含まれます。 ENR には、key-value ペアとして編成された任意のデータを入力することも可能です。 これらの key-value ペアには、ノードの IP アドレスと、ノードが使用できるサブプロトコルの情報が含まれています。 コンセンサスクライアントは、ブートノードを特定するために [固有の ENR 構造](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#enr-structure)を使用し、現在のイーサリアムフォークとアテステーション(認証)ゴシップサブネットに関する情報を含む`eth2`フィールドを含みます(これにより、アテステーションが集約されている特定のピアセットにノードを接続します)。 +イーサリアム・ノード・レコード(ENR) は、イーサリアム 上のネットワークアドレス用に標準化されたフォーマットです。 ENRは、multiaddrとenodeに取って代わるものです。 ENRはノード間でより大きな情報交換を可能にするため、特に有用です。 ENRには署名、シーケンス番号、および署名の生成と検証に使用されるIDスキームの詳細を示すフィールドが含まれます。 ENRには、key-valueペアとして編成された任意のデータを入力することも可能です。 これらのkey-valueペアには、ノードのIPアドレスと、ノードが使用できるサブプロトコルの情報が含まれています。 コンセンサスクライアントは、ブートノードを特定するために [固有のENR構造](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#enr-structure)を使用し、現在のイーサリアムフォークとアテステーション(認証)ゴシップサブネットに関する情報を含む`eth2`フィールドを含みます(これにより、アテステーションが集約されている特定のピアセットにノードを接続します)。 ## 参考文献 {#further-reading} diff --git a/public/content/translations/ja/developers/docs/networking-layer/portal-network/index.md b/public/content/translations/ja/developers/docs/networking-layer/portal-network/index.md new file mode 100644 index 00000000000..8b2327ad5ac --- /dev/null +++ b/public/content/translations/ja/developers/docs/networking-layer/portal-network/index.md @@ -0,0 +1,82 @@ +--- +title: ポータルネットワーク +description: リソースが少ないクライアントをサポートするように設計され、現在開発中のネットワークである「ポータルネットワーク」の概要 +lang: ja +--- + +イーサリアムは、イーサリアムクライアントソフトウェアを実行するコンピュータによって構成されるネットワークです。 これらの各コンピュータは、「ノード」と呼ばれます。 クライアントソフトウェアは、イーサリアムネットワーク上でデータの送受信を行い、イーサリアムプロトコルのルールに従ってデータを検証します。 ノードは、自身のディスクストレージ内に大量の履歴データを保存し、ネットワーク上にある他のノードからブロックとして知られる新しいパケット情報を受信すると、その履歴データに追加します。 このデータは、ノードが他のネットワークと一貫した情報を持っていることを常時確認するために必要となります。 つまり、ノードの実行には大量のディスクスペースが必要ということになります。 また、一部のノードの操作では、大量のRAMが必要になる場合があります。 + +そこで、このディスクストレージに関する問題を回避するために、すべての情報をクライアント自身に保存する代わりに、フルノードへ情報をリクエストする「ライト」ノードが開発されました。 しかし、ライトノードは自分で情報を検証できないため、代わりに別のノードを信用する必要があります。 つまり、ライトノードに情報を提供するために、フルノードが追加の処理を行う必要があるということになります。 + +ポータルネットワークは、イーサリアムにおける新たなネットワーク設計です。フルノードを信頼することなく、余計な負担をかけずに、必要なデータをネットワーク全体で小さな塊に分けて共有することで、「ライト」ノードのデータ可用性問題を解決することを目指しています。 + +[ノードとクライアントの詳細](/developers/docs/nodes-and-clients/) + +## ポータルネットワークが必要な理由 {#why-do-we-need-portal-network} + +イーサリアムノードは、イーサリアムブロックチェーンの全部または一部のコピーを保存します。 このローカルコピーを使って、トランザクションを検証し、ノードが正しいチェーンに進むよう徹底します。 また、このローカルに保存したデータにより、受信データが有効かつ正当であることを、他のエンティティを信頼せずに独立して検証できます。 + +ブロックチェーンのローカルコピーや、それに関連付いた状態およびレシートデータなどは、ノードのハードディスク容量を大量に消費します。 例えば、コンセンサスクライアントをペアにした[Geth](https://geth.ethereum.org)ノードを立ち上げるには、2 TBのハードディスクが推奨されています。 スナップ同期を使用すると、比較的最近のブロックのセットがもつチェーンデータのみを保存しますが、Gethでは一般的に、約650 GBのディスク容量を使います。また、一週間で約14 GB増加します(ノードを定期的に650 GBへプルーニングできます)。 + +イーサリアムでは大容量のディスクスペースを必要とするため、ノードを立ち上げるには高額な費用がかかる可能性があります。 一方、[履歴の有効期限](/roadmap/statelessness/#history-expiry)、[状態の有効期限](/roadmap/statelessness/#state-expiry)、[ステートレス](/roadmap/statelessness/)など、この問題に対するいくつかの解決策がイーサリアムのロードマップに記載されています。 しかし、これらの解決策の実装には数年を要すると考えられています。 また、チェーンデータのコピーを自身で保存せず、必要なデータをフルノードへリクエストする[ライトノード](/developers/docs/nodes-and-clients/light-clients/)があります。 ただし、ライトノードは正直なデータを提供するためにフルノードを信頼する必要があり、フルノードはライトノードが必要とするデータを提供しなければならないため負荷がかかります。 + +ポータルネットワークは、ライトノードがデータを取得する代替方法を提供することを目指しています。この方法では、フルノードを信頼する必要がなく、フルノードで実行する処理を大幅に追加する必要もありません。 イーサリアムノードがネットワーク全体でデータを共有する新たな方法を導入することで、これを実現します。 + +## ポータルネットワークの仕組み {#how-does-portal-network-work} + +厳密なプロトコルによって、イーサリアムノードが相互に通信する方法が定義されています。 実行クライアントは、[DevP2P](/developers/docs/networking-layer/#devp2p)と呼ばれるサブプロトコルのセットを使用して通信します。一方、コンセンサスクライアントは、[libP2P](/developers/docs/networking-layer/#libp2p)と呼ばれる別のサブプロトコルのスタックを使用します。 これらのプロトコルは、ノード間で受け渡せるデータのタイプを定義します。 + +![devP2PおよびlibP2P](portal-network-devp2p-libp2p.png) + +ノードは、[JSON-RPC API](/developers/docs/apis/json-rpc/)を通して特定のデータを提供することもできます。このAPIにより、アプリやウォレットは、イーサリアムノードと情報を交換できます。 しかし、ライトクライアントへデータを提供する理想的なプロトコルは存在していません。 + +現状では、ライトクライアントは、DevP2PまたはlibP2pを使って、特定のチェーンデータの一部分をリクエストすることができません。これらのプロトコルは、チェーンの同期、ブロックとトランザクションのゴシップのみを目的に設計されているからです。 ライトクライアントがこの情報をダウンロードすると、クライアントが「ライト」でなくなるため、適切ではありません。 + +JSON-RPC APIは、ライトクライアントのデータリクエストに理想的な選択肢ではありません。データを提供する特定のフルノードまたは集中型のRPCプロバイダーへの接続に依存しているためです。 これでは、ライトクライアントは、特定のノードもしくはプロバイダーが正直であることを信頼する必要があります。また、フルノードは、多数のライトクライアントから来る大量のリクエストを処理する必要があります。これでは、通信帯域要件が増えてしまいます。 + +ポータルネットワークのポイントとしては、既存のイーサリアムクライアントの設計制約を除き、全体を再設計し、軽量化に焦点を合わせて構築することです。 + +ポータルネットワークのコアとなるアイデアは、現在のネットワークスタックの最良の部分を活用することです。これを実現するには、[DHT](https://en.wikipedia.org/wiki/Distributed_hash_table)(Bittorrentと類似)を使って、履歴データや現在のチェーンヘッドのアイデンティティを軽量のDevP2P形式のピアツーピア分散型ネットワークを介して提供し、ライトクライアントによって必要とされる情報を有効化します。 + +このアイデアは、各ノードにイーサリアム全体の履歴データの一部を割り当て、特定の具体的な役割を追加することです。 その結果、リクエストされた特定のデータが保存されているノードを探し出し、そのデータを取得して提供することができます。 + +ライトノードは、これまでは1つのノードに大量のデータをフィルタリングしてもらっていました。しかし、今後は、ライトノードのネットワーク全体で素早くフィルタリングを行うことで、各ノードのデータ処理量を小さくしていきます。 + +目標は、ライトウェイトポータルクライアントの分散ネットワークで次のことを可能にすることです。 + +- チェーンヘッドの追跡 +- 直近と過去のチェーンデータの同期 +- 状態データの検索 +- トランザクションのブロードキャスト +- [EVM](/developers/docs/evm/)を使ったトランザクションの実行 + +このネットワーク設計による利点は、次の通りです。 + +- 集中化したプロバイダーへの依存が減る +- インターネット帯域使用量が減る +- 同期が短くなる、または同期が不要になる +- リソースに制約のあるデバイスでもアクセスできる(1GB以下のメモリ、100MB以下のディスク、1CPU) + +以下の図は、ポータルネットワークでやり取りできる現行のクライアントの機能を示しています。ユーザーは、非常に少ないリソースのデバイスでも、これらの機能にアクセスできます。 + +![ポータルネットワークテーブル](portal-network-table2.png) + +## デフォルトのクライアント多様性 {#client-diversity-as-default} + +ポータルネットワークのデベロッパーは、最初から3種類のポータルネットワーククライアントを構築することを決めていました。 + +ポータルネットワークのクライアントは、以下の通りです。 + +- [Trin](https://github.com/ethereum/trin): Rustで開発 +- [Fluffy](https://nimbus.team/docs/fluffy.html): Nimで開発 +- [Ultralight](https://github.com/ethereumjs/ultralight): Typescriptで開発 + +依存しないクライアント実装が複数存在することで、イーサリアムネットワークの回復力と分散化が強化されます。 + +1つのクライアントに問題や脆弱性が生じても、他のクライアントは通常通り運用を続けられるため、単一障害点を防ぐことができます。 また、多様なクライアントの実装により、イノベーションと競争が促進されるだけでなく、エコシステム内の改善が促進され、単一文化によるリスクが軽減されます。 + +## 参考文献 {#futher-reading} + +- [ポータルネットワーク(ボゴタ開発者会議でのPiper Merriamによる発表)](https://www.youtube.com/watch?v=0stc9jnQLXA) +- [ポータルネットワークのDiscord](https://discord.gg/CFFnmE7Hbs) +- [ポータルネットワークのウェブサイト](https://www.ethportal.net/) diff --git a/public/content/translations/ja/developers/docs/nodes-and-clients/archive-nodes/index.md b/public/content/translations/ja/developers/docs/nodes-and-clients/archive-nodes/index.md new file mode 100644 index 00000000000..c850d1e148b --- /dev/null +++ b/public/content/translations/ja/developers/docs/nodes-and-clients/archive-nodes/index.md @@ -0,0 +1,80 @@ +--- +title: イーサリアム・アーカイブノード +description: アーカイブノードの概要 +lang: ja +sidebarDepth: 2 +--- + +アーカイブノードは、すべての状態の履歴をもつアーカイブをビルドするように構成されたイーサリアムクライアントのインスタンスです。 特定のユースケースにおいて、アーカイブノードは便利なツールですが、フルノードよりも実行する難易度が高くなっています。 + +## 前提知識 {#prerequisites} + +[イーサリアムノード](/developers/docs/nodes-and-clients/)のコンセプト、 [アーキテクチャ](/developers/docs/nodes-and-clients/node-architecture/)、[同期戦略](/developers/docs/nodes-and-clients/#sync-modes)、[実行](/developers/docs/nodes-and-clients/run-a-node/)の経験、[ノードの使用](/developers/docs/apis/json-rpc/)などの知識があることを前提にしています。 + +## アーカイブノードとは + +アーカイブノードの重要性を理解するには、まず「状態」の概念を明確にする必要があります。 イーサリアムは、_トランザクションベースの状態マシン_と言えます。 トランザクションを実行するアカウントとアプリケーションで構成され、トランザクションはイーサリアムの状態を変更します。 各アカウントおよびコントラクトに関する情報を持つグローバルデータは、状態と呼ばれるツリーデータベースに保存されます。 グローバルデータは、実行レイヤー(EL)クライアントが管理します。具体的には、以下のものが含まれます。 + +- アカウント残高とノンス +- コントラクトコードとストレージ +- コンセンサス関連のデータ(例: ステーキングデポジットコントラクト) + +イーサリアムクライアントでは、ネットワークとやり取りし、新しいブロックを検証・生成するために、常に最新の状態である「最新の変更(チェーンの先端)」を把握している必要があります。 フルノードとして構成された実行レイヤークライアントは、ネットワークの最新の状態を検証・追跡しますが、一部の過去の状態のみをキャッシュします。例えば、 最後の128ブロックに関連付けられた状態では、チェーンの再編成を処理して、最新のデータに素早くアクセスすることができます。 この最新の状態は、すべてのクライアントにおいて受信したトランザクションを検証するのに必要であり、ネットワークで使用されます。 + +状態は、特定のブロックにおけるネットワークの状態を瞬間的に記録したスナップショットであり、アーカイブは、ネットワークの状態の履歴を再生したものと考えることができます。 + +状態の履歴は、安全に取り除くことができます。これは、ネットワークの動作には関係なく、クライアントが古いデータをすべて保持しても意味がないためです。 最近のブロック(例: 先頭から128ブロック)より前の状態は、事実上破棄されます。 フルノードは、ブロックチェーンの履歴データ(ブロックとトランザクション)と、リクエストに応じて古い状態を再生成するのに使用する予備のスナップショットの履歴のみを保存しています。 再生成は、EVMで過去のトランザクションを再実行することによって行われます。取得したい状態が最も近いスナップショットからか遠く離れている場合、計算負荷が高くなる傾向があります。 + +フルノードで状態の履歴にアクセスするには、大量の計算が必要です。 クライアントでは、過去のトランザクションをすべて実行して、ジェネシスから1つの状態の履歴を計算する必要があるかもしれません。 アーカイブノードは、最新の状態だけでなく、各ブロックの後に作成されたすべての状態の履歴を保存することで、計算負荷の問題を解決します。 ただし、ディスク容量が大きくなってしまうというデメリットもあります。 + +ネットワークでは、すべての履歴データを保存・提供するのに、アーカイブノードに依存していないことが重要です。 上記で述べたように、すべての状態の一時的な履歴は、フルノードから導出することができます。 トランザクションは、どのフルノード(現在は400G未満)にも保存されています。これらのトランザクションを再実行することで、アーカイブ全体を構築することができます。 + +### ユースケース + +トランザクションの送信、コントラクトのデプロイ、コンセンサスの検証など、通常のイーサリアムの用途では、状態の履歴にアクセスする必要はありません。 そのため、通常のネットワークでのやり取りにおいて、ユーザーはアーカイブノードを必要としません。 + +状態のアーカイブによる主なメリットは、状態の履歴に関するクエリに素早くアクセスできることです。 例えば、アーカイブノードは、次の結果を即座に返します。 + +- _ブロック15537393におけるアカウント 0x1337... が持っているETHの残高はいくらか?_ +- _ブロック1920000におけるコントラクト0xのトークン0xの残高はいくらか?_ + +上述したように、フルノードでは、EVMを実行してこのデータを生成する必要があります。これはCPUを使用し、処理に時間がかかります。 一方、アーカイブノードでは、ディスク上のデータにアクセスするため、即座に応答を返すことができます。 これは、インフラストラクチャの側面において、以下の役割を担う人に役立ちます。 + +- ブロックエクスプローラなどのサービスプロバイダー +- 研究者 +- セキュリティアナリスト +- Dappデベロッパー +- 監査とコンプライアンス + +履歴データにアクセスできる無料の[サービス](/developers/docs/nodes-and-clients/nodes-as-a-service/)がいくつかあります。 アーカイブノードは実行時に要求事項が多く、その大半にアクセス制限があるため、頻度の低いアクセスには適していますが、 履歴データに常時アクセスが必要なプロジェクトにおいては、独自で実行することを検討してください。 + +## 実装と利用方法 + +この文脈でのアーカイブノードとは、状態データベースを処理してJSON-RPCエンドポイントを提供する、ユーザー向けの実行レイヤークライアントによって提供されるデータを指します。 設定オプション、同期時間、データベースサイズなどは、クライアントによって異なる場合があります。 詳細は、クライアントのドキュメントを参照してください。 + +独自にアーカイブノードを立ち上げる前に、各クライアントの[ハードウェア要件](/developers/docs/nodes-and-clients/run-a-node/#requirements)などの違いを把握しておきましょう。 ほとんどのクライアントにおいて、アーカイブ機能は最適化されていないため、12TB以上のスペースが必要になります。 その一方で、エリゴンのような実装では、同じデータを3TB未満に保存できるため、アーカイブノードを実行するのに最適な方法となります。 + +## 推奨実行環境 + +アーカイブノードは、[ノードの実行における一般的な推奨事項](/developers/docs/nodes-and-clients/run-a-node/)とは異なり、ハードウェアとメンテナンスの要件がより厳しくなっています。 そのため、エリゴンの[主要な機能](https://github.com/ledgerwatch/erigon#key-features)を考慮すると、[エリゴン](/developers/docs/nodes-and-clients/#erigon)のクライアント実装を使うのが最も実用的であると言えます。 + +### ハードウェア + +クライアントのドキュメントで、所定のモードの要件を必ず確認するようにしてください。 アーカイブノードでは、ディスクスペースが最大の要件となります。 クライアントにもよりますが、3TBから12TBが必要になります。 HDDは、大容量データの保存には適しているかもしれませんが、同期して常にチェーンの先頭を更新するには、SSDドライブが必要です。 [SATA](https://www.cleverfiles.com/help/sata-hard-drive.html)ドライブでも十分ですが、最低でも [TLC](https://blog.synology.com/tlc-vs-qlc-ssds-what-are-the-differences)以上の品質のものを選びましょう。 ディスクは、十分なスロットがあるデスクトップコンピュータまたはサーバーが適しています。 このような専用デバイスは、稼働時間の長いノードに最適です。 ノートパソコンで実行しても全く問題ありませんが、移植性の面で追加コストがかかります。 + +全データを1つのボリュームに収めるため、複数のディスクを [RAID0](https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_0)や[LVM](https://web.mit.edu/rhel-doc/5/RHEL-5-manual/Deployment_Guide-en-US/ch-lvm.html)を使って結合する必要があります。 [ZFS](https://en.wikipedia.org/wiki/ZFS)では、低レベルのエラーの影響を受けずに正しいデータを確実に書き込む「コピーオンライト」をサポートしているため、検討する価値があるかもしれません。 + +特に専門的なセットアップにおいては、さらなる安定性とセキュリティのために、偶発的なデータベースの破損を防ぐ[ECCメモリ](https://en.wikipedia.org/wiki/ECC_memory)の使用を検討してください。 RAMのサイズは通常、フルノードと同等のサイズにすることが推奨されますが、RAMのサイズが大きいほど、同期の速度は向上します。 + +アーカイブモードのクライアントは、最初の同期中に、ジェネシス以降のすべてのトランザクションを実行します。 CPUによって実行速度が異なるため、CPUが高速であれば、最初の同期にかかる時間を短くすることができます。 通常のコンシューマー向けのコンピューターでは、最初の同期に最大1か月程度かかる場合があります。 + +## 参考文献 {#further-reading} + +- [イーサリアムフルノードとアーカイブノードの比較](https://www.quicknode.com/guides/infrastructor/ethereum-full-node-vs-archive-node) - *QuickNode、2022年9月* +- [自分のイーサリアムアーカイブノードを構築する](https://tjayrush.medium.com/building-your-own-ethereum-archive-node-72c014affc09) - _Thomas Jay Rush、2021年8月_ +- [エリゴン、エリゴンのRPC、TrueBlocks(スクレイピングとAPI)をサービスとしてセットアップする方法](https://magnushansson.xyz/blog_posts/crypto_defi/2022-01-10-Erigon-Trueblocks) _ – Magnus Hansson、2022年9月更新_ + +## 関連トピック {#related-topics} + +- [ ノードとクライアント](/developers/docs/nodes-and-clients/) +- [ノードの運用](/developers/docs/nodes-and-clients/run-a-node/) diff --git a/public/content/translations/ja/developers/docs/nodes-and-clients/bootnodes/index.md b/public/content/translations/ja/developers/docs/nodes-and-clients/bootnodes/index.md new file mode 100644 index 00000000000..9953360a995 --- /dev/null +++ b/public/content/translations/ja/developers/docs/nodes-and-clients/bootnodes/index.md @@ -0,0 +1,31 @@ +--- +title: イーサリアムブートノードの概要 +description: ブートノードを理解するための基礎知識。 +lang: ja +--- + +新しいノードがイーサリアムのネットワークに参加する際には、既存のノードに接続して、新しいピアを検出しなければなりません。 イーサリアムネットワークへのエントリポイントとなるこれらのノードをブートノードと呼びます。 クライアントは通常、ブートノードのリストをハードコードしています。 これらのブートノードは通常、イーサリアム・ファウンデーションのDevopsチームまたはクライアントチームによって実行されています。 ブートノードは、静的ノードとは異なるという点に注意してください。 静的ノードは何度も呼び出されますが、ブートノードは、接続するピアが十分にない場合や、ノードが自力で新しい接続をする必要がある場合にのみ呼び出されます。 + +## ブートノードへの接続 {#connect-to-a-bootnode} + +クライアントには、ほとんどブートノードのリストが組み込まれていますが、自分のブートノードを実行したり、クライアントにハードコードされているリストに載っていないブートノードも使用することができます。 そのような場合は、クライアントの起動時に、以下のように指定します。これはGethの例です。各クライアントのドキュメントを確認してください 。 + +``` +geth --bootnodes "enode://@:" +``` + +## ブートノードの起動 {#run-a-bootnode} + +ブートノードとは、NAT([ネットワークアドレス変換](https://www.geeksforgeeks.org/network-address-translation-nat/))の背後にないフルノードのことを指します。 公開されているフルノードは、すべてブートノードとして動作します。 + +ノードを起動すると、[enode](/developers/docs/networking-layer/network-addresses/#enode)がログに記録されます。これは、他のユーザーがあなたのノードに接続するための公開識別子です。 + +通常、enodeは再起動するたびに再び生成されます。ブートノードで永続的なenodeを生成する方法については、クライアントのドキュメントを必ず参照してください。 + +ブートノードの性能を高めるには、接続可能なピアの最大数を増やすことをお勧めします。 多数のピアでブートノードを実行すると、必要な帯域幅が大幅に増加することに注意してください。 + +## 使用可能なブートノード {#available-bootnodes} + +go-ethereum内にある組み込みブートノードのリストは、[こちら](https://github.com/ethereum/go-ethereum/blob/master/params/bootnodes.go#L23)で確認できます。 これらのブートノードは、イーサリアム・ファウンデーションとgo-ethereumチームによってメンテナンスされています。 + +ボランティアによって管理されている、他のブートノードのリストもあります。 少なくとも1つの公式ブートノードを必ず含めるようにしてください。公式ブートノードを含めないと、イクリプス攻撃を受ける可能性があります。 diff --git a/public/content/translations/ja/developers/docs/nodes-and-clients/client-diversity/index.md b/public/content/translations/ja/developers/docs/nodes-and-clients/client-diversity/index.md index 18a2d42bb82..e45dead9146 100644 --- a/public/content/translations/ja/developers/docs/nodes-and-clients/client-diversity/index.md +++ b/public/content/translations/ja/developers/docs/nodes-and-clients/client-diversity/index.md @@ -25,15 +25,15 @@ sidebarDepth: 2 ### 攻撃耐性 {#resilience} -クライアントの多様性は、攻撃に対する耐性も同時にもたらします。 例えば、[特定のクライアントに対する攻撃](https://twitter.com/vdWijden/status/1437712249926393858)で不正なチェーンへと改ざんしようとする試みが成功する可能性は低くなります。これは、他のクライアントに同じような攻撃ができる可能性は低く、正規のチェーンは壊れないためです。 クライアントの多様性が低いほど、多数派のクライアントへの攻撃に関するリスクが高まります。 クライアントの多様性がネットワーク上の悪意のある攻撃に対する重要な防御となることは、既に証明されています。例えば、2016 年の上海 DOS 攻撃の事例は、多数派のクライアント(Geth)に対して、ブロックごとに何万回も遅いディスク i/o 操作を実行したため起こりました。 この脆弱性を持たない他のクライアントもオンラインであったため、イーサリアムは Geth の脆弱性が修正されている間も攻撃に耐え、稼働を続けることができました。 +クライアントの多様性は、攻撃に対する耐性も同時にもたらします。 例えば、[特定のクライアントに対する攻撃](https://twitter.com/vdWijden/status/1437712249926393858)で不正なチェーンへと改ざんしようとする試みが成功する可能性は低くなります。これは、他のクライアントに同じような攻撃ができる可能性は低く、正規のチェーンは壊れないためです。 クライアントの多様性が低いほど、多数派のクライアントへの攻撃に関するリスクが高まります。 クライアントの多様性がネットワーク上の悪意のある攻撃に対する重要な防御となることは、既に証明されています。例えば、2016年の上海DOS攻撃の事例は、多数派のクライアント(Geth)に対して、ブロックごとに何万回も遅いディスクi/o操作を実行したため起こりました。 この脆弱性を持たない他のクライアントもオンラインであったため、イーサリアムはGethの脆弱性が修正されている間も攻撃に耐え、稼働を続けることができました。 ### プルーフ・オブ・ステークにおけるファイナリティ {#finality} -イーサリアムノードの 33%以上を占めるコンセンサスクライアントのバグがあると、ビーコンチェーンのファイナライズを妨げる可能性があります。つまり、トランザクションの取り消しや改ざんが発生するおそれがあります。 これはイーサリアム上に構築された多くのアプリ、特に分散型金融(DeFi)にとって非常に大きな問題となります。 +イーサリアムノードの33%以上を占めるコンセンサスクライアントのバグがあると、コンセンサスレイヤーのファイナライズを妨げる可能性があります。つまり、トランザクションの取り消しや改ざんが発生するおそれがあります。 これはイーサリアム上に構築された多くのアプリ、特に分散型金融(DeFi)にとって非常に大きな問題となります。 - さらに、3 分の 2 のマジョリティを占めるクライアントの重大なバグにより、チェーンが誤って スプリットし、ファイナライズされ、大量のバリデータが無効なチェーン上で立ち往生する可能性があります。 これらのバリデータが正しいチェーンに再び参加しようとする場合、スラッシングのペナルティを受けるか、時間がかかり高額となる任意退出後に、再度アクティベーションを行います。 スラッシングの規模は過失のあるノードの数に比例し、3 分の 2 のマジョリティが最大のスラッシング(32 ETH)を受けます。 + さらに、3分の2のマジョリティを占めるクライアントの重大なバグにより、チェーンが誤って スプリットし、ファイナライズされ、大量のバリデータが無効なチェーン上で立ち往生する可能性があります。 これらのバリデータが正しいチェーンに再び参加しようとする場合、スラッシングのペナルティを受けるか、時間がかかり高額となる任意退出後に、再度アクティベーションを行います。 スラッシングの規模は過失のあるノードの数に比例し、3分の2のマジョリティが最大のスラッシング(32 ETH)を受けます。 -これらは可能性が低いシナリオですが、アクティブなノードにクライアントを均等に分散することで、イーサリアムのエコシステムはリスクを軽減することが出来ます。 特定のコンセンサスクライアントが、全ノードの 33%のシェアを占めないことが理想です。 +これらは可能性が低いシナリオですが、アクティブなノードにクライアントを均等に分散することで、イーサリアムのエコシステムはリスクを軽減することが出来ます。 特定のコンセンサスクライアントが、全ノードの33%のシェアを占めないことが理想です。 ### 責任の共有 {#responsibility} @@ -43,15 +43,15 @@ sidebarDepth: 2 ![クライアントの多様性を示す円グラフ](./client-diversity.png) _図のデータは[ethernodes.org](https://ethernodes.org)と[clientdiversity.org](https://clientdiversity.org/)から引用_ -上の 2 つの円グラフは、実行レイヤーとコンセンサスレイヤーの現在(2022 年 1 月の執筆時点)のクライアントの多様性のスナップショットを示しています。 実行レイヤーの大多数は[Geth](https://geth.ethereum.org/)が占めており、1 位と大差をつけて[Open Ethereum](https://openethereum.github.io/)が 2 位、次に[Erigon](https://github.com/ledgerwatch/erigon)、[Nethermind](https://nethermind.io/)と続きますが、その他のクライアントはネットワークの 1%未満に過ぎません。 コンセンサスレイヤーで最も一般的に使用されている[Prysm](https://prysmaticlabs.com/#projects)は、Geth ほど独占しているわけではありませんが、それでもネットワークの 60%以上を占めています。 [Lighthouse](https://lighthouse.sigmaprime.io/)と[Teku](https://consensys.net/knowledge-base/ethereum-2/teku/)がそれぞれ約 20%と約 14%を占め、他のクライアントはほとんど使われていません。 +上の2つの円グラフは、実行レイヤーとコンセンサスレイヤーの現在(2022年1月の執筆時点)のクライアントの多様性のスナップショットを示しています。 実行レイヤーの大多数は[Geth](https://geth.ethereum.org/)が占めており、1位と大差をつけて[Open Ethereum](https://openethereum.github.io/)が2位、次に[Erigon](https://github.com/ledgerwatch/erigon)、[Nethermind](https://nethermind.io/)と続きますが、その他のクライアントはネットワークの1%未満に過ぎません。 コンセンサスレイヤーで最も一般的に使用されている[Prysm](https://prysmaticlabs.com/#projects)は、Gethほど独占しているわけではありませんが、それでもネットワークの60%以上を占めています。 [Lighthouse](https://lighthouse.sigmaprime.io/)と[Teku](https://consensys.net/knowledge-base/ethereum-2/teku/)がそれぞれ約20%と約14%を占め、他のクライアントはほとんど使われていません。 -実行レイヤーのデータは[Ethernodes](https://ethernodes.org)から 2022 年 1 月 23 日に、 コンセンサスクライアントのデータは[Michael Sproul](https://github.com/sigp/blockprint)から取得されました。 ビーコンチェーンのクライアントは、コンセンサスクライアントを識別するための明確な痕跡を常に持っている訳ではないため、コンセンサスクライアントのデータを取得することはより困難です。 データはマイノリティクライアントの一部を混同する場合がある分類アルゴリズムを用いて生成されました(詳細は[こちら](https://twitter.com/sproulM_/status/1440512518242197516)を参照)。 上の図では、これらの曖昧な分類は、どちらか一方のラベル(Nimbus/Teku など)で記載されています。 いずれにせよ、ネットワークのマジョリティが Prysm を実行していることは明白です。 データは固定されたブロック群(この場合はスロット 2048001 から 2164916) のスナップショットです。Prysm の占める割合が高まり、68%を超えることもありました。 これはスナップショットに過ぎませんが、図中の値は、クライアントの多様性の現状をよく表すものです。 +実行レイヤーのデータは、2022年1月23日に[Ethernodes](https://ethernodes.org)から、 コンセンサスクライアントのデータは[Michael Sproul](https://github.com/sigp/blockprint)から取得しました。 コンセンサスレイヤーのクライアントは、コンセンサスクライアントを識別するための明確な痕跡を常に持っているわけではないため、コンセンサスクライアントのデータを取得することが難しい場合があります。 データはマイノリティクライアントの一部を混同する場合がある分類アルゴリズムを用いて生成されました(詳細は[こちら](https://twitter.com/sproulM_/status/1440512518242197516)を参照)。 上の図では、これらの曖昧な分類は、どちらか一方のラベル(Nimbus/Tekuなど)で記載されています。 いずれにせよ、ネットワークのマジョリティがPrysmを実行していることは明白です。 データは固定されたブロック群(この場合はスロット2048001から2164916) のスナップショットです。Prysmの占める割合が高まり、68%を超えることもありました。 これはスナップショットに過ぎませんが、図中の値は、クライアントの多様性の現状をよく表すものです。 コンセンサスレイヤーのクライアントの多様性についての最新のデータは、[clientdiversity.org](https://clientdiversity.org/)から入手できます。 ## 実行レイヤー {#execution-layer} -これまでクライアントの多様性に関する議論は、主にコンセンサスレイヤーに焦点が当てられていました。 しかし、実行クライアント[Geth](https://geth.ethereum.org)は現在、すべてのノードの 85%を占めています。 この高い占有率は、コンセンサスクライアントと同じ理由で問題になります。 例えば、トランザクション処理や実行ペイロードの構築に影響を与えるバグが Geth にあると、コンセンサスクライアントが問題や不具合のあるトランザクションをファイナライズする可能性があります。 そのため、使われる実行クライアントがより均一に分散されると、イーサリアムの健全性が高まります。ネットワークの 33%以上を占めるクライアントが存在しないことが理想です。 +これまでクライアントの多様性に関する議論は、主にコンセンサスレイヤーに焦点が当てられていました。 しかし、実行クライアント[Geth](https://geth.ethereum.org)は現在、すべてのノードの 85%を占めています。 この高い占有率は、コンセンサスクライアントと同じ理由で問題になります。 例えば、トランザクション処理や実行ペイロードの構築に影響を与えるバグがGethにあると、コンセンサスクライアントが問題や不具合のあるトランザクションをファイナライズする可能性があります。 そのため、使われる実行クライアントがより均一に分散されると、イーサリアムの健全性が高まります。ネットワークの33%以上を占めるクライアントが存在しないことが理想です。 ## マイノリティクライアントの使用 {#use-minority-client} @@ -75,7 +75,9 @@ sidebarDepth: 2 [Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) -[Lodester](https://github.com/ChainSafe/lodestar) - _レビューおよび監査中_ +[ロードスター](https://github.com/ChainSafe/lodestar) + +[プリズム](https://docs.prylabs.network/docs/getting-started) ノードオペレーターを大多数を占めるクライアントからの移行を奨励し、移行プロセスを加速できるよう、技術系のユーザーはマイノリティクライアント向けのチュートリアルやドキュメントの作成にご協力ください。 マイノリティコンセンサスクライアントへの移行に関するガイドは、 [clientdiversity.org](https://clientdiversity.org/)から入手できます。 @@ -86,9 +88,7 @@ sidebarDepth: 2 **コンセンサスレイヤー:** - [Rated.network](https://www.rated.network/) -- [clientdiversity.org](https://clientdiversity.org/) - -**実行レイヤー:** +- [clientdiversity.org](https://clientdiversity.org/) **実行レイヤー:** - [execution-diversity.info](https://execution-diversity.info/) - [Ethernodes](https://ethernodes.org/) @@ -96,11 +96,11 @@ sidebarDepth: 2 ## 参考文献 {#further-reading} - [イーサリアムのコンセンサスレイヤーにおけるクライアントの多様性について](https://mirror.xyz/jmcook.eth/S7ONEka_0RgtKTZ3-dakPmAHQNPvuj15nh0YGKPFriA) -- [イーサリアムマージ: マジョリティクライアントは自己責任での実行](https://dankradfeist.de/ethereum/2022/03/24/run-the-majority-client-at-your-own-peril.html) – _Dankrad Fiest、2022 年 3 月 24 日_ +- [イーサリアムマージ: マジョリティクライアントは自己責任での実行](https://dankradfeist.de/ethereum/2022/03/24/run-the-majority-client-at-your-own-peril.html) – _Dankrad Fiest、2022年3月24日_ - [クライアントの多様性の重要性](https://our.status.im/the-importance-of-client-diversity/) - [イーサリアムノードサービスのリスト](https://ethereumnodes.com/) -- [クライアントの多様性問題の「5 つの理由」](https://notes.ethereum.org/@afhGjrKfTKmksTOtqhB9RQ/BJGj7uh08) -- [イーサリアムの多様性と解決方法(Youtube)](https://www.youtube.com/watch?v=1hZgCaiqwfU) +- [クライアントの多様性問題の「5つの理由」](https://notes.ethereum.org/@afhGjrKfTKmksTOtqhB9RQ/BJGj7uh08) +- [イーサリアムの多様性と解決方法(YouTube)](https://www.youtube.com/watch?v=1hZgCaiqwfU) - [clientdiversity.org](https://clientdiversity.org/) ## 関連トピック {#related-topics} diff --git a/public/content/translations/ja/developers/docs/nodes-and-clients/index.md b/public/content/translations/ja/developers/docs/nodes-and-clients/index.md index 367ef3b41b6..b97515d3694 100644 --- a/public/content/translations/ja/developers/docs/nodes-and-clients/index.md +++ b/public/content/translations/ja/developers/docs/nodes-and-clients/index.md @@ -1,46 +1,38 @@ --- title: ノードとクライアント -description: イーサリアムノードとクライアントソフトの概要、およびノードを設定する方法、およびその必要性 +description: イーサリアムノードとクライアントソフトの概要、ノードを設定する方法とその必要性 lang: ja sidebarDepth: 2 --- -イーサリアムは、「ノード」と呼ばれるコンピュータの分散型ネットワークです。ノードで実行されているソフトウェアが、ブロックとトランザクションデータを検証します。 このソフトウェア・アプリケーションは「クライアント」と呼ばれ、コンピュータをイーサリアムノードにするために、必ず実行されなければならないものです。 - -**注意: 現在、実行クライアントを単独で実行することはできません。 [マージ](/roadmap/merge)以降、イーサリアムネットワークにアクセスするには、実行クライアントとコンセンサスクライアントの両方を実行する必要があります。** +イーサリアムは、「ノード」と呼ばれるコンピュータの分散型ネットワークです。ノードで実行されているソフトウェアが、ブロックとトランザクションデータを検証します。 このソフトウェアは、コンピュータをイーサリアムノードにするために、必ず実行する必要があります。 ノードを構成するには、 別々のソフトウェア (「クライアント」と呼ばれる) が2つ必要です。 ## 前提知識 {#prerequisites} -イーサリアムクライアントの独自のインスタンスを実行する前に、ピアツーピア・ネットワークの概念と[EVM の基本](/developers/docs/evm/)の理解が必要です。 まずは[イーサリアム入門](/developers/docs/intro-to-ethereum/)をご覧ください。 +イーサリアムクライアントの詳細を学び、自分で動かすには、P2Pネットワークの概念と[EVMの基本](/developers/docs/evm/)を理解する必要があります。 まずは[イーサリアム入門](/developers/docs/intro-to-ethereum/)を読んでください。 -初めてノードを運用する場合は、まず[イーサリアムノードの運用](/run-a-node)というユーザーフレンドリーな説明を確認してください。 +ノード運用初心者の方は、まず[イーサリアムノードの運用](/run-a-node)というユーザーフレンドリーな導入方法をチェックすることをお勧めします。 ## ノードとクライアントとは {#what-are-nodes-and-clients} -「ノード」とは、イーサリアムソフトウェアを実行している他のコンピュータに接続されているイーサリアムクライアントソフトウェアの何らかのインスタンスであり、ネットワークを形成します。 「クライアント」とは、プロトコルルールに対してデータを検証し、安全なネットワークを維持するイーサリアムの実装です。 - -マージを経て、イーサリアムは実行レイヤーとコンセンサスレイヤーの 2 つの要素で構成されています。 両方のレイヤーは異なるクライアントソフトウェアによって実行されています。 このページでは、これらを実行クライアントとコンセンサスクライアントと呼びます。 - -- 実行クライアントは(EL クライアントや実行エンジンとも呼ばれ、過去の名称は Eth1 クライアント)、ネットワークでブロードキャストされた新たなトランザクションを受け取り、EVM(イーサリアム仮想マシン)でトランザクションを実行し、すべての現在のイーサリアムデータの最新の状態とデータベースを保持する。 -- コンセンサスクライアントは(ビーコンノードや CL クライアントとも呼ばれる、旧称は ETh2 クライアント)、プルーフ・オブ・ステークのコンセンサスアルゴリズムを実行し、実行クライアントからの検証されたデータに基づき、ネットワークの合意を形成する。 - -[マージ](/roadmap/merge/)前は、コンセンサスレイヤーと実行レイヤーは別々のネットワークでした。イーサリアム上のすべてのトランザクションとユーザーアクティビティは、現在の実行レイヤーで行われていました。 1 つのクライアントソフトウェアが、実行環境を提供しとマイナーが生成するブロックのコンセンサス検証の両方を行っていました。 コンセンサスレイヤーの[ビーコンチェーン](/roadmap/beacon-chain/)は、2020 年 12 月から別個に実行されてきました。 ビーコンチェーンにより、プルーフ・オブ・ステークの導入とイーサリアムネットワークからのデータに基づくバリデータのネットワークの調整が始まりました。 +「ノード」とは、イーサリアムソフトウェアを実行している他のコンピュータと接続されたイーサリアムクライアントソフトウェアの任意のインスタンスであり、ネットワークを形成します。 「クライアント」とは、プロトコルルールに従ってデータを検証し、安全なネットワークを維持するイーサリアムの実装です。 ノードでは、コンセンサスクライアントと実行クライアントの2つのクライアントを実行する必要があります。 -マージにより、イーサリアムはこれらのネットワークを接続し、プルーフ・オブ・ステークへ移行しました。 イーサリアムの状態を検証するために、実行クライアントとコンセンサスクライアントは、同時に稼働します。 +- 実行クライアント(ELクライアントや実行エンジンとも呼ばれ、過去の名称はEth1クライアント)は、ネットワークでブロードキャストされた新たなトランザクションを受け取り、EVM(イーサリアム仮想マシン)でトランザクションを実行し、すべての現在のイーサリアムデータの最新の状態とデータベースを保持します。 +- コンセンサスクライアント(ビーコンノードやCLクライアントとも呼ばれ、過去の名称はETh2クライアント)は、プルーフ・オブ・ステークのコンセンサスアルゴリズムを実行し、実行クライアントからの検証されたデータに基づき、ネットワークの合意を形成します。 「バリデータ」と呼ばれる3つ目のソフトウェアもあります。バリデータをコンセンサスクライアントに追加することで、ネットワークのセキュリティの確保にノードを参加させることができます。 -様々なソフトウェアを組み合わせたモジュラー型設計は、[カプセル化された複雑さ](https://vitalik.eth.limo/general/2022/02/28/complexity.html)と呼ばれます。 このアプローチにより、マージをシームレスに実行でき、[レイヤー 2 エコシステム](/layer-2/)などの個々のクライアントを再利用することができました。 +これらのクライアントは、連携してイーサリアムチェーンのヘッドを追跡し、ユーザーがイーサリアムネットワークとやり取りできるようにします。 複数のソフトウェアを組み合わせたモジュラー型設計は、[カプセル化された複雑性](https://vitalik.ca/general/2022/02/28/complexity.html)と呼ばれます。 このアプローチにより、[マージ](/roadmap/merge)をシームレスに実行できるようになりました。また、クライアントソフトウェアの保守や開発が容易になり、[レイヤー2エコシステム](/layer-2/)などの各クライアントを再利用できるようになりました。 ![実行クライアントとコンセンサスクライアントの連結](./eth1eth2client.png) 実行クライアントとコンセンサスクライアントの統合の簡略図 ### クライアントの多様性 {#client-diversity} -[実行クライアント](/developers/docs/nodes-and-clients/#execution-clients)と[コンセンサスクライアント](/developers/docs/nodes-and-clients/#consensus-clients)の両方は、異なるチームがさまざまなプログラミング言語で開発しています。 +[実行クライアント](/developers/docs/nodes-and-clients/#execution-clients)と[コンセンサスクライアント](/developers/docs/nodes-and-clients/#consensus-clients)は、それぞれ異なるチームが、さまざまなプログラミング言語を使って開発しています。 -複数のクライアント実装が、単一のコードベースへの依存を減らし、ネットワークをより強固にします。 理想的な目標としては、どのクライアントもネットワークの大多数を占めることなく、多様性を達成し、単一障害点を減らすことです。 また、言語の多様性はより広範なデベロッパーコミュニティを招くことにつながり、デベロッパーの希望言語で開発できます。 +複数のクライアント実装が、単一のコードベースへの依存を減らし、ネットワークをより強固にします。 理想は、どのクライアントもネットワークの大多数を占めることなく、多様性を実現し、単一障害点を減らすことです。 また、多様な言語を揃えることで、デベロッパーコミュニティがより広範になり、デベロッパーの希望言語で開発できるようになります。 -[クライアントの多様性](/developers/docs/nodes-and-clients/client-diversity/)についてもっと詳しく +[クライアントの多様性についての詳細](/developers/docs/nodes-and-clients/client-diversity/) -これらのクライアント実装に共通しているのは、一つの仕様に則っているということです。 仕様がイーサリアムネットワークとブロックチェーンの機能を規定しており、 すべての技術的な詳細が定義されています。仕様は下記で確認することができます。 +これらのクライアント実装は、すべて同じ仕様に従っています。 仕様はイーサリアムネットワークとブロックチェーンの機能や技術的な詳細を定義しており、 下記で確認することができます。 - 元々は[イーサリアムイエローペーパー](https://ethereum.github.io/yellowpaper/paper.pdf) - [実行クライアントの仕様](https://github.com/ethereum/execution-specs/) @@ -49,55 +41,59 @@ sidebarDepth: 2 ### ネットワークのノードの追跡 {#network-overview} -イーサリアムネットワークのノードの概要をリアルタイムで提供するトラッカーが複数あります。 分散型ネットワークの性質上、これらのクローラーはネットワークの限定されたビューしか提供できず、異なる結果を報告する可能性があることに注意してください。 +イーサリアムネットワークのノードの概要をリアルタイムで提供しているトラッカーが複数あります。 しかし、分散型ネットワークの性質上、これらのクローラーはネットワークの一部しか把握できず、異なる結果を報告する可能性があることに注意してください。 -- Etherscan による[ノードのマップ](https://etherscan.io/nodetracker) -- Bitfly による[Ethernodes](https://ethernodes.org/) +- Etherscanによる[ノードのマップ](https://etherscan.io/nodetracker) +- Bitflyによる[Ethernodes](https://ethernodes.org/) - [イーサリアムノードクローラー](https://crawler.ethereum.org/) -- [Nodewatch](https://www.nodewatch.io/): Chainsafe によるコンセンサスノードのクローリング +- [Nodewatch](https://www.nodewatch.io/): Chainsafeによるコンセンサスノードのクローリング ## ノードの類型 {#node-types} -[自分でノードを実行](/developers/docs/nodes-and-clients/run-a-node/)したい場合、ノードにはいくつかの種類があり、それぞれデータの扱い方が異なります。 実際に、クライアントが実行できるノードには、ライトノード、フルノード、アーカイブノードの 3 種類があります。 また、異なる同期戦略のオプションがあり、同期時間を短縮できます。 同期とは、イーサリアムの状態についての最新情報をどれだけ迅速に取得できるかを指します。 +[自分でノードを実行](/developers/docs/nodes-and-clients/run-a-node/)したい場合、ノードの種類を選ぶ必要があります。ノードにはいくつかの種類があり、それぞれデータの扱い方が異なります。 実際に、クライアントが実行できるノードには、ライトノード、フルノード、アーカイブノードの3種類があります。 また、同期時間を短縮する同期戦略のオプションを選ぶこともできます。 同期とは、イーサリアムの状態についての最新情報をどれだけ迅速に取得できるかを意味します。 ### フルノード {#full-node} +フルノードは、各ブロックごとのブロックボディーと状態データのダウンロードおよび検証に加え、ブロックチェーンの各ブロックの検証を行います。 フルノードにはさまざまな種類があります。ジェネシスブロックから開始してブロックチェーンの履歴にあるすべてのブロックを1つずつ検証するものや、 直近のブロックで有効性が信頼できるものから検証を開始するものがあります(例: Gethの「スナップ同期」) 。 ディスク領域を節約するため、フルノードは検証の開始位置に関係なく、比較的最近のデータ(通常は直近の128ブロック)のローカルコピーのみを保存し、古いデータを削除できるようにしています。 古いデータは、必要に応じて再生成されます。 + - 完全なブロックチェーンデータを保存(ただし、フルノードは定期的にプルーニングされており、最初のジェネシス(誕生)までさかのぼる状態は保存されていない) - ブロック検証に参加し、すべてのブロックと状態を検証する -- フルノードからすべての状態が得られる(ただし、非常に古い状態はアーカイブノードへのリクエストから再構築) +- すべての状態は、ローカルストレージから取得するか、フルノードによって「スナップショット」から再生成できます。 - ネットワークに貢献し、リクエストに応じてデータを提供する -### ライトノード {#light-node} +### アーカイブノード {#archive-node} -すべてのブロックをダウンロードするのではなく、ライトノードはブロックヘッダーをダウンロードします。 これらのヘッダーには、ブロックの内容に関するサマリー情報のみが含まれます。 ライトノードが必要とするその他の情報は、フルノードから取得します。 ライトノードは受信したデータをブロック ヘッダーの状態ルートに対して個別に検証できます。 ライトノードでは、フルノードを実行するために必要な強力なハードウェアや高帯域幅がなくても、イーサリアムネットワークに参加できます。 最終的には、ライトノードは携帯電話や組み込み機器で動作できるようになる可能性があります。 ライトノードはコンセンサスには参加せず、マイナーやバリデータにはなれませんが、フルノードと同じ機能でイーサリアムブロックチェーンにアクセスできます。 +アーカイブノードは、ジェネシスからすべてのブロックを検証し、ダウンロードしたデータを永久に保存するフルノードです。 -実行クライアントの Geth には、[ライト同期(Light sync)](https://github.com/ethereum/devp2p/blob/master/caps/les.md)オプションがあります。 しかし、ライト Geth ノードはデータを取得する上で、フルノードに依存しています。 ライトノードへデータを提供するフルノードはほとんどなく、ライトノードはしばしばピアを見つけることができません。 現在、コンセンサスレイヤーには本番使用可能なライトクライアントは存在しませんが、開発中のクライアントはいくつかあります。 +- フルノードに保存されているすべてを保持し、過去の状態のアーカイブを構築する。 例えば、ブロック4,000,000のアカウント残高をクエリしたい場合、または簡単にかつ確実にトレースを使用してマイニングを行うことなく、自分のトランザクションセットをテストしたい場合などに必要。 +- データがテラバイト単位になるため、平均的なユーザーにとってアーカイブノードは魅力的なものではないが、ブロックエクスプローラー、ウォレットベンダー、チェーン分析などのサービスに有用。 -また、[ゴシップネットワーク](https://www.ethportal.net/)を介してライトクライアントデータを提供する方法もあります。 ゴシップネットワークは、フルノードがリクエストに応答することなくライトノードのネットワークをサポートできるため好都合です。 +アーカイブ以外の任意のモードでクライアントを同期すると、ブロックチェーンデータがプルーニングされます。 つまり、すべての過去の状態を保存するアーカイブは存在しませんが、フルノードは必要に応じて構築できます。 -イーサリアムはまだ多数のライトノードをサポートしていませんが、ライトノードのサポートは近い将来急速に発展すると予想される領域です。 +[アーカイブノードの詳細](/developers/docs/nodes-and-clients/archive-nodes) -### アーカイブノード {#archive-node} +### ライトノード {#light-node} -- フルノードに保存されているすべてを保持し、過去の状態のアーカイブを構築する。 例えば、ブロック 4,000,000 のアカウント残高をクエリしたい場合、または簡単にかつ確実にトレースを使用してマイニングを行うことなく、自分のトランザクションセットをテストしたい場合などに必要。 -- データがテラバイト単位になるため、平均的なユーザーにとってアーカイブノードは魅力的なものではないが、ブロックエクスプローラー、ウォレットベンダー、チェーン分析などのサービスに有用。 +ライトノードは、すべてのブロックをダウンロードする代わりに、ブロックヘッダーのみをダウンロードします。 ブロックヘッダーには、ブロックの内容に関するサマリー情報が含まれています。 ライトノードは、必要に応じて、フルノードからブロックヘッダー以外の情報を取得します。 また、受信したデータをブロックヘッダーの状態ルートに対して個別に検証できます。 ライトノードでは、フルノードを実行するために必要な強力なハードウェアや高帯域幅がなくても、イーサリアムネットワークに参加できます。 最終的には、ライトノードは携帯電話や組み込み機器で動作できるようになる可能性があります。 ライトノードはコンセンサスには参加せず、マイナーやバリデータにはなれませんが、フルノードと同じ機能とセキュリティ保証でイーサリアムブロックチェーンにアクセスできます。 -アーカイブ以外の任意のモードでクライアントを同期すると、ブロックチェーンデータがプルーニングされます。 つまり、すべての過去の状態を保存するアーカイブは存在しませんが、フルノードは必要に応じて構築できます。 +イーサリアムでは、ライトクライアントの開発が活発に行われています。コンセンサスレイヤーと実行レイヤーの新しいライトクライアントが、まもなくリリースされる予定です。 また、[ゴシップネットワーク](https://www.ethportal.net/)を介して、ライトクライアントデータを提供する方法もあります。 ゴシップネットワークは、フルノードがリクエストに応答することなくライトノードのネットワークをサポートできるため効率的です。 + +イーサリアムでは現在、ライトノードは多数サポートされていませんが、今後急速に普及していくと考えられています。 特に、[Nimbus](https://nimbus.team/)、[Helios](https://github.com/a16z/helios)、[LodeStar](https://lodestar.chainsafe.io/)などのクライアントは、現在ライトノードを重点的に開発しています。 ## イーサリアムノードを運用する必要性 {#why-should-i-run-an-ethereum-node} -ノードを運用することで、直接的にトラストレスで、かつプライベートにイーサリアムを利用できると同時に、イーサリアムをより強固にし、分散化に貢献することができます。 +ノードを実行することで、イーサリアムを直接、トラストレスかつプライベートに利用することができます。また、イーサリアムのネットワークをより強固にし、分散化の促進に貢献することができます。 ### メリット {#benefits-to-you} -自分のノードを運用すると、プライベートで自己完結したトラストレスな形でイーサリアムを利用することができます。 クライアントを使って自分でデータを検証できるので、ネットワークを信頼する必要はありません。 「信頼せず検証」はブロックチェーンでよく言われるマントラです。 +自分のノードを実行すると、プライベートで自己完結したトラストレスな形でイーサリアムを利用することができます。 クライアントを使って自分でデータを検証できるので、ネットワークを信頼する必要はありません。 「信頼するな、検証せよ」はブロックチェーンで頻繁に唱えられるマントラです。 - ノードはすべてのトランザクションとブロックをコンセンサスルールに対して検証する。 つまり、ネットワークの他のノードに依存したり、完全に信頼する必要がない。 -- 自分のノードでイーサリアムウォレットを使用可能。 ランダムなノードに自分のアドレスや残高を漏らす必要がないため、より安全かつプライベートに分散型アプリ(Dapp)を利用できる。 自身のクライアントですべてをチェックできる。 [MetaMask](https://metamask.io)、[Frame](https://frame.sh/)、[他の多くのウォレット](/wallets/find-wallet/)は RPC インポート機能を提供し、自分のノードを使用できる。 -- イーサリアムからのデータに依存する他のサービスを実行および自分でホスト可能 (例えば、ビーコンチェーンのバリデータ、レイヤー 2 などのソフトウェア、インフラストラクチャ、ブロックエクスプローラー、ペイメントプロセッサーなど)。 -- 独自のカスタム[RPC エンドポイント](/developers/docs/apis/json-rpc/)を提供できる。 それがコミュニティ向けに公開されたイーサリアムエンドポイント、または非公開のエンドポイントであっても、あなたのノードを他の人が使用でき、結果として中央集権的な大手プロバイダを回避できる。 -- **プロセス間通信(IPC)**を利用してノードに接続、またはノードを書き換えプラグインとしてプログラムの読み込みが可能。 これにより、レイテンシーが低くなり、Web3 ライブラリを使用して大量のデータを処理する場合、またはトランザクションをできるだけ早く置き換える必要がある場合に(フロントランニング)、非常に有用。 -- ETH を直接ステーキングでき、ネットワークの安全性に貢献し、同時に報酬を得ることができる。 始めるには[ソロステーキング](/staking/solo/)を参照。 +- 自分のノードでイーサリアムウォレットを使用可能。 仲介業者に自分のアドレスや残高情報を渡す必要がないため、より安全かつプライベートに分散型アプリ(Dapp)を利用できる。 自身のクライアントですべてをチェックできる。 [MetaMask](https://metamask.io)、[Frame](https://frame.sh/)、[他の多くのウォレット](/wallets/find-wallet/)はRPCインポート機能を提供し、自分のノードを使用できる。 +- イーサリアムからのデータに依存する他のサービスを実行および自分でホスト可能 (例えば、ビーコンチェーンのバリデータ、レイヤー2などのソフトウェア、インフラストラクチャ、ブロックエクスプローラー、ペイメントプロセッサーなど)。 +- 独自のカスタム[RPCエンドポイント](/developers/docs/apis/json-rpc/)を提供できる。 このエンドポイントをコミュニティに公開することで、巨大な中央集権型プロバイダーへの依存を減らすことができる。 +- **プロセス間通信(IPC)**を利用してノードに接続、またはノードを書き換えプラグインとしてプログラムの読み込みが可能。 これにより、レイテンシーが低くなり、Web3ライブラリを使用して大量のデータを処理する場合、またはトランザクションをできるだけ早く置き換える必要がある場合に(フロントランニング)、非常に有用。 +- ETHを直接ステーキングでき、ネットワークの安全性に貢献し、同時に報酬を得ることができる。 始めるには[ソロステーキング](/staking/solo/)を参照。 ![アプリケーションやノードを介してイーサリアムにアクセスする方法](./nodes.png) @@ -108,188 +104,171 @@ sidebarDepth: 2 - フルノードがコンセンサスルールを強制するため、ルールに従わないブロックが受け入れられることはない。 これはネットワークのセキュリティ強化につながる(すべてのノードが完全な検証ができないライトノードの場合では、バリデータがネットワークに対して攻撃できる恐れがあるため)。 - [プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos/#what-is-pos)の暗号経済的な防御を上回る攻撃の場合、正しいチェーンを選ぶフルノードによって、社会的回復が行われる。 - ネットワークのノード数が増えることで、分散化の究極の目標である多様で堅牢なネットワークとなり、検閲耐性があり、信頼性の高いシステムになる。 -- フルノードからのブロックチェーンデータに依存するライトクライアントに、ブロックチェーンデータへのアクセスを提供する。 ネットワークの使用量が高いとき、ライトノードが同期するのに十分な数のフルノードが必要。 ライトノードはブロックチェーン全体を保持せず、[ブロックヘッダーのステートルート](/developers/docs/blocks/#block-anatomy)を利用してデータを検証する。 必要に応じて、ライトノードはブロックからより多くの情報のリクエストを行う。 +- フルノードからのブロックチェーンデータに依存するライトクライアントに、ブロックチェーンデータへのアクセスを提供する。 ライトノードはブロックチェーンの全データを保持せず、代わりに、[ブロックヘッダーのステートルート](/developers/docs/blocks/#block-anatomy)を利用してデータを検証する。 また、必要に応じて、フルノードから追加情報のリクエストを行う。 -あなたがフルノードを運用すると、イーサリアムのネットワーク全体がその恩恵を受けることになります。 +フルノードを実行すると、バリデータを実行しなくても、イーサリアムネットワーク全体がそのメリットを享受することができます。 ## 自分のノードの運用 {#running-your-own-node} -自分のイーサリアムクライアントの運用に興味がありますか? +自分のイーサリアムクライアントを運用してみませんか? -初心者にやさしい導入方法については、[ノードの運用](/run-a-node)ページで詳細を確認してください。 +初心者向けの導入方法については、[ノードの運用](/run-a-node)ページをご覧ください。 -技術的な方向けには、[自分のノードを立ち上げる](/developers/docs/nodes-and-clients/run-a-node/)を参照し、詳細やオプションを確認してください。 +上級者の方は、[自分のノードを立ち上げる](/developers/docs/nodes-and-clients/run-a-node/)を参照し、詳細やオプションを確認してください。 ## 代替手段 {#alternatives} -自分のノードを設定するには時間とリソースがかかりますが、常に独自のインスタンスを実行する必要はありません。 この場合では、[Infura](https://infura.io)、[Alchemy](https://alchemyapi.io)、[Chainstack](https://chainstack.com)、または[QuikNode](https://www.quiknode.io)のようなサードパーティーの API プロバイダーを利用できます。 あるいは、[ArchiveNode](https://archivenode.io/)というコミュニティが資金提供しているアーカイブノードがあり、時間とリソースに余裕のない独立デベロッパーのためにイーサリアムブロックチェーンのアーカイブデータを提供しています。 これらのサービスの概要については、 [ノード・アズ・ア・サービス(NaaS)](/developers/docs/nodes-and-clients/nodes-as-a-service/)で確認してください。 +自分のノードを設定するには、時間とリソースがかかりますが、必ずしも独自のインスタンスを実行する必要はありません。 サードパーティのAPIプロバイダーを利用すれば負担を軽減できます。 これらのサービスの概要については、 [ノード・アズ・ア・サービス(NaaS)](/developers/docs/nodes-and-clients/nodes-as-a-service/)で確認してください。 -コミュニティでパブリックな API を持つイーサリアムノードが運用されている場合、MetaMask のようなライトウォレットを[カスタム RPC を介して](https://metamask.zendesk.com/hc/en-us/articles/360015290012-Using-a-Local-Node)コミュニティノードに向けることができ、ランダムなサードパーティを使うよりも、よりプライバシーを確保できます。 +コミュニティでパブリックなAPIを持つイーサリアムノードが運用されている場合、カスタムRPCを介してウォレットをコミュニティノードに向けることができ、ランダムなサードパーティを使うよりも、プライバシーを確保することができます。 一方で、自分のクライアントを運用している場合は、必要としている友人とクライアントを共有できます。 -## 実行クライアント(旧 「Eth1 クライアント」) {#execution-clients} +## 実行クライアント {#execution-clients} -イーサリアムコミュニティは、異なるプログラミング言語で、さまざまなチームによって開発された、複数のオープンソースの実行クライアント(旧称は「Eth1 クライアント」または「イーサリアムクライアント」) を維持しています。 これにより、ネットワークがより強固になり、[多様性](/developers/docs/nodes-and-clients/client-diversity/)を実現します。 理想的な目標としては、どのクライアントもネットワークの大多数を占めることなく、多様性を達成し、単一障害点を減らすことです。 +イーサリアムコミュニティでは、異なるプログラミング言語で、さまざまなチームが開発した、複数のオープンソースの実行クライアント(旧称は「Eth1クライアント」または「イーサリアムクライアント」)を維持しています。 これにより、ネットワークがより強固になり、[多様性](/developers/docs/nodes-and-clients/client-diversity/)を実現しています。 理想は、どのクライアントもネットワークの大部分を占めることなく、多様性を実現し、単一障害点を減らすことです。 -この表は、いくつかのクライアントをまとめたものです。 これらはすべて[クライアントテスト](https://github.com/ethereum/tests)に合格し、アクティブにネットワークのアップグレードで最新の状態に維持されています。 +この表は、いくつかのクライアントの情報をまとめたものです。 これらのクライアントはすべて、[クライアントテスト](https://github.com/ethereum/tests)に合格しており、ネットワークのアップグレードによって最新の状態に維持されています。 -| クライアント | 言語 | オペレーティングシステム | ネットワーク | 同期戦略 | 状態剪定 | -| ----------------------------------------------- | -------- | ------------------------ | --------------------------------------------------- | ------------------------------- | -------------------- | -| [Geth](https://geth.ethereum.org/) | Go | Linux、Windows、macOS | メインネット、Sepolia、Görli、Ropsten、Rinkeby | スナップ、フル | アーカイブ、プルーン | -| [Nethermind](http://nethermind.io/) | C#、.NET | Linux、Windows、macOS | メインネット、Sepolia、Görli、Ropsten、Rinkeby など | スナップ(配信なし) 、高速、フル | アーカイブ、プルーン | -| [Besu](https://besu.hyperledger.org/en/stable/) | Java | Linux、Windows、macOS | メインネット、Sepolia、Görli、Ropsten、Rinkeby など | 高速、フル | アーカイブ、プルーン | -| [Erigon](https://github.com/ledgerwatch/erigon) | Go | Linux、Windows、macOS | メインネット、Sepolia、Görli、Rinkeby、Ropsten など | フル | アーカイブ、プルーン | - -**OpenEthereum は[非推奨](https://medium.com/openethereum/gnosis-joins-erigon-formerly-turbo-geth-to-release-next-gen-ethereum-client-c6708dd06dd)となり、メンテナンスされていません。**注意して使用し、できれば他のクライアントに切り替えてください。 +| クライアント | 言語 | オペレーティングシステム | ネットワーク | 同期戦略 | 状態剪定 | +| ----------------------------------------------- | ------- | ------------------- | ----------------------- | ----------------- | ---------- | +| [Geth](https://geth.ethereum.org/) | Go | Linux、Windows、macOS | メインネット、Sepolia、Goerli | スナップ、フル | アーカイブ、プルーン | +| [Nethermind](http://nethermind.io/) | C#、.NET | Linux、Windows、macOS | メインネット、Sepolia、Goerliなど | スナップ(配信なし) 、高速、フル | アーカイブ、プルーン | +| [Besu](https://besu.hyperledger.org/en/stable/) | Java | Linux、Windows、macOS | メインネット、Sepolia、Goerliなど | スナップ、高速、フル | アーカイブ、プルーン | +| [Erigon](https://github.com/ledgerwatch/erigon) | Go | Linux、Windows、macOS | メインネット、Sepolia、Goerliなど | フル | アーカイブ、プルーン | +| [Reth](https://github.com/paradigmxyz/reth) | Rust | Linux、Windows、macOS | メインネット、Sepolia、Goerliなど | フル | アーカイブ、プルーン | サポートされているネットワークの詳細については、[イーサリアムネットワーク](/developers/docs/networks/)をご覧ください。 -各クライアントには独自のユースケースとメリットがあります。自分の好みに基づいて選択してください。 多様性により、クライアントが異なる機能やユーザー対象に特化することができます。 機能、サポート、プログラミング言語、またはライセンスに基づいて、クライアントを選択することをお勧めします。 +各クライアントには、それぞれに応じたユースケースとメリットがあります。自分に合ったクライアントを選択してください。 多様性により、さまざまな機能やユーザー層に合わせた実装が可能です。 機能、サポート、プログラミング言語、またはライセンスなどの観点から、クライアントを選択することをお勧めします。 ### Besu {#besu} -ハイパーレジャー・ベスは、パブリックネットワークと許可型ネットワーク向けのエンタープライズグレードのイーサリアムクライアントです。 トレースから GraphQL まで、イーサリアムメインネットのすべての機能を実行し、広範なモニタリングを行い、公開コミュニティチャンネルと企業向けの商用 SLA の両方で、ConsenSys 社によりサポートされています。 Java 実装で、Apache 2.0 ライセンスです。 +ハイパーレジャーBesuは、パブリックネットワークと許可型ネットワークの両方に対応する、エンタープライズグレードのイーサリアムクライアントです。 イーサリアムメインネットのすべての機能を実行するクライアントは、ConsenSys社によりサポートされています。トレースからGraphQLまで、幅広いモニタリング機能を備えており、公開コミュニティチャンネルと企業向けの商用SLAの両方に対応しています。 また、Javaで実装されており、Apache 2.0ライセンスです。 -機能とセットアップの詳細については、Besu の広範な[ドキュメント](https://besu.hyperledger.org/en/stable/)に記載されています。 +機能とセットアップの詳細については、Besuの完全版[ドキュメント](https://besu.hyperledger.org/en/stable/)に記載されています。 ### Erigon {#erigon} -Erigon(旧称: Turbo-Geth)は、Go Ethereum のフォークとして始まり、速度とディスク容量の効率に特化しています。 Erigon はイーサリアムを完全に再構築された実装で、現在は Go 実装ですが など他の言語でも開発中です。 Erigon は、より高速、よりモジュラー型、より最適化されたイーサリアムの実装を提供することを目的としています。 2TB 程度のディスク容量で、3 日以内にフルアーカイブノードの同期ができます。 +Erigon(旧称: Turbo-Geth)は、Go Ethereumのフォークから派生したものであり、速度とディスク容量の効率を重視しています。 イーサリアムの完全に再設計された実装であり、現在はGoで書かれていますが、他の言語での実装も開発中です。 Erigonは、より高速で、よりモジュール化されており、より最適化されたイーサリアムの実装を目指しています。 2TB程度のディスク容量があれば、3日以内にフルアーカイブノードの同期が可能です。 -### Go Ethereum (Geth) {#geth} +### Go Ethereum(Geth) {#geth} -Go Ethereum(略して Geth) は、イーサリアムプロトコルのオリジナルの実装の 1 つです。 現在、最も普及しているクライアントであり、ユーザーやデベロッパー向けのツールの種類も豊富です。 Go 実装で、完全にオープンソースで、GNU LGPL v3 の下でライセンスされています。 +Go Ethereum(略してGeth)は、イーサリアムプロトコルのオリジナルの実装の1つです。 現在、最も普及しているクライアントであり、ユーザーやデベロッパー向けのツールの種類も豊富です。 Go言語で実装されており、完全にオープンソースで、GNU LGPL v3ライセンスの下で提供されています。 -詳細については、Geth の[ドキュメント](https://geth.ethereum.org/docs/)を参照してください。 +Gethの詳細については、[ドキュメント](https://geth.ethereum.org/docs/)を参照してください。 ### Nethermind {#nethermind} -Nethermind は C# .NET の技術スタックで開発されたイーサリアムの実装で、LGPL-3.0 ライセンスです。ARM を含むすべての主要なプラットフォームで稼働します。 以下のような優れたパフォーマンスを提供します。 +Nethermindは、C# .NETの技術スタックで開発されたイーサリアムの実装で、LGPL-3.0ライセンスの下で提供されています。ARMを含むすべての主要なプラットフォームに対応しており、 以下のような優れたパフォーマンスを発揮します。 - 最適化された仮想マシン - 状態アクセス -- ネットワーク機能と、Prometheus/Grafana ダッシュボード、シークエンス・エンタープライズ・ロギング・サポート、JSON RPC トレース、分析プラグインなどの豊富な機能 +- ネットワーク機能と、Prometheus/Grafanaダッシュボード、シークエンス・エンタープライズ・ロギング・サポート、JSON RPCトレース、分析プラグインなどの豊富な機能 -また、Nethermind には[詳細なドキュメント](https://docs.nethermind.io)、強力な開発サポート、オンラインコミュニティ、プレミアムユーザー向けの 24 時間年中無休のサポートもあります。 +また、Nethermindは、[詳細なドキュメント](https://docs.nethermind.io)、強力な開発サポート、オンラインコミュニティ、プレミアムユーザー向けの24時間年中無休のサポートなど、充実したサポート体制を整えています。 -## コンセンサスクライアント(旧「Eth2」クライアント) {#consensus-clients} +## コンセンサスクライアント {#consensus-clients} -[コンセンサスアップグレード](/roadmap/beacon-chain/)に対応する複数のコンセンサスクライアント(旧称: 「Eth2」クライアント) があります。 ビーコンチェーンを実行しており、[マージ](/roadmap/merge/)以降、実行クライアントにプルーフ・オブ・ステークの合意メカニズムを提供します。 +[コンセンサスアップグレード](/roadmap/beacon-chain/)に対応する複数のコンセンサスクライアント(旧称: 「Eth2」クライアント) があります。 コンセンサスクライアントは、フォーク選択アルゴリズム、アテステーションの処理、[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos)の報酬とペナルティの管理など、コンセンサスに関連するロジックをすべて担っています。 -| クライアント | 言語 | オペレーティングシステム | ネットワーク | -| ------------------------------------------------------------- | ---------- | ------------------------ | ---------------------------------------------------------------- | -| [Lighthouse](https://lighthouse.sigmaprime.io/) | Rust | Linux、Windows、macOS | ビーコンチェーン、Goerli、Pyrmont、Sepolia、Ropsten など | -| [Lodestar](https://lodestar.chainsafe.io/) | TypeScript | Linux、Windows、macOS | ビーコンチェーン、Goerli、Sepolia、Ropsten など | -| [Nimbus](https://nimbus.team/) | Nim | Linux、Windows、macOS | ビーコンチェーン、Goerli、Sepolia、Ropsten など | -| [Prysm](https://docs.prylabs.network/docs/getting-started/) | Go | Linux、Windows、macOS | ビーコンチェーン、Gnosis、Goerli、Pyrmont、Sepolia、Ropsten など | -| [Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) | Java | Linux、Windows、macOS | ビーコンチェーン、Gnosis、Goerli、Sepolia、Ropsten など | +| クライアント | 言語 | オペレーティングシステム | ネットワーク | +| ------------------------------------------------------------- | ---------- | ------------------- | ------------------------------------------------ | +| [Lighthouse](https://lighthouse.sigmaprime.io/) | Rust | Linux、Windows、macOS | ビーコンチェーン、Goerli、Pyrmont、Sepolia、Ropstenなど | +| [Lodestar](https://lodestar.chainsafe.io/) | TypeScript | Linux、Windows、macOS | ビーコンチェーン、Goerli、Sepolia、Ropstenなど | +| [Nimbus](https://nimbus.team/) | Nim | Linux、Windows、macOS | ビーコンチェーン、Goerli、Sepolia、Ropstenなど | +| [Prysm](https://docs.prylabs.network/docs/getting-started/) | Go | Linux、Windows、macOS | ビーコンチェーン、Gnosis、Goerli、Pyrmont、Sepolia、Ropstenなど | +| [Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) | Java | Linux、Windows、macOS | ビーコンチェーン、Gnosis、Goerli、Sepolia、Ropstenなど | ### Lighthouse {#lighthouse} -Lighthouse は、Apache-2.0 ライセンスの下、Rust で書かれたコンセンサスクライアントの実装です。 Sigma Prime により管理され、ビーコンチェーンの誕生以降安定し、本番リリースされています。 様々なエンタープライズ、ステーキングプール、個人からの信頼を得ています。 デスクトップ PC から高度な自動デプロイまで、幅広い環境における安全性、パフォーマンス、相互運用性を目指しています。 +Lighthouseは、Apache-2.0ライセンスの下、Rustで書かれたコンセンサスクライアントの実装です。 Sigma Primeによって管理されており、ビーコンチェーン誕生以降、安定したパフォーマンスで稼働しています。 また、さまざまなエンタープライズやステーキングプール、個人からの信頼を得ています。 デスクトップPCから高度な自動デプロイまで、あらゆる環境における安全性、パフォーマンス、相互運用性を目指しています。 -ドキュメントは、[Lighthouse Book](https://lighthouse-book.sigmaprime.io/)にあります。 +ドキュメントは、[Lighthouse Book](https://lighthouse-book.sigmaprime.io/)で参照できます。 ### Lodestar {#lodestar} -Lodestar は LGPL-3.0 ライセンスの下、Typescript で書かれ、本番対応のコンセンサスクライアントの実装です。 ChainSafe Systems 社により管理され、ソロステーカー、デベロッパー、研究者向けのコンセンサスクライアントの中で最も新しいものです。 Loadstar は、イーサリアムプロトコルを JavaScript で実装したビーコンノードとバリデータクライアントで構成されています。 ライトクライアントでのイーサリアムの使いやすさを向上させ、より多くのデベロッパーグループがアクセスできるようし、エコシステムの多様性にさらに貢献することを目指しています。 +Lodestarは、LGPL-3.0ライセンスの下、Typescriptで書かれた、本番環境に対応したコンセンサスクライアントの実装です。 ChainSafe Systems社によって管理されており、ソロステーカー、デベロッパー、研究者向けのコンセンサスクライアントの中で最も新しいものです。 Loadstarは、イーサリアムプロトコルをJavaScriptで実装した、ビーコンノードとバリデータクライアントから構成されています。 ライトクライアントでのイーサリアムの使いやすさを向上させ、より多くのデベロッパーグループがアクセスできるようにすることで、エコシステムの多様性にさらに貢献することを目指しています。 -詳細については、[Lodestar のウェブサイト](https://lodestar.chainsafe.io/)をご覧ください。 +詳細については、[Lodestarのウェブサイト](https://lodestar.chainsafe.io/)をご覧ください。 ### Nimbus {#nimbus} -Nimbus は Apache-2.0 ライセンスの下、Nim で書かれたコンセンサスクライアントの実装です。 ソロステーカーやステーキングプールで使用されており、本番対応のクライアントです。 Nimbus はリソース効率を重視して設計されており、リソースに制限のあるデバイスや企業のインフラストラクチャ上でも、安定性や報酬のパフォーマンスを損なわずに簡単に実行できます。 リソース利用量が少ないということは、ネットワークに負荷がかかったときでも、クライアントの安全域が大きくなることを意味します。 - -Trinity により実装されています。 高速同期のように機能しますが、最新のブロックを実行するために必要なデータもダウンロードします。開始から数分以内にチェーンをクエリできます。 +Nimbusは、Apache-2.0ライセンスの下、Nimで書かれたコンセンサスクライアントの実装です。 ソロステーカーやステーキングプールで使用されており、本番環境に対応したクライアントです。 Nimbusはリソース効率を重視して設計されており、リソースに制限のあるデバイスや企業のインフラストラクチャ上でも、安定性や報酬のパフォーマンスを損なわずに簡単に実行できます。 リソース利用量が少ないと、ネットワークに負荷がかかっても、クライアントは安全に動作します。 -- 最初に状態を同期し、数分で RPC にクエリ可能 -- まだ開発中で、完全に信頼できるわけではなく、バックグラウンド同期が遅くなり、RPC 応答が失敗する可能性がある - -詳しくは、[Nimbus のドキュメント](https://nimbus.guide/)をご覧ください。 +詳しくは、[Nimbusのドキュメント](https://nimbus.guide/)をご覧ください。 ### Prysm {#prysm} -Prysm は GPL-3.0 ライセンスの下、Go で書かれたフル機能のオープンソースのコンセンサスクライアントです。 オプションのウェブアプリの UI を備え、自宅でステーキングするユーザーと機関ユーザー両方向けに、ユーザーエクスペリエンス、ドキュメント、設定可能性を優先しているのが特徴です。 +Prysmは、GPL-3.0ライセンスの下、Goで書かれたフル機能のオープンソースのコンセンサスクライアントです。 オプションのWebアプリのUIを備え、自宅でステーキングするユーザーと機関ユーザーの両方に向けて、ユーザーエクスペリエンス、ドキュメント、設定可能性を優先しているのが特徴です。 -詳しくは、[Prysm のドキュメント](https://docs.prylabs.network/docs/getting-started/)をご覧ください。 +詳しくは、[Prysmのドキュメント](https://docs.prylabs.network/docs/getting-started/)をご覧ください。 ### Teku {#teku} -Teku はオリジナルのビーコンチェーンで誕生したクライアントの 1 つです。 セキュリティ、堅牢性、安定性、使いやすさ、パフォーマンスのよくある目標に加えて、Teku はさまざまなコンセンサスクライアント標準に完全に準拠することを特に目指しています。 +Tekuは、オリジナルのビーコンチェーンで誕生したクライアントの1つです。 セキュリティ、堅牢性、安定性、使いやすさ、パフォーマンスなどの基本的な目標に加えて、Tekuはさまざまなコンセンサスクライアント標準に完全に準拠することを特に重視しています。 -Teku は非常に柔軟なデプロイメントオプションを提供しています。 ビーコンノードとバリデータクライアントをシングルプロセスとして一緒に実行でき、ソロステーカーにとって非常に便利です。または、高度なステーキング操作用にノードを個別に実行することもできます。 さらに、署名キーのセキュリティとスラッシング保護のため、[Web3Signer](https://github.com/ConsenSys/web3signer/)と完全に相互運用可能です。 +Tekuは、非常に柔軟なデプロイメントオプションを提供しています。 ビーコンノードとバリデータクライアントをシングルプロセスとして実行できるので、ソロステーカーにとって非常に便利です。または、高度なステーキング操作を行う場合は、個別にノードを実行することもできます。 さらに、署名キーのセキュリティとスラッシング保護のために、[Web3Signer](https://github.com/ConsenSys/web3signer/)と完全に互換性があります。 -Teku は Java 実装で、Apache 2.0 ライセンスです。 Besu や Web3Signer を手がける ConsenSys 社のプロトコルチームによる開発です。 詳しくは、[Teku のドキュメント](https://docs.teku.consensys.net/en/latest/)をご覧ください。 +Tekuは、Javaで実装されており、Apache 2.0でライセンスされています。 BesuやWeb3Signerを手がけるConsenSys社のプロトコルチームによって開発されています。 詳しくは、[Tekuのドキュメント](https://docs.teku.consensys.net/en/latest/)をご覧ください。 ## 同期モード {#sync-modes} -ネットワークの現在のデータを追って検証するには、イーサリアムクライアントは最新のネットワーク状態と同期する必要があります。 これは、ピアからデータをダウンロードし、暗号的に完全性を検証し、ローカルのブロックチェーンデータベースを構築することで行われます。 +イーサリアムクライアントがネットワークの現在のデータを追って検証するには、最新のネットワーク状態と同期する必要があります。 そのためには、ピアからデータをダウンロードし、暗号的に完全性を検証した上で、ローカルのブロックチェーンデータベースを構築する必要があります。 -同期モードには、さまざまなトレードオフを持つ異なるアプローチがあります。 また、各クライアントにより、同期アルゴリズムの実装に違いがあります。 実装の詳細については、常にクライアントの公式ドキュメントを参照してください。 +同期モードには、さまざまなトレードオフを持つ異なるアプローチがあります。 また、各クライアントによって、同期アルゴリズムの実装が異なります。 そのため、実装の詳細については、必ずクライアントの公式ドキュメントを参照してください。 ### 実行レイヤーの同期モード {#execution-layer-sync-modes} -#### フル同期(Full sync) {#full-sync} +#### フルアーカイブ同期 {#full-sync} フル同期は、ヘッダー、トランザクション、レシートを含むすべてのブロックをダウンロードし、最初のジェネシス(誕生)からの全ブロックを実行することで、ブロックチェーンの状態を段階的に生成します。 - すべてのトランザクションを検証することにより、信用する必要性を最小限に抑え、最高のセキュリティを提供 - トランザクション数が増えると、全トランザクションを処理するのに数日から数週間かかることがある -#### 高速同期(Fast sync) {#fast-sync} +#### フルスナップ同期 {#snap-sync} -高速同期は、ヘッダー、トランザクション、レシートを含むすべてのブロックをダウンロードし、全ヘッダーを検証の上、状態をダウンロードし、検証したヘッダーに対して状態を検証します。 +スナップ同期は、フルアーカイブ同期と同様に、ブロックごとにチェーンを検証します。ただし、ジェネシスブロックからではなく、本物のブロックチェーンの一部であることが確認されている、より直近の「信頼できる」チェックポイントから始めます。 ノードは、一定期間を経過したデータを削除しますが、定期的にチェックポイントを保存します。 これらのスナップショットは、すべての状態データを永久に保存するのではなく、必要なときに再生成するために使用されます。 -- 合意メカニズムのセキュリティに依存 -- 同期には数時間しかかからない +- 現在イーサリアムメインネットでデフォルトとなっている最速の同期戦略 +- セキュリティを損なうことなく、ディスク使用量とネットワーク帯域幅を大幅に節約可能 + +[スナップ同期の詳細](https://github.com/ethereum/devp2p/blob/master/caps/snap.md) #### 軽量同期(Light sync) {#light-sync} -軽量クライアントモード(Light client mode)は、すべてのブロックヘッダー、ブロックデータをダウンロードし、ランダムに検証を行います。 信頼できるチェックポイントからのチェーンの先端のみを同期します。 +ライトクライアントモードでは、すべてのブロックヘッダーとブロックデータをダウンロードし、ランダムに検証を行います。 信頼できるチェックポイントからチェーンの先端までのみを同期します。 - デベロッパーへの信頼と合意メカニズムに依存し、最新の状態のみを取得 - クライアントは数分で現在のネットワーク状態で使用できるようになる -[ライトクライアントの詳細](https://www.parity.io/blog/what-is-a-light-client/) +**注: ** 現在、プルーフ・オブ・ステークのイーサリアムでは、軽量同期は利用できません。軽量同期の新しいバージョンが、まもなくリリースされる予定です。 -#### スナップ同期(Snap sync) {#snap-sync} - -スナップ同期はクライアント同期の最新のアプローチであり、Geth チームによって開発されました。 ピアが提供するダイナミック・スナップショットを使用して、中間ツリーノードをダウンロードすることなく、すべてのアカウントデータとストレージデータを取得し、ローカルでマークルツリーを再構築します。 - -- 現在イーサリアムメインネットでデフォルトとなっている最速の同期戦略 -- セキュリティを損なうことなく、ディスク使用量とネットワーク帯域幅を大幅に節約可能 - -[スナップ同期の詳細](https://github.com/ethereum/devp2p/blob/master/caps/snap.md) +[ライトクライアントの詳細](/developers/docs/nodes-and-clients/light-clients/) -| クライアント | ディスクサイズ(高速同期) | ディスクサイズ(フルアーカイブ) | -| ------------ | ------------------------ | ------------------------------ | -| Geth | 400GB 以上 | 6TB 以上 | -| OpenEthereum | 280GB 以上 | 6TB 以上 | -| Nethermind | 500GB 以上 | 12TB 以上 | -| Besu | 750GB 以上 | 5TB 以上 | -| Erigon | N/A | 1TB 以上 | +### コンセンサスレイヤーの同期モード {#consensus-layer-sync-modes} -#### オプティミスティック同期(Optimistic sync) {#optimistic-sync} +#### オプティミスティック同期 {#optimistic-sync} -オプティミスティック同期はマージ後の同期戦略で、オプトインで下位互換性(他の同期モードと互換性がある)があるように設計されており、実行ノードが確立された方法で同期できます。 実行エンジンはビーコンブロックを完全に検証せず、*オプティミスティックに(楽観的に)*インポートでき、最新の先頭を探し、上記の方法でチェーンの同期を開始します。 次に、実行クライアントが追いつくと、ビーコンチェーンのトランザクションの有効性をコンセンサスクライアントに通知します。 +オプティミスティック同期はマージ後の同期戦略で、オプトインで下位互換性を備えており、実行ノードが確立された方法で同期できます。 実行エンジンは、ビーコンブロックを完全に検証せず、_オプティミスティックに(楽観的に)_インポートすることができます。そして、最新のブロックの先頭を探し、上記の方法でチェーンの同期を開始します。 次に、実行クライアントが追いつくと、ビーコンチェーンのトランザクションの有効性をコンセンサスクライアントに通知します。 [オプティミスティック同期の詳細](https://github.com/ethereum/consensus-specs/blob/dev/sync/optimistic.md) -#### チェックポイント同期(Checkpoint sync) {#checkpoint-sync} +#### チェックポイント同期 {#checkpoint-sync} -チェックポイント同期は、弱い主観性同期(Weak Subjectivity Sync)とも呼ばれ、ビーコンノードの同期でユーザーエクスペリエンスが優れています。 これは[弱い主観性(Weak Subjectivity)](/developers/docs/consensus-mechanisms/pos/weak-subjectivity/)の前提に基づいており、最初のジェネシスブロック からではなく、最新の「弱い主観性チェックポイント」からビーコンチェーンを同期します。 [ジェネシスブロック](/glossary/#genesis-block)からの同期と同様の信頼性を仮定したチェックポイント同期により、初期同期の時間を大幅に短縮できます。 +チェックポイント同期は、弱い主観性同期とも呼ばれ、ビーコンノードの同期において優れたユーザーエクスペリエンスを実現します。 これは[弱い主観性](/developers/docs/consensus-mechanisms/pos/weak-subjectivity/)の前提に基づいており、最初のジェネシスブロックからではなく、最新の「弱い主観性チェックポイント」からビーコンチェーンを同期します。 [ジェネシスブロック](/glossary/#genesis-block)からの同期と同様の信頼性を保ちつつ、初期同期の時間を大幅に短縮できます。 -実運用では、ノードがリモートサービスに接続して最新のファイナライズされた状態をダウンロードし、その時点からのデータの検証を続けます。 データを提供しているサードパーティは信頼できるものであり、慎重に選ばれる必要があります。 +実運用では、ノードがリモートサービスに接続して最新のファイナライズされた状態をダウンロードし、その時点からデータの検証を続けます。 データ提供元のサードパーティは信頼できるものである必要があるため、慎重に選ぶ必要があります。 [チェックポイント同期](https://notes.ethereum.org/@djrtwo/ws-sync-in-practice)の詳細 ## 参考文献 {#further-reading} -インターネットには、イーサリアムクライアントに関する情報がたくさんあります。 ここでは、参考になりそうなリソースをいくつか紹介します。 +インターネット上には、イーサリアムクライアントに関する情報がたくさんあります。 その中から、特に参考になりそうなリソースをいくつか紹介します。 -- [イーサリアム 101 - パート 2 - ノードについての理解](https://kauri.io/ethereum-101-part-2-understanding-nodes/48d5098292fd4f11b251d1b1814f0bba/a) _– 2019 年 2 月 13 日 - Wil Barnes_ -- [イーサリアムフルノードの運用: 手間を省きたい人向けのガイド](https://medium.com/@JustinMLeroux/running-ethereum-full-nodes-a-guide-for-the-barely-motivated-a8a13e7a0d31) _2019 年 11 月 7 日 - Justin Leroux_ +- [イーサリアム101 - パート2 - ノードについての理解](https://kauri.io/ethereum-101-part-2-understanding-nodes/48d5098292fd4f11b251d1b1814f0bba/a) _– 2019年2月13日 - Wil Barnes_ +- [イーサリアムフルノードの運用: 手間を省きたい人向けのガイド](https://medium.com/@JustinMLeroux/running-ethereum-full-nodes-a-guide-for-the-barely-motivated-a8a13e7a0d31) _2019年11月7日 - Justin Leroux_ ## 関連トピック {#related-topics} @@ -298,5 +277,4 @@ Teku は Java 実装で、Apache 2.0 ライセンスです。 Besu や Web3Signe ## 関連チュートリアル {#related-tutorials} -- [Geth](/developers/tutorials/run-light-node-geth/)でノードを運用 _– Geth のダウンロード、インストール、実行方法。 同期モード、Javascript コンソールなど。_ -- [MicroSD カードを挿入するだけで、Raspberry Pi 4 をバリデータノードにする – インストールガイド](/developers/tutorials/run-node-raspberry-pi/) _– Raspberry Pi 4 をフラッシュし、イーサネットケーブルを接続し、SSD ディスクを接続して、電源を入れることで、Raspberry Pi 4 を、実行レイヤー(メインネット)とコンセンサスレイヤー(ビーコンチェーン / バリデータ)の両方もしくは片方を実行するフルイーサリアムノードにする。_ +- [MicroSDカードを挿入するだけで、Raspberry Pi 4をバリデータノードにする – インストールガイド](/developers/tutorials/run-node-raspberry-pi/) _– Raspberry Pi 4をフラッシュし、イーサネットケーブルを接続し、SSDディスクを接続して電源を入れることで、Raspberry Pi 4を、実行レイヤー(メインネット)とコンセンサスレイヤー(ビーコンチェーン/バリデータ)の両方もしくは片方を実行するフルイーサリアムノードにする。_ diff --git a/public/content/translations/ja/developers/docs/nodes-and-clients/light-clients/index.md b/public/content/translations/ja/developers/docs/nodes-and-clients/light-clients/index.md new file mode 100644 index 00000000000..587be2b2d34 --- /dev/null +++ b/public/content/translations/ja/developers/docs/nodes-and-clients/light-clients/index.md @@ -0,0 +1,61 @@ +--- +title: ライトクライアント +description: イーサリアムライトクライアントの概要 +lang: ja +--- + +イーサリアムとやり取りする最もトラストレスで、プライバシーが保護され、分散化され、検閲耐性のある方法は、フルノードを実行することです。 フルノードを持っていると、ブロックチェーンのコピーを自分自身で保持するため、即座にクエリを投げられます。また、イーサリアムのピアツーピアネットワークにも直接アクセスすることができます。 しかし、フルノードの実行には、大容量のメモリとストレージ、そしてCPUが必要です。 そのため、すべての人が自分のノードを実行できるわけではありません。 イーサリアムのロードマップには、これを解決するためのステートレスなどの解決策がありますが、実装には数年かかる見通しです。 短期的な解決策としては、フルノードの利点を一部犠牲にして、ハードウェア要件を大幅に低下させ、 パフォーマンスを向上させるライトクライアントがあります。 + +## ライトクライアントとは {#what-is-a-light-client} + +ライトノードとは、ライトクライアントのソフトウェアを実行しているノードです。 ブロックチェーンデータのコピーを保存して、すべての変更を自分で検証するかわりに、ライトクライアントは、必要なデータをいくつかのプロバイダーにリクエストをします。 プロバイダーは、フルノードに直接接続するか、中央集権型のRPCサーバーを通して接続する場合があります。 このデータは、ライトノードによって検証され、チェーンの先頭に追いつくことができます。 ライトノードは、ブロックヘッダーのみを処理し、必要に応じて実際のブロックのコンテンツをダウンロードします。 ノードがどの程度軽量になるかは、実行するライトクライアントソフトウェアとフルクライアントソフトウェアの組み合わせによって決まります。 例えば、最も軽量なノードは、ライト実行クライアントとライトコンセンサスクライアントを実行します。 また、多くのノードは、フル実行クライアントとライトコンセンサスクライアントを組み合わせて実行したり、その逆を選択したりするかもしれません。 + +## ライトクライアントが動作する仕組み {#how-do-light-clients-work} + +イーサリアムがプルーフ・オブ・ステークに基づいたコンセンサスメカニズムを使い始めた当時、ライトクライアントを特別にサポートするための新しいインフラストラクチャが導入されました。 この仕組みは、**同期委員会**として機能する512台あるバリデータのサブセットを1.1日ごとにランダムに選ぶことで機能します。 同期委員会は、最新のブロックのヘッダーに署名します。 すべてのブロックヘッダーには、同期委員会のバリデータによる集約された署名と、どのバリデータが署名し、どのバリデーターが署名しなかったかを示す「ビットフィールド」があります。 また、各ヘッダーには、次のブロックの署名に参加することになっているバリデータのリストもあります。 つまり、ライトクライアントでは、受信したデータの署名が同期委員会のものであることがすぐに確認できます。また、前のブロックから予想したデータと受信したデータを比較することで、同期委員会が本物であることも確認できます。 この方法で、ライトクライアントは、実際にブロック自体をダウンロードせずに、要約された情報を含むヘッダーだけで、最新のイーサリアムのブロックが持つ情報を更新し続けることができます。 + +実行レイヤーでは、ライト実行クライアントの仕様が統一されていません。 ライト実行クライアントの範囲は、フル実行クライアントの「ライトモード」とは異なる場合があります。「ライトモード」では、フルノードと同じEVMとネットワーク機能をすべて備えています。しかし、関連するデータをダウンロードせずにブロックヘッダーのみを検証するか、イーサリアムとのやり取りにおいてリクエストをRPCプロバイダーへ転送することに依存した、よりシンプルなクライアントになるかもしれません。 + +## ライトクライアントが重要である理由 {#why-are-light-clients-important} + +ライトクライアントが重要な理由は、ユーザーがデータプロバイダーを妄信せず、受信したデータを自分で検証できるようになるからです。また、ライトクライアントはフルノードに比べて、計算リソースを大幅に節約できます。 ライトクライアントが受信するデータは、ランダムに選ばれたイーサリアムのバリデータ512台のうち、少なくとも3分の2の署名が付いたブロックヘッダーで確認できます。 このブロックヘッダーは、データが正しいことの非常に強力な証明です。 + +ライトクライアントは、コンピューティングパワー、メモリ、ストレージをそれほど必要としないため、携帯電話で実行したり、アプリに埋め込んだり、ブラウザの一部として実行したりできます。 サードパーティプロバイダーに依存するのと変わらないほどスムーズに、信頼を最小限に抑えてイーサリアムへアクセスできるのがライトクライアントです。 + +ここで簡単な例を上げてみましょう。 例えば、自分のアカウントの残高を確認したい場合を考えてみましょう。 確認するには、イーサリアムノードにリクエストを送信する必要があります。 リクエストされたノードは、イーサリアムが持つ状態のローカルコピーをチェックして残高を確認し、結果を返します。 ノードに直接アクセスできない場合は、中央集権化されたオペレーターが提供するデータを使用することになります。 中央集権化されたオペレーターへリクエストを送信すると、彼らはノードを確認し、その結果を返します。 ここで問題となるのは、このプロバイダーが正しい情報を提供していると信頼しなければならないことです。 自分自身で検証できなければ、その情報が正しいかどうかは決してわかりません。 + +ライトクライアントは、この問題を解決します。 外部のプロバイダーにデータを要求する必要はありますが、データを受信すると、証明が添付されており、ライトノードはこの証明を使って、ブロックヘッダーで受信した情報と照合することができます。 これにより、信頼できるオペレーターに代わって、イーサリアムでデータの正確性を検証することができます。 + +## ライトクライアントが可能にするイノベーション {#what-innovations-do-light-clients-enable} + +ライトクライアントの主な利点は、ハードウェアの要件を問わず、サードパーティへの依存を最小限に抑え、より多くの人が単独でイーサリアムにアクセスできるようになることです。 ユーザーにとっては、自分でデータを検証できるというメリットがあります。ネットワークにとっても、チェーンを検証するノードの数と多様性が増加するメリットがあります。 + +ストレージやメモリ、処理能力が小さいデバイスでも、イーサリアムノードを実行できるようになることは、ライトクライアントによって実現される重要なイノベーションひとつです。 現在のイーサリアムノードは、大量のコンピューティングリソースを必要としますが、ライトクライアントはブラウザに埋め込むことができ、携帯電話、さらにはスマートウォッチなどの小型デバイスでも実行できる可能性があります。 つまり、携帯電話でイーサリアムウォレットと組み込みクライアントを実行できるということです。 その結果、モバイルウォレットはデータに関して中央集権的なデータプロバイダーに依存する必要がなくなり、より分散化された運用が可能になります。 + +この拡張により、**IoT(モノのインターネット)**デバイスでもライトクライアントを実行できるようになります。 ライトクライアントでは、同期委員会によって提供されるセキュリティ保証を活用して、トークンの残高やNFTの所有権を即座に証明できます。これは、IoTネットワーク上でのさまざまな用途につながります。 例えば、[自転車のレンタルサービス](https://youtu.be/ZHNrAXf3RDE?t=929)を想像してみてください。ライトクライアントが組み込まれているアプリを使用して、そのレンタルサービスのNFTを所有していることをすぐに確認し、自転車のロックを解除して、乗ることができます。 + +ライトクライアントは、イーサリアムのロールアップにもメリットがあります。 ロールアップの大きな問題のひとつは、イーサリアムメインネットからロールアップに資金を移動するブリッジを標的としたハッキングです。 脆弱性のひとつが、ユーザーがブリッジに入金したことを検出するためにロールアップが使用するオラクルです。 オラクルが不正なデータを提供すると、ロールアップはブリッジに入金があったと誤解し、誤って資金をリリースしてしまう可能性があります。 ロールアップに組み込まれたライトクライアントは、汚染されたオラクルを保護するのに役立ちます。なぜなら、ブリッジへの入金時に、トークンをリリースする前に、ロールアップで検証できる証明を添付できるからです。 このコンセプトは、他のチェーン間ブリッジにも適用できます。 + +ライトクライアントは、イーサリアムウォレットのアップグレードにも使えます。 RPCプロバイダーから提供されるデータを信頼する代わりに、組み込みのライトクライアントを使用して、ウォレットに送信されたデータを直接検証できます。 これでウォレットのセキュリティが高まります。 RPC プロバイダーが誤ったデータを不正に提供した場合、組み込みのライトクライアントは、それを検出できるでしょう。 + +## ライトクライアント開発の現状 {#current-state-of-development} + +現在、さまざまなライトクライアントの開発が進められています。ライトクライアントには、実行クライアント、コンセンサスクライアント、実行およびコンセンサスクライアントを結合したものがあります。 本ページの執筆時点で周知となっているライトクライアントの実装は、次の通りです。 + +- [Lodestar](https://github.com/ChainSafe/lodestar/tree/unstable/packages/light-client): TypeScriptで実装されたコンセンサスライトクライアント +- [Helios](https://github.com/a16z/helios): Rustで実装された実行およびコンセンサスを結合したライトクライアント +- [Geth](https://github.com/ethereum/go-ethereum/tree/master/light): Goで実装された実行クライアントのライトモード(開発中) +- [Nimbus](https://nimbus.guide/el-light-client.html): Nimで実装されたコンセンサスライトクライアント + +現時点では、これらはまだ本番環境で使用できるものではありません。 + +また、ライトクライアントがイーサリアムのデータにアクセスする方法の改善にも、多くの作業が必要です。 現状、ライトクライアントは、クライアント/サーバーモデルを使用したフルノードへのRPCリクエストが必要ですが、将来的には、[ポータルネットワーク](https://www.ethportal.net/)などのピアツーピアのゴシッププロトコルを使用して、ライトクライアントに対してデータを提供できるようになります。 + +[バークルツリー](/roadmap/verkle-trees/)や[ステートレス](/roadmap/statelessness/)などの[ロードマップ](/roadmap/)アイテムの導入により、ライトクライアントのセキュリティ保証もフルクライアントと同等になるでしょう。 + +## 参考文献 {#further-reading} + +- [Zsolt FelfodhiによるGethライトクライアントの説明](https://www.youtube.com/watch?v=EPZeFXau-RE) +- [Etan Kisslingによるライトクライアントネットワークの説明](https://www.youtube.com/watch?v=85MeiMA4dD8) +- [Etan Kisslingによるマージ後のライトクライアントの説明](https://www.youtube.com/watch?v=ZHNrAXf3RDE) +- [Piper Merriamによる記事『機能的なライトクライアントを実現するための困難な道のり』](https://snakecharmers.ethereum.org/the-winding-road-to-functional-light-clients/) diff --git a/public/content/translations/ja/developers/docs/nodes-and-clients/node-architecture/index.md b/public/content/translations/ja/developers/docs/nodes-and-clients/node-architecture/index.md new file mode 100644 index 00000000000..d69bd1572cd --- /dev/null +++ b/public/content/translations/ja/developers/docs/nodes-and-clients/node-architecture/index.md @@ -0,0 +1,59 @@ +--- +title: ノードアーキテクチャ +description: イーサリアムノードの構成についての概要 +lang: ja +--- + +イーサリアムノードは、[実行クライアント](/developers/docs/nodes-and-clients/#execution-clients)と[コンセンサスクライアント](/developers/docs/nodes-and-clients/#consensus-clients)の2つのクライアントで構成されています。 + +イーサリアムが[プルーフ・オブ・ワーク](/developers/docs/consensus-mechanisms/pow/)を使っていた時は、フルイーサリアムノードを実行するためには、実行クライアントだけで十分でした。 しかし、[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pow/)の実装以降、実行クライアントに加えて、[「コンセンサスクライアント」](/developers/docs/nodes-and-clients/#consensus-clients)と呼ばれる別のソフトウェアも必要になりました。 + +以下の図は、2つのイーサリアムクライアント間の関係を示しています。 それぞれのクライアントは、独自のピアツーピア(P2P)・ネットワークに接続しています。 実行クライアントは、ピアツーピア・ネットワークでトランザクションをゴシップし、ローカルのトランザクションプールを管理することができます。一方、コンセンサスクライアントは、ピアツーピア・ネットワークでブロックをゴシップし、コンセンサスを確立し、チェーンの成長を促進します。そのため、別々のピアツーピア・ネットワークが必要になります。 + +![](node-architecture-text-background.png) + +_この画像は、 geth.ethereum.orgから提供されたものです。Gethのロゴを使用して、実行クライアントを表しています。実行クライアントには、他にErigon、Nethermind、Besuなどがあります。_ + +この2つのクライアント構造を実現するには、コンセンサスクライアントがトランザクションのバンドルを実行クライアントに渡す必要があります。 実行クライアントは、トランザクションがイーサリアムのルールに違反していないこと、提案されたイーサリアムの状態に対する更新が正しいことを確認するために、トランザクションをローカルで実行します。 同様に、ノードがブロック生成者に選ばれた場合、コンセンサスクライアントは、新しいブロックに含めるトランザクションのバンドルをGethに要求し、それらのトランザクションを実行してグローバル状態を更新する必要があります。 このクライアント間の通信は、[エンジンAPI](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md)使ったローカルRPC接続で行われます。 + +## 実行クライアントの役割 {#execution-client} + +実行クライアントは、トランザクションの処理、トランザクションのゴシップ、状態の管理、イーサリアム仮想マシン([EVM](/developers/docs/evm/))のサポートを行います。 しかし、ブロックの構築、ブロックのゴシップ、またはコンセンサスロジックの処理は、**行いません**。 これらは、コンセンサスクライアントが行います。 + +実行クライアントは、トランザクションのリスト、更新された状態ツリー、その他の実行に関わるデータ等の実行ペイロードを作成します。 コンセンサスクライアントは、各ブロックごとに実行ペイロードを取り込みます。 実行クライアントには、新しいブロックでトランザクションを再実行して、トランザクションが有効であることを確認する役割もあります。 [イーサリアム仮想マシン(EVM)](/developers/docs/evm)と呼ばれる、実行クライアントに組み込まれたコンピュータ上でトランザクションが実行されます。 + +また、実行クライアントは、[RPCメソッド](/developers/docs/apis/json-rpc)を通じてイーサリアムへのユーザーインターフェースを提供します。これにより、ユーザーは、イーサリアムブロックチェーンにクエリを実行したり、トランザクションを送信したり、スマートコントラクトをデプロイしたりすることができます。 [Web3js](https://docs.web3js.org/)や[Web3py](https://web3py.readthedocs.io/en/v5/)などのライブラリや、ブラウザウォレットなどのユーザーインターフェースでは、RPC呼び出しを処理するのが一般的です。 + +要約すると、実行クライアントは、以下の役割を担っています。 + +- イーサリアムへのユーザーゲートウェイ +- イーサリアム仮想マシン、イーサリアムの状態およびトランザクションプールのホーム + +## コンセンサスクライアントの役割 {#consensus-client} + +コンセンサスクライアントは、ノードがイーサリアムネットワークとの同期を維持するための、すべてのロジックを扱います。 具体的には、ピアからブロックを受信し、フォーク選択アルゴリズムを実行して、バリデータの有効残高に応じて最も多くのアテステーションを蓄積しているチェーンを常時フォローします。 実行クライアントと同様に、コンセンサスクライアントにも独自のピアツーピア・ネットワークがあります。そのネットワークを通じて、ブロックとアテステーションを共有します。 + +コンセンサスクライアントは、ブロックの証明やブロックの提案には参加しません。これは、バリデータが行います。バリデータは、コンセンサスクライアントにあるオプションのアドオンです。 バリデータがないコンセンサスクライアントは、チェーンの先頭に追い付き、ノードを同期するだけです。 これにより、ユーザーは正しいチェーン上にいることを確認でき、実行クライアントを使用してイーサリアムでトランザクションを行うことができます。 + +## バリデータ {#validators} + +ノードオペレーターは、デポジットコントラクトに32ETHを入金することで、コンセンサスクライアントにバリデータを追加することができます。 バリデータクライアントは、コンセンサスクライアントにバンドルされており、いつでもノードに追加することができます。 バリデータは、アテステーションとブロック提案を行います。 ノードがETHで報酬を得たり、ペナルティやスラッシングによってETHを失うのは、バリデータが担う責任です。 バリデータソフトウェアを実行することで、ノードは新しいブロックの提案候補者となることができます。 + +[ステーキングの詳細](/staking/) + +## ノードのコンポーネントの比較 {#node-comparison} + +| 実行クライアント | コンセンサスクライアント | バリデータ | +| --------------------------------- | ------------------------------- | ----------------- | +| ピアツーピア・ネットワークを介したトランザクションのゴシップを行う | ピアツーピアを介したブロックとアテステーションのゴシップを行う | ブロックの提案を行う | +| トランザクションを実行/再実行する | フォークチョイスアルゴリズムを実行する | 報酬またはペナルティを発生させる | +| 受信した状態の変更を検証する | チェーンの先頭を追跡する | アテステーションを作成する | +| 状態ツリーとレシートツリーを管理する | ビーコン状態(コンセンサス情報や実行情報を含む) を管理する | ステークには32ETHが必要となる | +| 実行ペイロードを作成する | RANDAO内に蓄積しているランダム性を追跡する | スラッシュされる可能性がある | +| イーサリアムとやり取りできるJSON-RPC APIを公開する | 正当化とファイナライズを追跡する | | + +## 参考文献 {#further-reading} + +- [プルーフオブステーク](/developers/docs/consensus-mechanisms/pos) +- [ブロック提案](/developers/docs/consensus-mechanisms/pos/block-proposal) +- [バリデータの報酬とペナルティ](/developers/docs/consensus-mechanisms/pos/rewards-and-penalties) diff --git a/public/content/translations/ja/developers/docs/nodes-and-clients/nodes-as-a-service/index.md b/public/content/translations/ja/developers/docs/nodes-and-clients/nodes-as-a-service/index.md index bcc56e423a6..eb61adfbdf7 100644 --- a/public/content/translations/ja/developers/docs/nodes-and-clients/nodes-as-a-service/index.md +++ b/public/content/translations/ja/developers/docs/nodes-and-clients/nodes-as-a-service/index.md @@ -15,7 +15,7 @@ sidebarDepth: 2 ## ステーカー {#stakoooooooooooooors} -ソロステーカーは、サードパーティプロバイダーを使用せず、自分のインフラストラクチャを運用する必要があります。 これは、実行クライアントとコンセンサスクライアントの両方を実行することを意味します。 [マージ](/roadmap/merge)前は、コンセンサスクライアントのみを実行し、実行データに関しては中央集中型のプロバイダーを使用できましたが、これはもうできなくなり、ソロステーカーは、両方のクライアントを実行する必要があります。 しかし、このプロセスを容易にするために利用できるサービスがあります。 +ソロステーカーは、サードパーティプロバイダーを使用せず、自分のインフラストラクチャを運用する必要があります。 これは、実行クライアントとコンセンサスクライアントの両方を実行することを意味します。 [マージ](/roadmap/merge)前は、コンセンサスクライアントのみを実行し、実行データは中央集権型のプロバイダーから取得できました。マージ後は、両方のクライアントを実行する必要はありますが、 ステーキングを容易にするサービスが提供されています。 詳細については、[ノードの運用](/developers/docs/nodes-and-clients/run-a-node/)をご覧ください。 @@ -25,13 +25,13 @@ sidebarDepth: 2 ノード運用サービスプロバイダーは、分散ノードクライアントの実行を代行し、利用者の負担を軽減してくれます。 -これらのサービスは通常、ブロックチェーンへの書き込みと読み込みに使用できる API キーを提供します。 多くの場合、メインネットに加えて [イーサリアムテストネット](/developers/docs/networks/#ethereum-testnets)にもアクセスできます。 +これらのサービスは通常、ブロックチェーンへの書き込みと読み込みに使用できる APIキーを提供します。 多くの場合、メインネットに加えて [イーサリアムテストネット](/developers/docs/networks/#ethereum-testnets)にもアクセスできます。 サービスによっては、自分専用ノードの運用を提供するものもあり、ロードバランサーを使用してノード間のアクティビティを分散するものもあります。 -ほとんどのノードサービスとの統合は非常に簡単で、自己ホストノードを交換、またはサービス自体を切り替えるには、コードを 1 行変更するだけです。 +ほとんどのノードサービスとの統合は非常に簡単で、自己ホストノードを交換、またはサービス自体を切り替えるには、コードを1行変更するだけです。 -多くの場合、ノード運用サービスは様々な[ノードクライアント](/developers/docs/nodes-and-clients/#execution-clients)と[型](/developers/docs/nodes-and-clients/#node-types)を実行します。1 つの API でクライアント固有のメソッドに加えて、フルノードとアーカイブノードにアクセスできます。 +多くの場合、ノード運用サービスは様々な[ノードクライアント](/developers/docs/nodes-and-clients/#execution-clients)と[型](/developers/docs/nodes-and-clients/#node-types)を実行します。1つのAPI でクライアント固有のメソッドに加えて、フルノードとアーカイブノードにアクセスできます。 ノード運用サービスには秘密鍵やあなたの情報を保管してはいけないことにご留意ください。 @@ -39,7 +39,7 @@ sidebarDepth: 2 ノード運用サービスの利用の主なメリットは、自分でノードの保守と管理に時間を費やす必要がないことです。 これにより、インフラストラクチャのメンテナンスを心配する必要がなくなり、製品の構築に集中することができます。 -独自のノードの運用は、ストレージから処理能力、貴重なエンジニアリング時間など、非常に高価になります。 スケーリング時にノードを多数立ち上げたり、最新バージョンにアップグレードしたり、状態の一貫性を確実にするなどの作業は、望んでいる Web3 製品の作成に必要なリソースや時間を削いでしまいます。 +独自のノードの運用は、ストレージから処理能力、貴重なエンジニアリング時間など、非常に高価になります。 スケーリング時にノードを多数立ち上げたり、最新バージョンにアップグレードしたり、状態の一貫性を確実にするなどの作業は、望んでいるWeb3製品の作成に必要なリソースや時間を削いでしまいます。 ## ノード運用サービス利用のデメリット {#cons-of-using-a-node-service} @@ -54,66 +54,118 @@ sidebarDepth: 2 - [**Alchemy**](https://alchemy.com/) - [ドキュメント](https://docs.alchemyapi.io/) - 機能 - - 月間 3 億のコンピュートユニット(約 3 千万件の getLatestBlock リクエスト)の最大無料ティア - - Polygon、Starknet、Optimism、Arbitrum などの複数のチェーン対応 - - イーサリアム分散型アプリ(Dapp)と分散型金融(DeFi)のトランザクション量の約 70%を供給 - - Alchemy Notify によるリアルタイム Webhook アラート + - 月間3億のコンピュートユニット(約3千万件のgetLatestBlockリクエスト)の最大無料ティア + - Polygon、Starknet、Optimism、Arbitrumなどの複数のチェーン対応 + - イーサリアム分散型アプリ(Dapp)と分散型金融(DeFi)のトランザクション量の約70%を供給 + - Alchemy NotifyによるリアルタイムWebhookアラート - クラス最高のサポートと信頼性/安定性 - - Alchemy の NFT API + - AlchemyのNFT API - リクエストエクスプローラー、メンプールウォッチャー、および コンポーザーを備えたダッシュボード - 統合されたテストネットフォーセットのアクセス - - 18,000 人のアクティブユーザーを持つ開発者のための Discord コミュニティ + - 18,000人のアクティブユーザーを持つ開発者のためのDiscordコミュニティ +- [**All That Node**](https://allthatnode.com/) + - [ドキュメント](https://docs.allthatnode.com/) + - 機能 + - 1日あたり15万リクエストの最大の無料ティア + - 24以上のブロックチェーンノードへのアクセス + - RPC、HTTPS、WSSエンドポイント + - アーカイブデータへの無制限アクセス + - 24時間年中無休のサポートと99.9%超の稼働時間 + - 複数のチェーンで利用可能なフォーセット + - 無制限のAPIキー数でエンドポイントに無制限アクセス + - トレース/デバッグ名前空間が利用可能 + - 自動アップデート + - 技術サポート - [**Ankr**](https://www.ankr.com/) - [ドキュメント](https://docs.ankr.com/) - 機能 - - Ankr Protocol - 8 チェーン以上の Public RPC API エンドポイントへのオープンアクセス + - Ankr Protocol - 8チェーン以上の公開RPC APIエンドポイントへのオープンアクセス - ロードバランシングとノードのヘルスモニタリングにより、最も近い利用可能なノードへの高速で信頼性の高いゲートウェイを実現 - - プレミアムティアは WSS エンドポイント、レートリミットの上限なし - - ワンクリックで 40 チェーン以上のフルノードとバリデータノードをデプロイ可能 + - WSSエンドポイントと上限なしのレートリミットを実現するプレミアムティア + - 40チェーン以上のフルノードとバリデータノードをワンクリックでデプロイ - 従量課金制 - 分析ツール - ダッシュボード - - RPC、HTTPS および WSS エンドポイント + - RPC、HTTPSおよびWSSエンドポイント - ダイレクトサポート +- [**Blast**](https://blastapi.io/) + - [ドキュメント](https://docs.blastapi.io/) + - 機能 + - RPCとWSSのサポート + - マルチリージョンでのノードホスティング + - 分散型インフラストラクチャ + - 公開API + - 専用無料プラン + - マルチチェーンサポート(17種類以上のブロックチェーン) + - アーカイブノード + - 年中無休のDiscordサポート + - 年中無休のモニタリングとアラート + - 全体的なSLAは99.9% + - 暗号資産での支払い - [**BlockDaemon**](https://blockdaemon.com/) - [ドキュメント](https://ubiquity.docs.blockdaemon.com/) - - メリット + - 利点 - ダッシュボード - - ノード単位での課金 + - ノード単位ごと - 分析 +- [**BlockPI**](https://blockpi.io/) + - [ドキュメント](https://docs.blockpi.io/) + - 機能 + - ロバストで分散型のノード構造 + - HTTPSとWSSで最大40までのエンドポイント + - 無料の入会パッケージと月額パッケージ + - トレースメソッドおよびアーカイブデータのサポート + - パッケージの有効期限は最大90日 + - カスタムプランおよび従量課金制 + - 暗号資産での支払い + - ダイレクトサポートおよび技術サポート - [**Chainstack**](https://chainstack.com/) - [ドキュメント](https://docs.chainstack.com/) - 機能 - 無料共有ノード - 共有アーカイブノード - - GraphQL サポート - - RPC と WSS エンドポイント + - GraphQLサポート + - RPCとWSSエンドポイント - 専用フルノードとアーカイブノード - 専用デプロイの高速同期 - - BYOC (Bring your own cloud、クラウド持ち込み) + - BYOC(Bring your own cloud、クラウド持ち込み) - 時間課金制 - - 24 時間年中無休のダイレクトサポート + - 24時間年中無休のダイレクトサポート - [**DataHub**](https://datahub.figment.io) - [ドキュメント](https://docs.figment.io/) - 機能 - - 毎月 3 百万件のリクエストの無料ティアオプション - - RPC と WSS エンドポイント - - 専用のフルノードとアーカイブノード + - 毎月300万件のリクエストの無料ティアオプション + - RPCとWSSエンドポイント + - 専用フルノードとアーカイブノード - 自動スケーリング(ボリューム割引) - 無料のアーカイブデータ - サービス分析 - ダッシュボード - - 24 時間年中無休のダイレクトサポート + - 24時間年中無休のダイレクトサポート - 暗号通貨での支払い(エンタープライズ) +- [DRPC](https://drpc.org/) + - [ドキュメント](https://docs.drpc.org/) + - 機能 + - 分散型RPCノード + - 15以上のノードプロバイダー + - ノードバランシング + - 無料ティアで毎月無制限のコンピューティングユニット + - データ検証 + - カスタムエンドポイント + - httpおよびWSSエンドポイント + - キー無制限(無料および有料ティア) + - 柔軟なフォールバックオプション + - [公開エンドポイント](https://eth.drpc.org) + - 無料共有アーカイブノード - [**GetBlock**](https://getblock.io/) - [ドキュメント](https://getblock.io/docs/get-started/authentication-with-api-key/) - 機能 - - 40 以上のブロックチェーンノードへのアクセス - - 4 万の無料デイリーリクエスト - - 無制限の API キー + - 40以上のブロックチェーンノードへのアクセス + - 毎日4万件の無料リクエスト + - APIキー無制限 - 高速接続(1GB/秒) - トレース+アーカイブ - - 高度な分析 + - 高度な解析 - 自動アップデート - 技術サポート - [**InfStones**](https://infstones.com/) @@ -122,11 +174,11 @@ sidebarDepth: 2 - 従量課金制 - 分析 - ダッシュボード - - 独自の API エンドポイント + - 独自のAPIエンドポイント - 専用フルノード - 専用デプロイの高速同期 - - 24 時間年中無休のダイレクトサポート - - 50 以上のブロックチェーンノードへのアクセス + - 24時間年中無休のダイレクトサポート + - 50以上のブロックチェーンノードへのアクセス - [**Infura**](https://infura.io/) - [ドキュメント](https://infura.io/docs) - 機能 @@ -139,22 +191,33 @@ sidebarDepth: 2 - [ドキュメント](https://docs.kaleido.io/) - 機能 - 無料スターターティア - - イーサリアムノードのワンクリック・デプロイ + - イーサリアムノードのワンクリックデプロイ - カスタマイズ可能なクライアントとアルゴリズム(Geth、Quorum & Besu || PoA、IBFT & Raft) - - 500 以上の管理 API とサービス API - - イーサリアムトランザクション送信のための RESTful インターフェイス(Apache Kafka のサポート) - - イベント配信のためのアウトバウンドストリーム(Apache Kafka のサポート) + - 500以上の管理APIとサービス API + - イーサリアムトランザクション送信のためのRESTfulインターフェイス(Apache Kafkaのサポート) + - イベント配信のためのアウトバウンドストリーム(Apache Kafkaのサポート) - 「オフチェーン」の付随サービスの豊富なコレクション(例: 双方向の暗号化されたメッセージングトランスポート) - ガバナンスとロールベースのアクセス制御を備えた簡単なネットワーク・オンボーディング - - 管理者とエンドユーザーの両方の高度なユーザー管理 - - スケーラビリティと復元力に優れたエンタープライズ レベルのインフラストラクチャ - - Cloud HSM 秘密鍵管理 + - 管理者およびエンドユーザー向けの高度なユーザー管理 + - スケーラビリティと回復力に優れたエンタープライズレベルのインフラストラクチャ + - Cloud HSM秘密鍵管理 - イーサリアムメインネットテザリング - - ISO 27k および SOC 2 Type 2 認証 + - ISO 27kおよびSOC 2 Type 2認証 - 動的ランタイム設定(例: クラウド統合の追加、ノードイングレスの変更など) - - マルチクラウド、マルチリージョン、ハイブリッド展開オーケストレーションのサポート - - シンプルな時間単位の SaaS ベース価格 - - SLA と 24 時間年中無休のサポート + - マルチクラウド、マルチリージョン、ハイブリッド・デプロイ・オーケストレーションのサポート + - SaaSベースのシンプルな価格設定(時間単位) + - SLAと24時間年中無休のサポート +- [**Lava Network**](https://www.lavanet.xyz/) + - [ドキュメント](https://docs.lavanet.xyz/) + - 機能 + - テストネットの無料利用 + - 分散型冗長性による高い稼働時間 + - オープンソース + - 完全に分散化されたSDK + - Ethers.jsとの統合 + - 直観的なプロジェクト・マネージメント・インターフェース + - コンセンサスベースのデータ整合性 + - マルチチェーンサポート - [**Moralis**](https://moralis.io/) - [ドキュメント](https://docs.moralis.io/) - 機能 @@ -164,107 +227,160 @@ sidebarDepth: 2 - クロスチェーンサポート - 従量課金制 - ダッシュボード - - 独自のイーサリアム SDK - - 独自の API エンドポイント + - 独自のイーサリアムSDK + - 独自のAPIエンドポイント - ダイレクト技術サポート +- [**NodeReal MegaNode**](https://nodereal.io/) + - [ドキュメント](https://docs.nodereal.io/nodereal/meganode/introduction) + - 機能 + - 信頼性の高い、高速かつスケーラブルなRPC APIサービス + - Web3デベロッパー向けに改良されたAPI + - マルチチェーンサポート + - 無料で開始 - [**NOWNodes**](https://nownodes.io/) - [ドキュメント](https://documenter.getpostman.com/view/13630829/TVmFkLwy) - 機能 - - 50 以上のブロックチェーンノードへのアクセス - - 無料の API キー + - 50以上のブロックチェーンノードへのアクセス + - APIキー無料 - ブロックエクスプローラー - - API 応答時間 1 秒以下 - - 24 時間年中無休のサポートチーム + - API応答時間: 1秒未満 + - 24時間年中無休のサポートチーム - パーソナルアカウントマネージャー - 共有、アーカイブ、バックアップ、専用ノード - [**Pocket Network**](https://www.pokt.network/) - [ドキュメント](https://docs.pokt.network/home/) - 機能 - - 分散 RPC プロトコルとマーケットプレイス - - 1 日あたり百万件のリクエスト無料ティア(エンドポイントあたり最大 2) + - 分散型RPCプロトコルとマーケットプレイス + - 1日あたり100万件のリクエストができる無料ティア(エンドポイントあたり最大2件) - [パブリックエンドポイント](https://docs.pokt.network/home/resources/public-rpc-endpoints) - - プレステーク+プログラム(1 日に百万件を超えるリクエストが必要な場合) - - 15 以上のブロックチェーン対応 - - アプリケーションへのサービスで POKT を獲得する 6400 以上のノード + - プレステーク+プログラム(1日に100万件を超えるリクエストが必要な場合) + - 15以上のブロックチェーン対応 + - アプリケーションへのサービスでPOKTを獲得する6400以上のノード - アーカイブノード、トレース付きアーカイブノード、テストネットノードサポート - - イーサリアムメインネットノードクライアントの多様性 + - イーサリアムメインネットのノードクライアントの多様性 - 単一障害点なし - ゼロダウンタイム - - 費用対効果の高いほぼゼロ・トークノミクス(ネットワーク参加に POKT を 1 回ステーキング) + - 高コスト効率のゼロに近いトークノミクス(ネットワーク帯域幅を利用するためにPOKTを1回ステーキング) - 月々のコストなし、インフラストラクチャを資産に変更 - プロトコルに組み込まれたロードバランシング - - 1 日あたりのリクエスト件数と、1 時間あたりのノード数を無限に拡張可 + - 1日あたりのリクエスト件数と、1時間あたりのノード数を無限に拡張 - 最もプライベートで検閲耐性のあるオプション - ハンズオンデベロッパーサポート - [Pocket Portal](https://bit.ly/ETHorg_POKTportal)ダッシュボードと分析 - [**QuickNode**](https://www.quicknode.com) - - [ドキュメント](https://www.quicknode.com/docs/) + - [ドキュメンテーション](https://www.quicknode.com/docs/) - 機能 - - 業界をリードする性能と信頼性 - - 24 時間年中無休のテクニカルサポートとデベロッパーの Discord コミュニティ - - 地理的なバランスを考慮した、マルチ クラウド/メタル、低遅延ネットワーク - - マルチチェーンサーポート(Optimism、Arbitrum、Polygon 他 11 種以上) - - スピードと安定性を考慮したミドルレイヤー (コールルーティング、キャッシュ、インデックス作成) - - Webhook によるスマートコントラクト・モニタリング - - 直感的なダッシュボード、分析スイート、RPC コンポーザー - - 高度なセキュリティ機能 (JWT、マスキング、ホワイトリスト) - - NFT データと分析 API - - [SOC2 認証](https://www.quicknode.com/security) - - デベロッパーからエンタープライズまで適する + - 24時間年中無休の技術サポートとデベロッパーのDiscordコミュニティ + - 地理的なバランスを考慮した、マルチクラウド/メタルの低遅延ネットワーク + - マルチチェーンサーポート(Optimism、Arbitrum、Polygon他11種以上) + - スピードと安定性を考慮したミドルレイヤー(コールルーティング、キャッシュ、インデックス作成) + - Webhookによるスマートコントラクト・モニタリング + - 直感的なダッシュボード、分析スイート、RPCコンポーザー + - 高度なセキュリティ機能(JWT、マスキング、ホワイトリスト) + - NFTデータと分析API + - [SOC2認証](https://www.quicknode.com/security) + - デベロッパーからエンタープライズまで幅広く対応 - [**Rivet**](https://rivet.cloud/) - - [ドキュメント](https://rivet.readthedocs.io/en/latest/) + - [ドキュメンテーション](https://rivet.readthedocs.io/en/latest/) - 機能 - 無料ティアオプション - 従量課金制 - [**SenseiNode**](https://senseinode.com) - - [ドキュメント](https://docs.senseinode.com/) + - [ドキュメンテーション](https://docs.senseinode.com/) - 機能 - 専用ノードと共有ノード - ダッシュボード - - ラテンアメリカの様々な地域で、AWS 外の複数のホスティングプロバイダーを使ったホスティング - - Prysm と Lighthouse クライアント + - ラテンアメリカの様々な地域に拠点を置く複数のホスティングプロバイダーを利用して、AWS外部でホスティング + - PrysmとLighthouseクライアント - [**SettleMint**](https://console.settlemint.com/) - - [ドキュメント](https://docs.settlemint.com/) + - [ドキュメンテーション](https://docs.settlemint.com/) - 機能 - 無料トライアル - 従量課金制 - - GraphQL サポート - - RPC と WSS エンドポイント + - GraphQLサポート + - RPCとWSSエンドポイント - 専用フルノード - - BYOC (Bring your own cloud、クラウド持ち込み) + - BYOC(Bring your own cloud、クラウド持ち込み) - 分析ツール - ダッシュボード - 時間課金制 - ダイレクトサポート +- [**Tenderly**](https://tenderly.co/web3-gateway) + - [ドキュメンテーション](https://docs.tenderly.co/web3-gateway/web3-gateway) + - 機能 + - 1か月あたり2,500万Tenderlyユニットを含む無料ティア + - 履歴データへの無料アクセス + - 読込負荷の高いワークロードの処理速度を最大で8倍に高速化 + - 100%一貫性のある読み取りアクセス + - JSON RPCエンドポイント + - UIベースのRPCリクエストビルダーおよびリクエストプレビュー + - 密接に統合されたTenderly開発、デバック、テストツール + - トランザクションのシミュレーション + - 使用量分析およびフィルタリング + - 鍵管理への簡単なアクセス + - チャット、メール、Discordによる専用エンジニアリングサポート - [**Watchdata**](https://watchdata.io/) - [ドキュメント](https://docs.watchdata.io/) - 機能 - データの信頼性 - - ダウンタイムがなく、途切れない接続 + - ダウンタイムなしの途切れない接続 - プロセスの自動化 - 無料プラン - - 高制限でどのユーザーにも適する - - 様々なノードに対応 + - すべてのユーザーに対応する上限 + - さまざまなノードに対応 - リソーススケーリング - 高速処理速度 - [**ZMOK**](https://zmok.io/) - [ドキュメント](https://docs.zmok.io/) - 機能 - - サービス化の先駆者 - - 検索/フィルタリング機能があるグローバルトランザクションメンプール - - トランザクション送信のトランザクションフィーとガス代の制限なし + - サービスとしてのフロントランニング + - 検索/フィルタリング機能を備えたグローバルトランザクションメンプール + - トランザクション送信時のトランザクションフィーとガス代が無制限 - 新規ブロックの最速の取得とブロックチェーンの読み取り - - API 呼び出しあたりのベストプライス保証 + - API呼び出しあたりのベストプライス保証 +- [**Chainbase**](https://www.chainbase.com/) + - [ドキュメント](https://docs.chainbase.com) + - 機能 + - 高可用性、高速、スケーラブルなRPCサービス + - マルチチェーンサポート + - 無料プラン + - ユーザーフレンドリーなダッシュボード + - RPCを超えたブロックチェーンデータサービスの提供 + +[**Zeeve**](https://www.zeeve.io/) + +- [ドキュメント](https://www.zeeve.io/docs/) +- 機能 + - エンタープライズグレードのノーコード自動化プラットフォームで、デプロイメント、モニタリング、ブロックチェーンノードの管理、ネットワークを提供 + - 30以上のプロトコルと統合をサポート、さらに追加中 + - 実世界のユースケースに合わせた分散型ストレージ、分散型ID、ブロックチェーンレジャーデータAPIなどの付加価値のあるWeb3インフラストラクチャサービス + - 年中無休のサポートとプロアクティブなモニタリングにより、ノードの正常性を常に確保 + - RPCエンドポイントでは、APIへのアクセス認証、直感的なダッシュボードと分析機能により手間をかけずに管理 + - マネージドクラウドおよび、自身のクラウドオプションを持ち込み両方を提供します。メジャーなプロバイダーであるAWS、Azure、Google Cloud、Digital Ocean、およびオンプレミスなどすべてをサポート + - 常にユーザーに最も近いノードに接続するために、インテリジェントルーティングを利用 + +[**Tokenview**](https://services.tokenview.io/) + +- [ドキュメント](https://services.tokeniew/docs?type=nodeService) +- 機能 + - 年中無休の技術サポートおよび開発者向けテレグラムコミュニティ + - マルチチェーンサポート(ビットコイン、イーサリアム、トロン、BNBスマートチェーン、イーサリアムクラシック) + - RPCおよびWSSの両方のエンドポイントが利用可能 + - アーカイブデータAPIへの無制限アクセス + - リクエストエクスプローラーとメンプールウォッチャーを備えたダッシュボード + - NFTデータAPIおよびウェブフック通知 + - 暗号資産での支払い + - 追加の動作要件のための外部支援 ## 参考文献 {#further-reading} -- [イーサリアムノードサービスの一覧](https://ethereumnodes.com/) +- [イーサリアムノードサービスのリスト](https://ethereumnodes.com/) ## 関連トピック {#related-topics} -- [ノードとクライアント](/developers/docs/nodes-and-clients/) +- [ ノードとクライアント](/developers/docs/nodes-and-clients/) ## 関連チュートリアル {#related-tutorials} -- [Alchemy を使用したイーサリアム開発入門](/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/) -- [Web3 と Alchemy を使用したトランザクションの送信ガイド](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) +- [Alchemyを使用したイーサリアム開発入門](/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/) +- [Web3とAlchemyを使用したトランザクションの送信ガイド](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) diff --git a/public/content/translations/ja/developers/docs/nodes-and-clients/run-a-node/index.md b/public/content/translations/ja/developers/docs/nodes-and-clients/run-a-node/index.md index 5bc9f33adbe..83b5d819d6a 100644 --- a/public/content/translations/ja/developers/docs/nodes-and-clients/run-a-node/index.md +++ b/public/content/translations/ja/developers/docs/nodes-and-clients/run-a-node/index.md @@ -7,7 +7,7 @@ sidebarDepth: 2 自分自身のノードを立ち上げ、運用することは、さまざまなメリットがあります。新しい可能性が開かれ、エコシステムのサポートへの貢献にもつながります。 このページは、自分のノードを立ち上げ、イーサリアムのトランザクション検証に参加する方法について説明します。 -[マージ](/roadmap/merge)以降、イーサリアムノードの運用には、**実行レイヤー(EL)**クライアントと**コンセンサスレイヤー(CL)**クライアントの 2 つが必要であることに注意してください。 このページでは、この 2 つのクライアントをインストール、設定、接続してイーサリアムノードを立ち上げる方法を紹介します。 +[マージ](/roadmap/merge)以降、イーサリアムノードの運用には、**実行レイヤー(EL)**クライアントと**コンセンサスレイヤー(CL)**クライアントの2つが必要であることに注意してください。 このページでは、この2つのクライアントをインストール、設定、接続してイーサリアムノードを立ち上げる方法を紹介します。 ## 前提知識 {#prerequisites} @@ -27,7 +27,7 @@ sidebarDepth: 2 環境を整えたら、[初心者向けのインターフェース](#automatized-setup)か、高度なオプションが使用できるターミナルを使った[手動](#manual-setup)かを選び、クライアントをインストールします。 -ノードが実行して同期が取れたら、使用する準備が整いますが、メンテナンスには常に意識を向ける必要があります。 +ノードが実行され同期が完了したら、[使用](#using-the-node)できる状態になりますが、[メンテナンス](#operating-the-node)は常に意識しておく必要があります。 ![クライアントのセットアップ](./diagram.png) @@ -38,149 +38,144 @@ sidebarDepth: 2 イーサリアムクライアントは、コンシューマーグレードのコンピュータで動作します。マイニング専用マシンのような特別なハードウェアは必要ありません。 そのため、ノードのデプロイメントには、ニーズに合わせた様々なオプションがあります。 簡単にするため、ローカルの物理マシンとクラウドサーバの両方でノードを実行することしましょう。 - クラウド - - プロバイダーは高可用性のサーバと静的なパブリック IP アドレスを提供 + - プロバイダーは高可用性のサーバと静的なパブリックIPアドレスを提供 - 専用または仮想サーバを構築するよりも容易に利用可能 - サードパーティであるサーバプロバイダーを信頼しなければならないトレードオフが発生 - フルノードに必要なストレージ容量により、レンタルサーバの価格が高くなることがある - 自分のハードウェア - トラストレスで主権的なアプローチ - - 1 回限りの投資 + - 1回限りの投資 - 事前設定された専用マシンを購入することも可能 - マシンやネットワークの物理的な準備、メンテナンス、トラブルシューティングが必要 -どちらの選択肢も、上記のような異なるメリットがあります。 従来型のクラウドコンピューティングプロバイダに加えて、クラウドソリューションを探している場合は、ノードのデプロイに焦点を当てたサービスもあります。 例: - -- [QuikNode](https://www.quiknode.io/) -- [BlockDaemon](https://blockdaemon.com) -- [Alchemy](https://www.alchemy.com/) - -ホスティングされたノードのオプションについては、[ノード・アズ・ア・サービス](/developers/docs/nodes-and-clients/nodes-as-a-service/)も参照してください。 +どちらの選択肢も、上記のような異なるメリットがあります。 従来型のクラウドコンピューティングプロバイダーに加えて、クラウドソリューションを探している場合は、ノードのデプロイに焦点を当てたサービスもあります。 ホスティングされたノードのオプションについての詳細は、[ノード・アズ・ア・サービス](/developers/docs/nodes-and-clients/nodes-as-a-service/)を参照してください。 #### ハードウェア {#hardware} -しかし、検閲耐性をもつ分散型ネットワークは、クラウドプロバイダに依存すべきではありません。 クラウドではなく、ローカルハードウェア上でノードを実行することが、エコシステムにとってより健全となります。 [推計](https://www.ethernodes.org/networkType/Hosting)によると、クラウド上で動作するノードの割合が多く、単一障害点となる可能性があることが示唆されています。 +しかし、検閲耐性を備えた分散型ネットワークは、クラウドプロバイダーに依存すべきではありません。 クラウドではなく、ローカルハードウェア上でノードを実行することが、エコシステムにとってより健全です。 [推計](https://www.ethernodes.org/networkType/Hosting)によると、クラウド上で動作するノードの割合が多く、単一障害点となる可能性があります。 イーサリアムクライアントは、デスクトップパソコン、ノートパソコン、サーバ、あるいはシングルボードコンピュータ上で動作させることができます。 パーソナルコンピュータでクライアントを実行することも可能ですが、ノード専用マシンを用意することで、プライマリコンピュータへの影響を最小限に抑えながら、パフォーマンスとセキュリティを大幅に向上させることができます。 -自分のハードウェアの使用は非常に簡単です。 シンプルなオプションだけでなく、より技術的な方向けの高度なセットアップ方法も多数用意されています。 それでは、自分自身のマシンでイーサリアムクライアントを実行するための要件と方法を見てみましょう。 +自分のハードウェアを使うのは非常に簡単です。 シンプルなオプションだけでなく、より技術的な方向けの高度なセットアップ方法も多数用意されています。 それでは、自分のマシンでイーサリアムクライアントを実行するための要件と方法を見ていきましょう。 #### 必要条件 {#requirements} -ハードウェア要件はクライアントによって異なりますが、ノードは同期を維持する必要があるだけなので、通常、要件はそれほど高くありません。 より多くの計算能力を必要とするマイニングと混同しないでください。 ただし、より強力なハードウェアでは同期時間とパフォーマンスは改善します。 +ハードウェア要件はクライアントによって異なりますが、ノードは同期を維持する必要があるだけなので、通常はそれほど高くありません。 マイニングとは異なり、ノードは多くの計算能力を必要としないため、混同しないでください。 ただし、より強力なハードウェアでは、同期時間とパフォーマンスは向上します。 クライアントをインストールする前に、コンピュータに十分なリソースがあることを確認してください。 最小システム要件と推奨システム要件は以下のとおりです。 -ハードウェアのボトルネックは、主にディスク容量です。 イーサリアムブロックチェーンの同期は、非常に多くの入出力を必要とし、多くのディスクスペースが必要です。 同期後も数百 GB の空き容量を確保できる、ソリッド・ステート・ドライブ(SSD)を用意することをお勧めします。 +ハードウェアのボトルネックは、主にディスク容量です。 イーサリアムブロックチェーンの同期は、非常に多くの入出力を必要とし、多くのディスクスペースが必要です。 そのため、同期後も数百GBの空き容量を確保できる、ソリッド・ステート・ドライブ(SSD)を用意することをお勧めします。 データベースのサイズと初期同期の速度は、選択したクライアント、設定、[同期戦略](/developers/docs/nodes-and-clients/#sync-modes)によって異なります。 -また、インターネット接続が[帯域幅の上限](https://wikipedia.org/wiki/Data_cap)により制限されていないことを確認してください。 ネットワークにブロードキャストされたデータが制限を超える可能性があるため、従量非制限の接続を使用することをお勧めします。 +また、インターネット接続が[帯域幅の上限](https://wikipedia.org/wiki/Data_cap)により制限されていないことを確認してください。 ネットワークにブロードキャストされたデータが制限を超える可能性があるため、従量制限のない接続を使用することをお勧めします。 -##### オペレーティングシステム {#operating-system} +##### オペレーティングシステム -すべてのクライアントは、Linux、MacOS、Windows などの主要なオペレーティングシステムに対応しています。 自分に最適なオペレーティングシステム(OS)を使って、通常のデスクトップまたはサーバマシンでノードを実行できます。 潜在的な問題やセキュリティの脆弱性を回避するために、お使いの OS が最新の状態になっていることを確認してください。 +すべてのクライアントは、Linux、MacOS、Windowsなどの主要なオペレーティングシステムに対応しています。 自分に最適なオペレーティングシステム(OS)を使って、通常のデスクトップまたはサーバマシンでノードを実行できます。 潜在的な問題やセキュリティの脆弱性を回避するために、お使いのOSが最新の状態になっていることを確認してください。 -##### 最小システム要件 {#minimum-requirements} +##### 最小システム要件 - CPU: デュアルコア以上 -- RAM 8GB -- ディスク空き容量 700GB -- 帯域幅 10MB/秒以上 +- RAM: 8GB +- 2TB: SSD +- 帯域幅: 10MB/秒以上 -##### 推奨される仕様 {#recommended-hardware} +##### 推奨される仕様 -- 高速 CPU クアッドコア以上 -- RAM 16GB 以上 -- 高速 SSD 1TB 以上 -- 帯域幅 25MB/秒以上 +- 高速CPU: クアッドコア以上 +- RAM: 16GB以上 +- 高速SSD: 2TB以上 +- 帯域幅: 25MB/秒以上 選択した同期モードとクライアントによって必要容量が変わります。以下に各クライアントに必要なディスク容量の概算を記載します。 -| クライアント | ディスクサイズ(スナップ同期) | ディスクサイズ(フルアーカイブ) | -| ------------ | ---------------------------- | ------------------------------ | -| Geth | 500GB 以上 | 12TB 以上 | -| Nethermind | 500GB 以上 | 12TB 以上 | -| Besu | 800GB 以上 | 12TB 以上 | -| Erigon | N/A | 2.5TB 以上 | +| クライアント | ディスクサイズ(スナップ同期) | ディスクサイズ(フルアーカイブ) | +| ---------- | --------------- | ---------------- | +| Geth | 500GB以上 | 12TB以上 | +| Nethermind | 500GB以上 | 12TB以上 | +| Besu | 800GB以上 | 12TB以上 | +| Erigon | N/A | 2.5TB以上 | -- 注: エリゴンにはスナップ同期はありませんが、フルプルーニングが可能(約 500GB) +- 注: エリゴンにはスナップ同期機能はありませんが、フルプルーニングは可能です(約500GB) -コンセンサスクライアントには、必要な容量はクライアントの実装や有効にした機能(バリデータスラッシャーなど)によって変わりますが、概ねビーコンデータ用にさらに 200GB を必要とします。 多数のバリデータを実行すると、帯域幅への負荷も大きくなります。 こちらの分析に、[コンセンサスクライアントの要件詳細](https://medium.com/@migalabs/analysis-of-ethereum-2-consensus-clients-dfede8e0145e)が記載されています。 +コンセンサスクライアントの必要な容量は、クライアントの実装や有効にした機能(バリデータスラッシャーなど)によって変わりますが、概ねビーコンデータ用にさらに200GB必要です。 また、多数のバリデータを実行すると、帯域幅への負荷も大きくなります。 [こちら](https://medium.com/@migalabs/analysis-of-ethereum-2-consensus-clients-dfede8e0145e)に、本分析のコンセンサスクライアントの要件詳細が記載されています。 #### プラグ・アンド・プレイ・ソリューション {#plug-and-play} -自分のハードウェアでノードを実行するのに最も簡単な方法は、プラグ・アンド・プレイ・ボックスを使用することです。 事前設定されたマシンを使うと、注文、接続、実行と最も簡単に実行することができます。 何もかもが事前設定されており、自動実行され、直感的なガイドとダッシュボードでソフトウェアを監視・制御できます。 +自分のハードウェアでノードを実行する最も簡単な方法は、プラグ・アンド・プレイ・ボックスを使用することです。 事前に設定されたマシンを使うと、注文、接続、実行まで、最も簡単に実行することができます。 すべてが事前設定されており、自動実行され、直感的なガイドとダッシュボードでソフトウェアを監視・制御できます。 - [DappNode](https://dappnode.io/) - [Avado](https://ava.do/) #### シングルボードコンピュータ {#ethereum-on-a-single-board-computer} -Raspberry Pi のような ARM アーキテクチャを持つシングルボードコンピュータを使用すると、イーサリアムノードを簡単かつ安価に実行できます。 [Ethereum on ARM](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/)は、Raspberry Pi やその他の ARM ボード向けに、実行クライアントとコンセンサスクライアントが容易に実行できるイメージを複数提供しています。 +Raspberry PiのようなARMアーキテクチャのシングルボードコンピュータを使用すると、イーサリアムノードを簡単かつ安価に実行できます。 [Ethereum on ARM](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/)は、Raspberry Piやその他のARMボード向けに、実行クライアントとコンセンサスクライアントが容易に実行できるイメージを複数提供しています。 -これらのようなデバイスは、小型、価格が手頃、効率が良く、自宅でノードを運用するのに理想的な反面、性能には限界があることに留意してください。 +これらのデバイスは、小型で価格も手頃、効率も良く、自宅でノードを運用するのに適していますが、性能には限界があることに注意が必要です。 ## ノードの立ち上げ {#spinning-up-node} 実際のクライアント設定は、自動ランチャーを使うか、または手動で直接設定できます。 -上級者でない場合は、ランチャー(インストールをガイドし、クライアントのセットアッププロセスを自動化するソフトウェア)を使用することをお勧めします。 とはいえ、ターミナルの使用経験があれば、手動設定は簡単です。 +上級者でない場合は、ランチャー(インストールをガイドし、クライアントの設定を自動化するソフトウェア)を使用することをお勧めします。 ターミナルの操作に慣れている方は、手動設定も可能です。 ### ガイド付き設定 {#automatized-setup} -複数プロジェクトが、クライアント設定のユーザーエクスペリエンスの向上を目指しています。 ランチャーはクライアントのインストールと設定を自動的に行います。クライアントのガイド付きセットアップと監視用にグラフィック・インターフェイスを提供しているランチャーもあります。 +複数のプロジェクトが、クライアント設定のユーザーエクスペリエンスの向上を目指しています。 ランチャーは、クライアントのインストールと設定を自動化します。また、クライアントのガイド付きセットアップと監視用にグラフィック・インターフェースを提供しているランチャーもあります。 -数回クリックするだけでクライアントをインストールし、制御できる便利なプロジェクトを下記に紹介します。 +数回クリックするだけで、クライアントのインストールや制御ができる便利なプロジェクトを紹介します。 -- [DappNode](https://docs.dappnode.io/get-started/installation/custom-hardware/installation/overview/) - DappNode はベンダーからのマシンだけに提供されているのではなく、 ノードランチャーやコントロールセンターのソフトウェアは多くの機能があり、任意のハードウェアで使用可能。 -- [eth-docker](https://eth-docker.net/docs/About/Overview/) - Docker を使った自動設定は、簡単で安全なステーキングに焦点を当てており、ターミナルと Docker の基本的な知識が必要。少し上級のユーザー向け。 -- [Stereum](https://stereum.net/ethereum-node-setup/) - SSH 接続でリモートサーバにクライアントをインストールするためのランチャー。GUI セットアップガイド、コントロールセンター、その他多くの機能搭載。 +- [DappNode](https://docs.dappnode.io/user/quick-start/first-steps/) - DappNodeはベンダーから提供されるマシンに限らず、 ノードランチャーやコントロールセンターのソフトウェアは多くの機能があり、任意のハードウェアで使用可能。 +- [eth-docker](https://eth-docker.net/) - Dockerを使った自動設定は、簡単で安全なステーキングに焦点を当てており、ターミナルとDockerの基本的な知識が必要。少し上級のユーザー向け。 +- [Stereum](https://stereum.net/ethereum-node-setup/) - SSH接続でリモートサーバにクライアントをインストールするためのランチャー。GUIセットアップガイド、コントロールセンター、その他多くの機能搭載。 - [NiceNode](https://www.nicenode.xyz/) - コンピュータ上でノードを実行するためのランチャー。分かりやすいユーザーエクスペリエンスが特徴。 クライアントを選択し、数回クリックするだけで開始可能。 現在、開発中。 +- [Sedge](https://docs.sedge.nethermind.io/docs/intro) - ノードのセットアップツールでCLIのウィザードを使いDocker構成を自動生成。 NethermindによってGoで開発。 ### 手動でのクライアント設定 {#manual-setup} -もう一つのオプションは、手動でクライアントソフトウェアをダウンロードし、確認・設定することです。 グラフィック・インターフェイスを提供しているクライアントはありますが、手動設定はターミナルの基本的なスキルが必要となりますが、はるかに汎用性があります。 +もう1つのオプションは、クライアントソフトウェアを手動でダウンロードして、確認・設定することです。 グラフィック・インターフェースを提供するクライアントもありますが、手動設定にはターミナルの基本的なスキルが必要となります。ただし、より幅広い用途に対応できます。 -前述したように、自分のイーサリアムノードを立ち上げるには、コンセンサスクライアントと実行クライアントをペアで実行する必要があります。 一部のクライアントには、他の種類のライトクライアントが含まれいるものがあり、それ以外のソフトウェアを必要とせず同期します。 しかし、完全にトラストレスな検証にはコンセンサスクライアントと実行クライアントの両方が必要です。 +前述したように、自分のイーサリアムノードを立ち上げるには、コンセンサスクライアントと実行クライアントをペアで実行する必要があります。 一部のクライアントには、他の種類のライトクライアントが含まれているものがあり、それ以外のソフトウェアをインストールする必要なく同期できます。 しかし、完全にトラストレスな検証を行うためには、コンセンサスクライアントと実行クライアントの両方が必要です。 #### クライアントソフトウェアの取得 {#getting-the-client} まず、希望する[実行クライアント](/developers/docs/nodes-and-clients/#execution-clients)と[コンセンサスクライアント](/developers/docs/nodes-and-clients/#consensus-clients)ソフトウェアを取得する必要があります。 -オペレーティングシステムとアーキテクチャに適した、実行可能なアプリケーションやインストールパッケージをダウンロードするだけです。 必ず、ダウンロードしたパッケージの署名とチェックサムを確認してください。 インストールやアップデートを簡単にするためのリポジトリや Docker イメージを提供するクライアントもあります。 クライアントはすべてオープンソースなので、ソースからビルドすることもできます。 これはより高度な方法ですが、場合によっては必要な場合があります。 +オペレーティングシステムとアーキテクチャに適した、実行可能なアプリケーションやインストールパッケージをダウンロードするだけです。 ダウンロードしたパッケージの署名とチェックサムも必ず確認してください。 インストールやアップデートを簡単に行うためのリポジトリやDockerイメージを提供するクライアントもあります。 クライアントはすべてオープンソースなので、ソースからビルドすることもできます。 これはより高度な方法ですが、場合によっては必要になることがあります。 クライアントごとの手順は、上記のクライアントリストにリンクされているドキュメントに記載されています。 ここでは、ビルド済みのバイナリやインストール方法が掲載されているクライアントのリリースページを紹介します。 -##### 実行クライアント {#execution-clients} +##### 実行クライアント - [Besu](https://github.com/hyperledger/besu/releases) -- [Erigon](https://github.com/ledgerwatch/erigon#usage) (ビルド済みのバイナリを提供していないためコンパイル要) +- [Erigon](https://github.com/ledgerwatch/erigon/releases) - [Geth](https://geth.ethereum.org/downloads/) - [Nethermind](https://downloads.nethermind.io/) -また、クライアントの多様性は[実行レイヤーで問題](/developers/docs/nodes-and-clients/client-diversity/#execution-layer)となっていることにも注意が必要です。 マイノリティの実行クライアントの運用を検討することをお勧めします。 +また、[実行レイヤーにおいても](/developers/docs/nodes-and-clients/client-diversity/#execution-layer)、クライアントの多様性が問題となっていることにも注意が必要です。 マイノリティの実行クライアントの運用を検討することをお勧めします。 -##### コンセンサスクライアント {#consensus-clients} +##### コンセンサスクライアント - [Lighthouse](https://github.com/sigp/lighthouse/releases/latest) -- [Lodestar](https://chainsafe.github.io/lodestar/install/source/) (ビルド済みのバイナリを提供していないため、Docker イメージを使用またはソースからビルド) +- [Lodestar](https://chainsafe.github.io/lodestar/install/source/)(ビルド済みのバイナリを提供していないため、Dockerイメージを使用またはソースからビルド) - [Nimbus](https://github.com/status-im/nimbus-eth2/releases/latest) - [Prysm](https://github.com/prysmaticlabs/prysm/releases/latest) - [Teku](https://github.com/ConsenSys/teku/releases) -[クライアントの多様性](/developers/docs/nodes-and-clients/client-diversity/)は、バリデータを実行しているコンセンサスノードにとって重要です。 マジョリティのバリデータが単一のクライアントを実行していると、ネットワークのセキュリティが危険にさらされます。 そのため、マイノリティクライアントを選択することをお勧めします。 +バリデータを実行しているコンセンサスノードにとって、[クライアントの多様性](/developers/docs/nodes-and-clients/client-diversity/)は重要です。 マジョリティのバリデータが単一のクライアントを実行していると、ネットワークのセキュリティが危険にさらされます。 そのため、マイノリティクライアントを選択することをお勧めします。 [最新のネットワーククライアントの使用状況](https://clientdiversity.org/)を参照し、[クライアントの多様性](/developers/docs/nodes-and-clients/client-diversity)についてご覧ください。 -##### ソフトウェアの検証 {#verifying-the-software} +##### ソフトウェアの検証 -インターネットからソフトウェアをダウンロードする場合は、ダウンロードしたファイルの完全性を検証することをお勧めします。 このステップは任意ですが、特にイーサリアムクライアントのような重要なインフラストラクチャの一部では、潜在的な攻撃ベクトルを認識し、回避することが重要です。 ビルド済みのバイナリをダウンロードした場合、それを信頼する必要がありますが、攻撃者が実行ファイルを悪意のあるものにすり替えるというリスクがあります。 +インターネットからソフトウェアをダウンロードする場合は、ダウンロードしたファイルの完全性を検証することをお勧めします。 このステップは任意ですが、特にイーサリアムクライアントのような重要なインフラストラクチャの一部では、潜在的な攻撃ベクトルを認識し、回避することが重要です。 ビルド済みのバイナリをダウンロードした場合、その出所を信頼する必要がありますが、攻撃者が実行ファイルを悪意のあるものにすり替えるというリスクもあります。 -デベロッパーはリリースしたバイナリに、デベロッパーの PGP キーで署名しているためめ、デベロッパーが作ったソフトウェアそのものを間違いなく実行していることを暗号的に検証できます。 デベロッパーが使用した公開鍵は、クライアントのリリースページやドキュメントに記載されており、そこから入手できます。 リリースされているクライアントと署名をダウンロードした後、[GnuPG](https://gnupg.org/download/index.html)などの PGP 実装を使って、簡単に検証できます。 [Linux](https://www.tecmint.com/verify-pgp-signature-downloaded-software/)または[Windows/MacOS](https://freedom.press/training/verifying-open-source-software/)の`gpg`を使って、オープンソースソフトウェアを検証するチュートリアルを確認してください。 +デベロッパーはリリースしたバイナリに、デベロッパーのPGPキーで署名しています。そのため、デベロッパーが作成したソフトウェアそのものを間違いなく実行していることを暗号的に検証できます。 デベロッパーが使用した公開鍵は、クライアントのリリースページやドキュメントに記載されており、そこから入手できます。 リリースされたクライアントと署名をダウンロードしたら、[GnuPG](https://gnupg.org/download/index.html)などのPGP実装を使って、簡単に検証できます。 [Linux](https://www.tecmint.com/verify-pgp-signature-downloaded-software/)または[Windows/MacOS](https://freedom.press/training/verifying-open-source-software/)の`gpg`を使って、オープンソースソフトウェアを検証するチュートリアルを確認してください。 -ダウンロードしたソフトウェアを検証するもう 1 つの方法としては、ハッシュが(一意の暗号論的指紋)、デベロッパーによって提供されたものと一致するかどうかを確認することです。 これは PGP を使うよりもさらに簡単で、ハッシュだけを提供するクライアントもあります。 ダウンロードしたソフトウェアに対しハッシュ関数を実行し、リリースページに載っているものと比較してください。 例: +ダウンロードしたソフトウェアを検証するもう1つの方法は、ハッシュが(一意の暗号論的指紋)、デベロッパーによって提供されたものと一致するかどうかを確認することです。 これはPGPを使うよりもさらに簡単で、ハッシュだけを提供するクライアントもあります。 ダウンロードしたソフトウェアに対しハッシュ関数を実行し、リリースページに記載されているものと比較してください。 以下の例を確認してください: ``` sha256sum teku-22.6.1.tar.gz @@ -190,33 +185,33 @@ sha256sum teku-22.6.1.tar.gz #### クライアントのセットアップ {#client-setup} -クライアントソフトウェアのインストール、ダウンロード、またはコンパイルが完了したら、実行する準備が整い、 あとは適切な設定を行うだけです。 クライアントは豊富な設定オプションを提供しており、様々な機能を有効化できます。 +クライアントソフトウェアのインストール、ダウンロード、またはコンパイルが完了したら、実行する準備が整い、 あとは適切な設定を行うだけです。 クライアントには、さまざまな機能を有効化できる豊富な設定オプションが提供されています。 -まずは、クライアントのパフォーマンスやデータ使用量に大きく影響するオプションから紹介します。 [同期モード](/developers/docs/nodes-and-clients/#sync-modes)とは、ブロックチェーンデータのダウンロードと検証のさまざまな方法を表します。 ノードを開始する前に、使用するネットワークと同期モードを決める必要があります。 考慮すべき最も重要なことは、クライアントに必要なディスク容量と同期時間です。 どの同期モードがデフォルトであるかをクライアントのドキュメントで確認してください。 デフォルトの同期モードが適切でなければ、セキュリティレベル、利用可能なデータ、およびコストに基づいて別の同期モードを選択します。 同期アルゴリズムとは別に、さまざまな種類の古いデータをプルーニングすることもできます。 プルーニングは、最近のブロックから利用できない状態ツリーノードなど、古いデータを削除します。 +まずは、クライアントのパフォーマンスやデータ使用量に大きく影響するオプションから紹介します。 [同期モード](/developers/docs/nodes-and-clients/#sync-modes)とは、ブロックチェーンデータのダウンロードと検証のさまざまな方法のことです。 ノードを開始する前に、使用するネットワークと同期モードを決める必要があります。 考慮すべき最も重要なことは、クライアントに必要なディスク容量と同期にかかる時間です。 クライアントのドキュメントで、デフォルトの同期モードを確認してください。 デフォルトの同期モードが適切でない場合は、セキュリティレベル、利用可能なデータ、コストを考慮して、別の同期モードを選択します。 同期アルゴリズムとは別に、さまざまな種類の古いデータを剪定することもできます。 剪定により古いデータが削除されます。例えば、最近のブロックから到達できない状態のtrieノードを削除します。 -その他の基本設定オプションは、例えば ネットワークの選択(メインネットまたはテストネット)、RPC または WebSocket などの HTTP エンドポイントの有効化などです。 クライアントのドキュメントには、すべての機能とオプションが載っています。 CLI (コマンドラインインターフェース)または設定ファイルに直接、対応するフラグを指定してクライアントを実行することで、さまざまなクライアント設定ができます。 各クライアントによって多少異なりますので、設定オプションの詳細については、公式ドキュメントまたはヘルプページを必ず参照してください。 +その他の基本設定オプションとしては、ネットワークの選択(メインネットまたはテストネット)、HTTPエンドポイント(RPCまたはWebSocketなど)の有効化などがあります。 クライアントのドキュメントには、すべての機能とオプションが記載されています。 CLI(コマンドラインインターフェース)または設定ファイルに直接、対応するフラグを指定してクライアントを実行することで、さまざまなクライアント設定ができます。 ただし、各クライアントによって設定オプションが多少異なるため、詳細については、公式ドキュメントまたはヘルプページを必ず参照してください。 -テストのため、テストネットの 1 つでクライアントを実行することを推奨します。 詳しくは、[対応ネットワークの概要](/developers/docs/nodes-and-clients/#execution-clients)を参照してください。 +テストを行う場合は、テストネットの1つでクライアントを実行することをお勧めします。 詳しくは、[対応ネットワークの概要](/developers/docs/nodes-and-clients/#execution-clients)をご覧ください。 基本設定による実行クライアントの実行例は、次のセクションに記載されています。 #### 実行クライアントの開始 {#starting-the-execution-client} -イーサリアムクライアントソフトウェアを開始する前に、環境の準備ができているか最終チェックをしてください。 以下の事項などを確認してください。 +イーサリアムクライアントソフトウェアを起動する前に、環境が整っていることを最終チェックします。 具体的には、以下の事項などを確認してください。 - 選択したネットワークと同期モードを考慮した十分なディスク容量があること。 -- メモリと CPU が他のプログラムによって停止されないこと。 +- メモリやCPUが他のプログラムによって妨害されないこと。 - オペレーティングシステムが最新バージョンに更新されていること。 - システムが正しい時刻と日付になっていること。 -- ルーターとファイアウォールは、リスニングポートの接続を受け付けること。 デフォルトでは、イーサリアムクライアントはリスナー (TCP) ポートとディスカバリー(UDP)ポートを使用し、ポート番号はともに 30303 がデフォルト。 +- リスニングポートに接続できるようにルーターとファイアウォールを設定していること。 イーサリアムクライアントは、デフォルトでリスナー(TCP)ポートとディスカバリー(UDP)ポートを使用し、30303に設定していること。 最初にテストネットでクライアントを実行して、すべてが正常に動作していることを確認します。 -最初にデフォルトではないクライアントを設定する必要があります。 フラグまたは設定ファイルを使って、希望の設定に変更できます。 各クライアントにより機能や設定構文は異なります。 具体的な内容については、お使いのクライアントのドキュメントを確認してください。 +最初にデフォルトではないクライアントを設定する必要があります。 フラグや設定ファイルを使って、希望の設定に変更できます。 各クライアントにより機能や設定構文が異なるため、 具体的な内容については、お使いのクライアントのドキュメントを確認してください。 -実行クライアントとコンセンサスクライアントは、[Engine API](https://github.com/ethereum/execution-apis/tree/main/src/engine)で指定された認証済みエンドポイントを介して通信します。 実行クライアントはコンセンサスクライアントに接続するために、既知のパスで[`jwtsecret`](https://jwt.io/)を生成する必要があります。 セキュリティと安定性の理由から、両方のクライアントは同じマシン上で実行する必要があり、ローカル RPC 接続で相互に認証するので、両方のクライアントがこのパスを知っていなければなりません。 また、実行クライアントは認証された API のリスニングポートを定義する必要があります。 +実行クライアントとコンセンサスクライアントは、[エンジンAPI](https://github.com/ethereum/execution-apis/tree/main/src/engine)で指定された認証済みエンドポイントを介して通信します。 実行クライアントはコンセンサスクライアントに接続するために、既知のパスで[`jwtsecret`](https://jwt.io/)を生成する必要があります。 セキュリティと安定性の理由から、両方のクライアントは同じマシン上で実行する必要があり、ローカルRPC接続で相互認証を行うため、両方のクライアントがこのパスを共有していなければなりません。 また、実行クライアントは認証されたAPIのリスニングポートを定義する必要があります。 -このトークンはクライアントソフトウェアによって自動的に生成されます。場合によっては、自分で作成することもあります。 [OpenSSL](https://www.openssl.org/)を使って生成できます。 +このトークンは、通常はクライアントソフトウェアによって自動的に生成されます。ただし、自分で作成しなければならないこともあります。その場合は、 [OpenSSL](https://www.openssl.org/)を使用してください。 ``` openssl rand -hex 32 > jwtsecret @@ -227,21 +222,21 @@ openssl rand -hex 32 > jwtsecret このセクションでは、実行クライアントの開始について説明します。 あくまでも基本的な設定例となりますが、以下の設定でクライアントを起動します。 - この例では、メインネットに接続するネットワークを指定 - - [テストネット](/developers/docs/networks/)のいずれか 1 つを選択して、セットアップの予備テストも実行可 + - [テストネット](/developers/docs/networks/)のいずれか1つを選択して、セットアップの予備テストも実行可 - ブロックチェーンを含むすべてのデータが格納されるデータディレクトリを定義 - パスは必ず実際のものに変更する(例: 外付けドライブのディレクトリの指定など) -- クライアントと通信するためのインターフェイスを有効化 - - コンセンサスクライアントとの通信で利用する JSON RPC と Engine API を含む -- API 認証で使う`jwtsecret`のパスを定義 +- クライアントと通信するためのインターフェースを有効化 + - コンセンサスクライアントとの通信で利用するJSON RPCとエンジンAPIを含む +- API認証で使う`jwtsecret`のパスを定義 - 例えば、`/tmp/jwtsecret`など、クライアントがアクセス可能な実際のパスにする -これは基本的な例であることに注意してください。それ以外の設定はすべてデフォルトになっています。 各クライアントのドキュメントをよく読み、デフォルト、設定、機能について学びましょう。 バリデータの実行、モニタリングなど、その他の機能の詳細については、各クライアントのドキュメントを参考にしてください。 +これは基本的な例であることに注意してください。それ以外の設定はすべてデフォルトになっています。 各クライアントのドキュメントをよく読み、デフォルト、設定、機能について理解しましょう。 バリデータの実行やモニタリングなど、その他の機能の詳細については、各クライアントのドキュメントを参照してください。 -> 注意: 例のバックスラッシュ`\`は見やすさのために記載しており、設定フラグは 1 行で定義できます。 +> 注: 例のバックスラッシュ`\`は見やすさのために記載しており、設定フラグは1行で定義できます。 -##### Besu の実行 +##### Besuの実行 -この例では、メインネットで Besu を起動し、ブロックチェーンデータをデフォルトフォーマットで`/data/ethereum`に保存し、コンセンサスクライアントへの接続のために JSON RPC と Engine RPC を有効にしています。 Engine API は、トークン`jwtsecret`で認証され、`localhost`からのみ呼び出しが許可されます。 +この例では、メインネットでBesuを起動し、ブロックチェーンデータをデフォルトフォーマットで`/data/ethereum`に保存し、コンセンサスクライアントへの接続のためにJSON RPCとEngine RPCを有効にしています。 エンジンAPIは、トークン`jwtsecret`で認証され、`localhost`からの呼び出しのみが許可されます。 ``` besu --network=mainnet \ @@ -253,17 +248,17 @@ besu --network=mainnet \ --engine-jwt-secret=/path/to/jwtsecret ``` -Besu には、一連の質問に答えることで設定ファイルを生成できるランチャーオプションもあります。 対話型ランチャーを実行するには、以下の通りです。 +Besuには、一連の質問に答えることで設定ファイルを生成できるランチャーオプションもあります。 対話型ランチャーは、以下のように実行できます。 ``` besu --Xlauncher ``` -[Besu のドキュメント](https://besu.hyperledger.org/en/latest/HowTo/Get-Started/Starting-node/)で、追加のオプションと設定の詳細を参照してください。 +[Besuのドキュメント](https://besu.hyperledger.org/en/latest/HowTo/Get-Started/Starting-node/)で、追加のオプションと設定の詳細を参照してください。 -##### Erigon の実行 +##### Erigonの実行 -この例では、Erigon をメインネットで起動、ブロックチェーンデータを`/data/ethereum`に保存、JSON RPC を有効化、許可するネームスペースを定義、また`jwtsecret`パスで定義されるコンセンサスクライアントへの接続認証を有効にしています。 +この例では、Erigonをメインネットで起動して、ブロックチェーンデータを`/data/ethereum`に保存します。また、JSON RPCを有効にして、許可するネームスペースを定義します。さらに、`jwtsecret`パスで定義されるコンセンサスクライアントへの接続認証を有効にしています。 ``` erigon --chain mainnet \ @@ -272,25 +267,26 @@ erigon --chain mainnet \ --authrpc.jwtsecret=/path/to/jwtsecret ``` -Erigon はデフォルトで 8GB の HDD でフル同期を行い、アーカイブデータは 2TB 以上となります。 `datadir`が十分な空き容量のあるディスクを指していることを確認するか、さまざまな種類のデータを削除する`--prune`フラグを検討してください。 詳細については、Erigon の`--help`オプションを参照してください。 +Erigonは、デフォルトで8GBのHDDでフル同期を行います。アーカイブデータは2TB以上になるので、 `datadir`が十分な空き容量のあるディスクを指していることを確認するか、さまざまな種類のデータを削除する`--prune`フラグを検討してください。 詳細については、Erigonの`--help`オプションを参照してください。 -##### Geth の実行 +##### Gethの実行 -この例では、Geth をメインネットで起動、ブロックチェーンデータを`/data/ethereum`に保存、JSON RPC を有効化、許可するネームスペースを定義しています。 また、コンセンサスクライアントに接続するための認証を有効化し、認証に必要な`jwtsecret`を定義し、許可する接続のオプションも合わせて(この例では`localhost`からのみ)定義しています。 +この例では、Gethをメインネットで起動し、ブロックチェーンデータを`/data/ethereum`に保存します。また、JSON RPCを有効にして、許可するネームスペースを定義します。 さらに、コンセンサスクライアントに接続するための認証を有効にし、認証に必要な`jwtsecret`を定義し、許可する接続のオプションも合わせて(この例では`localhost`からのみ)定義しています。 ``` geth --mainnet \ --datadir "/data/ethereum" \ - --http --http.api="eth,web3,net" \ + --http --authrpc.addr localhost \ --authrpc.vhosts="localhost" \ + --authrpc.port 8551 --authrpc.jwtsecret=/path/to/jwtsecret ``` -[すべての設定オプションのドキュメント](https://geth.ethereum.org/docs/interface/command-line-options)と[コンセンサスクライアントと Geth を実行する方法](https://geth.ethereum.org/docs/interface/consensus-clients)を参照してください。 +[すべての設定オプションのドキュメント](https://geth.ethereum.org/docs/fundamentals/command-line-options)を確認し、[コンセンサスクライアントとGethを実行する方法](https://geth.ethereum.org/docs/getting-started/consensus-clients)についての詳細を参照してください。 -##### Nethermind の実行 +##### Nethermindの実行 -Nethermind は、様々な[インストールオプション](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/getting-started)を提供しています。 ガイド付きセットアップ機能を備えたランチャーを含むさまざまなバイナリがパッケージに含まれており、インタラクティブに設定できます。 あるいは、実行ファイルそのものであるランナーもあり、設定フラグを付けて実行することもできます。 JSON RPC はデフォルトで有効になっています。 +Nethermindは、さまざまな[インストールオプション](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/getting-started)を提供しています。 パッケージには、ガイド付きセットアップ機能を備えたランチャーなどのさまざまなバイナリが含まれており、インタラクティブに設定できます。 他にも、設定フラグを付けて実行できるランナーなどがあります。 JSON RPCはデフォルトで有効になっています。 ``` Nethermind.Runner --config mainnet \ @@ -298,38 +294,38 @@ Nethermind.Runner --config mainnet \ --JsonRpc.JwtSecretFile=/path/to/jwtsecret ``` -Nethermind は、Nethermind とコンセンサスクライアントを実行するための[完全ガイド](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/running-nethermind-post-merge)を提供しています。 +Nethermindのドキュメントは、Nethermindとコンセンサスクライアントの実行方法をすべて網羅した[完全ガイド](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/running-nethermind-post-merge)です。 -実行クライアントはコア機能と選択されたエンドポイントを開始し、ピアを探し始めます。 ピアが正常に見つかった後、クライアントは同期を開始します。 実行クライアントは、コンセンサスクライアントからの接続を待機します。 クライアントが正常に現在の状態に同期されると、現在のブロックチェーンデータが利用可能になります。 +実行クライアントは、コア機能と選択したエンドポイントを起動し、ピアを探し始めます。 ピアが見つかったら、同期を開始します。 また、コンセンサスクライアントからの接続を待ちます。 クライアントが正常に現在の状態に同期されると、現在のブロックチェーンデータが利用できるようになります。 #### コンセンサスクライアントの開始 {#starting-the-consensus-client} -実行クライアントへのローカル RPC 接続を確立させために、コンセンサスクライアントを正しいポート設定で起動する必要があります。 コンセンサスクライアントは、公開した実行クライアントのポートを引数に設定して実行する必要があります。 +実行クライアントへのローカルRPC接続を確立させるために、コンセンサスクライアントを正しいポート設定で起動する必要があります。 コンセンサスクライアントは、公開した実行クライアントのポートを引数に設定して実行します。 -コンセンサスクライアントは、RPC 接続を認証するために実行クライアントの`jwt-secret`へのパスも必要です。 上記の実行例と同様に、各コンセンサスクライアントは、jwt トークンファイルパスを引数とする設定フラグを持っています。 これは実行クライアントに使われる`jwtsecret`のパスと一致しなければなりません。 +コンセンサスクライアントは、RPC接続を認証するために実行クライアントの`jwt-secret`へのパスも必要です。 上記の実行例と同様に、各コンセンサスクライアントには、jwtトークンファイルパスを引数とする設定フラグがあります。 このパスは、実行クライアントに使われる`jwtsecret`のパスと一致しなければなりません。 -バリデータを運用する予定がある場合は、フィーを受け取るイーサリアムアドレスを指定する設定フラグを必ず追加してください。 これはバリデータのイーサ報酬が蓄積されるアドレスになります。 各コンセンサスクライアントは、例えば`--suggested-fee-recipient=0xabcd1`のように、イーサリアムアドレスを引数に取るオプションがあります。 +バリデータを実行する予定がある場合は、フィーを受け取るイーサリアムアドレスを指定する設定フラグを必ず追加してください。 このアドレスは、バリデータのイーサ報酬が蓄積されるアドレスです。 各コンセンサスクライアントは、`--suggested-fee-recipient=0xabcd1`のように、イーサリアムアドレスを引数に取るオプションがあります。 テストネットでビーコンノードを起動する場合、[チェックポイント同期](https://notes.ethereum.org/@launchpad/checkpoint-sync)にパブリックエンドポイントを使用すると、同期時間が大幅に短縮されます。 #### コンセンサスクライアントの実行 -##### Lighthouse の実行 +##### Lighthouseの実行 -Lighthouse を実行する前に、[Lighthouse Book](https://lighthouse-book.sigmaprime.io/installation.html)でインストールと設定方法の詳細を参照してください。 +Lighthouseを実行する前に、[Lighthouse Book](https://lighthouse-book.sigmaprime.io/installation.html)でインストールと設定方法の詳細を参照してください。 ``` -lighthouse beacon_node +lighthouse beacon_node \ --network mainnet \ --datadir /data/ethereum \ --http \ --execution-endpoint http://127.0.0.1:8551 \ - --execution-jwt /path/to/jwtsecret \ + --execution-jwt /path/to/jwtsecret ``` -##### Lodestar の実行 +##### Lodestarの実行 -Lodestar ソフトウェアをコンパイルするか、Docker イメージをダウンロードしてインストールしてください。 詳細については、[ドキュメント](https://chainsafe.github.io/lodestar/)、およびより包括的な[セットアップガイド](https://hackmd.io/@philknows/rk5cDvKmK)を参照してください。 +Lodestarソフトウェアをコンパイルするか、Dockerイメージをダウンロードしてインストールしてください。 詳細については、[ドキュメント](https://chainsafe.github.io/lodestar/)または総合[セットアップガイド](https://hackmd.io/@philknows/rk5cDvKmK)を参照してください。 ``` lodestar beacon \ @@ -340,9 +336,9 @@ lodestar beacon \ --jwt-secret="/path/to/jwtsecret" ``` -##### Nimbus の実行 +##### Nimbusの実行 -Nimbus には、コンセンサスクライアントと実行クライアントの両方が含まれています。 Nimbus は計算能力の低いデバイスでも実行できます。 [必要なものと Nimbus 自体のインストール後](https://nimbus.guide/quick-start.html)、コンセンサスクライアントを実行できます。 +Nimbusには、コンセンサスクライアントと実行クライアントの両方を備えています。 計算能力の低いデバイスでも実行可能です。 [必要なものをインストールした後](https://nimbus.guide/quick-start.html)、コンセンサスクライアントを実行できます。 ``` nimbus_beacon_node \ @@ -352,119 +348,118 @@ nimbus_beacon_node \ --jwt-secret="/path/to/jwtsecret" ``` -##### Prysm の実行 +##### Prysmの実行 -Prysm には、簡単に自動インストールできるスクリプトがあります。 詳細については、[Prysm ドキュメント](https://docs.prylabs.network/docs/install/install-with-script)を参照してください。 +Prysmには、簡単に自動インストールできるスクリプトがあります。 詳細については、[Prysmドキュメント](https://docs.prylabs.network/docs/install/install-with-script)を参照してください。 ``` ./prysm.sh beacon-chain \ - --mainnet + --mainnet \ --datadir /data/ethereum \ --execution-endpoint=http://localhost:8551 \ --jwt-secret=/path/to/jwtsecret ``` -##### Teku の実行 +##### Tekuの実行 ``` teku --network mainnet \ --data-path "/data/ethereum" \ --ee-endpoint http://localhost:8551 \ - --ee-jwt-secret-file "/path/to/jwtsecret" \ + --ee-jwt-secret-file "/path/to/jwtsecret" ``` -コンセンサスクライアントが実行クライアントに接続し、デポジットコントラクトを読み込みバリデータを識別します。また、他のビーコンノードのピアにも接続し、ジェネシスブロック(最初のブロック)からコンセンサススロットの同期を開始します。 ビーコンノードが現在のエポックに達すると、ビーコン API がバリデータで使用できるようになります。 詳細については、[ビーコンノード API](https://eth2docs.vercel.app/)を参照してください。 +コンセンサスクライアントが実行クライアントに接続し、デポジットコントラクトを読み込みバリデータを識別します。同時に、他のビーコンノードのピアにも接続し、ジェネシスブロック(最初のブロック)からコンセンサススロットの同期を開始します。 ビーコンノードが現在のエポックに到達すると、バリデータはビーコンAPIを使用できるようになります。 詳細については、[ビーコンノードAPI](https://eth2docs.vercel.app/)を参照してください。 ### バリデータの追加 {#adding-validators} -コンセンサスクライアントは、バリデータが接続するビーコンノードとして機能します。 各コンセンサスクライアントは、それぞれのバリデータ・ソフトウェアを搭載しています。詳細については、各ドキュメントに記載されています。 +コンセンサスクライアントは、バリデータが接続するビーコンノードとして機能します。 各コンセンサスクライアントは、それぞれのバリデータソフトウェアを搭載しています。詳細については、各ドキュメントに記載されています。 -自分でバリデータを実行すると、[ソロステーキング](/staking/solo/)ができます。これはイーサリアムネットワークをサポートする上で、最も影響があり、トラストレスな方法です。 しかし、これには 32 ETH のデポジットが必要になります。 より少ない金額で自分のノードでバリデータを実行するには、[Rocket Pool](https://rocketpool.net/node-operators)など、パーミッションレスなノードオペレータの分散型プールに関心を持つかもしれません。 +自分でバリデータを実行すると、[ソロステーキング](/staking/solo/)ができます。これはイーサリアムネットワークをサポートする上で、最も影響力があり、トラストレスな方法です。 ただし、32 ETHのデポジットが必要となります。 費用を抑えたい場合は、[Rocket Pool](https://rocketpool.net/node-operators)など、パーミッションレスなノードオペレータの分散型プールに参加することで、少ない費用でバリデータを実行することもできます。 -ステーキングとバリデータのキー生成の最も簡単な方法は、[Goerli テストネット・ステーキングランチパッド](https://goerli.launchpad.ethereum.org/)を使うことです。これにより、[Goerli でノードを実行](https://notes.ethereum.org/@launchpad/goerli)し、自分のセットアップをテストすることができます。 メインネットへの準備ができたら、今度は[メインネット・ステーキングランチパッド](https://launchpad.ethereum.org/)を使って、同じ手順を繰り返します。 +ステーキングとバリデータのキーを生成するには、[Goerliテストネット・ステーキングランチパッド](https://goerli.launchpad.ethereum.org/)を使うのが最も簡単です。Goerliテストネットでは、実際に[ノードを実行](https://notes.ethereum.org/@launchpad/goerli)して、自分のセットアップをテストすることができます。 メインネットに移行する準備ができたら、今度は[メインネット・ステーキングランチパッド](https://launchpad.ethereum.org/)を使って、同じ手順を繰り返します。 ステーキングオプションの概要については、[ステーキング](/staking)ページをご覧ください。 ### ノードの使用 {#using-the-node} -実行クライアントは、トランザクションの送信、イーサリアムネットワーク上のスマートコントラクトとの対話やデプロイなど、様々な用途で使用可能な[RPC API エンドポイント](/developers/docs/apis/json-rpc/)を提供します。 +実行クライアントは、トランザクションの送信や、イーサリアムネットワーク上のスマートコントラクトとの対話やデプロイなど、さまざまな用途で使用可能な[RPC APIエンドポイント](/developers/docs/apis/json-rpc/)を提供します。 - 適切なプロトコルで手動呼び出し(例: `curl`) - 指定したコンソールの接続(例: `geth attach`) -- Web3 ライブラリを用いたアプリケーションへの実装(例: [web3.py](https://web3py.readthedocs.io/en/stable/overview.html#overview)、[ethers](https://github.com/ethers-io/ethers.js/)) +- Web3ライブラリを用いたアプリケーションへの実装(例: [web3.py](https://web3py.readthedocs.io/en/stable/overview.html#overview)、[ethers](https://github.com/ethers-io/ethers.js/)) -クライアントが異なれば、RPC エンドポイントの実装も異なります。 しかし、すべてのクライアントで使用できる標準的な JSON-RPC があります。 概要については、[JSON-RPC ドキュメント](/developers/docs/apis/json-rpc/)を参照してください。 イーサリアムネットワークからの情報を必要とするアプリケーションは、この RPC を使用できます。 例えば、人気のウォレットである MetaMask では、[自分自身の RPC エンドポイントに接続](https://metamask.zendesk.com/hc/en-us/articles/360015290012-Using-a-Local-Node)することができ、プライバシーとセキュリティに大きな利点があります。 +クライアントによって、RPCエンドポイントの実装は異なります。 しかし、すべてのクライアントで使用できる標準的なJSON-RPCがあります。 概要については、[JSON-RPCドキュメント](/developers/docs/apis/json-rpc/)を参照してください。 イーサリアムネットワークからの情報を必要とするアプリケーションは、このRPCを使用できます。 例えば、人気のウォレットであるMetaMaskでは、[自分自身のRPCエンドポイントに接続](https://metamask.zendesk.com/hc/en-us/articles/360015290012-Using-a-Local-Node)することができ、プライバシーとセキュリティの向上を実現できます。 -コンセンサスクライアントは、すべて[Beacon API](https://ethereum.github.io/beacon-APIs)を公開しており、これを利用してコンセンサスクライアントの状態を確認したり、[Curl](https://curl.se)などのツールを使ってリクエストを送り、ブロックやコンセンサスデータをダウンロードすることができます。 これに関する詳細については、各コンセンサスクライアントのドキュメントを参照してください。 +コンセンサスクライアントは、すべて[ビーコンAPI](https://ethereum.github.io/beacon-APIs)を公開しており、これを利用してコンセンサスクライアントの状態を確認したり、[Curl](https://curl.se)などのツールを使ってリクエストを送り、ブロックやコンセンサスデータをダウンロードしたりすることができます。 詳細については、各コンセンサスクライアントのドキュメントを参照してください。 -#### RPC への接続 {#reaching-rpc} +#### RPCへの接続 {#reaching-rpc} -実行クライアントの JSON-RPC デフォルトポートは`8545`ですが、設定でローカルエンドポイントのポート番号を変更できます。 デフォルトでは、RPC インターフェイスはコンピュータのローカルホストからのみアクセス可能です。 リモートからアクセスできるようにするには、アドレスを`0.0.0.0`に変更し、パブリックに公開することができます。 これにより、ローカルネットワークおよびパブリック IP アドレスで接続可能になります。 ほとんどの場合、ルーターでポート転送も設定する必要があります。 +実行クライアントのJSON-RPCデフォルトポートは`8545`ですが、設定でローカルエンドポイントのポートを変更することもできます。 デフォルトでは、RPCインターフェースはコンピュータのローカルホストからしかアクセスできません。 リモートからアクセスするには、アドレスを`0.0.0.0`に変更して、パブリックに公開します。 これにより、ローカルネットワーク内だけでなく、パブリックIPアドレスでも接続できるようになります。 また、ほとんどの場合、ルーターでポート転送を設定する必要があります。 インターネットにポートを公開するアプローチは、インターネット上の誰でもノードをコントロールできるようになるため、注意が必要です。 悪意のある者がノードにアクセスしてシステムをダウンさせたり、クライアントをウォレットとして使用している場合は、資金が盗まれる可能性があります。 -これを回避するには、危険性のある RPC メソッドを変更できないようにすることです。 例えば、Geth の場合、フラグで変更可能なメソッドを明示することができます。`--http.api web3,eth,txpool`. +これを回避するには、危険性のあるRPCメソッドを変更できないようにすることです。 例えば、Gethの場合、フラグで変更可能なメソッドを明示することができます。`--http.api web3,eth,txpool`. -RPC インターフェイスへのアクセスは、エッジレイヤー API の開発、もしくは Nginx のようなウェブサーバアプリケーションからクライアントのローカルアドレスやポートに接続することで拡張できます。 デベロッパーは、ミドルレイヤーを活用することで、RPC インターフェースへセキュアな`https`接続用の証明書を設定することもできます。 +RPCインターフェースへのアクセスは、エッジレイヤーAPIの開発、もしくはNginxのようなWebサーバアプリケーションから、クライアントのローカルアドレスやポートに接続することで拡張できます。 デベロッパーは、ミドルレイヤーを活用することで、RPCインターフェースを安全に`https`接続で使えるように、証明書を設定することもできます。 -ノードの RPC エンドポイントへのアクセスを付与する方法は、ウェブサーバ、プロキシ、または外向けの REST API の設定だけではありません。 別の方法として、独自の[Tor](https://www.torproject.org/)オニオンサービス上でノードをホストすると、プライバシーを保護しつつ、パブリックからアクセス可能なエンドポイントを設定することができます。 これにより、静的なパブリック IP アドレスやオープンポートを使用せずに、ローカルネットワーク外から RPC に到達できます。 ただし、Tor ネットワークはすべてのアプリケーションでサポートされているわけではなく、接続問題が発生する可能性があるネットワーク経由からのみ、RPC エンドポイントがアクセス可能になることに注意してください。 +ノードのRPCエンドポイントへのアクセスを付与する方法は、Webサーバやプロキシ、外向けのREST APIを設定するだけではありません。 独自の[Tor](https://www.torproject.org/)オニオンサービス上でノードをホストすれば、プライバシーを保護しつつ、パブリックからアクセス可能なエンドポイントを設定することができます。 これにより、静的なパブリックIPアドレスやオープンポートを使用せずに、ローカルネットワーク外からRPCにアクセスできます。 ただし、Torネットワークはすべてのアプリケーションでサポートされているわけではなく、接続が不安定なネットワーク経由からのみRPCエンドポイントにアクセスできる点に注意してください。 -これを行うには、自身の[オニオンサービス](https://community.torproject.org/onion-services/)を作成する必要があります。 自分自身のオニオンサービスをセットアップするには、[ドキュメント](https://community.torproject.org/onion-services/setup/)を参照してください。 RPC ポートへのプロキシを使って Web サーバを指すか、直接 RPC を指すことができます。 +これを行うには、自身の[オニオンサービス](https://community.torproject.org/onion-services/)を作成する必要があります。 オニオンサービスのセットアップ方法は、[ドキュメント](https://community.torproject.org/onion-services/setup/)を参照してください。 RPCポートへのプロキシを使ってWebサーバを指すか、直接RPCを指すことができます。 -最後に、最も一般的な VPN を使って、内部ネットワークへのアクセスを提供することもできます。 ユースケースとノードへアクセスが必要なユーザーの人数にもよりますが、安全な VPN 接続は選択肢の一つとなります。 [OpenVPN](https://openvpn.net/)は、フル機能の SSL VPN です。OSI レイヤー 2 やレイヤー 3 の安全なネットワーク拡張機能を実装し、業界標準の SSL/TLS プロトコルを使います。また、証明書ベースの柔軟なクライアント認証方法もサポートしており、スマートカード認証またはユーザ名/パスワード認証の組み合わせも可能で、ユーザーやグループ固有のアクセスコントロールポリシーをファイヤーウォールルールを使い VPN の仮想インターフェースに適用できます。 +最後に、最も一般的なVPNを使って、内部ネットワークへのアクセスを提供することもできます。 ユースケースやノードへのアクセスが必要なユーザーの人数によっては、安全なVPN接続は選択肢の1つとなります。 [OpenVPN](https://openvpn.net/)は、OSIレイヤー2やレイヤー3の安全なネットワーク拡張機能を実装した、フル機能のSSL VPNです。業界標準のSSL/TLSプロトコルを用いており、証明書ベースの認証やスマートカード認証、ユーザ名/パスワード認証など、さまざまな柔軟なクライアント認証方法に対応しています。また、ファイアウォールルールを使って、ユーザーやグループ固有のアクセスコントロールポリシーを設定し、VPNの仮想インターフェースに適用することもできます。 ### ノードの運用 {#operating-the-node} -ノードが正常に動作するように、定期的に監視する必要があります。 時折メンテナンスが必要になる場合があります。 +ノードが正常に動作するためには、定期的に監視し、 必要に応じてメンテナンスを行う必要があります。 #### ノードのオンライン状態の維持 {#keeping-node-online} -ノードが常時オンラインになっている必要はありませんが、ネットワークと同期させるためにできるだけオンラインにしておく必要があります。 シャットダウンして再起動することもできますが、以下の点に留意してください。 +ノードが常時オンラインになっている必要はありませんが、ネットワークと同期させるためにできるだけオンラインにしておく必要があります。 シャットダウンして再起動することもできますが、以下の点に注意してください。 -- 最新の状態をディスクに書き込みれ中の場合は、シャットダウンには数分程度かかることがある。 +- 最新の状態をディスクに書き込み中の場合は、シャットダウンには数分程度かかることがある。 - 強制シャットダウンを行うと、データベースに損傷を与え、ノード全体の再同期が必要になることがある。 -- クライアントはネットワークとの同期が解除され、再起動時に再同期が必要。 ノードは最後にシャットダウンされたところから同期を開始できるが、オフラインになっていた時間に応じて処理時間が増加。 +- クライアントはネットワークとの同期が解除され、再起動時に再同期が必要になる。 ノードは最後にシャットダウンされたところから同期を開始できるが、オフラインになっていた時間に応じて処理時間が増加する。 -*これはコンセンサスレイヤーのバリデータノードには適用されません。*ノードをオフラインにすると、ノードに依存するすべてのサービスに影響を及ぼします。 *ステーキング*目的でノードを実行している場合は、可能な限りダウンタイムを最小限に抑えるようにしてください。 +_これはコンセンサスレイヤーのバリデータノードには適用されません。_ノードをオフラインにすると、ノードに依存するすべてのサービスに影響を及ぼします。 _ステーキング_目的でノードを実行している場合は、可能な限りダウンタイムを最小限に抑えるようにしてください。 #### クライアントサービスの作成 {#creating-client-services} -起動時にクライアントを自動起動するサービスを作成することを検討してください。 例えば、Linux サーバでは`systemd`などでサービスを作成し、権限が制限されたユーザーの下で、適切な設定でクライアントを実行し、自動的に再起動するように作成するのが最善の方法でしょう。 +起動時にクライアントを自動起動するサービスを作成することを検討してください。 例えば、Linuxサーバでは`systemd`などでサービスを作成し、権限が制限されたユーザーの下で、適切な設定でクライアントを実行し、自動的に再起動するように作成するのがお勧めです。 #### クライアントの更新 {#updating-clients} -クライアントソフトウェアを最新のセキュリティパッチ、機能、 [EIP](/eips/)で、最新の状態に保つ必要があります。 特に、[ハードフォーク](/history/)の前に、正しいクライアントバージョンを実行していることを確認してください。 +クライアントソフトウェアは、最新のセキュリティパッチ、機能、 [EIP](/eips/)の最新バージョンを常にインストールしておく必要があります。 特に、[ハードフォーク](/history/)が行われる前に、正しいクライアントバージョンを実行していることを確認してください。 > 重要なネットワーク更新の前には、イーサリアム・ファウンデーション(EF)の[ブログ](https://blog.ethereum.org)で投稿されます。 [これらのお知らせを購読する](https://groups.google.com/a/ethereum.org/g/announcements)ことで、ノードの更新が必要なときにメールで通知を受け取ることができます。 -クライアントの更新は非常に簡単です。 各クライアントのドキュメントに具体的な手順が記載されていますが、一般的には最新版をダウンロードし、新しい実行ファイルを使ってクライアントを再起動するだけです。 アップデートが適用され、クライアントは前回終了したところから再開するはずです。 +クライアントの更新は非常に簡単です。 各クライアントのドキュメントに具体的な手順が記載されていますが、一般的には、最新版をダウンロードし、新しい実行ファイルを使ってクライアントを再起動するだけです。 アップデートが適用され、クライアントは前回終了したところから再開します。 -各クライアントは、ピアツーピアプロトコルで使用される人間が判読できるバージョン文字列を持っていますが、コマンドラインからもアクセスできます。 このバージョン文字列を使って、ユーザーは自分が正しいバージョンを実行していることを確認でき、ブロックエクスプローラーやその他の分析ツールは、ネットワーク上で特定のクライアントの分散を定量化します。 バージョン文字列の詳細については、個々のクライアントのドキュメントを参照してください。 +各クライアントは、ピアツーピアプロトコルで使用される、人間が判読できるバージョン文字列を持っており、この文字列はコマンドラインからもアクセスできます。 このバージョン文字列を使って、ユーザーは自分が正しいバージョンを実行していることを確認できるほか、ネットワーク上で特定のクライアントの分散を定量化するために使われるブロックエクスプローラーやその他の分析ツールにも役立ちます。 バージョン文字列の詳細については、個々のクライアントのドキュメントを参照してください。 #### その他のサービスの実行 {#running-additional-services} -自分でノードを実行すると、イーサリアムクライアント RPC に直接アクセスを必要とするサービスを利用できます。 これらは[レイヤー 2 ソリューション](/developers/docs/scaling/#layer-2-scaling)、ウォレットのバックエンド、ブロックエクスプローラー、デベロッパーツール、その他のイーサリアムインフラストラクチャのようなイーサリアム上に構築されたサービスです。 +自分でノードを実行すると、イーサリアムクライアントRPCへの直接アクセスを必要とするサービスを利用できます。 これらは、[レイヤー2ソリューション](/developers/docs/scaling/#layer-2-scaling)、ウォレットのバックエンド、ブロックエクスプローラー、デベロッパーツール、その他のイーサリアムインフラストラクチャのような、イーサリアム上に構築されたサービスです。 #### ノードの監視 {#monitoring-the-node} -ノードを適切に監視するために、メトリクスの収集を検討してください。 クライアントが提供するメトリクス・エンドポイントから、ノードに関する包括的なデータを取得できます。 [InfluxDB](https://www.influxdata.com/get-influxdb/)や[Prometheus](https://prometheus.io/) のようなツールを使用して、データベースを作成でき、[Grafana](https://grafana.com/)のようなソフトウェアで視覚化やグラフ化ができます。 このソフトウェアを使用するための多くのセットアップと、ノードとネットワーク全体を視覚化するためのさまざまな Grafana ダッシュボードがあります。 一例として、[Geth の監視に関するグチュートリアル](/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/)を参照してください。 +ノードを適切に監視するために、メトリクスの収集を検討してください。 クライアントが提供するメトリクスエンドポイントから、ノードに関する包括的なデータを取得できます。 [InfluxDB](https://www.influxdata.com/get-influxdb/)や[Prometheus](https://prometheus.io/)などのツールを使用して、データベースを作成することができます。また、[Grafana](https://grafana.com/)などのソフトウェアを使って、データの視覚化やグラフ化を行うことができます。 このソフトウェアを使用するには、さまざまなセットアップ方法があり、ノードやネットワーク全体を視覚化するためのGrafanaダッシュボードも多種用意されています。 一例として、[Gethの監視に関するチュートリアル](/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/)を参照してください。 -モニタリングの一環として、必ずマシンのパフォーマンスを監視してください。 ノードの初期の同期中、クライアントソフトウェアは CPU と RAM に非常に大きな負荷がかかる場合があります。 Grafana に加えて、OS が提供する`htop`や`uptime`などのツールを使用して監視を行うこともできます。 +モニタリングを行う際は、必ずマシンのパフォーマンスも監視してください。 ノードの初期同期中は、クライアントソフトウェアがCPUとRAMに大きな負荷をかけることがあります。 Grafanaに加えて、OSが提供する`htop`や`uptime`などのツールでも監視できます。 ## 参考文献 {#further-reading} - [イーサリアムステーキングガイド](https://github.com/SomerEsat/ethereum-staking-guides) _– Somer Esat、頻繁に更新_ - [ガイド|イーサリアムメインネットでステーキングをするためのバリデータのセットアップ方法](https://www.coincashew.com/coins/overview-eth/guide-or-how-to-setup-a-validator-on-eth2-mainnet) _CoinCashew、定期的に更新_ -- [ETHStaker によるテストネットでのバリデータ運用ガイド](https://github.com/remyroy/ethstaker#guides) - _ETHStaker、定期的に更新_ -- [イーサリアムステーキングガイド](https://github.com/SomerEsat/ethereum-staking-guides) _– Somer Esat、定期的に更新_ -- [ノード運用者向けのマージに関するよくある質問](https://notes.ethereum.org/@launchpad/node-faq-merge) - _2022 年 7 月_ -- [イーサリアムのフル検証ノードになるためのハードウェア要件の分析](https://medium.com/coinmonks/analyzing-the-hardware-requirements-to-be-an-ethereum-full-validated-node-dc064f167902) _– Albert Palau、2018 年 9 月 24 日_ -- [イーサリアムフルノードの運用: 完全ガイド](https://medium.com/@JustinMLeroux/running-ethereum-full-nodes-a-guide-for-the-barely-motivated-a8a13e7a0d31) _2019 年 11 月 7 日 - Justin Leroux_ -- [イーサリアムメインネットでハイパーレジャー Besu ノードの運用: メリット・要件・セットアップ](https://pegasys.tech/running-a-hyperledger-besu-node-on-the-ethereum-mainnet-benefits-requirements-and-setup/) _– Felipe Faraggi、2020 年 5 月 7 日_ -- [モニタリングスタックで Nethermind イーサリアムクアイアントのデプロイ](https://medium.com/nethermind-eth/deploying-nethermind-ethereum-client-with-monitoring-stack-55ce1622edbd) _– Nethermind.eth、2020 年 7 月 8 日_ +- [ETHStakerによるテストネットでのバリデータ運用ガイド](https://github.com/remyroy/ethstaker#guides) - _ETHStaker、定期的に更新_ +- [ノード運用者向けのマージに関するよくある質問](https://notes.ethereum.org/@launchpad/node-faq-merge) - _2022年7月_ +- [イーサリアムのフル検証ノードになるためのハードウェア要件の分析](https://medium.com/coinmonks/analyzing-the-hardware-requirements-to-be-an-ethereum-full-validated-node-dc064f167902) _– Albert Palau、2018年9月24日_ +- [イーサリアムフルノードの運用: 手間を省きたい人向けのガイド](https://medium.com/@JustinMLeroux/running-ethereum-full-nodes-a-guide-for-the-barely-motivated-a8a13e7a0d31) _2019年11月7日 - Justin Leroux_ +- [イーサリアムメインネットでハイパーレジャーBesuノードの運用: メリット、要件、セットアップ](https://pegasys.tech/running-a-hyperledger-besu-node-on-the-ethereum-mainnet-benefits-requirements-and-setup/) _– Felipe Faraggi、2020年5月7日_ +- [モニタリングスタックでNethermindイーサリアムクライアントのデプロイ](https://medium.com/nethermind-eth/deploying-nethermind-ethereum-client-with-monitoring-stack-55ce1622edbd) _– Nethermind.eth、2020年7月8日_ ## 関連トピック {#related-topics} -- [ノードとクライアント](/developers/docs/nodes-and-clients/) +- [ ノードとクライアント](/developers/docs/nodes-and-clients/) - [ブロック](/developers/docs/blocks/) - [ネットワーク](/developers/docs/networks/) diff --git a/public/content/translations/ja/developers/docs/oracles/index.md b/public/content/translations/ja/developers/docs/oracles/index.md index 2bd074657cf..c6744b93de9 100644 --- a/public/content/translations/ja/developers/docs/oracles/index.md +++ b/public/content/translations/ja/developers/docs/oracles/index.md @@ -4,9 +4,9 @@ description: オラクルを通じて、イーサリアムのスマートコン lang: ja --- -オラクルは、ブロックチェーンの外部(オフチェーン)のデータソースからデータを取り出し、ブロックチェーンの内部(オンチェーン)に記入することで、スマートコントラクトで利用できるようにするためのデータフィードです。 オラクルが必要なのは、イーサリアム上で実行されるスマートコントラクトは、ブロックチェーンネットワークの外部に保存された情報にアクセスできないためです。 +オラクルは、ブロックチェーンでオフチェーンのデータソースを利用可能にするスマートコントラクト向けのデータフィードです。 イーサリアムベースのスマートコントラクトでは、デフォルトでブロックチェーンのネットワークの外に保存されている情報にアクセスできないため必要になります。 -スマートコントラクトにオフチェーンの入力データを実行する機能を与えることで、分散型アプリケーションの価値が高まります。 例えば分散型の予測市場は、予測結果に関する情報につきオラクルに依存しており、これによってユーザーの予測を検証することが可能になります。 アメリカの次期大統領が誰になるかという予測に、アリスさんが 20 ETH を賭けたと仮定してみましょう。 このユースケースの場合、予測市場を提供する Dapp は、選挙結果を確認し、ユーザー(例えば、アリス)が支払対象に含まれるかを確認するためにオラクルが必要になります。 +オフチェーンのデータを使用してスマートコントラクトを実行できるようにすることで、分散型アプリケーションの実用性と価値を高めることができます。 例えば、オンチェーンの予測市場では、オラクルに依存しており、結果に関する情報を提供することでユーザーの予測を検証します。 アメリカの次期大統領が誰になるかという予測に、アリスさんが20 ETHを賭けたと仮定してみましょう。 このユースケースの場合、予測市場を提供するDappは、選挙結果を確認し、ユーザー(例えば、アリス)が支払対象に含まれるかを確認するためにオラクルが必要になります。 ## 前提知識 {#prerequisites} @@ -14,51 +14,51 @@ lang: ja ## ブロックチェーンにおけるオラクルとは何か? {#what-is-a-blockchain-oracle} -オラクルとは、ブロックチェーン上で実行されるスマートコントラクトに対し、外部情報(チェーン外部に保存された情報)を取得し、検証し、送信するアプリケーションです。 オラクルは、オフチェーンのデータを「引き出し」、送信するだけでなく、ブロックチェーン内部の情報を外部システムに「送り出す」ことも可能です。 この「プッシュ」の例としては、イーサリアムのトランザクションを通じてユーザーが手数料を送信した際に、スマートロックを解除するオラクルが挙げられます。 +オラクルとは、ブロックチェーン上で実行されるスマートコントラクトに対し、外部情報(チェーン外部に保存された情報)を取得し、検証し、送信するアプリケーションです。 オラクルは、オフチェーンデータを「プル」して、イーサリアムにブロードキャストすることに加え、ブロックチェーンの情報を外部のシステムに「プッシュ」することもできます。例えば、ユーザがイーサリムのトランザクションを経由して料金を送金するとスマートロックを解除するなどです。 -オラクルは、ブロックチェーン上のコントラクトと、オフチェーンのデータ提供者との間を接続する「ブリッジ」として機能します。 オラクルを活用しない場合、スマートコントラクトのアプリケーションはオンチェーンのデータしかアクセスできません。 オラクルは、オフチェーンのデータを活用するスマートコントラクトの機能をトリガーするメカニズムを提供するのです。 +オラクルが無いと、スマートコントラクトは完全にオンチェーンのデータだけに限定されてしまいます。 -オラクルには、データソースの種類(ソースが 1 つであるか複数であるか)、信頼モデル(集中型か分散型か)、およびシステムのアーキテクチャ(即時読み取り型、公開/講読型、および要求/対応型)により様々な種類があります。 さらに、オンチェーンのコントラクトで使用するために外部データを取得するタイプ(入力用のオラクル)、ブロックチェーン上の情報をオフチェーンのアプリケーションに送信するタイプ(出力用のオラクル)、あるいはオフチェーンの処理タスクを実行するタイプ(処理用のオラクル)に区別することが可能です。 +オラクルには、データソースの種類(ソースが1つであるか複数であるか)、信頼モデル(集中型か分散型か)、およびシステムのアーキテクチャ(即時読み取り型、公開/講読型、および要求/対応型)により様々な種類があります。 さらに、オンチェーンのコントラクトで使用するために外部データを取得するタイプ(入力用のオラクル)、ブロックチェーン上の情報をオフチェーンのアプリケーションに送信するタイプ(出力用のオラクル)、あるいはオフチェーンの処理タスクを実行するタイプ(処理用のオラクル)に区別することが可能です。 ## スマートコントラクトにオラクルが必要な理由 {#why-do-smart-contracts-need-oracles} -大部分の開発者にとって、スマートコントラクトとは、ブロックチェーン上の特定のアドレスで実行されるコードの集合に過ぎません。 しかし、[より一般的なスマートコントラクトの定義](/smart-contracts/)は、「特定の条件を満たすことで、当事者間の合意を強制できる自己実行型のソフトウェアプログラム」というものです。このため、「スマートコントラクト」と呼ばれます。 +多くの開発者にとって、スマートコントラクトとは、ブロックチェーン上の特定のアドレスで実行されるコードの集合に過ぎません。 しかし、[より一般的なスマートコントラクトの定義](/smart-contracts/)は、「特定の条件を満たすことで、当事者間の合意を強制できる自己実行型のソフトウェアプログラム」というものです。このため、「スマートコントラクト」と呼ばれます。 しかし、イーサリアムは決定論的なシステムであるため、スマートコントラクトを用いてユーザー間の合意を強制するプロセスは簡単には実現できません。 [決定論的なシステム](https://en.wikipedia.org/wiki/Deterministic_algorithm)とは、特定の初期状態と入力を与えられた場合に常に同一の結果を出力するシステムを指し、入力から出力を計算する過程においてランダム性や変化が発生しません。 -ブロックチェーンでは、ユーザーに対して、ブロックチェーン上で保存されたデータ*のみ*に基づく単純な二項対立(真または偽)の質問に基づいてコンセンサスに達するように制限することで、決定論的な実行を実現しています。 このような質問の例としては、以下のようなものがあります: +ブロックチェーンでは、ユーザーに対して、ブロックチェーン上で保存されたデータ_のみ_に基づく単純な二項対立(真または偽)の質問に基づいてコンセンサスに達するように制限することで、決定論的な実行を実現しています。 このような質問の例としては、以下のようなものがあります: - 「 (公開鍵で特定された) アカウント所有者は、このトランザクションにペアの秘密鍵で署名したか?」 - 「このアカウントは、このトランザクションの実行に必要な十分な資金を持つか?」 - 「このトランザクションは、このスマートコントラクトの文脈において有効か?」 等々。 -ブロックチェーンでは、外部ソースからの情報(つまり、現実世界の情報)を参照する場合、決定論的な処理が不可能になり、ブロックチェーンの状態変化が正当であるか否かについて各ノードが合意できなくなります。 価格情報を提供する一般的な API を通じて現在の ETH/USD の交換レートを取得し、トランザクションを実行するスマートコントラクトの例を考えてみましょう。 この為替レートは頻繁に変化すると予想されるため(この API 自体が非推奨となったり、ハッキングされる可能性を無視したとしても)、このスマートコントラクトにおける同一のコードを実行するノードが得る出力は常に異なる可能性があります。 +ブロックチェーンでは、外部ソースからの情報(つまり、現実世界の情報)を参照する場合、決定論的な処理が不可能になり、ブロックチェーンの状態変化が正当であるか否かについて各ノードが合意できなくなります。 価格情報を提供する一般的なAPIを通じて現在のETH/USDの交換レートを取得し、トランザクションを実行するスマートコントラクトの例を考えてみましょう。 この為替レートは頻繁に変化すると予想されるため(このAPI自体が非推奨となったり、ハッキングされる可能性を無視したとしても)、このスマートコントラクトにおける同一のコードを実行するノードが得る出力は常に異なる可能性があります。 -イーサリアムのように、世界中に数千ものノードがトランザクションを処理するパブリックブロックチェーンにとっては、決定論的な処理は欠くことができません。 真実性を担保する中心的な権威が存在しないため、各ノードは、ひとつのトランザクションにおいて同一の状態に到達すると想定されているためです。 例えば、A というノードがスマートコントラクトのコードを実行した場合の出力が「3」である一方で、B というノードの出力が「7」である場合、コンセンサスが崩壊するため、イーサリアムが持つ分散型のコンピューティングプラットフォームとしての価値が損なわれます。 +イーサリアムのように、世界中に数千ものノードがトランザクションを処理するパブリックブロックチェーンにとっては、決定論的な処理は欠くことができません。 真実性を担保する中心的な権威が存在しないため、同じトランザクションを適用した後に同じ状態に到達するメカニズムがノードに必要になります。 例えば、Aというノードがスマートコントラクトのコードを実行した場合の出力が「3」である一方で、Bというノードの出力が「7」である場合、コンセンサスが崩壊するため、イーサリアムが持つ分散型のコンピューティングプラットフォームとしての価値が損なわれます。 このシナリオはさらに、外部ソースから情報を引き出すことが可能なブロックチェーンを設計する際の問題点を浮き彫りにします。 オラクルは、オフチェーンのソースから情報を取り出し、ブロックチェーン上で保存してスマートコントラクトで使用できるようにすることで、この問題を解消します。 オンチェーンで保存された情報は改変不能な状態で公開されているため、イーサリアムのノードは、コンセンサスを破壊することなく、安全にオフチェーンのデータを読み込んで状態変化を計算できるのです。 通常オラクルは、この機能を提供するために、オンチェーンで実行されるスマートコントラクトと、何らかのオフチェーンのコンポーネントで構成されています。 オンチェーンのスマートコントラクトは、他のスマートコントラクトから提供されるデータリクエストを受け取ると、オラクルノードと呼ばれるオフチェーンのコンポーネントにこのリクエストを引き渡します。 このオラクルノードは、アプリケーション・プログラミング・インターフェース(API)などを用いてデータソースをクエリし、トランザクションを送信することで、リクエストされたデータをスマートコントラクトのストレージに保存することができます。 -つまり、ブロックチェーンにおけるオラクルとは、ブロックチェーンと外部環境の間に存在する情報のギャップを橋渡しする役割を提供することで、「ハイブリッド型のスマートコントラクト」を実現するものです。 ハイブリッド型のスマートコントラクトとは、オンチェーンのコントラクトコードとオフチェーンのインフラを組み合わせて機能するスマートコントラクトです。 本記事の冒頭で紹介した分散型の予測市場は、ハイブリッド型のスマートコントラクトの代表例だと言えます。 その他の例としては、複数のオラクルを通じて特定の気候現象が発生したことが確認できた場合に保険金を支払うことができる農作物保険のスマートコントラクトが挙げられるでしょう。 +つまり、ブロックチェーンにおけるオラクルとは、ブロックチェーンと外部環境の間に存在する情報のギャップを橋渡しする役割を提供することで、「ハイブリッド型のスマートコントラクト」を実現するものです。 ハイブリッド型のスマートコントラクトとは、オンチェーンのコントラクトコードとオフチェーンのインフラを組み合わせて機能するスマートコントラクトです。 分散型の予測市場は、ハイブリッド型のスマートコントラクトの代表例だと言えます。 その他の例としては、複数のオラクルを通じて特定の気候現象が発生したことが確認できた場合に保険金を支払うことができる農作物保険のスマートコントラクトが挙げられるでしょう。 ## オラクル問題とは何か? {#the-oracle-problem} -スマートコントラクトでは、ひとつまたは複数のエンティティに依存してオフチェーンのデータへのアクセスを提供し、トランザクションのデータペイロードを保存することで、ブロックチェーンの外部にある情報を簡単に取得することができます。 しかしこの方法では、以下のような新たな問題が発生します: +オラクルは重要な問題を解決する一方で、次のような複雑な問題も生じます。 - コントラクトに読み込まれた情報が、適切なソースから抽出されているかや、改変されていないかを検証するにはどうすればよいか? - このデータが、常に参照可能で定期的に更新されることを保証するにはどうすればよいか? -このいわゆる「オラクル問題」は、ブロックチェーンのオラクルを用いてスマートコントラクトに情報を送信する際にどのような問題が発生するかを示しています。 オラクルからのデータの適切性を確認することは非常に重要であり、データが適切でなければ、スマートコントラクトを実行した際に正しくない結果が出力されてしまいます。 また、トラストレス性を維持することも同様に重要です。特定のオラクル運用者が正確な情報を提供するという「信頼」が必要になる場合、スマートコントラクトの最も根本的な特性が失われるからです。 +このいわゆる「オラクル問題」は、ブロックチェーンのオラクルを用いてスマートコントラクトに情報を送信する際にどのような問題が発生するかを示しています。 スマートコントラクトが正しく実行されるためには、オラクルからのデータが正しい必要があります。 さらに、正確な情報を提供するためにオラクルのオペレータを「信頼」しなければならないことは、スマートコントラクトの「トラストレス」の側面を損なうことになります。 -実際のオラクルは、このオラクル問題を解決するために様々なアプローチを採用しており、個別のアプローチについては以下のセクションで紹介します。 完璧なソリューションを提供するオラクルは存在しませんが、以下のような課題にどのように対処しているかに従って、各オラクルの利点を検討すべきだと言えるでしょう: +さまざまなオラクルが、オラクル問題に対して異なる解決策を用意しています。これについては後ほど説明します。 オラクルは通常、次の課題にどのように対処するかによって評価されます。 -1. **正確性**:オラクルは、オフチェーン上の無効なデータに基づいてスマートコントラクトの状態変化をトリガーしてはなりません。 このため、オラクルはデータの*真正性*および*完全性*を保証する必要があります。データの真正性とは、適切な情報ソースから取得されたことを意味し、完全性とはオンチェーンで送信されるまで取得した状態に手を加えられない(改変されない)ことを意味します。 +1. **正確性**:オラクルは、オフチェーン上の無効なデータに基づいてスマートコントラクトの状態変化をトリガーしてはなりません。 オラクルは、 データの_真正性_と_整合性_を保証する必要があります。 真正性とは、適切な情報ソースから取得されたことを意味し、完全性とはオンチェーンで送信されるまで取得した状態に手を加えられない(改変されない)ことを意味します。 -2. **可用性**:オラクルは、スマートコントラクトがアクションを実行し、状態変化をトリガーするのを遅延させたり、妨害してはなりません。 可用性を維持するためには、オラクルから取得されるデータは常に*リクエストに基づき取得可能*である必要があります。 +2. **可用性**:オラクルは、スマートコントラクトがアクションを実行し、状態変化をトリガーするのを遅延させたり、妨害してはなりません。 つまり、オラクル由来のデータは中断することなく_リクエストに応じて利用可能_でなければなりません。 -3. **インセンティブとの両立性**:オラクルは、オフチェーンのデータ提供者に対し、スマートコントラクトに正しい情報を提供する意欲を高めるようなインセンティブを提供するものでなければなりません。 インセンティブの両立性には、*アトリビュータビリティ*と *アカウンタビリティ*が含まれます。 アトリビュータビリティとは、当該の外部情報とその提供者を相互に関連付けできる性質を指し、アカウンタビリティとは、データ提供者に対して提供するデータの品質について責任を負わせる(つまり、データの品質に応じて報酬/罰金を課す)性質を指します。 +3. **インセンティブとの両立性**:オラクルは、オフチェーンのデータ提供者に対し、スマートコントラクトに正しい情報を提供する意欲を高めるようなインセンティブを提供するものでなければなりません。 インセンティブの両立性には、_アトリビュータビリティ_と _アカウンタビリティ_が含まれます。 アトリビュータビリティとは、当該の外部情報とその提供者を相互に関連付けできる性質を指し、アカウンタビリティとは、データ提供者に対して提供するデータの品質について責任を負わせる性質を指します。そのため、提供された情報の質に基づいて報酬を与えたり、ペナルティを与えたりすることができます。 ## ブロックチェーンにおけるオラクルサービスの仕組み {#how-does-a-blockchain-oracle-service-work} @@ -78,11 +78,11 @@ lang: ja ### オラクルコントラクト {#oracle-contract} -オラクルコントラクトとは、オラクルサービスを提供するオンチェーンのコンポーネントであり、その他のスマートコントラクトからのデータリクエストをリッスンし、データクエリをオラクルノードにリレーした上で、返送されたデータをクライアントであるスマートコントラクトにブロードキャストします。 オラクルコントラクトはさらに、返送されたデータポイントに対して一定の処理を実行し、リクエスト元のスマートコントラクトに集計値を送信することができます。 +オラクルコントラクトは、オラクルサービス用のオンチェーンコンポーネントです。 他のコントラクトからのデータのリクエストをリッスンしており、データクエリーをオラクルーノードへ中継します。そして、オラクルノードから返送されたデータをクライアントコントラクトへブロードキャストします。 さらに、オラクルコントラクトでは、返送されたデータポイントに対して一定の処理を実行し、リクエスト元のスマートコントラクトに集計値を送信することができます。 オラクルコントラクトは、クライアントのコントラクトがデータリクエストを行う際に呼び出す関数の一部を公開します。 新たなクエリを受け取ったスマートコントラクトは、このデータリクエストの詳細を含む[ログイベント](/developers/docs/smart-contracts/anatomy/#events-and-logs)を発行します。 ログイベントが発行されると、このログを講読しているオフチェーンのノードに対して通知が送信され(通常は、JSON-RPC`eth_subscribe`コマンドを用いる)、これらのノードはログイベントで定義されたデータを取得する作業を開始します。 -以下は、Pedro Costa が作成した[オラクルコントラクトのサンプルコード](https://medium.com/@pedrodc/implementing-a-blockchain-oracle-on-ethereum-cedc7e26b49e)です。 このコードは、他のスマートコントラクトからのリクエストに応じて、オフチェーンの API をクエリし、リクエストされた情報をブロックチェーンで保存するというシンプルなオラクルサービスを提供します: +以下は、Pedro Costaが作成した[オラクルコントラクトのサンプルコード](https://medium.com/@pedrodc/implementing-a-blockchain-oracle-on-ethereum-cedc7e26b49e)です。 このコードは、他のスマートコントラクトからのリクエストに応じて、オフチェーンのAPIをクエリし、リクエストされた情報をブロックチェーンで保存するというシンプルなオラクルサービスを提供します: ```solidity pragma solidity >=0.4.21 <0.6.0; @@ -198,49 +198,45 @@ contract Oracle { ### オラクルノード {#oracle-nodes} -オラクルノードとは、オラクルサービスにおけるオフチェーンのコンポーネントであり、サードパーティのサーバ上でホスティングされた API などの外部ソースから情報を抽出し、オンチェーンに置くことで、スマートコントラクトが消費できるようにします。 オラクルノードは、オンチェーンのオラクルコントラクトからのイベントをリッスンし、ログに記載されたタスクを実行します。 +オラクルノードは、オラクルサービス用のオフチェーンコンポーネントです。 オラクルノードは、サードパーティのサーバーでホストされているAP などの外部ソースから情報を抽出します。そして、スマートコントラクで使用できるようにオンチェーンへ送信します。 オラクルノードは、オンチェーンのオラクルコントラクトからのイベントをリッスンし、ログに記載されたタスクを実行します。 -オラクルノードにおける一般的なタスクとしては、API サービスに対して[HTTP GET](https://www.w3schools.com/tags/ref_httpmethods.asp)を送信し、レスポンスを解析して適切なデータを抽出した上で、ブロックチェーンが読み取り可能な出力としてフォーマットし、オラクルコントラクトへのトランザクションに含めることでオンチェーンに送信するというものがあります。 オラクルノードはまた、「真正性証明」を用いて、提出された情報の正当性および完全性を証明するように要求される場合がありますが、これについては以下のセクションで説明します。 +オラクルノードにおける一般的なタスクとしては、APIサービスに対して[HTTP GET](https://www.w3schools.com/tags/ref_httpmethods.asp)を送信し、レスポンスを解析して適切なデータを抽出した上で、ブロックチェーンが読み取り可能な出力としてフォーマットし、オラクルコントラクトへのトランザクションに含めることでオンチェーンに送信するというものがあります。 オラクルノードはまた、「真正性証明」を用いて、提出された情報の正当性および完全性を証明するように要求される場合がありますが、これについては以下のセクションで説明します。 -計算型のオラクルも、負荷が大きい計算タスク(ガス代およびブロックサイズの制限により、オンチェーンでの実行が非現実的であるため)を実行するためにオフチェーンのノードに依存します。 例えば、ランダムであることが検証可能な値を生成するタスク(ブロックチェーンベースのゲームで用いる)につき、オラクルノードが活用される場合があります。 +計算型のオラクルも、計算タスク(ガス代およびブロックサイズの制限により、オンチェーンでの実行が非現実的であるため)を実行するためにオフチェーンのノードに依存します。 例えば、ランダムであることが検証可能な値を生成するタスク(ブロックチェーンベースのゲームで用いる)につき、オラクルノードが活用される場合があります。 ## オラクルの設計パターン {#oracle-design-patterns} -オラクルには、_即時読み取り型_、_公開=講読型_、および*要求=対応型*などの様々な種類があり、イーサリアムのスマートコントラクトでは、公開=講読型および要求=対応型が広く活用されています。 以下に、これら 2 つのオラクルサービスについて簡単に紹介します: +オラクルには、_即時読み取り型_、_出版/講読型_、および_リクエスト/レスポンス型_などの様々な種類があり、イーサリアムのスマートコントラクトでは、出版/講読型およびリクエスト/レスポンス型が広く活用されています。 ここでは、出版/購読型モデルとリクエスト/レスポンス型モデルについて簡単に説明します。 -### 公開=講読型のオラクル {#publish-subscribe-oracles} +### 出版/購読型のオラクル {#publish-subscribe-oracles} -公開=講読のメカニズムに基づくオラクルサービスは、他のコントラクトが定期的に読み込むことができる情報を提供する「データフィード」を公開するものです。 このデータフィードにおけるデータは頻繁に変化すると想定されるため、クライアントであるコントラクトは、オラクルのストレージに含まれるデータが更新されたかどうかをリッスンする必要があります。 このようなデータフィードの代表例としては、ETH/USD 交換レートの最新情報を提供するオラクルがあります。 +このタイプのオラクルでは、他のコントラクトが定期的に情報を読み込むことが可能な「データフィード」を提供します。 このデータフィードにおけるデータは頻繁に変化すると想定されるため、クライアントであるコントラクトは、オラクルのストレージに含まれるデータが更新されたかどうかをリッスンする必要があります。 例えば、最新の ETH-USDにおける価格情報をユーザーに提供するオラクルがあります。 -### 要求=応答型のオラクル {#request-response-oracles} +### リクエスト/レスポンス型のオラクル {#request-response-oracles} -要求=応答型のメカニズムにおいては、クライアントのコントラクトは公開=講読型のオラクルでは提供されない任意のデータをリクエストできます。 要求=応答型のオラクルは、以下の場合に最も適しています: +リクエスト/レスポンス型のメカニズムにおいては、クライアントのコントラクトは出版/購読型のオラクルでは提供されない任意のデータをリクエストできます。 リクエスト/レスポンス型のオラクルは、データセットが大きすぎてスマート コントラクトのストレージに保存できない場合や、ユーザーが常時データのごく一部しか必要としない場合に適しています。 -- データセットが大規模すぎるために、スマートコントラクト内のストレージに保存できない。 - -- ユーザーがある時点で必要とするのは、データセット全体のごく一部のみである - -要求=応答型のオラクルは、公開=講読型よりも複雑ですが、基本的な機能は上記セクションで説明した通りです。 この種類のオラクルは、データリクエストを受け取るオンチェーンのコンポーネントを持ち、オフチェーンのノードによる処理のためにリクエストを転送します。 +リクエスト/レスポンス型のオラクルは、出版/購読型よりも複雑ですが、基本的な機能は上記セクションで説明した通りです。 この種類のオラクルは、データリクエストを受け取るオンチェーンのコンポーネントを持ち、オフチェーンのノードによる処理のためにリクエストを転送します。 データのクエリを開始するユーザーは、オフチェーンの情報ソースから情報を取得するコストを負担しなければなりません。 クライアントのコントラクトはさらに、オラクルコントラクトが当該リクエストで指定されたコールバック機能を通じてレスポンスを提供する際に発生するガス代につき、これを負担するのに十分な資金を持つ必要があります。 -## オラクルの種類 {#types-of-oracles} +## 集権型オラクルと分散型オラクルの比較 {#types-of-oracles} ### 集中型のオラクル {#centralized-oracles} -集中型のオラクルとは、オフチェーンの情報を集約し、リクエストに応じてオラクルコントラクトのデータを更新する作業に責任を負う単一のエンティティによって管理されたオラクルを指します。 集中型のオラクルは、単一の真実ソースを持つため、効率的であると言えます。 集中型のオラクルは、広く承認された署名を持つ所有者が直接、独自のデータセットを公開する場合においては望ましいとも言えるでしょう。 その一方で、集中型のオラクルにはいくつかの問題も存在します。 +集中型のオラクルとは、オフチェーンの情報を集約し、リクエストに応じてオラクルコントラクトのデータを更新する作業に責任を負う単一のエンティティによって管理されたオラクルを指します。 集中型のオラクルは、単一の真実ソースを持つため、効率的であると言えます。 集中型のオラクルは、広く承認された署名を持つ所有者が直接、独自のデータセットを公開する場合においてはよく機能します。 しかし、次のような欠点があります。 #### 正確性を保証しにくい {#low-correctness-guarantees} -集中型のオラクルでは、提供された情報が正しいか否かを確認する方法がありません。 オラクルの提供者は「名声を持つ」かもしれませんが、その評判は、提供者が不正行為を絶対に行わないことや、ハッカーがシステムを改ざんするという可能性を除去するものではありません。 当該オラクルが改ざんされた場合、スマートコントラクトは不適切なデータに基づいて実行されることになります。 +集中型のオラクルでは、提供された情報が正しいか否かを確認する方法がありません。 たとえ「評判の良い」プロバイダーであっても、不正が行われたり、ハッキングを受ける可能性はあります。 当該オラクルが改ざんされた場合、スマートコントラクトは不適切なデータに基づいて実行されることになります。 #### 可用性が低い {#poor-availability} -集中型のオラクルは、他のスマートコントラクトに対してオフチェーンのデータを常に提供することを保証しません。 オラクルの提供者が当該サービスを廃止したり、ハッカーがオラクルのオフチェーン・コンポーネントを乗っ取ってしまった場合、あなたのスマートコントラクトは Dos 攻撃の被害を受ける可能性があります。 +集中型のオラクルは、他のスマートコントラクトに対してオフチェーンのデータを常に提供することを保証しません。 オラクルの提供者が当該サービスを廃止したり、ハッカーがオラクルのオフチェーン・コンポーネントを乗っ取ってしまった場合、あなたのスマートコントラクトはDos攻撃の被害を受ける可能性があります。 #### インセンティブと両立しにくい {#poor-incentive-compatibility} -集中型のオラクルでは、データ提供者に対して正確/未改変の情報を送信するようにインセンティブを提要する仕組みが存在しないか、設計が不十分な場合が少なくありません。 オラクルサービスの代価として手数料を支払うことにより、サービス提供者に対して正直な行動を促すことは可能ですが、このようなインセンティブでは不十分な場合もあり得ます。 スマートコントラクトは莫大な規模の価値を管理するものであるため、オラクルデータを改ざんすることで得られる利益もかつてなく大きくなっているのです。 +集中型のオラクルでは、データ提供者に対して正確/未改変の情報を送信するようにインセンティブを提要する仕組みが存在しないか、設計が不十分な場合が少なくありません。 正確性に対してオラクルに支払っても、公正であることが保証されるわけではありません。 この問題は、スマートコントラクトによって管理される金額が増加するにつれて大きくなります。 ### 分散型のオラクル {#decentralized-oracles} @@ -260,11 +256,11 @@ contract Oracle { 真正性の証明には、以下のようなものがあります: -**トランスポートレイヤー・セキュリティ(TLS)証明**:オラクルノードでは、トランスポートレイヤー・セキュリティ(TLS)プロトコルに基づくセキュアな HTTP 接続を使用して、外部ソースからデータを取得することが多いです。 一部の分散型オラクルでは、TLS セッションを検証し(つまり、ノードが特定のサーバーとの間で情報を交換したことを確認し)、当該セッションにおける内容が未改変であることを確認するために、真正性証明を利用します。 +**トランスポートレイヤー・セキュリティ(TLS)証明**:オラクルノードでは、トランスポートレイヤー・セキュリティ(TLS)プロトコルに基づくセキュアなHTTP接続を使用して、外部ソースからデータを取得することが多いです。 一部の分散型オラクルでは、TLSセッションを検証し(つまり、ノードが特定のサーバーとの間で情報を交換したことを確認し)、当該セッションにおける内容が未改変であることを確認するために、真正性証明を利用します。 -**信頼された実行環境(TEE)のアテステーション**:[信頼された実行環境](https://en.wikipedia.org/wiki/Trusted_execution_environment)(TEE)とは、ホストシステムの運用プロセスから分離された、サンドボックス化された計算環境です。 TEE では、当該の計算環境においおて保存/使用されるアプリケーションコードまたはデータの完全性、機密性、および不変性が保証されます。 ユーザーはまた、当該のアプリケーション・インスタンスが信頼された実行環境において実行されていることを証明するアテステーションを生成することもできます。 +**信頼された実行環境(TEE)のアテステーション**:[信頼された実行環境](https://en.wikipedia.org/wiki/Trusted_execution_environment)(TEE)とは、ホストシステムの運用プロセスから分離された、サンドボックス化された計算環境です。 TEEでは、当該の計算環境においおて保存/使用されるアプリケーションコードまたはデータの完全性、機密性、および不変性が保証されます。 ユーザーはまた、当該のアプリケーション・インスタンスが信頼された実行環境において実行されていることを証明するアテステーションを生成することもできます。 -分散型オラクルの中には、オラクルノードの運用者に対して TEE のアテステーションを要求するものもあります。 このアテステーションは、ノードの運用者がオラクルクライアントのインスタンスを信頼された実行環境で実行していることを、ユーザーに保証するものです。 TEE では、当該アプリケーションのコードおよびデータを改変したり、読み取るような外部プロセスが実行できないため、このようなアテステーションを通じて、オラクルノードが当該情報を未改変かつ機密の状態に保ったことを証明できます。 +分散型オラクルの中には、オラクルノードの運用者に対してTEEのアテステーションを要求するものもあります。 このアテステーションは、ノードの運用者がオラクルクライアントのインスタンスを信頼された実行環境で実行していることを、ユーザーに保証するものです。 TEEでは、当該アプリケーションのコードおよびデータを改変したり、読み取るような外部プロセスが実行できないため、このようなアテステーションを通じて、オラクルノードが当該情報を未改変かつ機密の状態に保ったことを証明できます。 #### コンセンサスに基づく情報の検証 {#consensus-based-validation-of-information} @@ -274,7 +270,7 @@ contract Oracle { ##### データの正確性に関する投票/ステーキング -一部の分散型オラクルでは、参加者に対し、データクエリ(例:「2020 年の米国大統領選挙では誰が当選したか?」)への回答に対して、投票またはステーキングを要求します。 この際の投票/ステーキングには、当該ネットワークのネイティブトークンが使用されます。 この投票およびステーキングは、集計プロトコルにより集約され、多数派が支持した回答が正当な回答とされます。 +一部の分散型オラクルでは、参加者に対し、データクエリ(例:「2020年の米国大統領選挙では誰が当選したか?」)への回答に対して、投票またはステーキングを要求します。 この際の投票/ステーキングには、当該ネットワークのネイティブトークンが使用されます。 この投票およびステーキングは、集計プロトコルにより集約され、多数派が支持した回答が正当な回答とされます。 多数派の回答とは異なる回答を提供したノードは、ペナルティとして、より適切な値を提供したユーザーに保有トークンを奪われることになります。 各ノードに対して、データ提供前に担保の差し出しを義務付けることで、リターン最大化を目指す合理的な経済アクターと想定されるユーザーに対し、正直な行動を取るように誘導するインセンティブを与えることができます。 @@ -282,29 +278,29 @@ contract Oracle { ##### シェリングポイントのメカニズム -[シェリングポイント]()とは、特定の問題につき複数のエンティティ間におけるコミュニケーションが存在しない場合、常に同一のソリューションに回帰するというゲーム理論上の概念です。 シェリングポイントのメカニズムは、分散型のオラクルネットワークにおいて、データリクエストへの回答について各ノードがコンセンサスを得るためにしばしば利用されます。 +[シェリングポイント](https://en.wikipedia.org/wiki/Focal_point_(game_theory))とは、特定の問題につき複数のエンティティ間におけるコミュニケーションが存在しない場合、常に同一のソリューションに回帰するというゲーム理論上の概念です。 シェリングポイントのメカニズムは、分散型のオラクルネットワークにおいて、データリクエストへの回答について各ノードがコンセンサスを得るためにしばしば利用されます。 -シェリングポイントの初期の実例としては、[SchellingCoin](https://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/)があります。これは、「スケーラー」質問(「ETH の価格はいくらか」といった大きさで回答できる質問)に対して、参加者がデポジットを入金することで回答できるデータフィードの提案でした。 全体の回答値のうち 25%から 75%の[パーセンタイル](https://en.wikipedia.org/wiki/Percentile)を提出した回答者に報酬が提供される一方で、中央値から大きく外れた回答を提供したユーザーには罰金が課せられます。 +シェリングポイントの初期の発想としては、[SchellingCoin](https://blog.ethereum.org/2014/03/28/schellingcoin-a-minimal-trust-universal-data-feed/)があります。これは、「スケーラー」質問(「ETHの価格はいくらか」といった大きさで回答できる質問)に対して、参加者がデポジットを入金することで回答できるデータフィードの提案でした。 全体の回答値のうち25%から75%の[パーセンタイル](https://en.wikipedia.org/wiki/Percentile)を提出した回答者に報酬が提供される一方で、中央値から大きく外れた回答を提供したユーザーには罰金が課せられます。 -SchellingCoin は現存していませんが、多くの分散型オラクル、特に[Maker Protocol を使用するオラクル](https://docs.makerdao.com/smart-contract-modules/oracle-module)では、シェリングポイントのメカニズムを活用することでオラクルデータの正確性を向上させています。 Maker プロトコルを採用したオラクルは、担保資産の市場価格を提出するノード(「リレイヤー」および「フィード」)で構成されるオフチェーンの P2P ネットワークと、提供された全ての値の中央値を算出するオンチェーンの「メディアナイザー」コントラクトで構成されます。 定められた遅延期間が経過すると、この中央値が当該資産における新たな参照価格になります。 +SchellingCoinは現存していませんが、多くの分散型オラクル、特に[Maker Protocolを使用するオラクル](https://docs.makerdao.com/smart-contract-modules/oracle-module)では、シェリングポイントのメカニズムを活用することでオラクルデータの正確性を向上させています。 Makerプロトコルを採用したオラクルは、担保資産の市場価格を提出するノード(「リレイヤー」および「フィード」)で構成されるオフチェーンのP2Pネットワークと、提供された全ての値の中央値を算出するオンチェーンの「メディアナイザー」コントラクトで構成されます。 定められた遅延期間が経過すると、この中央値が当該資産における新たな参照価格になります。 -シェリングポイントのメカニズムを採用している他のオラクルの例としては、[Chainlink オフチェーン報告](https://docs.chain.link/docs/off-chain-reporting/)および Witnet があります。 どちらのシステムでも、P2P ネットワークに含まれるオラクルノードからの回答は、平均値あるいは中央値といった単一の値に集約されます。 各ノードは、自らの回答がこの集約値とどれほど一致/乖離しているかに応じて、報酬/罰金を受けます。 +シェリングポイントのメカニズムを採用している他のオラクルの例としては、[Chainlinkオフチェーン報告](https://docs.chain.link/docs/off-chain-reporting/)および[Witnet](https://witnet.io/)があります。 どちらのシステムでも、P2Pネットワークに含まれるオラクルノードからの回答は、平均値あるいは中央値といった単一の値に集約されます。 各ノードは、自らの回答がこの集約値とどれほど一致/乖離しているかに応じて、報酬/罰金を受けます。 -シェリングポイントのメカニズムは、分散化を保証しつつ、オンチェーンのフットプリントを最小化できる(1 つのトランザクションのみ送信すればよい)点が魅力的だと言えます。 このメカニズムで分散化が可能なのは、各ノードに対して、提出済みの回答リストが平均値/中央値を算出するアルゴリズムに投入される事前に、同リストにサインオフすることが要求されるためです。 +シェリングポイントのメカニズムは、分散化を保証しつつ、オンチェーンのフットプリントを最小化できる(1つのトランザクションのみ送信すればよい)点が魅力的だと言えます。 このメカニズムで分散化が可能なのは、各ノードに対して、提出済みの回答リストが平均値/中央値を算出するアルゴリズムに投入される事前に、同リストにサインオフすることが要求されるためです。 ### 可用性 {#availability} 分散型のオラクルサービスでは、スマートコントラクトに対するオフチェーンデータの提供可能性が高くなります。 これは、オフチェーンの情報ソースと、この情報をオンチェーンに転送する役割を担うノードの両方を分散化することによって実現されています。 -この可用性により、オラクルコントラクトは、他のコントラクトのクエリを実行するために複数のノードに依存でき、これらの複数のノード自体もまた複数のデータソースに依存するため、障害耐性が高まります。 情報ソース*および*ノード=オペレーターの両方において分散化を実現することが必須であり、同一の情報ソースから取得した情報を複数のオラクルノードが提出するようなネットワークでは、集中型オラクルの場合と同じ問題が発生してしまいます。 +この可用性により、オラクルコントラクトは、他のコントラクトのクエリを実行するために複数のノードに依存でき、これらの複数のノード自体もまた複数のデータソースに依存するため、障害耐性が高まります。 情報ソース_および_ノード=オペレーターの両方において分散化を実現することが必須であり、同一の情報ソースから取得した情報を複数のオラクルノードが提出するようなネットワークでは、集中型オラクルの場合と同じ問題が発生してしまいます。 さらに、ステーキングベースのオラクルでは、データリクエストに迅速に対応しないノードペレーターに対してスラッシングを行うことも可能です。 これにより、オラクルノードに対して障害耐性を持つインフラに投資し、迅速にデータを提供するように促すことができます。 ### インセンティブと両立しやすい {#good-incentive-compatibility} -分散型のオラクルでは、オラクルノード間における[ビザンチン将軍問題](https://en.wikipedia.org/wiki/Byzantine_fault)動作を防ぐために、様々なインセンティブの仕組みを導入しています。 具体的には、以下の方法で*アトリビュータビリティ*と*アカウンタビリティ*を実現しています: +分散型のオラクルでは、オラクルノード間における[ビザンチン将軍問題](https://en.wikipedia.org/wiki/Byzantine_fault)動作を防ぐために、様々なインセンティブの仕組みを導入しています。 具体的には、以下の方法で_アトリビュータビリティ_と_アカウンタビリティ_を実現しています: -1. 分散型オラクルのノードに対しては、データリクエストに対してレスポンスを提供する際に当該データに対する証明が要求される場合が多いです。 この署名情報は、データをリクエストする際に信頼性が低いオラクルノードを排除するなど、オラクルノードの過去の行動を評価する際に有益です。 具体的な導入例としては、Chainlink の[オラクル・レビュテーション](https://oracle.reputation.link/)や、Witnet の[アルゴリズム・レピュテーション・システム](https://docs.witnet.io/intro/about/architecture#algorithmic-reputation-system)があります。 +1. 分散型オラクルのノードに対しては、データリクエストに対してレスポンスを提供する際に当該データに対する証明が要求される場合が多いです。 この署名情報は、データをリクエストする際に信頼性が低いオラクルノードを排除するなど、オラクルノードの過去の行動を評価する際に有益です。 Witnetの例としては、[アルゴリズミック評判システム](https://docs.witnet.io/intro/about/architecture#algorithmic-reputation-system)があります。 2. すでに述べたように、分散型のオラクルでは、提出するデータの真実性に対するノード本人の確信に対してステーキングを義務付ける場合があります。 このノードのクレームが確認されれば、このステークは、正直な行動への報酬と共に返却されます。 ただし、提出した情報が正しくない場合には没収される可能性があるため、一定の説明責任を担保する手段となります。 @@ -314,13 +310,15 @@ SchellingCoin は現存していませんが、多くの分散型オラクル、 ### 金融データを取り出す {#retrieving-financial-data} -[分散型ファイナンス](/defi/)(DeFi)の アプリケーションは、P2P による資産の貸出、借入、および取引を可能にするものです。 これらのサービスを提供するには、為替データ(仮想通貨における法定通貨建ての価値を算出するため、あるいは 2 種類のトークンの価格を比較するため)や、資本市場に関するデータ(トークン化された金や米ドル等の資産の価値を算出するため)など、様々な金融情報を取得する必要があります。 +[分散型ファイナンス](/defi/)(DeFi)の アプリケーションは、P2Pによる資産の貸出、借入、および取引を可能にするものです。 これらのサービスを提供するには、為替データ(仮想通貨における法定通貨建ての価値を算出するため、あるいはトークンの価格を比較するため)や、資本市場に関するデータ(トークン化された金や米ドル等の資産の価値を算出するため)など、様々な金融情報を取得する必要があります。 -例えば DeFi の貸出プロトコルを開発したい場合には、担保として預け入れられた様々な資産(例:ETH)の現在の市場価格をクエリできる機能が必要になります。 これは、スマートコントラクトに対して、担保資産の価値を評価し、ユーザーがシステムからどれだけ借入可能かを決定する機能を提供するためです。 +例えばDeFiの貸出プロトコルでは、担保として預け入れられた様々な資産(例:ETH)の現在の市場価格をクエリできる機能が必要になります。 これは、コントラクトに対して、担保資産の価値を評価し、ユーザーがシステムからどれだけ借入可能かを決定する機能を提供するためです。 -DeFi の分野でよく利用される「価格オラクル」(多くの場合、こう呼ばれます)の例としては、Chainlin の価格フィード、Compound Protocol の[公開価格フィード](https://compound.finance/docs/prices)、Uniswap の[時間加重平均価格(TWAPs)](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles)、および[Maker Oracles](https://docs.makerdao.com/smart-contract-modules/oracle-module)が挙げられます。 ただし、プロジェクトにこれらの価格オラクルを組み込む前に、導入に伴う注意事項についてよく理解しておく必要があります。 この[記事](https://blog.openzeppelin.com/secure-smart-contract-guidelines-the-dangers-of-price-oracles/)では、これらの価格オラクルを使用したい場合に検討すべき事項について詳細に分析しています。 +DeFiの分野でよく利用される「価格オラクル」(多くの場合、こう呼ばれます)の例としては、Chainlinの価格フィード、Compound Protocolの[公開価格フィード](https://compound.finance/docs/prices)、Uniswapの[時間加重平均価格(TWAPs)](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles)、および[Maker Oracles](https://docs.makerdao.com/smart-contract-modules/oracle-module)が挙げられます。 -以下のサンプルコードは、Chainlink の価格フォードを使用してスマートコントラクト上で最新の ETH 価格を取得するものです: +ビルダーは、プロジェクトにこれらの価格オラクルを組み込む前に、導入に伴う注意事項についてよく理解しておく必要があります。 この[記事](https://blog.openzeppelin.com/secure-smart-contract-guidelines-the-dangers-of-price-oracles/)では、これらの価格オラクルを使用したい場合に検討すべき事項について詳細に分析しています。 + +以下のサンプルコードは、Chainlinkの価格フォードを使用してスマートコントラクト上で最新のETH価格を取得するものです: ```solidity pragma solidity ^0.6.7; @@ -360,51 +358,49 @@ contract PriceConsumerV3 { ブロックチェーンベースのゲームや宝くじなど、一部のブロックチェーン・アプリケーションでは、適切に機能するために高度な予測不可能性およびランダム性が要求されます。 しかし、ブロックチェーンは決定論的な実行という特性を持つため、ランダム性を獲得する手段がありません。 -このような場合の通常のアプローチでは、`blockhash`などの擬似的な暗号機能を用いますが、[他のアクターによる操作](https://ethereum.stackexchange.com/questions/3140/risk-of-using-blockhash-other-miners-preventing-attack#:~:text=So%20while%20the%20miners%20can,to%20one%20of%20the%20players.)、つまりプルーフ・オブ・ワークのアルゴリズムを解決するマイナーによりランダム性が損なわれる可能性があります。 また、イーサリアムにおける[プルーフ・オブ・ステークへの移行](/upgrades/merge/)に伴い、開発者は、`blockhash`によるオンチェーンのランダム性を活用することができなくなりました(ただし、ビーコンチェーンの[RANDAO メカニズム](https://eth2book.info/altair/part2/building_blocks/randomness)は、ランダム性を提供する代替ソースとして機能します)。 +このような場合の通常のアプローチでは、`blockhash`などの擬似的な暗号機能を用いますが、[他のアクターによる操作](https://ethereum.stackexchange.com/questions/3140/risk-of-using-blockhash-other-miners-preventing-attack#:~:text=So%20while%20the%20miners%20can,to%20one%20of%20the%20players.)、つまりプルーフ・オブ・ワークのアルゴリズムを解決するマイナーによりランダム性が操作される可能性があります。 また、イーサリアムにおける[プルーフ・オブ・ステークへの移行](/roadmap/merge/)に伴い、開発者は、`blockhash`によるオンチェーンのランダム性を活用することができなくなりました(ただし、ビーコンチェーンの[RANDAOメカニズム](https://eth2book.info/altair/part2/building_blocks/randomness)は、ランダム性を提供する代替ソースとして機能します)。 ランダムな値をオフチェーンで生成した上でオンチェーンに送信することは可能ですが、このアプローチではユーザーに対する信頼性の要件が高くなります。 ユーザーは、生成された値が本当に予測不可能なメカニズムによって生成され、転送に伴う改変が生じていないことを信じなければならないためです。 -オフチェーンでの計算を念頭に置いて設計されたオラクルでは、オフチェーンでランダムな値をセキュアに生成した上で、生成プロセスの予測不可能性を確証する暗号化された証明と共にオンチェーンでブロードキャストすることで、この問題を解決します。 このようなアプローチの例としては、[Chainlink VRF](https://docs.chain.link/docs/chainlink-vrf/) (検証可能なランダム関数)があります。これは、証明可能な形で、公平かつ操作不可の乱数を生成する機能(RNG)であり、予測不可能な計算値を必要とする用途を持つ信頼性が高いスマートコントラクトを開発する上で有益です。 +オフチェーンでの計算を念頭に置いて設計されたオラクルでは、オフチェーンでランダムな値をセキュアに生成した上で、生成プロセスの予測不可能性を確証する暗号化された証明と共にオンチェーンでブロードキャストすることで、この問題を解決します。 このようなアプローチの例としては、[Chainlink VRF](https://docs.chain.link/docs/chainlink-vrf/) (検証可能なランダム関数)があります。これは、証明可能な形で、公平かつ操作不可の乱数を生成する機能(RNG)であり、予測不可能な計算値を必要とする用途を持つ信頼性が高いスマートコントラクトを開発する上で有益です。 例をもう一つあげると、 [API3 QRNG](https://docs.api3.org/explore/qrng/)が量子乱数生成器 (QRNG) を提供しています。これは、量子現象に基づくWeb3 RNGの公開メソッドであり、オーストラリア国立大学 (ANU) の好意により提供されています。 ### イベントの結果を取得する {#getting-outcomes-for-events} -オラクルを活用することで、現実世界で発生したイベントに応答できるスマートコントラクトを手軽に開発できます。 オラクルサービスでは、オラクルのオフチェーン・コンポーネントを通じて外部 API と接続し、外部のデータソースから取得した情報を消費することで、現実のイベントへの応答を可能にしています。 例えば、すでに紹介した予測用の Dapp の場合、信頼できるオフチェーンの情報ソース(例:AP)から選挙結果を取得するようにオラクルに要求することができます。 +オラクルを活用することで、現実世界で発生したイベントに応答できるスマートコントラクトを手軽に開発できます。 オラクルサービスでは、オラクルのオフチェーン・コンポーネントを通じて外部APIと接続し、外部のデータソースから取得した情報を消費することで、現実のイベントへの応答を可能にしています。 例えば、すでに紹介した予測用のDappの場合、信頼できるオフチェーンの情報ソース(例:AP)から選挙結果を取得するようにオラクルに要求することができます。 -オラクルを使って現実世界における結果に基づくデータを取得することで、分散型の保険サービスなどの新しいユースケースが可能になります。 保険サービスを提供するスマートコントラクトでは、正確な情報(例:気象データ、災害に関する報告など)がなければ正しく機能しません。 +オラクルを使用して現実世界の結果に基づいてデータを取得することで、斬新なユースケースを可能になります。ユースケースの例として、 分散型保険商品が効果的に機能させることがあります。この分野では、天気、災害などに関する正確な情報を必要としています。 ### スマートコントラクトの自動化 {#automating-smart-contracts} -スマートコントラクトは、一般的な誤解とは異なり、自動的に実行される訳ではありません。スマートコントラクトのコードを実行するには、外部所有アカウント(EOA)まあたはその他のコントラクトアカウントが適切な関数をトリガーする必要があるのです。 大部分の場合、スマートコントラクトに含まれる関数の大部分は公開されており、EOA およびその他のコントラクトにより呼び出すことができます。 +スマートコントラクトは、自動的に実行される訳ではありません。正確に言うと、スマートコントラクトのコードを実行するには、外部所有アカウント(EOA)まあたはその他のコントラクトアカウントが適切な関数をトリガーする必要があります。 大部分の場合、スマートコントラクトに含まれる関数の大部分は公開されており、EOAおよびその他のコントラクトにより呼び出すことができます。 -しかしスマートコントラクトには、他のコントラクトからはアクセスできない*プライベート関数*も含まれており、これらは Dapp の全般的な機能を実現する上で欠かせない関数である場合が多いです。 このようなプライベート関数の例としては、新規の NFT を定期的にミントする`mintERC721Token()`関数、予測市場で報酬を支払う関数、あるいは DEX においてステーキングされたトークンをアンロックする関数などが想定できるでしょう。 +しかしスマートコントラクトには、他のコントラクトからはアクセスできない_プライベート関数_も含まれており、これらはDappの全般的な機能を実現する上で欠かせない関数になっています。 このようなプライベート関数の例としては、新規のNFTを定期的にミントする`mintERC721Token()`関数、予測市場で報酬を支払う関数、あるいはDEXにおいてステーキングされたトークンをアンロックする関数などが想定できるでしょう。 開発者は、アプリケーションのスムーズな動作を保証するために、これらの関数を一定の間隔でトリガーする必要があります。 しかし、このようなアプローチでは、開発者が反復的なタスクのために費やす時間が増加してしまうため、スマートコントラクトを自動的に実行するアプローチが有益なのです。 一部の分散型オラクルのネットワークでは、ユーザーが定義したパラメータに従って、オフチェーンのオラクルノードがスマートコントラクトの関数をトリガーできる自動化サービスを提供しています。 このような自動化サービスは通常、ターゲットとなるコントラクトを当該のオラクルサービスに「登録」する必要がある他、オラクルの運用者に対して手数料を支払い、当該コントラクトをトリガーする際の条件または時間を指定する必要があります。 -このようなサービスの例としては、Chainlink の[Keeper Network](https://chain.link/keepers)があり、スマートコントラクトに対して、最小限の信頼性に基づき分散化された手法で定期的な保全タスクを実行するためのオプションが提供されています。 開発中のコントラクトを Keeper 互換にしたり、Upkeep サービスを利用したい場合は、Keeper の[公式ドキュメンテーション](https://docs.chain.link/docs/chainlink-keepers/introduction/)を参照してください。 +Chainlinkの[Keeper Network](https://chain.link/keepers)では、スマートコントラクトに対して、最小限の信頼性に基づき分散化された手法で定期的な保全タスクを実行するためのオプションが提供されています。 開発中のコントラクトをKeeper互換にしたり、Upkeepサービスを利用したい場合は、Keeperの[公式ドキュメント](https://docs.chain.link/docs/chainlink-keepers/introduction/)を参照してください。 ## ブロックチェーン・オラクルを使用する {#use-blockchain-oracles} -イーサリアムの Dapp で使用できるオラクル・アプリケーションとしては、以下があります: - -**[Chainlink](https://chain.link/)** - _Chainlink の分散型オラクルネットワークでは、インプット情報、アウトプット情報、および計算処理における改ざん防止を徹底することで、あらゆるブロックチェーンにおける複雑なスマートコントラクトをサポートしています。_ +イーサリアムのDappで使用できるオラクル・アプリケーションとしては、以下があります: -**[Witnet](https://witnet.io/)** - _Witnet は、パーミッションレス性、分散性、および耐検閲性を持つオラクルであり、スマートコントラクトを強力な暗号経済的な保証に基づいて現実世界のイベントに反応できるようにすることができます。_ +**[Chainlink](https://chain.link/)** - _Chainlinkの分散型オラクルネットワークでは、インプット情報、アウトプット情報、および計算処理における改ざん防止を徹底することで、あらゆるブロックチェーンにおける複雑なスマートコントラクトをサポートしています。_ -**[UMA オラクル](https://uma.xyz)** - _UMA のオプティミスティック・オラクルでは、保険、金融派生商品、および予測市場などのさまざまな用途を持つスマートコントラクトに対して、あらゆる種類のデータを迅速に取得する機能を追加することができます。_ +**[Witnet](https://witnet.io/)** - _Witnetは、パーミッションレス性、分散性、および耐検閲性を持つオラクルであり、スマートコントラクトを強力な暗号経済的な保証に基づいて現実世界のイベントに反応できるようにすることができます。_ -**[Tellor](https://tellor.io/)** - _Tellor は、あなたのスマートコントラクトが必要とする際に、常にどんな種類のデータでも取得可能にするための、透明性が高くパーミッションレスのオラクル・プロトコルです。_ +**[UMAオラクル](https://uma.xyz)** - _UMAのオプティミスティック・オラクルでは、保険、金融派生商品、および予測市場などのさまざまな用途を持つスマートコントラクトに対して、あらゆる種類のデータを迅速に取得する機能を追加することができます。_ -**[Band Protocol](https://bandprotocol.com/)** - _Band Protocol は、現実世界のデータを集約し、各種 API とスマートコントラクトを接続するための、クロスチェーンデータを対象とするオラクルプラットフォームです。_ +**[Tellor](https://tellor.io/)** - _Tellorは、あなたのスマートコントラクトが必要とする際に、常にどんな種類のデータでも取得可能にするための、透明性が高くパーミッションレスのオラクル・プロトコルです。_ -**[Provable](https://provable.xyz/)** - _Provable は、ブロックチェーンを利用した Dapp とあらゆる種類の外部 Web API を接続するサービスで、TLSNotary proof、信頼される実行環境(TEE)およびセキュアな暗号プリミティブを活用してデータの真正性を保証しています。_ +**[Band Protocol](https://bandprotocol.com/)** - _Band Protocolは、現実世界のデータを集約し、各種APIとスマートコントラクトを接続するための、クロスチェーンデータを対象とするオラクルプラットフォームです。_ -**[Paralink](https://paralink.network/)** - _Paralink は、イーサリアムおよびその他のメジャーなブロックチェーン上で実行されるスマートコントラクトを対象とする、オープンソースで分散化されたオラクルプラットフォームです。_ +**[Paralink](https://paralink.network/)** - _Paralinkは、イーサリアムおよびその他のメジャーなブロックチェーン上で実行されるスマートコントラクトを対象とする、オープンソースで分散化されたオラクルプラットフォームです。_ -**[Dos.Network](https://dos.network/)** - _DOS Network は、現実世界におけるデータや処理能力を活用することでブロックチェーンの使いやすさを向上させる、分散型のオラクルサービスネットワークです。_ +**[Pyth Network](https://pyth.network/)** - _Pyth Networkは、改ざん不可、分散化、および自己持続可能な特徴を持つ環境において、現実世界のデータを継続的にオンチェーンで公開するために設計された、ファーストパーティの金融オラクルネットワークです。_ -**[Pyth Network](https://pyth.network/)** - _Pyth Network は、改ざん不可、分散化、および自己持続可能な特徴を持つ環境において、現実世界のデータを継続的にオンチェーンで公開するために設計された、ファーストパーティの金融オラクルネットワークです。_ +**[API3 DAO](https://www.api3.org/)** - _API3 DAOでは、ファーストパーティのオラクルソリューションを提供しています。スマートコントラクトの分散型ソリューションにより、ソースの透明性、セキュリティ、スケーラビリティを向上させることができます。_ ## 参考文献 {#further-reading} @@ -414,18 +410,19 @@ contract PriceConsumerV3 { - [ブロックチェーン・オラクルとは?](https://betterprogramming.pub/what-is-a-blockchain-oracle-f5ccab8dbd72) — _パトリック・コリンズ作成。_ - [分散型オラクル:包括的な概要](https://medium.com/fabric-ventures/decentralised-oracles-a-comprehensive-overview-d3168b9a8841) — _ジュリアン・テヴェナード作成。_ - [イーサリアムにおける ブロックチェーン・オラクルの実装](https://medium.com/@pedrodc/implementing-a-blockchain-oracle-on-ethereum-cedc7e26b49e) – _ペドロ・コスタ作成。_ -- [スマートコントラクトが API コールを行えないのはなぜか?](https://ethereum.stackexchange.com/questions/301/why-cant-contracts-make-api-calls) — _StackExchange_ +- [スマートコントラクトがAPIコールを行えないのはなぜか?](https://ethereum.stackexchange.com/questions/301/why-cant-contracts-make-api-calls) — _StackExchange_ - [分散型のオラクルが必要な理由](https://newsletter.banklesshq.com/p/why-we-need-decentralized-oracles) — _Bankless_ - [価格オラクルを使用したい場合の検討事項](https://samczsun.com/so-you-want-to-use-a-price-oracle/) — _samczsun_ **ビデオ** - [オラクルによるブロックチェーンの有用性の拡大](https://youtu.be/BVUZpWa8vpw) — _Real Vision Finance_ +- [ファーストパーティーオラクルとサードバーティーオラクルの違い](https://blockchainoraclesummit.io/first-party-vs-third-party-oracles/) - _ブロックチェーン・オラクル・サミット_ **チュートリアル** -- [Solidity 上でイーサリアムの現在価格を取得する方法](https://blog.chain.link/fetch-current-crypto-price-data-solidity/) — _Chainlink_ +- [Solidity上でイーサリアムの現在価格を取得する方法](https://blog.chain.link/fetch-current-crypto-price-data-solidity/) — _Chainlink_ **プロジェクト実例** -- [Solidity を用いてイーサリアムに Chainlin をフルに導入する際のスタータープロジェクト](https://github.com/hackbg/chainlink-fullstack) — _HackBG_ +- [Solidityを用いてイーサリアムにChainlinをフルに導入する際のスタータープロジェクト](https://github.com/hackbg/chainlink-fullstack) — _HackBG_ diff --git a/public/content/translations/ja/developers/docs/scaling/index.md b/public/content/translations/ja/developers/docs/scaling/index.md index 3ed3642262a..e340dc20b5a 100644 --- a/public/content/translations/ja/developers/docs/scaling/index.md +++ b/public/content/translations/ja/developers/docs/scaling/index.md @@ -1,6 +1,6 @@ --- title: スケーリング -description: 現在イーサリアムコミュニティにおいて開発中の様々なスケーリングのオプションを紹介する。 +description: 現在イーサリアムコミュニティにおいて開発中のさまざまなスケーリングのオプションを紹介する。 lang: ja sidebarDepth: 3 --- @@ -9,7 +9,7 @@ sidebarDepth: 3 イーサリアムのユーザー規模が拡大するにつれ、イーサリアムブロックチェーンの処理能力は限界に達しつつあります。 これにより、イーサリアムネットワークの使用コストが増加しているため、「スケーリングソリューション」の必要性が高まってきました。 スケーリングを達成するという目標の下で、異なるアプローチを用いた様々なソリューションが研究、テスト、および実装されています。 -スケーラビリティの取り組みにおける主な目標は、分散化やセキュリティを犠牲にすることなく、トランザクション速度の向上(ファイナリティ到達までの時間短縮)ならびにトランザクションスループットの向上(毎秒あたりの処理件数の向上)を実現することです(詳細については、[イーサリアムのビジョン](/roadmap/vision/)をご覧ください)。 レイヤー 1 のイーサリアムブロックチェーンでは、需要が増化するとトランザクションが遅延し、[ガス価格](/developers/docs/gas/)が高騰します。 イーサリアムが有意義かつ大規模に利用されるようになるためには、ネットワークの速度とスループットを改善することが不可欠です。 +スケーラビリティの取り組みにおける主な目標は、分散化やセキュリティを犠牲にすることなく、トランザクション速度の向上(ファイナリティ到達までの時間短縮)ならびにトランザクションスループットの向上(毎秒あたりの処理件数の向上)を実現することです(詳細については、[イーサリアムのビジョン](/roadmap/vision/)をご覧ください)。 レイヤー1のイーサリアムブロックチェーンでは、需要が増化するとトランザクションが遅延し、[ガス価格](/developers/docs/gas/)が高騰します。 イーサリアムが有意義かつ大規模に利用されるようになるためには、ネットワークの速度とスループットを改善することが不可欠です。 速度とスループットが重要である一方で、スケーリングのソリューションはこれらの目標を、分散化とセキュリティという特性を失わずに実現しなければなりません。 中央集権化およびセキュリティの低下を防ぐためには、どんなユーザーでもノードとして参加できるように参入障壁を低くしておくことが重要です。 @@ -21,95 +21,93 @@ sidebarDepth: 3 ## オンチェーンにおけるスケーリング {#on-chain-scaling} -この手法は、イーサリアムプロトコル(レイヤー 1 の[メインネット](/glossary/#mainnet))の変更を必要とします。 この手法によるスケーリングは、現在シャーディングが主流になっています。 +オンチェーンスケーリングでは、イーサリアムプロトコル(レイヤー1の[メインネット](/glossary/#mainnet))を変更する必要があります。 長い間、ブロックチェーンのシャーディングによってイーサリアムが拡張されると期待されていました。 シャーディングとは、ブロックチェーンを複数の部分(シャード)に分割する技術であり、バリデータのサブセットによって検証される予定でした。 しかし、主要なスケーリング技術として、レイヤー2ロールアップによるスケーリングが引き継がれており、 より安く新しいデータ形式を追加することでサポートされています。このデータ形式は、ユーザーにとってロールアップを安価にするために特別に設計されています。 ### シャーディング {#sharding} -シャーディングとは、負荷を分散するためにデータベースを水平的に分割するプロセスを指します。 イーサリアムにおけるシャーディングとは、「シャード」と呼ばれる新たなチェーンを作成することで、ネットワークの混雑を解消し、毎秒あたりのトランザクション数を増加させる手法を指します。 これにより、バリデータは、イーサリアムネットワーク全体に含まれるすべてのトランザクションを処理する必要がなくなるため、負荷が軽減されます。 - -[シャーディング](/upgrades/sharding/) について詳しく知る。 +シャーディングは、データベースを分割するプロセスです。 バリデータのサブセットは、イーサリアム全体を追跡するのではなく、個々のシャードに対して責任を持ちます。 シャーディングは、長い間、イーサリアムの[ロードマップ](/roadmap/)に記載されていました。また、かつては、プルーフ・オブ・ステークへ切り替わるマージの前にリリースされる予定でした。 しかし、[レイヤー2ロールアップ](#layer-2-scaling)の急速な開発と、[ダンクシャーディング](/roadmap/danksharding)(バリデータが非常に効率的に検証できるロールアップデータであるブロブをイーサリアムブロックに追加すること)の開発により、イーサリアムコミュニティの関心は、シャーディングによるスケーリングからロールアップ中心のスケーリングへとシフトしました。 これにより、イーサリアムのコンセンサスロジックは比較的シンプルに保たれることになりました。 ## オフチェーンにおけるスケーリング {#off-chain-scaling} -オフチェーンのスケーリングソリューションは、レイヤー 1 のメインネットとは別個に実装されるため、既存のイーサリアムプロトコルを変更する必要がありません。 「レイヤー 2」ソリューションと呼ばれる一部のソリューションでは、[オプティミスティックロールアップ](/developers/docs/scaling/optimistic-rollups/)、[ゼロ知識ロールアップ](/developers/docs/scaling/zk-rollups/)、あるいは[ステートチャンネル](/developers/docs/scaling/state-channels/)のように、セキュリティ保護につきレイヤー 1 のイーサリアムコンセンサスに依存するものもあります。 一方、[サイドチェーン](#sidechains)、[バリディアム](#validium)、あるいは[プラズマチェーン](#plasma)といったソリューションでは、メインネットとは別個にセキュリティを保証する様々な形式の新規チェーンを作成します。 後者のソリューションでは、メインネットとやりとりするものの、各ソリューションの目標に合わせて様々な方法でセキュリティを維持しようとします。 +オフチェーンのスケーリングソリューションは、レイヤー1のメインネットとは別個に実装されるため、既存のイーサリアムプロトコルを変更する必要がありません。 「レイヤー2」ソリューションと呼ばれる一部のソリューションでは、[オプティミスティックロールアップ](/developers/docs/scaling/optimistic-rollups/)、[ゼロ知識ロールアップ](/developers/docs/scaling/zk-rollups/)、[ステートチャンネル](/developers/docs/scaling/state-channels/)など、レイヤー1のイーサリアムコンセンサスに依存してセキュリティを保護するものもあります。 一方、[サイドチェーン](#sidechains)、[バリディアム](#validium)、あるいは[プラズマチェーン](#plasma)などのソリューションでは、メインネットとは別に、さまざまな形式の新規チェーンを作成してセキュリティを保証します。 これらのソリューションでは、メインネットとやり取りするものの、各ソリューションの目標に合わせて、セキュリティを維持する方法は異なります。 -### レイヤー 2 のスケーリング {#layer-2-scaling} +### レイヤー2のスケーリング {#layer-2-scaling} -オフチェーンのソリューションのうち、セキュリティをイーサリアムメインネットに依存するものをレイヤー 2 のスケーリングソリューションと呼びます。 +オフチェーンのソリューションのうち、セキュリティをイーサリアムメインネットに依存するものをレイヤー2のスケーリングソリューションと呼びます。 -レイヤー 2 とは、メインネットが提供する堅牢かつ分散型のセキュリティモデルを活用しつつ、イーサリアムメインネット(レイヤー 1)外でトランザクションを実行することでアプリケーションのスケーラビリティを実現しようとするソリューションの総称です。 ネットワークの混雑によりトランザクション速度が低下すると、一部の Dapp では優れたユーザー体験を提供できなくなります。 さらに、ネットワークが混雑すると、トランザクションの送信者が価格をつり上げることでガス価格が上昇します。 これにより、イーサリアムの使用コストが非常に高額になる可能性があります。 +レイヤー2とは、メインネットが提供する堅牢かつ分散型のセキュリティモデルを活用しつつ、イーサリアムメインネット(レイヤー1)外でトランザクションを実行することでアプリケーションのスケーラビリティを実現しようとするソリューションの総称です。 ネットワークの混雑によりトランザクション速度が低下すると、一部のDappでは優れたユーザー体験を提供できなくなります。 また、ネットワークが混雑すると、トランザクションの送信者がガス代を高く支払うようになります。そのため、ガス代が上昇し、 イーサリアムの使用コストが非常に高額になる可能性があります。 -大部分のレイヤー 2 ソリューションは、1 台または複数のサーバークラスタで構成され、各サーバーはノード、バリデータ、オペレーター、シーケンサー、ブロック生成者といった名称で呼ばれます。 これらのレイヤー 2 のノードは、実装により、ノードを使用する個人、企業、または組織が実行する場合、サードパーティ事業者が実行する場合、あるいは多数の個人が参加するグループが実行する場合(メインネットの場合と同様)があります。 トランザクションは通常、レイヤー 1(メインネット)に直接送信されるのではなく、これらのレイヤー 2 のノードに送信されます。 一部のソリューションでは、トランザクションは送信先のレイヤー 2 のインスタンスにおいてバッチとしてグループ化されてからレイヤー 1 に固定されるため、その後はレイヤー 1 において確定され、改変できなくなります。 このプロセスが具体的にどう実行されるかは、様々なレイヤー 2 のテクノロジー/実装により大きく異なります。 +ほとんどのレイヤー2ソリューションは、サーバーまたはサーバー群を中心に構成されており、それぞれのサーバーは、ノード、バリデータ、オペレーター、シーケンサー、ブロックプロデューサーなどと呼ばれています。 これらのレイヤー2ノードは、実装方法によって、利用する個人や企業、団体、サードパーティのオペレーター、大規模な個人のグループなどが運営する場合があります(メインネットと同様)。 通常、取引はレイヤー1(メインネット)に直接送信されるのではなく、レイヤー2のノードに送信されます。 ソリューションによっては、レイヤー2のインスタンスがトランザクションをグループ化してレイヤー1に固定します。その後、レイヤー1によって安全性が確保されると、それ以降は変更できなくなります。 このプロセスの具体的な実行方法は、レイヤー2のテクノロジーや実装によって大きく異なります。 -個別のレイヤー 2 インスタンスは、多くのアプリケーションに解放され、共有される場合と、特定のプロジェクトによりデプロイされ、関連アプリケーションのみを専用でサポートする場合があります。 +特定のレイヤー2インスタンスは、オープンで多くのアプリケーションが共有するものもあれば、1つのプロジェクトがデプロイし、そのアプリケーションのみをサポートするものもあります。 -#### レイヤー 2 が必要な理由 {#why-is-layer-2-needed} +#### レイヤー2が必要な理由 {#why-is-layer-2-needed} - 毎秒あたりのトランザクション数を増加させることで、ユーザー体験が向上し、イーサリアムメインネットの混雑を軽減できる。 -- 複数のトランザクションを 1 つのトランザクションにロールアップしてメインネットに送信するため、ガス代が軽減でき、イーサリアムの包摂性が高まり、すべての人が利用できるようになる。 -- スケーラビリティを実現するためのアップデートは、分散化やセキュリティを犠牲にしてはならないが、レイヤー 2 はイーサリアムの基盤に基づくネットワークである。 -- アプリケーションごとに特化されたレイヤー 2 のネットワークでは、大規模な資産を取り扱う際に独自の効率性アップが実現できる。 +- 複数のトランザクションを1つのトランザクションにロールアップしてメインネットに送信するため、ガス代が軽減でき、イーサリアムの包摂性が高まり、すべての人が利用できるようになる。 +- スケーラビリティを実現するためのアップデートは、分散化やセキュリティを犠牲にしてはならないが、レイヤー2はイーサリアムの基盤に基づくネットワークである。 +- アプリケーションごとに特化されたレイヤー2のネットワークでは、大規模な資産を取り扱う際に独自の効率性アップが実現できる。 -[レイヤー 2 の詳細](/layer-2/) +[レイヤー2の詳細](/layer-2/) #### ロールアップ {#rollups} -ロールアップとは、レイヤー 1 の外部でトランザクションを実行した上で、データをレイヤー 1 に送信し、そこでコンセンサスを得るという手段です。 トランザクションデータはレイヤー 1 のブロックに含まれるため、ロールアップの安全性はイーサリアムのネイティブセキュリティにより保証されます。 +ロールアップとは、レイヤー1の外部でトランザクションを実行し、データをレイヤー1に送信して、そこでコンセンサスを得るという手段です。 トランザクションデータはレイヤー1のブロックに含まれるため、ロールアップの安全性はイーサリアムのネイティブセキュリティにより保証されます。 -ロールアップには、異なるセキュリティモデルを採用した以下の 2 種類があります: +ロールアップには、異なるセキュリティモデルを採用した以下の2種類があります。 - **オプティミスティック・ロールアップ**: トランザクションはデフォルトで有効であると仮定し、チャレンジが提起された場合のみ[**不正証明**](/glossary/#fraud-proof)を通じて計算を実行します。 [オプティミスティック・ロールアップの詳細](/developers/docs/scaling/optimistic-rollups/)。 - **ゼロ知識ロールアップ**: オフチェーンで計算を実行し、[**有効性証明**](/glossary/#validity-proof)をチェーンに送信します。 [ゼロ知識ロールアップの詳細](/developers/docs/scaling/zk-rollups/)。 #### ステートチャンネル {#channels} -ステートチャネルでは、マルチシグのコントラクトを通じて、参加者はオフチェーンで迅速かつ自由に取引を行うことでき、その上でメインネット上でファイナリティを実現します。 これにより、ネットワークの混雑、手数料、および遅延を最小限に抑えることができます。 現在利用されているチャネルとしては、ステートチャネルとペイメントチャネルがあります。 +ステートチャンネルでは、マルチシグのコントラクトを通じて、参加者はオフチェーンで迅速かつ自由に取引を行うことでき、その上でメインネット上でファイナリティを実現します。 これにより、ネットワークの混雑、手数料、遅延を最小限に抑えることができます。 現在利用されているチャンネルは、ステートチャンネルとペイメントチャンネルの2つです。 -[ステートチャネル](/developers/docs/scaling/state-channels/)について詳しく知る。 +[ステートチャンネル](/developers/docs/scaling/state-channels/)の詳細 ### サイドチェーン {#sidechains} -サイドチェーンは、EVM 互換の独立したブロックチェーンであり、メインネットと並行して実行されます。 イーサリアムとの互換性は双方向ブリッジで実現され、トランザクションは独自に選択したコンセンサスルールとブロックパラメータに基づいて実行されます。 +サイドチェーンは、EVM互換の独立したブロックチェーンであり、メインネットと並行して実行されます。 イーサリアムとの互換性は双方向ブリッジで実現され、トランザクションは独自に選択したコンセンサスルールとブロックパラメータに基づいて実行されます。 -[サイドチェーン](/developers/docs/scaling/sidechains/)について詳しく知る。 +[サイドチェーン](/developers/docs/scaling/sidechains/)の詳細 ### プラズマ {#plasma} -プラズマチェーンとは、メインのイーサリアムチェーンにおいて固定された別個のブロックチェーンで、不正証明([オプティミスティック・ロールアップ](/developers/docs/scaling/optimistic-rollups/)など)を用いて紛争を仲裁します。 +プラズマチェーンとは、メインのイーサリアムチェーンにおいて固定された別個のブロックチェーンで、不正証明([オプティミスティック・ロールアップ](/developers/docs/scaling/optimistic-rollups/)など)を用いて紛争を仲裁します。 -[プラズマ](/developers/docs/scaling/plasma/)について詳しく知る。 +[プラズマ](/developers/docs/scaling/plasma/)の詳細 ### バリディアム {#validium} -バリディアムチェーンは、ゼロ知識ロールアップと同様に有効性証明を使用しますが、データはレイヤー 1 であるメインのイーサリアムチェーン上に保存されません。 これにより、バリディアムチェーンごとの毎秒あたりのトランザクション数は 1 万件に達し、複数のバリディアムチェーンを並行して実行することができます。 +バリディアムチェーンはゼロ知識ロールアップのように有効性証明を使用しますが、メインのレイヤー1イーサリアムチェーン上にデータを保存しません。 そのため、バリディアムチェーンごとに毎秒1万のトランザクションを処理でき、複数のチェーンを並列に実行できます。 -[バリディアム](/developers/docs/scaling/validium/)について詳しく知る。 +[バリディアム](/developers/docs/scaling/validium/)の詳細 -## 様々なスケーリングソリューションが求められる理由とは? {#why-do-we-need-these} +## さまざまなスケーリングソリューションが求められる理由 {#why-do-we-need-these} -- 様々なソリューションは、イーサリアムネットワークにおける各部分の全般的な混雑を緩和できるだけでなく、単一障害点の発生を防ぐために役立ちます。 -- 複数のソリューションは、その全体においてさらに効力を発揮します。 つまり、様々なソリューションが共存し、調和的に機能することで、トランザクションの速度/スループットを今後爆発的に向上させることが可能になります。 -- すべてのソリューションにおいてイーサリアムのコンセンサス・アルゴリズムを直接活用する必要があるわけではなく、様々な代替手段によりその他の方法では得にくいメリットを得ることができます。 +- さまざまなソリューションは、イーサリアムネットワーク全体の混雑を緩和するだけでなく、単一障害点の発生を防ぐためにも役立ちます。 +- 複数のソリューションは、その全体においてさらに効力を発揮します。 つまり、多様なソリューションが共存し、調和的に機能することで、トランザクションの速度やスループットを今後爆発的に向上させることが可能になります。 +- すべてのソリューションにおいてイーサリアムのコンセンサス・アルゴリズムを直接活用する必要があるわけではなく、さまざまな代替手段によりその他の方法では得にくいメリットを得ることができます。 - 特定のスケーリング・ソリューションが[イーサリアムのビジョン](/roadmap/vision/)を完全に満たすことは不可能です。 ## 映像で学びたい場合 {#visual-learner} -_この動画の説明では、「レイヤー 2」という用語をオフチェーンでのスケーリング・ソリューション全般を指すものとして使用していますが、本記事では、「レイヤー 2」につき、レイヤー 1(メインネット)のコンセンサスに依存してセキュリティを保護するオフチェーンソリューションを指す用語としてを用いています。_ +_この動画の説明では、「レイヤー2」という用語をオフチェーンでのスケーリング・ソリューション全般を指すものとして使用していますが、本記事では、、レイヤー1(メインネット)のコンセンサスに依存してセキュリティを保護するオフチェーンソリューションを指す用語として「レイヤー2」を用いています。_ ## 参考文献 {#further-reading} - [ロールアップを重視したイーサリアム・ロードマップ](https://ethereum-magicians.org/t/a-rollup-centric-ethereum-roadmap/4698) _ヴィタリック・ブテリン作成。_ -- [イーサリアムのレイヤー 2 スケーリング・ソリューションに関する最新のアナリティクス](https://www.l2beat.com/) -- [イーサリアムの様々なレイヤー 2 のスケーリングソリューションを評価する:比較のフレームワーク](https://medium.com/matter-labs/evaluating-ethereum-l2-scaling-solutions-a-comparison-framework-b6b2f410f955) -- [ロールアップに関する不完全ガイド](https://vitalik.eth.limo/general/2021/01/05/rollup.html) +- [イーサリアムのレイヤー2スケーリング・ソリューションに関する最新のアナリティクス](https://www.l2beat.com/) +- [イーサリアムの様々なレイヤー2のスケーリングソリューションを評価する:比較のフレームワーク](https://medium.com/matter-labs/evaluating-ethereum-l2-scaling-solutions-a-comparison-framework-b6b2f410f955) +- [ロールアップに関する不完全ガイド](https://vitalik.ca/general/2021/01/05/rollup.html) - [イーサリアムを活用したゼロ知識ロールアップ:ワールドビーター](https://hackmd.io/@canti/rkUT0BD8K) - [オプティミスティック・ロールアップ とゼロ知識ロールアップの比較](https://limechain.tech/blog/optimistic-rollups-vs-zk-rollups/) - [ゼロ知識によるブロックチェーンのスケーラビリティ](https://ethworks.io/assets/download/zero-knowledge-blockchain-scaling-ethworks.pdf) - [ロールアップとデータシャードを組み合わせる手段が、高スケーラビリティを実現する唯一のサステナブルなソリューションである理由](https://polynya.medium.com/why-rollups-data-shards-are-the-only-sustainable-solution-for-high-scalability-c9aabd6fbb48) -- [有意義なレイヤー 3 とはどのようなものか?](https://vitalik.eth.limo/general/2022/09/17/layer_3.html) +- [有意義なレイヤー3とはどのようなものか?](https://vitalik.ca/general/2022/09/17/layer_3.html) -_イーサリアムを学ぶために利用したコミュニティリソースはありますか? このページを編集して追加しましょう!_ +_役に立ったコミュニティリソースがあれば、 ぜひこのページに追加してください。_ diff --git a/public/content/translations/ja/developers/docs/scaling/optimistic-rollups/index.md b/public/content/translations/ja/developers/docs/scaling/optimistic-rollups/index.md index 48f339a5ae8..f56eb9e4d15 100644 --- a/public/content/translations/ja/developers/docs/scaling/optimistic-rollups/index.md +++ b/public/content/translations/ja/developers/docs/scaling/optimistic-rollups/index.md @@ -4,13 +4,13 @@ description: イーサリアムにおけるスケーリングの問題に対す lang: ja --- -オプティミスティック・ロールアップは、イーサリアム(ベースレイヤー)のスループットを拡張するために設計されたレイヤー 2 (L2) プロトコルです。 トランザクションをオフチェーンで処理することで、イーサリアムメインネットの負荷を軽減するため、処理速度が大幅に改善されます。 オプティミスティック・ロールアップは、[サイドチェーン](/developers/docs/scaling/sidechains/)のような他のスケーリング・ソリューションとは異なり、トランザクションの結果をオンチェーンで公開することによってメインネットからセキュリティを引き出します。プラズマチェーンも、不正証明を使用してイーサリアム上で検証しますが、トランザクションのデータをイーサリアムに保存しない点が異なります。 +オプティミスティック・ロールアップは、イーサリアム(ベースレイヤー)のスループットを拡張するために設計されたレイヤー2 (L2) プロトコルです。 トランザクションをオフチェーンで処理することで、イーサリアムメインネットの負荷を軽減するため、処理速度が大幅に改善されます。 オプティミスティック・ロールアップは、[サイドチェーン](/developers/docs/scaling/sidechains/)のような他のスケーリング・ソリューションとは異なり、トランザクションの結果をオンチェーンで公開することによってメインネットからセキュリティを引き出します。プラズマチェーンも、不正証明を使用してイーサリアム上で検証しますが、トランザクションのデータをイーサリアムに保存しない点が異なります。 -イーサリアムにおける処理は、速度が遅く高価であるという欠点がありますが、オプティミスティック・ロールアップを用いることでスケーラビリティを 10〜100 倍向上させることができます。 さらに、トランザクションを`calldata`としてイーサリアムに書き込むため、ユーザーが負担するガス代を低く抑えることができます。 +イーサリアムにおける処理は、速度が遅く高価であるという欠点がありますが、オプティミスティック・ロールアップを用いることでスケーラビリティを10〜100倍向上させることができます。 さらに、トランザクションを`calldata`としてイーサリアムに書き込むため、ユーザーが負担するガス代を低く抑えることができます。 ## 前提知識 {#prerequisites} -[イーサリアムにおけるスケーリング](/developers/docs/scaling/)と[レイヤー 2](/layer-2/) のページを読み、理解しておくことをおすすめします。 +[イーサリアムにおけるスケーリング](/developers/docs/scaling/)と[レイヤー2](/layer-2/) のページを読み、理解しておくことをおすすめします。 ## オプティミスティック・ロールアップとは何か? {#what-is-an-optimistic-rollup} @@ -32,11 +32,11 @@ lang: ja オプティミスティック・ロールアップのアーキテクチャには、以下の構成要素が含まれています: -**オンチェーンのコントラクト**: オプティミスティック・ロールアップの動作は、イーサリアム上で実行されるスマートコントラクトにより制御されます。 具体的には、ロールアップされたブロックを保存するコントラクト、ロールアップの状態更新を監視するコントラクト、およびユーザーのデポジットを追跡するコントラクトが含まれます。 この意味で、イーサリアムは、オプティミスティック・ロールアップに対するベースレイヤー(つまり、「レイヤー 1」)であると言うことができます。 +**オンチェーンのコントラクト**: オプティミスティック・ロールアップの動作は、イーサリアム上で実行されるスマートコントラクトにより制御されます。 具体的には、ロールアップされたブロックを保存するコントラクト、ロールアップの状態更新を監視するコントラクト、およびユーザーのデポジットを追跡するコントラクトが含まれます。 この意味で、イーサリアムは、オプティミスティック・ロールアップに対するベースレイヤー(つまり、「レイヤー1」)であると言うことができます。 -**オフチェーンの仮想マシン(VM)**:オプティミスティック・ロールアップのプロトコルを管理するコントラクトはイーサリアム上で実行されますが、ロールアップのプロトコルにおける計算の実行と状態の保存は[イーサリアム仮想マシン](/developers/docs/evm/)とは別の仮想マシン上で行われます。 このオフチェーンの VM は、アプリケーションが稼働し、状態変更が実行される場所であるため、オプティミスティック・ロールアップにおける上位レイヤー(つまり、「レイヤー 2」)であると言えます。 +**オフチェーンの仮想マシン(VM)**:オプティミスティック・ロールアップのプロトコルを管理するコントラクトはイーサリアム上で実行されますが、ロールアップのプロトコルにおける計算の実行と状態の保存は[イーサリアム仮想マシン](/developers/docs/evm/)とは別の仮想マシン上で行われます。 このオフチェーンのVMは、アプリケーションが稼働し、状態変更が実行される場所であるため、オプティミスティック・ロールアップにおける上位レイヤー(つまり、「レイヤー2」)であると言えます。 -オプティミスティック・ロールアップは、イーサリアム仮想マシン(EVM)用に開発/コンパイルされたプログラムを実行するように設計されているため、オフチェーンの VM は EVM の設計仕様の多くを踏襲しています。 また、イーサリアムネットワークは、オンチェーンで計算された不正証明を用いて、オフチェーンの VM で計算された状態変更の有効性を強制することができます。 +オプティミスティック・ロールアップは、イーサリアム仮想マシン(EVM)用に開発/コンパイルされたプログラムを実行するように設計されているため、オフチェーンのVMはEVMの設計仕様の多くを踏襲しています。 また、イーサリアムネットワークは、オンチェーンで計算された不正証明を用いて、オフチェーンのVMで計算された状態変更の有効性を強制することができます。 オプティミスティック・ロールアップは、イーサリアムとは別個のプロトコルとして存在するものの、そのセキュリティ属性はイーサリアムに依存しているため、「ハイブリッド型のスケーリング・ソリューション」と呼ばれます。 特に、イーサリアムメインネットは、ロールアップにおけるオフチェーンでの計算の正しさと、この計算に用いられたデータの可用性を保証します。 このため、セキュリティをイーサリアムに依存しない、「純粋な」オフチェーンのスケーリング・プロトコル(例:[サイドチェーン](/developers/docs/scaling/sidechains/))と比較すると、オプティミスティック・ロールアップはよりセキュリティが堅牢であると言えます。 @@ -46,7 +46,7 @@ lang: ja すでに述べたように、オプティミスティック・ロールアップではトランザクションのデータを`calldata`としてイーサリアムに送信します。 ロールアップチェーンは送信されたトランザクションに基づき実行されるため、イーサリアムのベースレイヤーに含まれるコールデータの情報を用いて、どのユーザーでもロールアップのステートを実行し、状態遷移の正しさを検証することができます。 -[データ可用性](/developers/docs/data-availability/)が重要であるのは、状態データにアクセスできない場合、異議申立者はロールアップにおける無効な操作に異議を申し立てる上で必要な不正証明を作成できないためです。 イーサリアムがデータ可用性を保証するため、ロールアップのオペレータによる悪意の行動(例:無効なブロックの送信)が見過ごされる可能性が低くなります。 +[データ可用性](/developers/docs/data-availability/)が重要なのは、状態データにアクセスできないと、ロールアップにおける無効な操作に異議を申し立てる際に、必要な不正証明を作成することができたいからです。 イーサリアムがデータ可用性を保証するため、ロールアップのオペレータによる悪意の行動(例:無効なブロックの送信)が見過ごされる可能性が低くなります。 ### 検閲耐性 {#censorship-resistance} @@ -62,13 +62,13 @@ lang: ja - 各ユーザーは、トランザクションデータを用いて資金の所有権を証明するマークル証明を作成できるため、ロールアップから各自の資産を引き出すことができる。 -- 各ユーザーはさらに、トランザクションをシーケンサーに対してではなく、L1 に送信できる。この場合シーケンサーは、正当なブロックを引き続き作成するために、一定期間内に送信されたトランザクションをブロックに追加する必要がある。 +- 各ユーザーはさらに、トランザクションをシーケンサーに対してではなく、L1に送信できる。この場合シーケンサーは、正当なブロックを引き続き作成するために、一定期間内に送信されたトランザクションをブロックに追加する必要がある。 ### 決済 {#settlement} オプティミスティック・ロールアップにおいてイーサリアムが担うもう一つの役割は、決済レイヤーとしての役割です。 決済レイヤーとは、ブロックチェーンのエコシステム全体の基礎となり、セキュリティを提供すると同時に、他のチェーン(本トピックにおいては、オプティミスティック・ロールアップ)における仲裁が必要な紛争に対して、客観的なファイナリティを提供します。 -イーサリアムメインネットは、オプティミスティック・ロールアップにおいて不正証明を検証し、紛争を解消するハブの役割を担います。 さらに、ロールアップで実行されたトランザクションは、ロールアップのブロックがイーサリアム上で承認された*後*でなければ確定しません。 ロールアップのトランザクションは、イーサリアムのベースレイヤーで確定した後はロールバックできなくなります(チェーンの再編成というまれなケースを除く)。 +イーサリアムメインネットは、オプティミスティック・ロールアップにおいて不正証明を検証し、紛争を解消するハブの役割を担います。 さらに、ロールアップで実行されたトランザクションは、ロールアップのブロックがイーサリアム上で承認された_後_でなければ確定しません。 ロールアップのトランザクションは、イーサリアムのベースレイヤーで確定した後はロールバックできなくなります(チェーンの再編成というまれなケースを除く)。 ## オプティミスティック・ロールアップは、どのように実行されるのか? {#how-optimistic-rollups-work} @@ -80,7 +80,7 @@ lang: ja オプティミスティック・ロールアップチェーン上の他のバリデータは、当該ロールアップの状態に対する各自のコピーを用いて、送信されたトランザクションを実行することが求められます。 バリデータにおける最終的な状態がオペレーターが提案した状態と異なる場合、オペレーターは不正証明の計算を開始することでチャレンジを申し立てることができます。 -一部のオプティミスティック・ロールアップでは、パーミッションレスのバリデーター・システムを採用せず、単独の「シーケンサー」がチェーンを実行する場合もあります。 シーケンサーは、バリデータと同様に、トランザクションを処理し、ロールアップのブロックを作成した上で、ロールアップされたトランザクションを L1 チェーン(イーサリアムメインネット)に送信します。 +一部のオプティミスティック・ロールアップでは、パーミッションレスのバリデーター・システムを採用せず、単独の「シーケンサー」がチェーンを実行する場合もあります。 シーケンサーは、バリデータと同様に、トランザクションを処理し、ロールアップのブロックを作成した上で、ロールアップされたトランザクションをL1チェーン(イーサリアムメインネット)に送信します。 シーケンサーが通常のロールアップオペレーターと異なるのは、トランザクションの順序決定に対する権限がより大きいという点です。 さらに、シーケンサーはロールアップチェーンに対する優先アクセス権を持ち、オンチェーンのコントラクトにトランザクションを送信することができる唯一のエンティティとなります。 シーケンサー以外のノード、あるいは通常のユーザーが送信したトランザクションは、シーケンサーがそれらを新規バッチに追加するまでの間は、別個のインボックス上でキューに置かれた状態になります。 @@ -90,7 +90,7 @@ lang: ja `calldata`は、スマートコントラクトにおける変更不可で非永続的な領域であり、ほぼ[メモリ](/developers/docs/smart-contracts/anatomy/#memory)と同様に動作します。 `calldata`は、ブロックチェーンの[履歴ログ](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html?highlight=memory#logs)の一部としてオンチェーンで永続する一方で、イーサリアムの状態の一部としては保存されません。 `calldata`はイーサリアムの状態にまったく干渉しないので、オンチェーンでのデータ保存に伴う費用が安価になります。 -さらに、`calldata`のキーワードは、スマートコントラクトの実行時に Solidity 上の関数に引数を渡す際にも用いられます。 `calldata`は、トランザクションにおいて呼び出された関数を特定し、この関数に対する入力を任意のバイト列として保持します。 +さらに、`calldata`のキーワードは、スマートコントラクトの実行時にSolidity上の関数に引数を渡す際にも用いられます。 `calldata`は、トランザクションにおいて呼び出された関数を特定し、この関数に対する入力を任意のバイト列として保持します。 オプティミスティック・ロールアップにおける`calldata`は、オンチェーンのコントラクトにトランザクションの圧縮データを送信するために使用されます。 ロールアップのオペレーターは、ロールアップのコントラクトに含まれる必須の関数を呼び出し、関数の引数として圧縮データを渡す方法によって新規バッチを追加します。 ロールアップに伴うコストの大部分はオンチェーン上でのデータ保存に伴うものであるため、`calldata`の使用はユーザーの手数料を軽減します。 @@ -102,7 +102,7 @@ lang: ja オペレーターは、バッチ送信時において、新旧両方のステートルートを送信する必要があります。 古い方のステートルートがオンチェーンのコントラクトにおける既存のステートルートと一致する場合、既存のステートルートを破棄し、新しいステートルートで置き換えます。 -ロールアップのオペレーターはさらに、トランザクションバッチ自体のマークルルートに対してもコミットする必要があります。 これにより、どのユーザーも、[マークル証明](/developers/tutorials/merkle-proofs-for-offline-data-integrity/)を提示することで L1 上のバッチに当該トランザクションが追加されていることを証明することができます。 +ロールアップのオペレーターはさらに、トランザクションバッチ自体のマークルルートに対してもコミットする必要があります。 これにより、どのユーザーも、[マークル証明](/developers/tutorials/merkle-proofs-for-offline-data-integrity/)を提示することでL1上のバッチに当該トランザクションが追加されていることを証明することができます。 状態へのコミットメントは、特にステートルートの場合、オプティミスティック・ロールアップにおける状態遷移の正しさを証明するために必要です。 ロールアップのコントラクトは、オペレーターから送信された時点で新規のステートルートを受け入れますが、無効なステートルートを事後に削除し、ロールアップを正しい状態に復元することが可能です。 @@ -112,67 +112,67 @@ lang: ja アサーションに対して異議が申し立てられると、ロールアップ・プロトコルにより不正証明の計算が開始されます。 不正証明はその種類を問わず双方向性のやりとりを要するため、異議を申し立てるにはまず他のユーザーがアサーションを送信していなければなりません。 不正証明における各アプローチの違いは、その計算を行うにあたり何回のやりとりが必要とされるかです。 -1 回のやりとりを要求する証明スキームでは、異議申立の対象であるトランザクションを L1 上で再生し、無効なアサーションを検出します。 ロールアップのプロトコルでは、異議申立の対象であるトランザクションに対する L1(イーサリアムメインネット)上での再実行につき、検証者のコントラクトを用いてエミュレートし、計算されたステートルートによりこの異議申立における勝者を決定します。 異議申立者によるロールアップの正しい状態についての主張が認められた場合、オペレーターに対してはボンドの没収(スラッシング)によるペナルティが科せられます。 +1回のやりとりを要求する証明スキームでは、異議申立の対象であるトランザクションをL1上で再生し、無効なアサーションを検出します。 ロールアップのプロトコルでは、異議申立の対象であるトランザクションに対するL1(イーサリアムメインネット)上での再実行につき、検証者のコントラクトを用いてエミュレートし、計算されたステートルートによりこの異議申立における勝者を決定します。 異議申立者によるロールアップの正しい状態についての主張が認められた場合、オペレーターに対してはボンドの没収(スラッシング)によるペナルティが科せられます。 -ただし、不正検出のために L1 上でトランザクションを再実行するには、個別トランザクションに対する状態コミットメントを公開しなければならないため、ロールアップがオンチェーン上で公開しなければならないデータ量が増加します。 さらに、トランザクションの再実行はかなりのガス代を伴います。 これらの理由により、オプティミスティック・ロールアップでは複数回にわたるやりとりを通じた証明に移行中であり、これにより、無効なロールアップ操作を検出するという同じ目的をより効率的に実現できるようになるでしょう。 +ただし、不正検出のためにL1上でトランザクションを再実行するには、個別トランザクションに対する状態コミットメントを公開しなければならないため、ロールアップがオンチェーン上で公開しなければならないデータ量が増加します。 さらに、トランザクションの再実行はかなりのガス代を伴います。 これらの理由により、オプティミスティック・ロールアップでは複数回にわたるやりとりを通じた証明に移行中であり、これにより、無効なロールアップ操作を検出するという同じ目的をより効率的に実現できるようになるでしょう。 #### 複数回のやりとりによる証明 {#multi-round-interactive-proving} -複数回のやりとりによる証明では、L1 上の検証者コントラクトがアサーター/チャレンジャー間のやりとりのプロトコルを監視し、このコントラクトが最終的に虚偽のユーザーを決定します。 L2 上のノードが特定のアサーションに対してチャレンジを行うと、このアサーションを行ったアサーターは、異議申立のアサーションを二等分しなければなりません。 これにより、二等分されたアサーションは、それぞれがもう一方のアサーションと同数の計算ステップを含むことになります。 +複数回のやりとりによる証明では、L1上の検証者コントラクトがアサーター/チャレンジャー間のやりとりのプロトコルを監視し、このコントラクトが最終的に虚偽のユーザーを決定します。 L2上のノードが特定のアサーションに対してチャレンジを行うと、このアサーションを行ったアサーターは、異議申立のアサーションを二等分しなければなりません。 これにより、二等分されたアサーションは、それぞれがもう一方のアサーションと同数の計算ステップを含むことになります。 -次にチャレンジャーが、どちらのアサーションに異議を申し立てるかを選択します。 この分割プロセス(「二分割プロトコル」と呼ぶ)は、両当事者による紛争の対象が*単独の*実行ステップに対するアサーションになるまで継続されます。 対象が単独の実行ステップになった時点で、L1 上のコントラクトが不正な当事者を発見するための命令(および結果)を判定し、紛争が解決されます。 +次にチャレンジャーが、どちらのアサーションに異議を申し立てるかを選択します。 この分割プロセス(「二分割プロトコル」と呼ぶ)は、両当事者による紛争の対象が_単独の_実行ステップに対するアサーションになるまで継続されます。 対象が単独の実行ステップになった時点で、L1上のコントラクトが不正な当事者を発見するための命令(および結果)を判定し、紛争が解決されます。 -アサーターは、紛争の対象であるシングルステップ計算の正当性を証明するための「ワンステップ証明」を提供しなければなりません。 アサーターがこのワンステップ証明を提供できない場合、あるいは L1 上の検証者により当該証明が無効であると判定された場合、アサーターの申立は棄却されます。 +アサーターは、紛争の対象であるシングルステップ計算の正当性を証明するための「ワンステップ証明」を提供しなければなりません。 アサーターがこのワンステップ証明を提供できない場合、あるいはL1上の検証者により当該証明が無効であると判定された場合、アサーターの申立は棄却されます。 この種類の不正証明に関する注記: -1. 複数回のやりとりによる不正証明は、L1 チェーン上における紛争仲裁の作業量を最小化できるために効率的だと考えられています。 L1 チェーン上では、トランザクション全体を再生する必要はなく、ロールアップ実行における特定のステップのみを再実行すればよいからです。 +1. 複数回のやりとりによる不正証明は、L1チェーン上における紛争仲裁の作業量を最小化できるために効率的だと考えられています。 L1チェーン上では、トランザクション全体を再生する必要はなく、ロールアップ実行における特定のステップのみを再実行すればよいからです。 -2. 二分割プロトコルは、オンチェーンに送信するデータ量を軽減します(トランザクションごとに状態コミットメントを送信する必要がないためです)。 さらに、オプティミスティック・ロールアップのトランザクションは、イーサリアムのガス上限による制限を受けません。 反対にトランザクションを再実行するオプティミスティック・ロールアップの場合は、イーサリアムメインネット上の 1 回のトランザクションで実行をエミュレートできるように、L2 のトランザクションにおいてガス上限がより低く設定されていることを確認する必要があります。 +2. 二分割プロトコルは、オンチェーンに送信するデータ量を軽減します(トランザクションごとに状態コミットメントを送信する必要がないためです)。 さらに、オプティミスティック・ロールアップのトランザクションは、イーサリアムのガス上限による制限を受けません。 反対にトランザクションを再実行するオプティミスティック・ロールアップの場合は、イーサリアムメインネット上の1回のトランザクションで実行をエミュレートできるように、L2のトランザクションにおいてガス上限がより低く設定されていることを確認する必要があります。 -3. 悪意のアサーターが提供したボンドの一部はチャレンジャーに付与され、残りはバーンされます。 残余のボンドをバーンすることで、バリデータ間の共謀を防ぐことができます。2 名のバリデータが共謀して虚偽のチャレンジを開始した場合、彼らがステーキングした資産のうちかなりの部分が没収されるからです。 +3. 悪意のアサーターが提供したボンドの一部はチャレンジャーに付与され、残りはバーンされます。 残余のボンドをバーンすることで、バリデータ間の共謀を防ぐことができます。2名のバリデータが共謀して虚偽のチャレンジを開始した場合、彼らがステーキングした資産のうちかなりの部分が没収されるからです。 4. 複数回のやりとりによる証明では、アサーターとチャレンジャーの両者は指定された期間内にアクションを実行する必要があります。 期限までにアクションを実行しない場合、不履行の当事者の主張が退けられます。 #### オプティミスティック・ロールアップにおいて不正証明が重要である理由 {#fraud-proof-benefits} -不正証明は、オプティミスティック・ロールアップにおいて*トラストレスなファイナリティ*を強化する上で重要です。 トラストレスなファイナリティとは、有効なトランザクションは最終的に承認されるというオプティミスティック・ロールアップの特性を指す概念です。 +不正証明は、オプティミスティック・ロールアップにおいて_トラストレスなファイナリティ_を強化する上で重要です。 トラストレスなファイナリティとは、有効なトランザクションは最終的に承認されるというオプティミスティック・ロールアップの特性を指す概念です。 悪意のノードは、正当なロールアップブロックに対して、虚偽のチャレンジを開始することでその正当性確認を遅延させることができます。 しかし最終的に、不正証明によりロールアップブロックの正当性が証明され、有効化されます。 -この点は同時に、正直なノードが少なくとも*1 つ*存在しなければロールアップチェーンの正当性を保持できないという、オプティミスティック・ロールアップにおけるもう一つのセキュリティ特性に関連しています。 正直なノードは、有効なアサーションを送信するか、無効なアサーションに対して異議申立を行うことで、チェーンを適切に前進させることができます。 いずれの場合でも、正直なノードに対して異議を申し立てる悪意のノードは、不正証明プロセスを通じてステークを失うことになります。 +この点は同時に、正直なノードが少なくとも_1つ_存在しなければロールアップチェーンの正当性を保持できないという、オプティミスティック・ロールアップにおけるもう一つのセキュリティ特性に関連しています。 正直なノードは、有効なアサーションを送信するか、無効なアサーションに対して異議申立を行うことで、チェーンを適切に前進させることができます。 いずれの場合でも、正直なノードに対して異議を申し立てる悪意のノードは、不正証明プロセスを通じてステークを失うことになります。 -### L1 と L2 の相互運用性 {#l1-l2-interoperability} +### L1とL2の相互運用性 {#l1-l2-interoperability} -オプティミスティック・ロールアップは、イーサリアムメインネットとの相互運用性を念頭において開発されており、ユーザーはメッセージや任意のデータを L1/L2 間でやりとりできます。 また、EVM との互換性も提供されるため、既存の[Dapp](/developers/docs/dapps/)をオプティミスティック・ロールアップに移植したり、イーサリアム開発ツールを用いて新規の Dapp を開発することができます。 +オプティミスティック・ロールアップは、イーサリアムメインネットとの相互運用性を念頭において開発されており、ユーザーはメッセージや任意のデータをL1/L2間でやりとりできます。 また、EVMとの互換性も提供されるため、既存の[Dapp](/developers/docs/dapps/)をオプティミスティック・ロールアップに移植したり、イーサリアム開発ツールを用いて新規のDappを開発することができます。 #### 1. 資産の移動 {#asset-movement} ##### ロールアップに参加する -オプティミスティック・ロールアップの利用を開始するには、当該ロールアップの L1 上の[ブリッジ](/developers/docs/bridges/)コントラクトに対して、ETH、ERC-20 トークン、あるいはその他の受け入れ可能な資産を入金します。 このブリッジコントラクトは、当該トランザクションを L2 にリレーし、L2 において同価値の資産をミントした上で、ユーザーがオプティミスティック・ロールアップで指定したアドレスにその資産を送信します。 +オプティミスティック・ロールアップの利用を開始するには、当該ロールアップのL1上の[ブリッジ](/developers/docs/bridges/)コントラクトに対して、ETH、ERC-20トークン、あるいはその他の受け入れ可能な資産を入金します。 このブリッジコントラクトは、当該トランザクションをL2にリレーし、L2において同価値の資産をミントした上で、ユーザーがオプティミスティック・ロールアップで指定したアドレスにその資産を送信します。 -ユーザーが作成したトランザクション(L1 から L2 への入金など)は通常、シーケンサーがロールアップのコントラクトに再提出するまではキュー上で保留されます。 ただし、検閲耐性を維持するために、キュー保留の上限期間を超えて遅延した場合は、トランザクションをオンチェーンのロールアップコントラクトに直接送信することが認められています。 +ユーザーが作成したトランザクション(L1からL2への入金など)は通常、シーケンサーがロールアップのコントラクトに再提出するまではキュー上で保留されます。 ただし、検閲耐性を維持するために、キュー保留の上限期間を超えて遅延した場合は、トランザクションをオンチェーンのロールアップコントラクトに直接送信することが認められています。 -一部のオプティミスティック・ロールアップでは、シーケンサーによるユーザーの検閲を防止するためにより明確なアプローチが採用されています。 このアプローチを採用したロールアップでは、ロールアップチェーン上で処理されたトランザクションに加えて、直前のブロック(例:入金)以降に L1 上のコントラクトに送信されたすべてのトランザクションにより、ブロックが定義されます。 シーケンサーが L1 上のトランザクションを無視する場合、(おそらく)正しくないステートルートを公開することになるため、シーケンサーは、ユーザーが作成したメッセージを L1 に送信した以降にこれを遅延することが不可能になります。 +一部のオプティミスティック・ロールアップでは、シーケンサーによるユーザーの検閲を防止するためにより明確なアプローチが採用されています。 このアプローチを採用したロールアップでは、ロールアップチェーン上で処理されたトランザクションに加えて、直前のブロック(例:入金)以降にL1上のコントラクトに送信されたすべてのトランザクションにより、ブロックが定義されます。 シーケンサーがL1上のトランザクションを無視する場合、(おそらく)正しくないステートルートを公開することになるため、シーケンサーは、ユーザーが作成したメッセージをL1に送信した以降にこれを遅延することが不可能になります。 ##### ロールアップから出金する -不正証明スキームが存在するため、オプティミスティック・ロールアップからイーサリアムに出金するプロセスはより複雑になっています。 L1 にエスクローされた資金を引き出すために L2 から L1 へのトランザクションを開始する場合、ユーザーは約 7 日間のチャレンジ期間が経過するのを待つ必要があります。 それ以外の点では、出金プロセス自体は非常にシンプルです。 +不正証明スキームが存在するため、オプティミスティック・ロールアップからイーサリアムに出金するプロセスはより複雑になっています。 L1にエスクローされた資金を引き出すためにL2からL1へのトランザクションを開始する場合、ユーザーは約7日間のチャレンジ期間が経過するのを待つ必要があります。 それ以外の点では、出金プロセス自体は非常にシンプルです。 -L2 上のロールアップで出金リクエストを開始すると、当該トランザクションが次のバッチに追加され、ロールアップ上のユーザー資産がバーンされます。 このバッチがイーサリアム上で公開されると、ユーザーは、ブロックに出金トランザクションが含まれることを証明するマークル証明を計算できるようになります。 その上で、遅延期間の終了と共に、L1 上でトランザクションが確定し、メインネットに資金を移動させることができます。 +L2上のロールアップで出金リクエストを開始すると、当該トランザクションが次のバッチに追加され、ロールアップ上のユーザー資産がバーンされます。 このバッチがイーサリアム上で公開されると、ユーザーは、ブロックに出金トランザクションが含まれることを証明するマークル証明を計算できるようになります。 その上で、遅延期間の終了と共に、L1上でトランザクションが確定し、メインネットに資金を移動させることができます。 -イーサリアムメインネットへの出金において要求される 1 週間の待機期間を回避するために、オプティミスティック・ロールアップのユーザーは**流動性プロバイダー**(LP)を利用することもできます。 流動性プロバイダーとは、手数料を代価として、保留されている L2 からの出金に対して所有権を引き継ぎ、L1 上でユーザーに資金を提供するサービスです。 +イーサリアムメインネットへの出金において要求される1週間の待機期間を回避するために、オプティミスティック・ロールアップのユーザーは**流動性プロバイダー**(LP)を利用することもできます。 流動性プロバイダーとは、手数料を代価として、保留されているL2からの出金に対して所有権を引き継ぎ、L1上でユーザーに資金を提供するサービスです。 流動性プロバイダーは、自ら当該チェーンを実行してユーザーの出金リクエストの正当性を確認した上で、資金を提供します。 これにより、流動性プロバイダーはこのトランザクションが最終的には承認されるとの保証(つまり、トラストレスなファイナリティ)を得ることができます。 -#### 2. EVM との互換性 {#evm-compatibility} +#### 2. EVMとの互換性 {#evm-compatibility} -デベロッパーにとってのオプティミスティック・ロールアップの優位性は、[イーサリアム仮想マシン(EVM)](/developers/docs/evm/)との互換性、あるいは等価性にあります。 EVM 互換のロールアップは、[イーサリアム・イエローペーパー](https://ethereum.github.io/yellowpaper/paper.pdf)の仕様に準拠しており、バイトコードの水準で EVM をサポートします。 +デベロッパーにとってのオプティミスティック・ロールアップの優位性は、[イーサリアム仮想マシン(EVM)](/developers/docs/evm/)との互換性、あるいは等価性にあります。 EVM互換のロールアップは、[イーサリアム・イエローペーパー](https://ethereum.github.io/yellowpaper/paper.pdf)の仕様に準拠しており、バイトコードの水準でEVMをサポートします。 -オプティミスティック・ロールアップの EVM 互換性は、次のような利点を持ちます: +オプティミスティック・ロールアップのEVM互換性は、次のような利点を持ちます: -i. デベロッパーは、イーサリアム上の既存のスマートコントラクトにつき、コードベースを大幅に修正せずにオプティミスティック・ロールアップのチェーンに移植できます。 これにより、イーサリアムのスマートコントラクトを L2 上でデプロイする時間を節約できます。 +i. デベロッパーは、イーサリアム上の既存のスマートコントラクトにつき、コードベースを大幅に修正せずにオプティミスティック・ロールアップのチェーンに移植できます。 これにより、イーサリアムのスマートコントラクトをL2上でデプロイする時間を節約できます。 ii. オプティミスティック・ロールアップを使用するデベロッパーやプロジェクトチームは、イーサリアムメインネットのインフラを活用できます。 具体的には、プログラム言語、コードライブラリ、テストツール、クライアントソフトウェア、デプロイ用のインフラなどが活用できます。 @@ -180,78 +180,78 @@ ii. オプティミスティック・ロールアップを使用するデベロ #### 3. クロスチェーンにおけるコントラクトの呼び出し {#cross-chain-contract-calls} -ユーザー(外部所有アカウント)が L2 上のコントラクトとやりとりを行うには、ロールアップ上のコントラクトにトランザクションを送信するか、あるいはこの作業をシーケンサーまたはバリデータに委任する必要があります。 オプティミスティック・ロールアップの場合はさらに、L1/L2 間のメッセージのリレーやデータの受け渡しにブリッジコントラクトを使用して、L2 上のコントラクトとのやりとりを行えます。 つまり、イーサリアムメインネット上の L1 コントラクトにおいて、L2 のオプティミスティック・ロールアップ上のコントラクトに含まれる機能を呼び出せるようにプログラムすることが可能です。 +ユーザー(外部所有アカウント)がL2上のコントラクトとやりとりを行うには、ロールアップ上のコントラクトにトランザクションを送信するか、あるいはこの作業をシーケンサーまたはバリデータに委任する必要があります。 オプティミスティック・ロールアップの場合はさらに、L1/L2間のメッセージのリレーやデータの受け渡しにブリッジコントラクトを使用して、L2上のコントラクトとのやりとりを行えます。 つまり、イーサリアムメインネット上のL1コントラクトにおいて、L2のオプティミスティック・ロールアップ上のコントラクトに含まれる機能を呼び出せるようにプログラムすることが可能です。 -このようなクロスチェーンのコントラクトでは、呼び出しが非同期で実行されます。つまり、呼び出しと実行の間に一定の時間が経過します。 この点は、呼び出された時点でただちに実行されるイーサリアム上の 2 つのコントラクト間の呼び出しとは異なります。 +このようなクロスチェーンのコントラクトでは、呼び出しが非同期で実行されます。つまり、呼び出しと実行の間に一定の時間が経過します。 この点は、呼び出された時点でただちに実行されるイーサリアム上の2つのコントラクト間の呼び出しとは異なります。 -クロスチェーンのコントラクト呼び出しの例としては、上述したトークンの入金が挙げられます。 L1 上のコントラクトは、ユーザーのトークンをエスクローすると共に、L2 の対応したコントラクトに対して、ロールアップ上で同額のトークンをミントするように指示するメッセージを送信します。 +クロスチェーンのコントラクト呼び出しの例としては、上述したトークンの入金が挙げられます。 L1上のコントラクトは、ユーザーのトークンをエスクローすると共に、L2の対応したコントラクトに対して、ロールアップ上で同額のトークンをミントするように指示するメッセージを送信します。 -クロスチェーンのメッセージ呼び出しはコントラクトの実行を伴いますが、通常は、計算に伴い発生する[ガス代](/developers/docs/gas/)は送信元が負担する必要があります。 ターゲットのチェーンにおいてトランザクションが失敗するのを防ぐために、ガス代の上限を高く設定することが推奨されます。 この点については、トークンをブリッジングするシナリオを想起すればよいでしょう。トランザクションにおける L1 側の作業(トークンの入金)がうまく行っても、L2 側の作業(新規トークンのミント)がガス代不足により実行されなければ、入金した資産は回収不能になります。 +クロスチェーンのメッセージ呼び出しはコントラクトの実行を伴いますが、通常は、計算に伴い発生する[ガス代](/developers/docs/gas/)は送信元が負担する必要があります。 ターゲットのチェーンにおいてトランザクションが失敗するのを防ぐために、ガス代の上限を高く設定することが推奨されます。 この点については、トークンをブリッジングするシナリオを想起すればよいでしょう。トランザクションにおけるL1側の作業(トークンの入金)がうまく行っても、L2側の作業(新規トークンのミント)がガス代不足により実行されなければ、入金した資産は回収不能になります。 -最後に、複数のコントラクト間における L2 から L1 へのメッセージ呼び出しにおいては、遅延の発生を考慮する必要があります(L1 から L2 への呼び出しは、通常数分後に実行されます)。 オプティミスティック・ロールアップからメインネットに送信されるメッセージは、チャレンジ期間が経過するまで実行できないためです。 +最後に、複数のコントラクト間におけるL2からL1へのメッセージ呼び出しにおいては、遅延の発生を考慮する必要があります(L1からL2への呼び出しは、通常数分後に実行されます)。 オプティミスティック・ロールアップからメインネットに送信されるメッセージは、チャレンジ期間が経過するまで実行できないためです。 ## オプティミスティック・ロールアップにおける手数料の仕組み {#how-do-optimistic-rollup-fees-work} -オプティミスティック・ロールアップでは、トランザクション 1 件ごとのユーザー手数料を表示するために、イーサリアムとほぼ同様のガス料金スキームを採用しています。 オプティミスティック・ロールアップで請求される手数料は、以下の要素により決定されます: +オプティミスティック・ロールアップでは、トランザクション1件ごとのユーザー手数料を表示するために、イーサリアムとほぼ同様のガス料金スキームを採用しています。 オプティミスティック・ロールアップで請求される手数料は、以下の要素により決定されます: -1. **状態の書き込み**: オプティミスティック・ロールアップでは、トランザクションデータおよびブロックヘッダー(直前のブロックにおけるヘッダーハッシュ、ステートルート、およびバッチルート)を、`calldata`としてイーサリアムメインネットに送信します。 イーサリアムにおけるトランザクション 1 件の最低コストは 21,000 ガスです。 オプティミスティック・ロールアップでは、複数のトランザクションを 1 つのブロックにバッチ化することで、L1 にトランザクションを書き込む費用を軽減しています(これにより、21,000 ガスを複数のユーザートランザクションで分割することができます)。 +1. **状態の書き込み**: オプティミスティック・ロールアップでは、トランザクションデータおよびブロックヘッダー(直前のブロックにおけるヘッダーハッシュ、ステートルート、およびバッチルート)を、`calldata`としてイーサリアムメインネットに送信します。 イーサリアムにおけるトランザクション1件の最低コストは21,000ガスです。 オプティミスティック・ロールアップでは、複数のトランザクションを1つのブロックにバッチ化することで、L1にトランザクションを書き込む費用を軽減しています(これにより、21,000ガスを複数のユーザートランザクションで分割することができます)。 -2. **`calldata`**:基本的なトランザクション料金を越える費用については、個別の状態書き込みにおける費用は L1 に送信される`calldata`のサイズで決定されます。 現在、`calldata`の費用は[EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)によって管理されています。`calldata`がゼロバイト以上であれば 16 ガス、ゼロバイトの場合は 4 ガスの費用が発生します。 ロールアップ事業者は、ユーザー手数料を軽減するためにトランザクションデータを圧縮し、イーサリアムに送信される`calldata`のバイト数を減らしています。 +2. **`calldata`**:基本的なトランザクション料金を越える費用については、個別の状態書き込みにおける費用はL1に送信される`calldata`のサイズで決定されます。 現在、`calldata`の費用は[EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)によって管理されています。`calldata`がゼロバイト以上であれば16ガス、ゼロバイトの場合は4ガスの費用が発生します。 ロールアップ事業者は、ユーザー手数料を軽減するためにトランザクションデータを圧縮し、イーサリアムに送信される`calldata`のバイト数を減らしています。 -3. **L2 オペレーターに対する手数料**: これは、イーサリアムにおけるマイナー手数料と同様に、トランザクション処理において発生する計算コストの代価としてロールアップのノードに支払われる報酬です。 L2 は処理能力が比較的高く、イーサリアムの場合のようにネットワークの混雑によりマイナーが高額な手数料を伴うトランザクションを優先的に処理するという状況が発生していないため、ロールアップのノードが請求するトランザクション手数料は比較的安価になっています。 +3. **L2オペレーターに対する手数料**: イーサリアムにおけるガス代と同様に、トランザクション処理において発生する計算コストの代価としてロールアップのノードに支払われる報酬です。 L2は処理能力が比較的高く、イーサリアムの場合のようにネットワークの混雑によりバリデータが高額な手数料を伴うトランザクションを優先的に処理するという状況が発生していないため、ロールアップのノードが請求するトランザクション手数料は比較的安価になっています。 -オプティミスティック・ロールアップにおいてユーザー手数料を引き下げるために導入されているメカニズムとしては、トランザクションのバッチ処理や、データ公開コストを軽減するための`calldata`の圧縮などがあります。 [L2 手数料トラッカー](https://l2fees.info/)を使えば、イーサリアムベースのオプティミスティック・ロールアップで発生する使用手数料をリアルタイムで確認できます。 +オプティミスティック・ロールアップにおいてユーザー手数料を引き下げるために導入されているメカニズムとしては、トランザクションのバッチ処理や、データ公開コストを軽減するための`calldata`の圧縮などがあります。 [L2手数料トラッカー](https://l2fees.info/)を使えば、イーサリアムベースのオプティミスティック・ロールアップで発生する使用手数料をリアルタイムで確認できます。 ## オプティミスティック・ロールアップは、どのようにイーサリアムのスケーラビリティを向上させるのか? {#scaling-ethereum-with-optimistic-rollups} 上述したように、オプティミスティック・ロールアップでは、圧縮したトランザクションデータをイーサリアムに送信して公開することで、データの可用性を保証します。 オンチェーン上で圧縮データを公開する機能は、オプティミスティック・ロールアップを通じてイーサリアムのスループットを拡大させる上で不可欠なものです。 -メインのイーサリアムチェーンは、各ブロックが保持できるデータ量に制限があり、これはガス単位で表示されます([平均のブロックサイズ](/developers/docs/blocks/#block-size)は 1,500 万ガスです)。 これは、各トランザクションにおいて使用できるガスに上限があることを意味すると同時に、トランザクションデータの圧縮によりブロックごとに処理されるトランザクションの数を増やし、直接的にスケーラビリティを向上させられることを意味します。 +メインのイーサリアムチェーンは、各ブロックが保持できるデータ量に制限があり、これはガス単位で表示されます([平均のブロックサイズ](/developers/docs/blocks/#block-size)は1,500万ガスです)。 これは、各トランザクションにおいて使用できるガスに上限があることを意味すると同時に、トランザクションデータの圧縮によりブロックごとに処理されるトランザクションの数を増やし、直接的にスケーラビリティを向上させられることを意味します。 -オプティミスティック・ロールアップでは、トランザクションデータを圧縮し、TPS レートを向上させる上で、いくつかの手法を用いています。 例えば この[記事](https://vitalik.eth.limo/general/2021/01/05/rollup.html)では、メインネット上の基本的なユーザートランザクション (Ether の送信)で生成されるデータ量と、ロールアップ上で同一のトランザクションが生成するデータ量を比較しています: +オプティミスティック・ロールアップでは、トランザクションデータを圧縮し、TPSレートを向上させる上で、いくつかの手法を用いています。 例えば この[記事](https://vitalik.ca/general/2021/01/05/rollup.html)では、メインネット上の基本的なユーザートランザクション (Etherの送信)で生成されるデータ量と、ロールアップ上で同一のトランザクションが生成するデータ量を比較しています: -| パラメータ | イーサリアム (L1) | ロールアップ (L2) | -| ---------- | ----------------- | ----------------- | -| ノンス | 〜3 | 0 | -| ガス価格 | 〜8 | 0 ~ 0.5 | -| ガス | 3 | 0 ~ 0.5 | -| To | 21 | 4 | -| 値 | 9 | 約 3 | -| 署名 | 〜68(2+33+33) | 〜0.5 | -| From | 0(署名から復元) | 4 | -| **合計** | **約 112 バイト** | **約 12 バイト** | +| パラメータ | イーサリアム (L1) | ロールアップ (L2) | +| ------ | ------------ | ----------- | +| ノンス | 〜3 | 0 | +| ガス価格 | 〜8 | 0~0.5 | +| ガス | 3 | 0~0.5 | +| To | 21 | 4 | +| 値 | 9 | 約3 | +| 署名 | 〜68(2+33+33) | 〜0.5 | +| From | 0(署名から復元) | 4 | +| **合計** | **約112バイト** | **約12バイト** | これらの数値を基にした大まかな計算により、オプティミスティック・ロールアップがどの程度スケーラビリティに貢献するのかを知ることができます: -1. 各ブロックのターゲットサーイズは 1,500 万ガスで、1 バイトのデータ検証には 16 ガスが必要です。 平均ブロックサイズを 16 ガスで割ると (15,000,000/16) 、平均サイズのブロックは**937,500 バイトのデータを保持できる**ことになります。 -2. ロールアップにおける基本的なトランザクションが 12 バイトを使用する場合、イーサリアムの平均的なブロックは**78,125 件のロールアップ・トランザクション**あるいは**39 件のロールアップバッチ**(各バッチが平均 2,000 件のトランザクションを持つ場合)を処理できます。 -3. イーサリアムで 15 秒ごとに新しいブロックが生成されるとすると、ロールアップの処理速度は、**1 秒間に約 5,208 件のトランザクション**に相当します。 これは、イーサリアムにおける 1 つのブロックが保持できる基本的なロールアップのトランザクション数(**78,125**)を平均のブロック時間(**15 秒**)で割ることで算出できます。 +1. 各ブロックのターゲットサーイズは1,500万ガスで、1バイトのデータ検証には16ガスが必要です。 平均ブロックサイズを16ガスで割ると (15,000,000/16) 、平均サイズのブロックは**937,500バイトのデータを保持できる**ことになります。 +2. ロールアップにおける基本的なトランザクションが12バイトを使用する場合、イーサリアムの平均的なブロックは**78,125件のロールアップ・トランザクション**あるいは**39件のロールアップバッチ**(各バッチが平均2,000件のトランザクションを持つ場合)を処理できます。 +3. イーサリアムで15秒ごとに新しいブロックが生成されるとすると、ロールアップの処理速度は、**1秒間に約5,208件のトランザクション**に相当します。 これは、イーサリアムにおける1つのブロックが保持できる基本的なロールアップのトランザクション数(**78,125**)を平均のブロック時間(**15秒**)で割ることで算出できます。 -イーサリアム上のブロック全体がすべてオプティミスティック・ロールアップのトランザクションである可能性はないため、この数値はかなり楽観的な推測です。 しかし、オプティミスティック・ロールアップによってイーサリアムのユーザーどれだけスケーラビリティを獲得できるかについて、おおよその見当をつけることができます(現在の実装では最大 2,000TPS を実現しています)。 +イーサリアム上のブロック全体がすべてオプティミスティック・ロールアップのトランザクションである可能性はないため、この数値はかなり楽観的な推測です。 しかし、オプティミスティック・ロールアップによってイーサリアムのユーザーどれだけスケーラビリティを獲得できるかについて、おおよその見当をつけることができます(現在の実装では最大2,000TPSを実現しています)。 -イーサリアムにおける[データシャーディング](/upgrades/shard-chains/)の導入により、オプティミスティック・ロールアップにおけるスケーラビリティも向上すると期待されます。 ロールアップ上のトランザクションは、ロールアップ以外の他のトランザクションとブロックスペースを共有しなければならないため、メインのイーサリアムチェーンにおけるデータのスループットにより処理能力が制限されます。 シャーディングにより L2 チェーン上でブロックごとにデータを公開できるスペースが増大するため、ロールアップのスループットがさらに向上するでしょう。 +イーサリアムに[データシャーディング](/roadmap/danksharding/)が導入されると、オプティミスティック・ロールアップのスケーラビリティも向上すると期待されています。 ロールアップ上のトランザクションは、ロールアップ以外の他のトランザクションとブロックスペースを共有しなければならないため、メインのイーサリアムチェーンにおけるデータのスループットにより処理能力が制限されます。 ダンクシャーディングでは、高価で永続的な`CALLDATA`の代わりに、安価で非永続的な 「ブロブ」 ストレージを使用して、ブロックごとにデータを公開します。そのために、L2チェーンが利用できるスペースを増やします。 ### オプティミスティック・ロールアップの長所と短所 {#optimistic-rollups-pros-and-cons} -| 長所 | 短所 | -| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| セキュリティやトラストレス性を犠牲にすることなく、スケーラビリティが大幅に向上する。 | 虚偽の異議申立により、トランザクションに遅延が発生する可能性がある。 | -| トランザクションデータは L1 チェーン上で保存されるため、透明性、セキュリティ、検閲耐性、および分散化が向上する。 | ロールアップにおける中央集権的なオペレーター(シーケンサー)により、トランザクションの順序が影響を受ける可能性がある。 | -| 不正証明により、トラストレスなファイナリティが保証され、少数の正直なユーザーによりチェーンのセキュリティを保護できる。 | 正直なノードが存在しない場合、悪意のオペレーターが無効なブロックや状態コミットメントを送信することで資金を盗み取れる。 | -| 特別なハードウェアを必要とする有効性証明(ゼロ知識ロールアップで用いる)とは異なり、不正証明の計算は L2 上の通常ノードが実行できる。 | 少なくとも 1 つの正直なノードがロールアップのトランザクションを実行し、不正証明を送信して無効な状態遷移に異議を申し立てるというセキュリティモデルに依存している。 | -| トラストレスなライブネスによる利益がある(つまり、どのユーザーでもトランザクションを実行し、アサーションを送信することでチェーンを前に進められる)。 | イーサリアムに資金が出金されるまでに、1 週間のチャレンジ期間が必要になる。 | -| チェーンのセキュリティを強化するために、よく設計された暗号経済的なインセンティブを導入している。 | すべてのトランザクションデータをオンチェーンに送信しなければならないため、費用がかさむ可能性がある。 | -| EVM および Solidity との互換性により、イーサリアムのネイティブスマートコントラクトをロールアップに移植したり、既存ツールを用いて新たな Dapp を構築できる。 | | +| 長所 | 短所 | +| ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| セキュリティやトラストレス性を犠牲にすることなく、スケーラビリティが大幅に向上する。 | 虚偽の異議申立により、トランザクションに遅延が発生する可能性がある。 | +| トランザクションデータはL1チェーン上で保存されるため、透明性、セキュリティ、検閲耐性、および分散化が向上する。 | ロールアップにおける中央集権的なオペレーター(シーケンサー)により、トランザクションの順序が影響を受ける可能性がある。 | +| 不正証明により、トラストレスなファイナリティが保証され、少数の正直なユーザーによりチェーンのセキュリティを保護できる。 | 正直なノードが存在しない場合、悪意のオペレーターが無効なブロックや状態コミットメントを送信することで資金を盗み取れる。 | +| 特別なハードウェアを必要とする有効性証明(ゼロ知識ロールアップで用いる)とは異なり、不正証明の計算はL2上の通常ノードが実行できる。 | 少なくとも1つの正直なノードがロールアップのトランザクションを実行し、不正証明を送信して無効な状態遷移に異議を申し立てるというセキュリティモデルに依存している。 | +| トラストレスなライブネスによる利益がある(つまり、どのユーザーでもトランザクションを実行し、アサーションを送信することでチェーンを前に進められる)。 | イーサリアムに資金が出金されるまでに、1週間のチャレンジ期間が必要になる。 | +| チェーンのセキュリティを強化するために、よく設計された暗号経済的なインセンティブを導入している。 | すべてのトランザクションデータをオンチェーンに送信しなければならないため、費用がかさむ可能性がある。 | +| EVMおよびSolidityとの互換性により、イーサリアムのネイティブスマートコントラクトをロールアップに移植したり、既存ツールを用いて新たなDappを構築できる。 | | ### オプティミスティック・ロールアップに関する説明動画 {#optimistic-video} -映像で学びたい方は、 Finematics によるオプティミスティック・ロールアップの説明をご覧ください: +映像で学びたい方は、 Finematicsによるオプティミスティック・ロールアップの説明をご覧ください: ### オプティミスティック・ロールアップの使用方法 {#use-optimistic-rollups} -Dapp に統合可能な、既存のオプティミスティック・ロールアップの実装が提供されています: +Dappに統合可能な、既存のオプティミスティック・ロールアップの実装が提供されています: @@ -259,7 +259,7 @@ Dapp に統合可能な、既存のオプティミスティック・ロールア - [オプティミスティック・ロールアップの仕組み(完全ガイド)](https://www.alchemy.com/overviews/optimistic-rollups) - [オプティミスティック・ロールアップについて必要なすべての知識](https://research.paradigm.xyz/rollups) -- [Arbitrum の基本ガイド](https://newsletter.banklesshq.com/p/the-essential-guide-to-arbitrum) -- [Optimism のロールアップはどのように機能するのか?](https://www.paradigm.xyz/2021/01/how-does-optimisms-rollup-really-work) -- [OVM の詳細を学ぶ](https://medium.com/ethereum-optimism/ovm-deep-dive-a300d1085f52) +- [Arbitrumの基本ガイド](https://newsletter.banklesshq.com/p/the-essential-guide-to-arbitrum) +- [Optimismのロールアップはどのように機能するのか?](https://www.paradigm.xyz/2021/01/how-does-optimisms-rollup-really-work) +- [OVMの詳細を学ぶ](https://medium.com/ethereum-optimism/ovm-deep-dive-a300d1085f52) - [オプティミスティック仮想マシンとは何か?](https://www.alchemy.com/overviews/optimistic-virtual-machine) diff --git a/public/content/translations/ja/developers/docs/scaling/plasma/index.md b/public/content/translations/ja/developers/docs/scaling/plasma/index.md index 8071743b60b..42e0d5e280d 100644 --- a/public/content/translations/ja/developers/docs/scaling/plasma/index.md +++ b/public/content/translations/ja/developers/docs/scaling/plasma/index.md @@ -26,13 +26,13 @@ sidebarDepth: 3 ### オフチェーンでの計算 {#off-chain-computation} -イーサリアムにおける現在の処理速度は、毎秒 15〜20 トランザクションが限界であり、短期的により多くのユーザーに対応するためのスケーラビリティが実現できる見通しは低いと言わざるを得ません。 この問題は主に、イーサリアムの[コンセンサス・メカニズム](/developers/docs/consensus-mechanisms/)では、ブロックチェーンの状態更新が発生するたびに、多くのノードがピアツーピアで検証しなければならないためです。 +イーサリアムにおける現在の処理速度は、毎秒15〜20トランザクションが限界であり、短期的により多くのユーザーに対応するためのスケーラビリティが実現できる見通しは低いと言わざるを得ません。 この問題は主に、イーサリアムの[コンセンサス・メカニズム](/developers/docs/consensus-mechanisms/)では、ブロックチェーンの状態更新が発生するたびに、多くのノードがピアツーピアで検証しなければならないためです。 -イーサリアムのコンセンサス・メカニズムはセキュリティを維持する上で必要ですが、あらゆるユースケースで必須なわけではありません。 例えば、アリスがボブに対して毎日 1 杯のコーヒー代を支払うという取引の場合、二人の間には一定の信頼関係があるため、イーサリアムのネットワーク全体でこれを検証する必要はないでしょう。 +イーサリアムのコンセンサス・メカニズムはセキュリティを維持する上で必要ですが、あらゆるユースケースで必須なわけではありません。 例えば、アリスがボブに対して毎日1杯のコーヒー代を支払うという取引の場合、二人の間には一定の信頼関係があるため、イーサリアムのネットワーク全体でこれを検証する必要はないでしょう。 プラズマでは、イーサリアムメインネットがすべてのトランザクションを検証する必要はないと前提します。 トランザクションをメインネット外で処理することで、ノードはすべてのトランザクションを検証する責任から解放されます。 -プラズマチェーンでは、処理速度とコストを最適化するためにオフチェーンでの計算が必須になります。 例えば、大部分のプラズマチェーンでは、トランザクションの順位付けと実行を管理する役割を、1 名の「オペレーター」に担わせています。 トランザクションを検証する役割を 1 つのエンティティのみに負わせることで、プラズマチェーンは処理時間をメインネットよりも短縮できるのです。 +プラズマチェーンでは、処理速度とコストを最適化するためにオフチェーンでの計算が必須になります。 例えば、大部分のプラズマチェーンでは、トランザクションの順位付けと実行を管理する役割を、1名の「オペレーター」に担わせています。 トランザクションを検証する役割を1つのエンティティのみに負わせることで、プラズマチェーンは処理時間をメインネットよりも短縮できるのです。 ### ステートコミットメント {#state-commitments} @@ -42,7 +42,7 @@ sidebarDepth: 3 マークルルートとは、大容量の情報を圧縮することができる暗号プリミティブです。 マークルルート(この文脈では「ブロックルート」とも呼びます)は、ひとつのブロックに含まれるすべてのトランザクションを表すことができます。 また、マークルルートを用いることで、あるデータセットの小規模な一部分に基づき全体を簡単に検証することができます。 例えばユーザーは、[マークル証明](/developers/tutorials/merkle-proofs-for-offline-data-integrity/#main-content)を生成して、対象のトランザクションが特定のブロックに追加されたことを証明することができます。 -マークルルートは、オフチェーンの状態についての情報をイーサリアムに提供する上で重要な役割を果たします。 マークルルートは、「特定の時点で保存したもの」と考えることができます。オペレーターは、「これがX時点におけるプラズマチェーンの状態であり、これがその証拠であるマークルルートです」とメインネットに伝えるのです。 オペレーターは、マークルルートによってプラズマチェーンの*現在の状態*にコミットすることになるので、これを「状態コミットメント」と呼びます。 +マークルルートは、オフチェーンの状態についての情報をイーサリアムに提供する上で重要な役割を果たします。 マークルルートは、「特定の時点で保存したもの」と考えることができます。オペレーターは、「これがX時点におけるプラズマチェーンの状態であり、これがその証拠であるマークルルートです」とメインネットに伝えるのです。 オペレーターは、マークルルートによってプラズマチェーンの_現在の状態_にコミットすることになるので、これを「状態コミットメント」と呼びます。 ### プラズマチェーンへの参加と退出 {#entries-and-exits} @@ -52,19 +52,19 @@ sidebarDepth: 3 #### プラズマチェーンに参加するには {#entering-the-plasma-chain} -ユーザー(以下では、アリスと呼びます)がプラズマチェーンに参加するには、プラズマコントラクトに ETH あるいはその他の ERC-20 トークンを入金する必要があります。 コントラクトへの入金を監視するプラズマのオペレーターは、アリスが初回に行った入金と同額を作成し、プラズマチェーン上のアリスのアドレスにリリースします。 アリスは、プラズマチェーン(子チェーン)上でこの資金を受け取ったことを確認することが義務付けられており、その上で、他のトランザクションでこの資金を使うことができます。 +ユーザー(以下では、アリスと呼びます)がプラズマチェーンに参加するには、プラズマコントラクトにETHあるいはその他のERC-20トークンを入金する必要があります。 コントラクトへの入金を監視するプラズマのオペレーターは、アリスが初回に行った入金と同額を作成し、プラズマチェーン上のアリスのアドレスにリリースします。 アリスは、プラズマチェーン(子チェーン)上でこの資金を受け取ったことを確認することが義務付けられており、その上で、他のトランザクションでこの資金を使うことができます。 #### プラズマチェーンから退出するには {#exiting-the-plasma-chain} -プラズマチェーンからの退出プロセスは、いくつかの理由により参加時よりも複雑です。 最大の理由は、イーサリアムは当該プラズマチェーンの状態について情報を持つものの、その情報が正しいかどうか検証できないためです。 つまり、悪意のユーザーは、正しくない主張(「私は 1,000 ETH を所有している」)と述べて、この主張を裏付けるために虚偽の証明を提出することで詐欺を働くことができるのです。 +プラズマチェーンからの退出プロセスは、いくつかの理由により参加時よりも複雑です。 最大の理由は、イーサリアムは当該プラズマチェーンの状態について情報を持つものの、その情報が正しいかどうか検証できないためです。 つまり、悪意のユーザーは、正しくない主張(「私は1,000 ETHを所有している」)と述べて、この主張を裏付けるために虚偽の証明を提出することで詐欺を働くことができるのです。 -このような悪意のユーザーによる資金の引き出しを防ぐために、「チャレンジ期間」という仕組みが導入されています。 チャレンジ期間(通常は 1 週間)においては、すべてのユーザーが出金リクエストに対して不正証明を用いて異議を申し立てることができます。 異議申立が認められれば、出金リクエストは却下されます。 +このような悪意のユーザーによる資金の引き出しを防ぐために、「チャレンジ期間」という仕組みが導入されています。 チャレンジ期間(通常は1週間)においては、すべてのユーザーが出金リクエストに対して不正証明を用いて異議を申し立てることができます。 異議申立が認められれば、出金リクエストは却下されます。 しかし通常のケースでは、ユーザーは正直に行動し、自分が所有する資金について正しい主張を行います。 この場合、アリスは、プラズマコントラクトにトランザクションを送信することで、ルートチェーン(イーサリアム)に対する出金リクエストを開始します。 -アリスは同時に、プラズマチェーン上で資金を作成するトランザクションが、特定のブロックに追加されていることを証明するマークル証明を提出しなければなりません。 これは、[未使用トランザクションのアウトプット(UTXO)](https://en.wikipedia.org/wiki/Unspent_transaction_output)モデルを採用した[プラズマ MVP](https://www.learnplasma.org/en/learn/mvp.html)など、プラズマのさまざまな開発サイクルにおいて必要になります。 +アリスは同時に、プラズマチェーン上で資金を作成するトランザクションが、特定のブロックに追加されていることを証明するマークル証明を提出しなければなりません。 これは、[未使用トランザクションのアウトプット(UTXO)](https://en.wikipedia.org/wiki/Unspent_transaction_output)モデルを採用した[プラズマMVP](https://www.learnplasma.org/en/learn/mvp.html)など、プラズマのさまざまな開発サイクルにおいて必要になります。 -[プラズマキャッシュ](https://www.learnplasma.org/en/learn/cash.html)などその他のプラズマでは、UTXO ではなく、[非代替性トークン(NFT)](/developers/docs/standards/tokens/erc-721/)として資金を表示します。 この場合、資金を引き出すには、プラズマチェーン上でトークンを所有していることを証明しなければなりません。 この証明は、当該トークンにおける最新の 2 回のトランザクションを送信し、同時にこれらのトランザクションがブロックに追加されたことを証明するマークル証明を提出することで行います。 +[プラズマキャッシュ](https://www.learnplasma.org/en/learn/cash.html)などその他のプラズマでは、UTXOではなく、[非代替性トークン(NFT)](/developers/docs/standards/tokens/erc-721/)として資金を表示します。 この場合、資金を引き出すには、プラズマチェーン上でトークンを所有していることを証明しなければなりません。 この証明は、当該トークンにおける最新の2回のトランザクションを送信し、同時にこれらのトランザクションがブロックに追加されたことを証明するマークル証明を提出することで行います。 ユーザーはさらに、自らの正直な行動を保証するために、出金リクエストにボンド(担保)を預け入れる必要があります。 異議申立を通じてアリスの出金リクエストが無効であることが証明された場合、アリスのボンドは没収され、その一部は異議申立を行ったユーザーに報酬として提供されます。 @@ -74,9 +74,9 @@ sidebarDepth: 3 あらゆるブロックチェーンと同様に、プラズマチェーンにおいても、参加ユーザーが悪意で行動した場合(資金の二重支出など)にトランザクションのインテグリティを強制するためのメカニズムが必要になります。 これを実現するために、プラズマチェーンでは不正証明を用いて、状態遷移の正しさに関する紛争を仲裁し、悪意の行動を罰しています。 不正証明は、あるプラズマ子チェーンが親チェーンまたはルートチェーンに対して苦情を申し立てるメカニズムとして用いられます。 -不正証明とは、特定の状態遷移が無効であるとの主張を指す用語です。 具体的には、アリスというユーザーが同じ資金を二度使用した場合が該当します。 アリスが、ボブとのトランザクションで彼女の UTXO をすでに使用したにも関わらず、この(すでにボブが所有している)UTXO を、他のトランザクションでも使用しようとするような場合です。 +不正証明とは、特定の状態遷移が無効であるとの主張を指す用語です。 具体的には、アリスというユーザーが同じ資金を二度使用した場合が該当します。 アリスが、ボブとのトランザクションで彼女のUTXOをすでに使用したにも関わらず、この(すでにボブが所有している)UTXOを、他のトランザクションでも使用しようとするような場合です。 -ボブは、アリスによる資金の引き出しを防ぐために、アリスはすでに当該 UTXO を以前のトランザクションで使用済みであることの証拠と、このトランザクションがブロックに追加済みであることを証明するマークル証明を提出することで、不正証明を作成することができます。 プラズマキャッシュでも同様のプロセスが実行され、ボブは、アリスが引き出そうとしているトークンはすでにボブに移転済みであることの証明を提供する必要があります。 +ボブは、アリスによる資金の引き出しを防ぐために、アリスはすでに当該UTXOを以前のトランザクションで使用済みであることの証拠と、このトランザクションがブロックに追加済みであることを証明するマークル証明を提出することで、不正証明を作成することができます。 プラズマキャッシュでも同様のプロセスが実行され、ボブは、アリスが引き出そうとしているトークンはすでにボブに移転済みであることの証明を提供する必要があります。 ボブの異議申立が認められると、アリスの出金リクエストは却下されます。 しかしこのアプローチでは、ボブは常にチェーン上の出金リクエストを監視しなければなりません。 ボブがオフラインであれば、アリスはチャレンジ期間の終了後に悪意の引き出しを実行できてしまうのです。 @@ -96,7 +96,7 @@ sidebarDepth: 3 このようなケースでは、通常の不正証明システムでは対応できません。 オペレーターは、アリスやボブの資金を自らのウォレットに転送する無効のトランザクションを作成した上で、不正証明を作成するのに必要なデータを秘匿することが簡単にできるからです。 これは、オペレーターが他のユーザーやメインネットに対してデータを提供することが義務付けられていないために発生する問題です。 -ですから、最も楽天的な解決策は、当該プラズマチェーンのユーザーを「大量退出」させることでしょう。 大量のユーザーを一挙に退出させることで、悪意のオペレーターにおける資金窃盗の試みを遅延させ、ユーザーに対する一定の保護策を講じることができます。 出金リクエストは、個々の UTXO(またはトークン)が作成された時点に基づいて順番付けられるため、悪意のオペレーターが正直なユーザーのトランザクションを先回りして実行することはできません。 +ですから、最も楽天的な解決策は、当該プラズマチェーンのユーザーを「大量退出」させることでしょう。 大量のユーザーを一挙に退出させることで、悪意のオペレーターにおける資金窃盗の試みを遅延させ、ユーザーに対する一定の保護策を講じることができます。 出金リクエストは、個々のUTXO(またはトークン)が作成された時点に基づいて順番付けられるため、悪意のオペレーターが正直なユーザーのトランザクションを先回りして実行することはできません。 それでもなお、無効な出金処理に伴う混乱に乗じて利益を得ようとする機会主義的なユーザーの発生を防ぐためには、大量退出時における出金リクエストについても検証できる方法が必要になります。 これは、出金を求める各ユーザーに対して、**有効であるチェーンの最後の状態**を送信することを義務付けるというシンプルな方法で解決できます。 @@ -106,17 +106,17 @@ sidebarDepth: 3 ## プラズマチェーンの長所と短所 {#pros-and-cons-of-plasma} -| 長所 | 短所 | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 高スループットおよびトランザクションあたりの低コスト。 | 汎用的な計算をサポートしない(スマートコントラクトを実行できない)。 述語論理により、基本的なトークンの転送、スワップ、およびその他数種類のトランザクションタイプのみに対応しています。 | -| 任意のユーザー間の取引に適している(プラズマチェーン上で設定されたユーザーペア間においては、間接費用が発生しない)。 | 資金の安全性を保護するには、ネットワークを定期的に監視する(ライブネス要件)か、この役割を特定のユーザーに委任する必要がある。 | -| メインチェーンとは無関係の具体的なユースケースで活用するために導入できる。 企業を含むあらゆるユーザーが、プラズマ上のスマートコントラクトをカスタマイズすることで、様々な文脈に合わせたスケーラブルなインフラを実現できる。 | データの保存およびリクエストによる提供につき、1 名あるいは複数のオペレーターに依存する。 | -| 計算およびストレージをオフチェーンに移動させることで、イーサリアムメインネットの負荷を軽減する。 | チャレンジ期間が設けられているため、出金プロセスは数日を要する。 この遅延は、代替可能資産であれば流動性プロバイダーが軽減できるが、それに伴って資本コストが発生する。 | -| | 大量のユーザーが一気に退出を求める場合、イーサリアムメインネットの混雑が予想される。 | +| 長所 | 短所 | +| -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| 高スループットおよびトランザクションあたりの低コスト。 | 汎用的な計算をサポートしない(スマートコントラクトを実行できない)。 述語論理により、基本的なトークンの転送、スワップ、およびその他数種類のトランザクションタイプのみに対応しています。 | +| 任意のユーザー間の取引に適している(プラズマチェーン上で設定されたユーザーペア間においては、間接費用が発生しない)。 | 資金の安全性を保護するには、ネットワークを定期的に監視する(ライブネス要件)か、この役割を特定のユーザーに委任する必要がある。 | +| メインチェーンとは無関係の具体的なユースケースで活用するために導入できる。 企業を含むあらゆるユーザーが、プラズマ上のスマートコントラクトをカスタマイズすることで、様々な文脈に合わせたスケーラブルなインフラを実現できる。 | データの保存およびリクエストによる提供につき、1名あるいは複数のオペレーターに依存する。 | +| 計算およびストレージをオフチェーンに移動させることで、イーサリアムメインネットの負荷を軽減する。 | チャレンジ期間が設けられているため、出金プロセスは数日を要する。 この遅延は、代替可能資産であれば流動性プロバイダーが軽減できるが、それに伴って資本コストが発生する。 | +| | 大量のユーザーが一気に退出を求める場合、イーサリアムメインネットの混雑が予想される。 | -## プラズマチェーンとレイヤー 2 のスケーリング・プロトコルとの比較 {#plasma-vs-layer-2} +## プラズマチェーンとレイヤー2のスケーリング・プロトコルとの比較 {#plasma-vs-layer-2} -プラズマは、以前はイーサリアムに対する有益なスケーリング・ソリューションだと考えられていましたが、現在では[レイヤー 2(L2)のスケーリング・プロトコル](/layer-2/)に取って代わられています。 L2 のスケーリング・ソリューションは、プラズマチェーンにおけるいくつかの問題点を解消しています: +プラズマは、以前はイーサリアムに対する有益なスケーリング・ソリューションだと考えられていましたが、現在では[レイヤー2(L2)のスケーリング・プロトコル](/layer-2/)に取って代わられています。 L2のスケーリング・ソリューションは、プラズマチェーンにおけるいくつかの問題点を解消しています: ### 効率性 {#efficiency} @@ -124,9 +124,9 @@ sidebarDepth: 3 ### スマートコントラクトへのサポート {#support-for-smart-contracts} -プラズマのフレームワークにおけるもう一つの問題は、[イーサリアムのスマートコントラクトを実行できない](https://ethresear.ch/t/why-smart-contracts-are-not-feasible-on-plasma/2598/4)点にありました。 このため、大部分のプラズマの実装は、単純な決済システムや ERC-20 トークンのやりとりを目的とするものでした。 +プラズマのフレームワークにおけるもう一つの問題は、[イーサリアムのスマートコントラクトを実行できない](https://ethresear.ch/t/why-smart-contracts-are-not-feasible-on-plasma/2598/4)点にありました。 このため、大部分のプラズマの実装は、単純な決済システムやERC-20トークンのやりとりを目的とするものでした。 -一方、オプティミスティック・ロールアップは[イーサリアム仮想マシン](/developers/docs/evm/)との互換性を持ち、イーサリアムネイティブの[スマートコントラクト](/developers/docs/smart-contracts/)を実行できるため、[分散型アプリケーション](/developers/docs/dapps/)のスケーラブルな展開を実現できる有益かつ*セキュア*なソリューションとなっています。 同様に、[EVM のゼロ知識実装(zkEVM)](https://ethresear.ch/t/a-zk-evm-specification/11549)の開発計画も進行中です。ゼロ知識ロールアップが任意のロジックを処理し、スマートコントラクトを実行できるようなります。 +一方、オプティミスティック・ロールアップは[イーサリアム仮想マシン](/developers/docs/evm/)との互換性を持ち、イーサリアムネイティブの[スマートコントラクト](/developers/docs/smart-contracts/)を実行できるため、[分散型アプリケーション](/developers/docs/dapps/)のスケーラブルな展開を実現できる有益かつ_セキュア_なソリューションとなっています。 同様に、[EVMのゼロ知識実装(zkEVM)](https://ethresear.ch/t/a-zk-evm-specification/11549)の開発計画も進行中です。ゼロ知識ロールアップが任意のロジックを処理し、スマートコントラクトを実行できるようなります。 ### データの可用性がない {#data-unavailability} @@ -150,27 +150,26 @@ sidebarDepth: 3 ### シャーディングとの比較 {#plasma-vs-sharding} -プラズマチェーンと[シャードチェーン](/upgrades/sharding/)はいずれも、イーサリアムメインネット上で定期的に暗号学的な証明を公開する点が共通しています。 しかし、そのセキュリティ特性は異なります。 +プラズマチェーンとシャードチェーンは、どちらもイーサリアムメインネット上で定期的に暗号学的な証明を公開しています。 しかし、そのセキュリティ特性は異なります。 シャードチェーンの場合、各データシャードに関する詳細情報を含む「照合ヘッダー」をメインネット上でコミットします。 メインネット上の各ノードは、データシャードの有効性を検証した上で強制するため、無効なシャード遷移を防止でき、悪意の行為からネットワークを保護することができます。 一方プラズマチェーンでは、子チェーンの状態について最小限の情報しかメインネットに提供されない点が異なります。 つまり、メインネットでは子チェーンで実行されたトランザクションを事実上検証できないため、プラズマチェーンの方がセキュリティが低くなります。 -### プラズマを使用する {#use-plasma} +**注**: イーサリアムブロックチェーンのシャーディングは、現在ロードマップに含まれていません。 代わりに、ロールアップと[ダンクシャーディング](/roadmap/danksharding)によるスケーリングが採用されています。 -複数のプロジェクトにおいて、Dapp で活用できるプラズマの実装が提供されています: +### プラズマの使用 {#use-plasma} -- [OMG Network](https://omg.network/) -- [Polygon](https://polygon.technology/) (旧 Matic Network) -- [Gluon](https://gluon.network/) -- [LeapDAO](https://ipfs.leapdao.org/) +複数のプロジェクトにおいて、Dappで活用できるプラズマの実装が提供されています。 + +- [Polygon](https://polygon.technology/)(旧Matic Network) ## 参考文献 {#further-reading} - [プラズマについて学ぶ](https://www.learnplasma.org/en/) - [「共有セキュリティ」の意味と重要性についての簡単な復習](https://old.reddit.com/r/ethereum/comments/sgd3zt/a_quick_reminder_of_what_shared_security_means/) -- [サイドチェーン、プラズマ、シャーディングの比較](https://vitalik.eth.limo/general/2019/06/12/plasma_vs_sharding.html) -- [プラズマを理解する(その 1:基本事項)](https://www.theblockcrypto.com/amp/post/10793/understanding-plasma-part-1-the-basics) +- [サイドチェーン、プラズマ、シャーディングの比較](https://vitalik.ca/general/2019/06/12/plasma_vs_sharding.html) +- [プラズマを理解する(その1:基本事項)](https://www.theblockcrypto.com/amp/post/10793/understanding-plasma-part-1-the-basics) - [プラズマの生と死](https://medium.com/dragonfly-research/the-life-and-death-of-plasma-b72c6a59c5ad#) -_役に立つコミュニティリソースをご存知の場合は、 ページを編集して追加してください。_ +_役に立ったコミュニティリソースがあれば、 ぜひこのページに追加してください。_ diff --git a/public/content/translations/ja/developers/docs/scaling/sidechains/index.md b/public/content/translations/ja/developers/docs/scaling/sidechains/index.md index f251217a98f..db36a52255d 100644 --- a/public/content/translations/ja/developers/docs/scaling/sidechains/index.md +++ b/public/content/translations/ja/developers/docs/scaling/sidechains/index.md @@ -5,7 +5,7 @@ lang: ja sidebarDepth: 3 --- -サイドチェーンとは、イーサリアムから独立して実行され、双方向のブリッジによりイーサリアムメインネットに接続されている別個のブロックチェーンです。 サイドチェーンは、メインネットとは異なるブロックのパラメータおよび[コンセンサス・アルゴリズム](/developers/docs/consensus-mechanisms/)を持つことができ、多くの場合トランザクションの効率的な処理のために設計されています。 しかし、イーサリアムのセキュリティ特性を活用できないため、トレードオフが発生します。 [レイヤー 2 のスケーリングソリューション](/layer-2/)とは異なり、サイドチェーンは状態変化やトンラザクションデータをイーサリアムメインネットに送信しません。 +サイドチェーンとは、イーサリアムから独立して実行され、双方向のブリッジによりイーサリアムメインネットに接続されている別個のブロックチェーンです。 サイドチェーンは、メインネットとは異なるブロックのパラメータおよび[コンセンサス・アルゴリズム](/developers/docs/consensus-mechanisms/)を持つことができ、多くの場合トランザクションの効率的な処理のために設計されています。 しかし、イーサリアムのセキュリティ特性を活用できないため、トレードオフが発生します。 [レイヤー2のスケーリングソリューション](/layer-2/)とは異なり、サイドチェーンは状態変化やトンラザクションデータをイーサリアムメインネットに送信しません。 サイドチェーンではさらに、高スループットを実現するために、分散性やセキュリティが低下します([スケーラビリティのトリレンマ](https://vitalik.eth.limo/general/2021/05/23/scaling.html))。 一方イーサリアムは、アップグレードに関する[ビジョン・ステートメント](/roadmap/vision/)で述べられているように、分散性およびセキュリティを犠牲にすることなくスケーリングを実現することを目指しています。 @@ -18,7 +18,7 @@ sidebarDepth: 3 サイドチェーンの独自性(イーサリアムとの相違点)のひとつとしては、採用されているコンセンサス・アルゴリズムが挙げられます。 サイドチェーンでは、コンセンサスをイーサリアムに依存せず、各サイドチェーンのニーズに合わせて別のコンセンサス・プロトコルを選択することができます。 サイドチェーンで用いられているコンセンサス・アルゴリズムの例としては、以下が挙げられます: - [プルーフ・オブ・オーソリティ](https://wikipedia.org/wiki/Proof_of_authority) -- [プルーフ・オブ・ステークの委任](https://en.bitcoinwiki.org/wiki/DPoS) +- [プルーフ・オブ・ステークの委任](https://en.bitcoin.it/wiki/Delegated_proof_of_stake) - [ビザンチン・フォールトトレランス](https://decrypt.co/resources/byzantine-fault-tolerance-what-is-it-explained) サイドチェーンは、イーサリアムと同様に、トランザクションを検証、処理し、ブロックを生成し、ブロックチェーンの状態を保存する検証ノード(バリデータ)を持ちます。 バリデータはさらに、サイドチェーンネットワーク全体におけるコンセンサスを維持し、悪意の攻撃から防御する責任を負います。 @@ -31,13 +31,13 @@ sidebarDepth: 3 ブロックチェーンにおいて、分散性を犠牲にせずにスケーラビリティを実現するには、特殊なハードウェアを持つユーザーに限らず、すべてのユーザーがノードを実行できるように開放されていなければなりません。 これこそ、イーサリアムネットワークにおいて、誰もが[フルノードを実行](/developers/docs/nodes-and-clients/#why-should-i-run-an-ethereum-node)できるように保証する取り組みが続けられている理由です。 -### EVM との互換性 {#evm-compatibility} +### EVMとの互換性 {#evm-compatibility} -一部のサイドチェーンは EVM 互換であるため、[イーサリアム仮想マシン(EVM)](/developers/docs/evm/)向けに開発されたスマートコントラクトを実行することができます。 EVM 互換のサイドチェーンは、[Solidity](/developers/docs/smart-contracts/languages/)やその他の EVM スマートコントラクト言語で書かれたスマートコントラクトをサポートするため、イーサリアムメインネット向けに開発されたスマートコントラクトは EVM 互換のサイドチェーンでも実行することができます。 +一部のサイドチェーンはEVM互換であるため、[イーサリアム仮想マシン(EVM)](/developers/docs/evm/)向けに開発されたスマートコントラクトを実行することができます。 EVM互換のサイドチェーンは、[Solidity](/developers/docs/smart-contracts/languages/)やその他のEVMスマートコントラクト言語で書かれたスマートコントラクトをサポートするため、イーサリアムメインネット向けに開発されたスマートコントラクトはEVM互換のサイドチェーンでも実行することができます。 -つまり、あなたが作成した[Dapp](/developers/docs/dapps/)をサイドチェーンで使用したい場合、あなたの[スマートコントラクト](/developers/docs/smart-contracts/)を当該のサイドチェーンでデプロイするだけでよいです。 サイドチェーンにおける Dapp の外観、感触、および動作はメインネットの場合とまったく同じです。Solidity 上でコントラクトを作成し、サイドチェーンの RPC を介してチェーンとのやりとりを行います。 +つまり、あなたが作成した[Dapp](/developers/docs/dapps/)をサイドチェーンで使用したい場合、あなたの[スマートコントラクト](/developers/docs/smart-contracts/)を当該のサイドチェーンでデプロイするだけでよいです。 サイドチェーンにおけるDappの外観、感触、および動作はメインネットの場合とまったく同じです。Solidity上でコントラクトを作成し、サイドチェーンのRPCを介してチェーンとのやりとりを行います。 -サイドチェーンが EVM 互換であるため、イーサリアムネイティブの Dapp にとっては有益な[スケーリングソリューション](/developers/docs/scaling/)であると言えるでしょう。 Dapp をサイドチェーンでデプロイすることにより、ユーザーは、特にメインネットが混雑している場合に、低いガス代と迅速なトランザクション実行という利点を享受できます。 +サイドチェーンがEVM互換であるため、イーサリアムネイティブのDappにとっては有益な[スケーリングソリューション](/developers/docs/scaling/)であると言えるでしょう。 Dappをサイドチェーンでデプロイすることにより、ユーザーは、特にメインネットが混雑している場合に、低いガス代と迅速なトランザクション実行という利点を享受できます。 ただし、すでに述べた通り、サイドチェーンの使用は大きなトレードオフを伴います。 個別のサイドチェーンはそれ自体でセキュリティ保護の責任を負い、イーサリアムのセキュリティ特性を継承しないためです。 これは、ユーザーに悪影響を及ぼしたり、資金をリスクにさらす悪意の行動を防止できないことを意味します。 @@ -45,20 +45,20 @@ sidebarDepth: 3 独立したブロックチェーンがイーサリアムメインネットのサイドチェーンとなるためには、イーサリアムメインネットとの間の資産の出し入れが容易に実行できる機能が必要です。 このイーサリアムとの相互運用性は、ブロックチェーン・ブリッジにより提供されます。 [ブリッジ](/bridges/)は、イーサリアムメインネット上でデプロイされたスマートコントラクトとサイドチェーンを用いて、メインネットとサイドチェーン間の資金移動を管理します。 -ブリッジはイーサリアムとサイドチェーン間の資金移動を手助けしますが、すでに発行された資産が実際に 2 つのチェーン間を移動する訳ではありません。 むしろ通常は、コインのミントおよびバーンを用いたメカニズムにより、複数のチェーン間で価値を移転します。 詳しくは、[ブリッジの仕組み](/developers/docs/bridges/#how-do-bridges-work)をご覧ください。 +ブリッジはイーサリアムとサイドチェーン間の資金移動を手助けしますが、すでに発行された資産が実際に2つのチェーン間を移動する訳ではありません。 むしろ通常は、コインのミントおよびバーンを用いたメカニズムにより、複数のチェーン間で価値を移転します。 詳しくは、[ブリッジの仕組み](/developers/docs/bridges/#how-do-bridges-work)をご覧ください。 ## サイドチェーンの長所と短所 {#pros-and-cons-of-sidechains} -| 長所 | 短所 | -| -------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| サイドチェーンの基盤技術は十分に確立されており、広範なリサーチおよび設計上の改善を経ています。 | サイドチェーンでは、スケーラビリティを実現するためのトレードオフとして、分散化およびトラストレス性がある程度犠牲になります。 | -| サイドチェーンは、全般的な計算をサポートし、EVM 互換性を提供します(イーサリアムネイティブの Dapp が実行可能)。 | サイドチェーンでは、別個のコンセンサスメカニズムが用いられるため、イーサリアムによるセキュリティ保証を活用できません。 | +| 長所 | 短所 | +| ------------------------------------------------------------------------- | ----------------------------------------------------------------------- | +| サイドチェーンの基盤技術は十分に確立されており、広範なリサーチおよび設計上の改善を経ています。 | サイドチェーンでは、スケーラビリティを実現するためのトレードオフとして、分散化およびトラストレス性がある程度犠牲になります。 | +| サイドチェーンは、全般的な計算をサポートし、EVM互換性を提供します(イーサリアムネイティブのDappが実行可能)。 | サイドチェーンでは、別個のコンセンサスメカニズムが用いられるため、イーサリアムによるセキュリティ保証を活用できません。 | | サイドチェーンは、トランザクションの処理効率を高め、ユーザーのトランザクション手数料を引き下げるために、様々なコンセンサスモデルを採用しています。 | サイドチェーンでは、より高い水準の信頼前提が必要になります(例:サイドチェーンでは、悪意のバリデータが共謀することで不正行為が実行可能です)。 | -| Dapp は、EVM 互換のサイドチェーンを用いて自らのエコシステムを拡張できます。 | | +| Dappは、EVM互換のサイドチェーンを用いて自らのエコシステムを拡張できます。 | | ### サイドチェーンの使用 {#use-sidechains} -複数のプロジェクトにおいて、Dapp と統合できるサイドチェーン実装が提供されています。 +複数のプロジェクトにおいて、Dappと統合できるサイドチェーン実装が提供されています。 - [Polygon PoS](https://polygon.technology/solutions/polygon-pos) - [Skale](https://skale.network/) @@ -68,6 +68,6 @@ sidebarDepth: 3 ## 参考文献 {#further-reading} -- [サイドチェーンを用いてイーサリアムの Dapp におけるスケーラビリティを実現する](https://medium.com/loom-network/dappchains-scaling-ethereum-dapps-through-sidechains-f99e51fff447) _2018 年 2 月 8 日、ジョルジオス・コンスタントプロス作成。_ +- [サイドチェーンを用いてイーサリアムのDappにおけるスケーラビリティを実現する](https://medium.com/loom-network/dappchains-scaling-ethereum-dapps-through-sidechains-f99e51fff447) _2018年2月8日、ジョルジオス・コンスタントプロス作成。_ _役に立つコミュニティリソースをご存知の場合は、 ページを編集して追加してください。_ diff --git a/public/content/translations/ja/developers/docs/scaling/state-channels/index.md b/public/content/translations/ja/developers/docs/scaling/state-channels/index.md index 5d78c7165b6..b87b05e52cc 100644 --- a/public/content/translations/ja/developers/docs/scaling/state-channels/index.md +++ b/public/content/translations/ja/developers/docs/scaling/state-channels/index.md @@ -5,17 +5,17 @@ lang: ja sidebarDepth: 3 --- -ステートチャネルは、ユーザーに対して、イーサリアムメインネットとのやりとりを最小限に抑えつつ、トランザクションをオフチェーンで安全に実行できる方法を提供します。 チャネル上のピア(同僚)は、当該チャネルをオープン/クローズするための 2 つのオンチェーンのトランザクションを送信するだけで、任意の数のトランザクションをオフチェーンで実行することができます。 これにより、トランザクションのスループットが大きく改善され、ユーザーの手数料が軽減できます。 +ステートチャネルは、ユーザーに対して、イーサリアムメインネットとのやりとりを最小限に抑えつつ、トランザクションをオフチェーンで安全に実行できる方法を提供します。 チャネル上のピア(同僚)は、当該チャネルをオープン/クローズするための2つのオンチェーンのトランザクションを送信するだけで、任意の数のトランザクションをオフチェーンで実行することができます。 これにより、トランザクションのスループットが大きく改善され、ユーザーの手数料が軽減できます。 ## 前提知識 {#prerequisites} -[イーサリアムスケーリング](/developers/docs/scaling/)と[レイヤー 2](/layer-2/)のページを読んで理解しておくことをお勧めします。 +[イーサリアムスケーリング](/developers/docs/scaling/)と[レイヤー2](/layer-2/)のページを読んで理解しておくことをお勧めします。 ## チャネルとは何か? {#what-are-channels} イーサリアムをはじめとするパブリックブロックチェーンでは、分散型のアーキテクチャによりオンチェーンのトランザクションをすべてのノードが実行しなければならないため、スケーラビリティを実現が大きな課題になります。 各ノードは、一般的なハードウェアを用いて各ブロックに含まれるトランザクションを処理しなければならないため、ネットワークの分散性を維持する上で、トランザクションのスループットには一定の限界が発生します。 ブロックチェーンにおけるチャネルとは、トランザクションの最終的な決済のセキュリティをメインチェーンに依存しつつ、ユーザー同士がオフチェーンでやりとりできるようにすることで、このスループットの問題を解消しようとするアプローチです。 -単純なピアツーピアのプロトコルであるチャネルを利用することで、チャネルに参加する 2 つのノードは、数多くのトランザクションを実行した上で、最終的な結果のみをブロックチェーンに送信するだけでよくなります。 チャネルは、暗号技術を用いることで、メインネットに送信されるサマリーデータがノード間で実行された一連の有効なトランザクションの真の結果であることを証明することができます。 [「マルチシグ」](/developers/docs/smart-contracts/#multisig)のスマートコントラクトは、各トランザクションが適切なノードにより署名されたことを保証します。 +単純なピアツーピアのプロトコルであるチャネルを利用することで、チャネルに参加する2つのノードは、数多くのトランザクションを実行した上で、最終的な結果のみをブロックチェーンに送信するだけでよくなります。 チャネルは、暗号技術を用いることで、メインネットに送信されるサマリーデータがノード間で実行された一連の有効なトランザクションの真の結果であることを証明することができます。 [「マルチシグ」](/developers/docs/smart-contracts/#multisig)のスマートコントラクトは、各トランザクションが適切なノードにより署名されたことを保証します。 チャネルにおける状態変化は参加ノードにより実行、検証されるため、実行レイヤーにおける計算を最低限に抑えることができます。 これにより、イーサリアムの混雑が解消され、ユーザーにとってはトランザクションの処理速度が改善されます。 @@ -23,15 +23,15 @@ sidebarDepth: 3 チャネルを廃止するには、当該チャネルにおける最終的な同意済み状態をオンチェーンに送信します。 これを受けて、マルチシグのスマートコントラクトは、チャネルの最終状態における各ノードの残高に従って、ロックされた資金を分配します。 -ピアツーピアのチャネルは、特に事前に定義された参加者が処理速度の明らかな低下をもたらすことなく高頻度でトランザクションを行いたい場合に有益です。 ブロックチェーンにおけるチャネルは、**ペイメントチャネル**と**ステートチャネル**の 2 種類に大別できます。 +ピアツーピアのチャネルは、特に事前に定義された参加者が処理速度の明らかな低下をもたらすことなく高頻度でトランザクションを行いたい場合に有益です。 ブロックチェーンにおけるチャネルは、**ペイメントチャネル**と**ステートチャネル**の2種類に大別できます。 ## ペイメントチャネル {#payment-channels} -ペイメントチャネルは、2 つのノードが共同で管理する「双方向の台帳」と呼べるでしょう。 この台帳における当初の残高は、チャネル開設時にオンチェーンのコントラクトにおいてロックされた両ユーザーからの入金の合計額になります。 ペイメントチャネルにおける送金は、チャネル開設時と最終的なチャネル廃止時におけるオンチェーンのトランザクションを除き、ブロックチェーン自体を関与させずに瞬時に実行することができます。 +ペイメントチャネルは、2つのノードが共同で管理する「双方向の台帳」と呼べるでしょう。 この台帳における当初の残高は、チャネル開設時にオンチェーンのコントラクトにおいてロックされた両ユーザーからの入金の合計額になります。 ペイメントチャネルにおける送金は、チャネル開設時と最終的なチャネル廃止時におけるオンチェーンのトランザクションを除き、ブロックチェーン自体を関与させずに瞬時に実行することができます。 チャネルの台帳における残高(つまり、ペイメントチャネルの状態)が変更される場合、チャネルに参加する全ユーザーの承認が必要になります。 イーサリアムにおけるトランザクションの場合と同じように、チャネルの更新は、参加ユーザー全員の署名によりファイナライズされたと見なされます。 -ペイメントチャネルは、ユーザーがオンチェーンで実行する単純なやりとり(例:ETH の送金、アトミックスワップ、少額決済など)の費用を軽減するために設計された最初期のスケーリング・ソリューションのひとつです。 チャネルの参加ユーザーは、送金の合計額がデポジットされたトークンの合計を超えない限り、ユーザー間のトランザクションを瞬時に何回でも無料で実行することができます。 +ペイメントチャネルは、ユーザーがオンチェーンで実行する単純なやりとり(例:ETHの送金、アトミックスワップ、少額決済など)の費用を軽減するために設計された最初期のスケーリング・ソリューションのひとつです。 チャネルの参加ユーザーは、送金の合計額がデポジットされたトークンの合計を超えない限り、ユーザー間のトランザクションを瞬時に何回でも無料で実行することができます。 ## ステートチャンネル {#state-channels} @@ -41,7 +41,7 @@ sidebarDepth: 3 一方で、ステートチャネルでは、ユーザーの残高情報を保持するだけでなく、当該コントラクトのストレージの現在状態(つまり、コントラクトに含まれる各変数の値)を追跡することができます。 -これにより、2 人のユーザー間で、スマートコントラクトをオフチェーンで実行することが可能になります。 この場合、スマートコントラクトの初期状態を変更するには、チャネルを開設した両ユーザー(ピア)の承認のみが必要になります。 +これにより、2人のユーザー間で、スマートコントラクトをオフチェーンで実行することが可能になります。 この場合、スマートコントラクトの初期状態を変更するには、チャネルを開設した両ユーザー(ピア)の承認のみが必要になります。 これは、先ほど挙げたスケーラビリティの問題を解消する一方で、セキュリティが低下する可能性をもたらします。 イーサリアムでは、状態遷移の有効性はコンセンサス・プロトコルにより強制されています。 これにより、スマートコントラクトの状態に対して無効な更新を提案したり、スマートコントラクトの実行を改変することは不可能になっているのです。 @@ -65,13 +65,13 @@ sidebarDepth: 3 チャネルの状態が初期化されると、各ピアは、自らが署名したトランザクションを他のピアに送信し、承認を求めることで、やりとりを行います。 参加ユーザーは、このようなトランザクションを通じて、自らが状態更新を開始したり、他のユーザーからの状態更新に署名したりします。 チャネルにおけるトランザクションは、以下の要素で構成されます: -- **ナンス**は、トランザクションのユニーク ID として機能し、リプレイ攻撃を防ぎます。 同時に、状態更新の発生順序を特定します(これは、紛争解決フェーズにおいて重要です)。 +- **ナンス**は、トランザクションのユニークIDとして機能し、リプレイ攻撃を防ぎます。 同時に、状態更新の発生順序を特定します(これは、紛争解決フェーズにおいて重要です)。 - チャネルの古い状態。 - チャネルの新しい状態。 -- 状態遷移をトリガーするトランザクション(例:アリスがボブに 5 ETH を送信するトランザクション)。 +- 状態遷移をトリガーするトランザクション(例:アリスがボブに5 ETHを送信するトランザクション)。 メインネットにおけるユーザー間の通常のやりとりとは異なり、チャネルの状態更新はオンチェーンでブロードキャストされません。これは、オンチェーンの負荷を最小化するというステートチャネルの目的に合致しています。 参加ユーザーが同意する限り、状態更新はイーサリアムのトランザクションと同様のファイナリティを持ちます。 参加者がメインネットのコンセンサスに依存するのは、紛争が発生した場合のみです。 @@ -97,13 +97,13 @@ sidebarDepth: 3 通常、チャネルの参加ユーザーは、事前にチャネルの廃止に同意し、最後の状態遷移に共同署名した上で、スマートコントラクトに送信します。 チャネルの更新がオンチェーン上で承認されると、オフチェーンにおけるスマートコントラクトの実行が終了し、参加ユーザーは各自の資金を持ってチャネルを退出します。 -しかし 1 名の参加ユーザーが、他のユーザーによる承認を待たずに、スマートコントラクトの実行終了とチャネルのファイナライズを要求するリクエストをオンチェーンで送信する可能性もあります。 上述したようなコンセンサスが維持できない状況が発生した場合、各参加ユーザーは、オンチェーンのコントラクトに対し、チャネルを廃止し、資金を分配させるようにトリガーすることができます。 これにより正直な参加ユーザーは、他のユーザーのアクションに関わらず常にデポジットを撤回できるため、**トラストレス性**が確保されます。 +しかし1名の参加ユーザーが、他のユーザーによる承認を待たずに、スマートコントラクトの実行終了とチャネルのファイナライズを要求するリクエストをオンチェーンで送信する可能性もあります。 上述したようなコンセンサスが維持できない状況が発生した場合、各参加ユーザーは、オンチェーンのコントラクトに対し、チャネルを廃止し、資金を分配させるようにトリガーすることができます。 これにより正直な参加ユーザーは、他のユーザーのアクションに関わらず常にデポジットを撤回できるため、**トラストレス性**が確保されます。 チャネルの廃止を実行したいユーザーは、当該アプリケーションの最後の有効な状態更新をオンチェーンのコントラクトに送信する必要があります。 この最後の有効な状態更新が正しければ(つまり、全参加ユーザーの署名を含んでいれば)、資金は各ユーザーに再分配されます。 -ただし、1 名のユーザーによる廃止リクエストに対しては、実行までの保留期間が発生します。 反対に、チャネルの廃止が満場一致で承認されている場合は、オンチェーンにおける廃止トランザクションはただちに実行されます。 +ただし、1名のユーザーによる廃止リクエストに対しては、実行までの保留期間が発生します。 反対に、チャネルの廃止が満場一致で承認されている場合は、オンチェーンにおける廃止トランザクションはただちに実行されます。 -1 名のユーザーによる廃止リクエストについて保留期間が発生するのは、不正行為の可能性を防止するためです。 例えば、1 名の参加ユーザーが、チャネルの古い状態をオンチェーンに送信して、イーサリアム上でチャネルをファイナライズしようとする可能性があります。 +1名のユーザーによる廃止リクエストについて保留期間が発生するのは、不正行為の可能性を防止するためです。 例えば、1名の参加ユーザーが、チャネルの古い状態をオンチェーンに送信して、イーサリアム上でチャネルをファイナライズしようとする可能性があります。 ステートチャネルでは、このようなアクションを防止するために、正直なユーザーが最新の有効状態をオンチェーンに送信することで、無効な状態更新に異議を申し立てることが可能になっています。 ステートチャネルは、より新しい同意済みの状態更新が、より古い状態更新よりも優先されるように設計されています。 @@ -115,7 +115,7 @@ sidebarDepth: 3 ステートチャネルはオフチェーンのプロトコルとして存在しますが、オンチェーンの構成要素、つまりチャネル開設時にイーサリアム上でデプロイされたスマートコントラクトを持ちます。 このコントラクトは、ステートチャネルにデポジットされた資産を管理し、状態更新を検証し、参加ユーザー間の紛争を仲裁する機能を持ちます。 -ステートチャネルは、[レイヤー 2](/layer-2/)のスケーリング・ソリューションとは異なり、メインネットに対してトランザクションデータやステートコミットメントを送信しません。 しかし、[サイドチェーン](/developers/docs/scaling/sidechains/)などと比較するとメインネットとの接続性が高いため、やや安全性が高いと言えます。 +ステートチャネルは、[レイヤー2](/layer-2/)のスケーリング・ソリューションとは異なり、メインネットに対してトランザクションデータやステートコミットメントを送信しません。 しかし、[サイドチェーン](/developers/docs/scaling/sidechains/)などと比較するとメインネットとの接続性が高いため、やや安全性が高いと言えます。 ステートチャネルは、以下の事項につきメインのイーサリアムプロトコルに依存します: @@ -137,11 +137,11 @@ sidebarDepth: 3 ## 仮想ステートチャネル {#virtual-state-channels} -ステートチャネルのネイティブ実装は、オフチェーンでアプリケーションを実行したい 2 名のユーザーが、新規のスマートコントラクトをデプロイすることを想定していました。 しかし、このようなアプローチは実現不可能であるだけでなく、ステートチャネルに求められるコスト効率性も失われます(オンチェーンでのトランザクション費用が大きくかさむため)。 +ステートチャネルのネイティブ実装は、オフチェーンでアプリケーションを実行したい2名のユーザーが、新規のスマートコントラクトをデプロイすることを想定していました。 しかし、このようなアプローチは実現不可能であるだけでなく、ステートチャネルに求められるコスト効率性も失われます(オンチェーンでのトランザクション費用が大きくかさむため)。 この問題点を解消するために、「仮想チャネル」が開発されました。 チャネルを開設/廃止するためにオンチェーンでのトランザクションが必要な通常のチャネルとは異なり、仮想チャネルは、メインチェーンとのやりとりを行うことなく、開設、実行、およびファイナライズが可能です。 このメソッドを用いて、紛争をオフチェーンで解決することすら可能です。 -仮想チャネルのシステムが機能するには、オンチェーンですでに資金が入金されている、いわゆる「台帳チャネル」が存在する必要があります。 これは、既存の台帳チャネルの上に 2 名のユーザー間の仮想チャネルを構築し、台帳チャネルの所有ユーザー(複数可)が仲介者の役割を果たすというモデルです。 +仮想チャネルのシステムが機能するには、オンチェーンですでに資金が入金されている、いわゆる「台帳チャネル」が存在する必要があります。 これは、既存の台帳チャネルの上に2名のユーザー間の仮想チャネルを構築し、台帳チャネルの所有ユーザー(複数可)が仲介者の役割を果たすというモデルです。 各仮想チャネルに参加するユーザーは、当該コントラクトの新規インスタンスを通じてやりとりを行い、台帳チャネルが複数のインスタンスをサポートします。 また、台帳チャネルの状態には複数のコントラクトにおけるストレージ状態が含まれるため、オフチェーンにおいて、複数のユーザーがアプリケーションを並列的に実行することが可能になります。 @@ -149,13 +149,13 @@ sidebarDepth: 3 ### 仮想ペイメントチャネル {#virtual-payment-channels} -仮想ペイメントチャネルは、仮想ステートチャネルと同じ発想に基づいており、同じネットワークに接続された参加ユーザーは、オンチェーンで新たなチャネルを開設する必要なしにメッセージをやりとりすることができます。 仮想ペイメントチャネルでは、送金は 1 名または複数の仲介者を介して実行されるため、意図した受取人のみが資金を受け取ることが保証されます。 +仮想ペイメントチャネルは、仮想ステートチャネルと同じ発想に基づいており、同じネットワークに接続された参加ユーザーは、オンチェーンで新たなチャネルを開設する必要なしにメッセージをやりとりすることができます。 仮想ペイメントチャネルでは、送金は1名または複数の仲介者を介して実行されるため、意図した受取人のみが資金を受け取ることが保証されます。 ## ステートチャネルの応用例 {#applications-of-state-channels} ### 支払い {#payments} -ブロックチェーンにおける初期のチャネルは、メインネットにおいて高額の手数料を発生させることなく、2 名のユーザーがオフチェーンで、迅速かつ安価な送金を行うことができるシンプルなプロトコルでした。 ペイメントチャネルは現在でも、イーサ(ETH)やその他のトークンの交換や預入を行う目的において有益だと言えます。 +ブロックチェーンにおける初期のチャネルは、メインネットにおいて高額の手数料を発生させることなく、2名のユーザーがオフチェーンで、迅速かつ安価な送金を行うことができるシンプルなプロトコルでした。 ペイメントチャネルは現在でも、イーサ(ETH)やその他のトークンの交換や預入を行う目的において有益だと言えます。 チャネルを活用した決済には、以下の利点があります: @@ -167,11 +167,11 @@ sidebarDepth: 3 4. **コスト**: ステートチャネルは特に、特定のユーザー集団が長期的に数多くの状態更新を交換する必要がある場合に有益だと言えます。 発生する唯一のコストは、ステートチャネルのスマートコントラクトの開始/終了に伴う費用のみです。決済コストは、チャネルの最終状態に従って配分されるため、チャネルの開設から廃止に至るまでの各状態変化のコストは最後の状態変化のコストよりも安価になります。 -ステートチャネルは、[ロールアップ](/developers/docs/scaling/#rollups)などのレイヤー 2 ソリューションで実装することで、さらに魅力的な決済手段になる可能性があります。 チャネルは、安価な決済手段を提供するものであるとは言え、開設時におけるメインネットでのオンチェーンコントラクトの設定費用は、特にガス料金が急騰した際には高額になる可能性があります。 イーサリアムベースのロールアップは[安価なトンラザクションフィー](https://l2fees.info/)を提供するため、チャネル参加者はセットアップ手数料を抑えることで全体の間接費用を削減できます。 +ステートチャネルは、[ロールアップ](/developers/docs/scaling/#rollups)などのレイヤー2ソリューションで実装することで、さらに魅力的な決済手段になる可能性があります。 チャネルは、安価な決済手段を提供するものであるとは言え、開設時におけるメインネットでのオンチェーンコントラクトの設定費用は、特にガス料金が急騰した際には高額になる可能性があります。 イーサリアムベースのロールアップは[安価なトンラザクションフィー](https://l2fees.info/)を提供するため、チャネル参加者はセットアップ手数料を抑えることで全体の間接費用を削減できます。 ### マイクロトランザクション {#microtransactions} -マイクロトランザクションとは、企業にとって損失が発生するような微少な価値(例:1 ドル未満)の決済を指します。 これらの事業体は、決済サービスプロバイダーに手数料を支払う必要がありますが、顧客売上の利益率が低すぎる場合には損失が発生する可能性があるためです。 +マイクロトランザクションとは、企業にとって損失が発生するような微少な価値(例:1ドル未満)の決済を指します。 これらの事業体は、決済サービスプロバイダーに手数料を支払う必要がありますが、顧客売上の利益率が低すぎる場合には損失が発生する可能性があるためです。 ペイメントチャネルは、マイクロトランザクションにおける間接費用を縮小することでこの問題を解消します。 例えばインターネットサービスプロバイダー(ISP)であれば、顧客が自社サービスを利用するごとに少額の支払いがストリーミングされるペイメントチャネルを開設することができます。 @@ -183,15 +183,15 @@ sidebarDepth: 3 多くのステートチャネルでは、オンチェーンのコントラクト上でコミットされた資金を管理するのに用意であるため、単純な相互のやりとりを行うアプリケーションのみに使用が限定されています。 また、オフチェーンのアプリケーションにおける状態を一定間隔で更新するユーザーの数が制限されるため、不正直なユーザー行動を罰するのが比較的容易です。 -また、ステートチャネルを用いたアプリケーションの効率性は、その設計により異なります。 例えば、デベロッパーはアプリケーションのチャネルコントラクトをオンチェーンで 1 回デプロイし、利用者がオンチェーンにアクセスすることなくアプリを再利用できるように設計することが可能です。 この場合、アプリケーションの当初のチャネルが台帳チャネルとして複数の仮想チャネルをサポートするので、アプリケーションのスマートコントラクトは、オフチェーン上で新規インスタンスとして実行することができます。 +また、ステートチャネルを用いたアプリケーションの効率性は、その設計により異なります。 例えば、デベロッパーはアプリケーションのチャネルコントラクトをオンチェーンで1回デプロイし、利用者がオンチェーンにアクセスすることなくアプリを再利用できるように設計することが可能です。 この場合、アプリケーションの当初のチャネルが台帳チャネルとして複数の仮想チャネルをサポートするので、アプリケーションのスマートコントラクトは、オフチェーン上で新規インスタンスとして実行することができます。 -ステートチャネルを用いたアプリケーションのユースケースとしては、ゲームの結果に基づいて資金が分配される 2 人対戦型のゲームが想定できるでしょう。 この場合のメリットとしては、各プレイヤーが相手プレイヤーを信頼する必要がなく(トラストレス性)、資金の分配や紛争の解決を管理するのはプレイヤーではなくオンチェーンのコントラクトである(分散性)という点です。 +ステートチャネルを用いたアプリケーションのユースケースとしては、ゲームの結果に基づいて資金が分配される2人対戦型のゲームが想定できるでしょう。 この場合のメリットとしては、各プレイヤーが相手プレイヤーを信頼する必要がなく(トラストレス性)、資金の分配や紛争の解決を管理するのはプレイヤーではなくオンチェーンのコントラクトである(分散性)という点です。 -ステートチャネルを用いたアプリケーションにおけるその他のユースケースとしては、ENS の名前解決サービスや NFT 台帳など、様々な可能性があります。 +ステートチャネルを用いたアプリケーションにおけるその他のユースケースとしては、ENSの名前解決サービスやNFT台帳など、様々な可能性があります。 ### アトミック送金 {#atomic-transfers} -初期のペイメントチャネルでは、2 名のユーザー間の送金のみが可能だったため、用途が限られていました。 しかし、仮想チャネルが導入されたことで、オンチェーン上で新規チャネルを開設せずに、仲介者を通した送金の転送(つまり、複数の P2P チャネルを利用した送金)が可能になりました。 +初期のペイメントチャネルでは、2名のユーザー間の送金のみが可能だったため、用途が限られていました。 しかし、仮想チャネルが導入されたことで、オンチェーン上で新規チャネルを開設せずに、仲介者を通した送金の転送(つまり、複数のP2Pチャネルを利用した送金)が可能になりました。 転送を伴う支払いは一般的に「マルチホップ送金」と呼ばれ、アトミックな性質を持ちます(つまり、トランザクションに含まれるすべての部分が成功しない限り、全体が無効になります)。 アトミック送金では、[ハッシュ化されたタイムロック・コントラクト(HTLCs)](https://en.bitcoin.it/wiki/Hash_Time_Locked_Contracts)を用いて、特定の条件を満たす場合のみ支払いが実行されるため、カウンターパーティリスクが軽減されます。 @@ -217,9 +217,9 @@ sidebarDepth: 3 ブロックチェーンでチャネルを開設するには、チャネルが存在する限り継続的にオンチェーンのスマートコントラクトで資金をロックする必要があります。 これにより、チャネルに参加するユーザーの流動性に関する問題が軽減されますが、メインネットに資金をロックできるユーザー以外はチャネルに参加できなくなります。 -しかし、オフチェーンのサービスプロバイダー(OSP)が提供する台帳チャネルを活用することで、ユーザーの流動性に伴う問題を軽減することが可能です。 台帳チャネルに接続した 2 名のピアが仮想チャネルを構築することで、完全にオフチェーンのチャネルを開設し、いつでもファイナライズすることが可能になります。 +しかし、オフチェーンのサービスプロバイダー(OSP)が提供する台帳チャネルを活用することで、ユーザーの流動性に伴う問題を軽減することが可能です。 台帳チャネルに接続した2名のピアが仮想チャネルを構築することで、完全にオフチェーンのチャネルを開設し、いつでもファイナライズすることが可能になります。 -OSP の側も、複数のピアが参加するチャネルを開設できるため、支払いの転送サービスを提供する上で有益です。 もちろん、このようなサービスを利用するユーザーは OSP に手数料を支払う必要があるため、好ましくないと思うユーザーもいるでしょう。 +OSPの側も、複数のピアが参加するチャネルを開設できるため、支払いの転送サービスを提供する上で有益です。 もちろん、このようなサービスを利用するユーザーはOSPに手数料を支払う必要があるため、好ましくないと思うユーザーもいるでしょう。 ### グリーフィング攻撃 {#griefing-attacks} @@ -237,11 +237,11 @@ OSP の側も、複数のピアが参加するチャネルを開設できるた ステートチャネルの参加ユーザーは状態更新を交互に送信しあうため、「順番ベースのアプリケーション」(例:対戦型のチェスゲーム)に最も適しています。 このアプローチでは、複数の状態更新を同時に実行する必要がないため、オンチェーンのコントラクトにおいて古い状態を送信したユーザーを罰する負担が軽減されます。 ただしこの設計の副作用として、トランザクションが相手方のアクションに依存するため、レイテンシーが増化し、全般的なユーザー体験の質が損なわれる可能性があります。 -一部のステートチャネルでは、当該のオフチェーンの状態につき、2 つの一方向性の状態(「インプレックス」)に分割し、双方における同時の状態更新を可能にする「全二重設計」を採用することで、この問題を解消しています。 このような設計は、オフチェーンのスループットを高め、トランザクションの遅延を軽減します。 +一部のステートチャネルでは、当該のオフチェーンの状態につき、2つの一方向性の状態(「インプレックス」)に分割し、双方における同時の状態更新を可能にする「全二重設計」を採用することで、この問題を解消しています。 このような設計は、オフチェーンのスループットを高め、トランザクションの遅延を軽減します。 ## ステートチャネルを使う {#use-state-channels} -複数のプロジェクトにおいて、Dapp に統合できるステートチャネルの実装が提供されています: +複数のプロジェクトにおいて、Dappに統合できるステートチャネルの実装が提供されています: - [Connext](https://connext.network/) - [Kchannels](https://www.kchannels.io/) @@ -253,8 +253,8 @@ OSP の側も、複数のピアが参加するチャネルを開設できるた **ステートチャンネル** -- [イーサリアムにおけるレイヤー 2 のスケーリング・ソリューションを理解する:ステートチャネル、プラズマ、および Truebit](https://medium.com/l4-media/making-sense-of-ethereums-layer-2-scaling-solutions-state-channels-plasma-and-truebit-22cb40dcc2f4)_ - 2018 年 2 月 12 日、ジョシュ・スターク作成。_ -- [ステートチャネルの説明](https://www.jeffcoleman.ca/state-channels/)_ - 2015 年 11 月 6 日、ジェフ・コールマン作成。_ +- [イーサリアムにおけるレイヤー2のスケーリング・ソリューションを理解する:ステートチャネル、プラズマ、およびTruebit](https://medium.com/l4-media/making-sense-of-ethereums-layer-2-scaling-solutions-state-channels-plasma-and-truebit-22cb40dcc2f4)_ - 2018年2月12日、ジョシュ・スターク作成。_ +- [ステートチャネルの説明](https://www.jeffcoleman.ca/state-channels/)_ - 2015年11月6日、ジェフ・コールマン作成。_ - [ステートチャネルの基礎](https://education.district0x.io/general-topics/understanding-ethereum/basics-state-channels/) - _District0x_ - [ブロックチェーンにおけるステートチャネル:現在の状況](https://ieeexplore.ieee.org/document/9627997) diff --git a/public/content/translations/ja/developers/docs/scaling/validium/index.md b/public/content/translations/ja/developers/docs/scaling/validium/index.md index 4f34deb4276..2082a43a18f 100644 --- a/public/content/translations/ja/developers/docs/scaling/validium/index.md +++ b/public/content/translations/ja/developers/docs/scaling/validium/index.md @@ -5,17 +5,17 @@ lang: ja sidebarDepth: 3 --- -バリディアムは、 [ゼロ知識ロールアップ](/developers/docs/scaling/zk-rollups/)のような有効性証明を使用してトランザクションの完全性を強化する[スケーリングソリューション](/developers/docs/scaling/)ですが、トランザクションのデータはイーサリアムメインネットに保存されません。 オフチェーンにおけるデータの可用性が低下するというトレードオフが存在する一方で、スケーラビリティが大幅に向上します(バリディアムでは、[1 秒間に 9,000 件以上のトランザクションが実行可能です](https://blog.matter-labs.io/zkrollup-vs-validium-starkex-5614e38bc263))。 +バリディアムは、 [ゼロ知識ロールアップ](/developers/docs/scaling/zk-rollups/)のような有効性証明を使用してトランザクションの完全性を強化する[スケーリングソリューション](/developers/docs/scaling/)ですが、トランザクションのデータはイーサリアムメインネットに保存されません。 オフチェーンにおけるデータの可用性が低下するというトレードオフが存在する一方で、スケーラビリティが大幅に向上します(バリディアムでは、[1秒間に9,000件以上のトランザクションが実行可能です](https://blog.matter-labs.io/zkrollup-vs-validium-starkex-5614e38bc263))。 ## 前提知識 {#prerequisites} -[イーサリアムのスケーリング](/developers/docs/scaling/)と[レイヤー 2](/layer-2) のページを読んで理解しておくことをおすすめします。 +[イーサリアムのスケーリング](/developers/docs/scaling/)と[レイヤー2](/layer-2) のページを読んで理解しておくことをおすすめします。 ## バリディアムとは何か? {#what-is-validium} -バリディアムは、オフチェーンにおけるデータの可用性および処理能力を用いてイーサリアムメインネット外でトランザクションを処理することでスループットの向上を目指すスケーリング・ソリューションです。 ゼロ知識ロールアップ(ZK ロールアップ)と同様に、バリディアムでは[ゼロ知識証明](/glossary/#zk-proof)を発行することで、オフチェーンのトランザクションをイーサリアム上で検証します。 これにより無効な状態遷移の発生を防ぐことができるため、バリディアムチェーンのセキュリティが強化されます。 +バリディアムは、オフチェーンにおけるデータの可用性および処理能力を用いてイーサリアムメインネット外でトランザクションを処理することでスループットの向上を目指すスケーリング・ソリューションです。 ゼロ知識ロールアップ(ZKロールアップ)と同様に、バリディアムでは[ゼロ知識証明](/glossary/#zk-proof)を発行することで、オフチェーンのトランザクションをイーサリアム上で検証します。 これにより無効な状態遷移の発生を防ぐことができるため、バリディアムチェーンのセキュリティが強化されます。 -ゼロ知識証明をはじめとする「有効性証明」は、ZK-SNARK(ゼロ知識であり、簡潔かつ非双方向の知識アーギュメント)または ZK-STARK(ゼロ知識であり、スケーラブルかつ透明性が高い知識アーギュメント)のいずれかに分類されます。 詳細については、[ゼロ知識証明](https://consensys.net/blog/blockchain-explained/zero-knowledge-proofs-starks-vs-snarks/)をご覧ください。 +ゼロ知識証明をはじめとする「有効性証明」は、ZK-SNARK(ゼロ知識であり、簡潔かつ非双方向の知識アーギュメント)またはZK-STARK(ゼロ知識であり、スケーラブルかつ透明性が高い知識アーギュメント)のいずれかに分類されます。 詳細については、[ゼロ知識証明](https://consensys.net/blog/blockchain-explained/zero-knowledge-proofs-starks-vs-snarks/)をご覧ください。 バリディアムでは、ユーザーの資金はイーサリアム上のスマートコントラクトで管理されます。 バリディアムは、ゼロ知識ロールアップの場合とよく似たほぼ瞬時の出金が可能です。出金リクエストに対する有効性証明がメインネット上で検証されると、ユーザーは[マークル証明](/developers/tutorials/merkle-proofs-for-offline-data-integrity/)を提供することで資金を引き出せるようになります。 マークル証明は、ユーザーの出金トランザクションが検証済みのトランザクション・バッチに含まれることを確認するもので、オンチェーンのコントラクトが当該の出金を処理することを許可します。 @@ -59,7 +59,7 @@ sidebarDepth: 3 ### 入金と出金 {#deposits-and-withdrawals} -各ユーザーは、オンチェーンのコントラクトに ETH(またはその他の ERC 互換トークン)を預け入れることで、イーサリアムからバリディアムに資金を移動できます。 当該コントラクトが入金イベントをオフチェーンのバリディアムにリレーし、入金額と同じ額がバリディアムチェーン上のユーザーアドレスに追加されます。 オペレーターは同時に、入金トランザクションを新規バッチに追加します。 +各ユーザーは、オンチェーンのコントラクトにETH(またはその他のERC互換トークン)を預け入れることで、イーサリアムからバリディアムに資金を移動できます。 当該コントラクトが入金イベントをオフチェーンのバリディアムにリレーし、入金額と同じ額がバリディアムチェーン上のユーザーアドレスに追加されます。 オペレーターは同時に、入金トランザクションを新規バッチに追加します。 資金をメインネットに戻したい場合は、バリディアム上で出金トランザクションを開始し、オペレーターに送信します。オペレーターは、この出金リクエストに対して検証を行った上で、次のバッチに追加します。 また、バリディアムチェーン上のユーザー資産は、ユーザーがバリディアムチェーンから退出する事前に破壊されます。 当該バッチに関連付けられた有効性証明が確認だれると、ユーザーはメインのコントラクトを呼び出し、初回のデポジットの残余分を引き出すことができます。 @@ -69,7 +69,7 @@ sidebarDepth: 3 オペレーターは、複数のトランザクションからなるバッチを実行した後、それに関連した有効性証明を検証者コントラクトに送信し、メインのコントラクトに新規のステートルートを提案します。 この証明が有効であれば、メインのコントラクトはバリディアムの状態を更新し、当該バッチに含まれるトランザクションの処理を確定します。 -ゼロ知識ロールアップとは異なり、バリディアム上のブロック生成者は、トランザクションを含むバッチのトランザクションデータを公開する必要がありません(ブロックヘッダーのみ公開すればよいです)。 これによりバリディアムは、メインのイーサリアムチェーンに状態データを`calldata`として公開する「ハイブリッド型」のスケーリング・プロトコル(つまり、[レイヤー 2](/layer-2/))ではなく、純粋にオフチェーンのスケーリング・プロトコルであると言えます。 +ゼロ知識ロールアップとは異なり、バリディアム上のブロック生成者は、トランザクションを含むバッチのトランザクションデータを公開する必要がありません(ブロックヘッダーのみ公開すればよいです)。 これによりバリディアムは、メインのイーサリアムチェーンに状態データを`calldata`として公開する「ハイブリッド型」のスケーリング・プロトコル(つまり、[レイヤー2](/layer-2/))ではなく、純粋にオフチェーンのスケーリング・プロトコルであると言えます。 ### データ可用性 {#data-availability} @@ -85,9 +85,9 @@ sidebarDepth: 3 #### データ可用性委員会(DAC) {#data-availability-committee} -一部のバリディアム・ソリューションでは、オフチェーンにおけるデータの可用性を保証するために、状態コピーの保存およびデータ可用性証明の提供を担う信頼されるエンティティの集団を指名します(これらのエンティティを総称して「データ可用性委員会」(DAC)と呼びます)。 DAC は、メンバーであるユーザーの数が限定されるため、導入やメンバー間の連携が容易になります。 +一部のバリディアム・ソリューションでは、オフチェーンにおけるデータの可用性を保証するために、状態コピーの保存およびデータ可用性証明の提供を担う信頼されるエンティティの集団を指名します(これらのエンティティを総称して「データ可用性委員会」(DAC)と呼びます)。 DACは、メンバーであるユーザーの数が限定されるため、導入やメンバー間の連携が容易になります。 -その一方で、通常ユーザーは、データを必要とする際に(例:マークル証明を生成するため)、その可用性について DAC を信頼しなければならなくなります。 また、DAC のメンバーが[悪意のアクターに侵入され](https://notes.ethereum.org/DD7GyItYQ02d0ax_X-UbWg?view)、オフチェーンのデータを秘匿してしまう可能性があります。 +その一方で、通常ユーザーは、データを必要とする際に(例:マークル証明を生成するため)、その可用性についてDACを信頼しなければならなくなります。 また、DACのメンバーが[悪意のアクターに侵入され](https://notes.ethereum.org/DD7GyItYQ02d0ax_X-UbWg?view)、オフチェーンのデータを秘匿してしまう可能性があります。 [バリディアムにおけるデータ可用性委員会の詳細](https://medium.com/starkware/data-availability-e5564c416424)をご覧ください。 @@ -99,66 +99,66 @@ sidebarDepth: 3 [バリディアムにおけるボンド提供型のデータ可用性の詳細](https://blog.matter-labs.io/zkporter-a-breakthrough-in-l2-scaling-ed5e48842fbf)をご覧ください。 -## Volitions とバリディアム {#volitions-and-validium} +## Volitionsとバリディアム {#volitions-and-validium} -バリディアムは様々な利点を提供する一方で、トレードオフ(特に、データの可用性)も存在します。 他の多くのスケーリング・ソリューションと同様に、バリディアムの様々な実装は具体的なユースケースに合わせて開発されており、そのひとつとして Volitions が挙げられます。 +バリディアムは様々な利点を提供する一方で、トレードオフ(特に、データの可用性)も存在します。 他の多くのスケーリング・ソリューションと同様に、バリディアムの様々な実装は具体的なユースケースに合わせて開発されており、そのひとつとしてVolitionsが挙げられます。 -Volitions は、ゼロ知識ロールアップとバリディアムチェーンを組み合わせたサービスであるため、これら 2 つのスケーリング・ソリューションを使い分けることが可能です。 Volitions を使えば、一部のトランザクションについてはバリディアムによるオフチェーンのデータ可用性を活用しつつ、必要に応じてオンデータのデータ可用性(ゼロ知識ロールアップ)も利用できる自由度を確保できるのです。 これにより、ユースケースごとの要請に応じて、どのトレードオフを選択するのかをユーザーが決定できます。 +Volitionsは、ゼロ知識ロールアップとバリディアムチェーンを組み合わせたサービスであるため、これら2つのスケーリング・ソリューションを使い分けることが可能です。 Volitionsを使えば、一部のトランザクションについてはバリディアムによるオフチェーンのデータ可用性を活用しつつ、必要に応じてオンデータのデータ可用性(ゼロ知識ロールアップ)も利用できる自由度を確保できるのです。 これにより、ユースケースごとの要請に応じて、どのトレードオフを選択するのかをユーザーが決定できます。 分散型取引所(DEX)の場合、高価値の取引に対してスケーラブルかつプライベートなインフラを提供するバリディアムが適しているかも知れません。 しかし同時に、より高いセキュリティ保証とトラストレス性を望むユーザーのために、ゼロ知識ロールアップを使用することもできます。 -## バリディアムにおける EVM との互換性 {#validiums-and-evm-compatibility} +## バリディアムにおけるEVMとの互換性 {#validiums-and-evm-compatibility} バリディアムは主に、ゼロ知識ロールアップと同じくトークンのスワップや決済といったシンプルな用途に適しています。 ゼロ知識の証明サーキットで[EVM](/developers/docs/evm/)の命令を証明しようとすると大きな間接費用が発生するため、バリディアムの実装において一般的な計算処理やスマートコントラクトの実行をサポートするのは困難です。 -一部のバリディアムのプロジェクトでは、効率的な証明のために最適化されたカスタムのバイトコードをコンパイルする際に EVM 互換の言語(例:Solidity、Vyper)を用いることで、この問題を回避しようとしています。 このアプローチは、ゼロ知識証明に対応したより新しい VM の場合に重要な EVM オペコードをサポートしていない可能性があるため、デベロッパは最善の利用体験を提供するために高レベル言語で直接コーディングしなければならないという欠点があります。 これにより、デベロッパはまったく新しい開発スタックを用いて Dapp を開発しなければならなくなり、現在のイーサリアム・インフラとの互換性が失われてしまうため、問題がさらに悪化します。 +一部のバリディアムのプロジェクトでは、効率的な証明のために最適化されたカスタムのバイトコードをコンパイルする際にEVM互換の言語(例:Solidity、Vyper)を用いることで、この問題を回避しようとしています。 このアプローチは、ゼロ知識証明に対応したより新しいVMの場合に重要なEVMオペコードをサポートしていない可能性があるため、デベロッパは最善の利用体験を提供するために高レベル言語で直接コーディングしなければならないという欠点があります。 これにより、デベロッパはまったく新しい開発スタックを用いてDappを開発しなければならなくなり、現在のイーサリアム・インフラとの互換性が失われてしまうため、問題がさらに悪化します。 -しかし一部の開発チームでは、既存の EVM オペコードをゼロ知識証明サーキットのために最適化する作業を進めています。 この取り組みを通じて、プログラムの正確な実行を証明する EVM 互換の VM としてのゼロ知識イーサリアム仮想マシン(zkEVM)の開発が期待されています。 ZkEVM が実現した場合、バリディアムチェーンはオフチェーンでスマートコントラクトを実行し、有効性証明を送信することで、オフチェーンにおける計算をイーサリアム上で(再実行せずに)証明することができます。 +しかし一部の開発チームでは、既存のEVMオペコードをゼロ知識証明サーキットのために最適化する作業を進めています。 この取り組みを通じて、プログラムの正確な実行を証明するEVM互換のVMとしてのゼロ知識イーサリアム仮想マシン(zkEVM)の開発が期待されています。 ZkEVMが実現した場合、バリディアムチェーンはオフチェーンでスマートコントラクトを実行し、有効性証明を送信することで、オフチェーンにおける計算をイーサリアム上で(再実行せずに)証明することができます。 -[zkEVM の詳細](https://www.alchemy.com/overviews/zkevm)をご覧ください。 +[zkEVMの詳細](https://www.alchemy.com/overviews/zkevm)をご覧ください。 ## バリディアムは、イーサリアムのスケーラビリティをどのように向上させるのか? {#scaling-ethereum-with-validiums} ### 1. オフチェーンにおけるデータ保存 {#off-chain-data-storage} -オプティミスティック・ロールアップやゼロ知識ロールアップといったレイヤー 2 のスケーリングプロジェクトでは、純粋にオフチェーンのみを活用したスケーリング・プロトコル(例:[プラズマ](/developers/docs/scaling/plasma/))の場合に実現可能な無限のスケーラビリティを犠牲にする代わりに、トランザクションデータの一部を L1 上で公開することでセキュリティを強化しています。 しかし同時に、ロールアップのスケーラビリティに関する特性は、イーサリアムメインネットのデータ帯域により制限されます([データシャーディング](/upgrades/sharding/)では、この理由により、イーサリアムのデータストレージ容量の向上を提案しています)。 +オプティミスティック・ロールアップやゼロ知識ロールアップといったレイヤー2のスケーリングプロジェクトでは、純粋にオフチェーンのみを活用したスケーリング・プロトコル(例:[プラズマ](/developers/docs/scaling/plasma/))の場合に実現可能な無限のスケーラビリティを犠牲にする代わりに、トランザクションデータの一部をL1上で公開することでセキュリティを強化しています。 しかし同時に、ロールアップのスケーラビリティに関する特性は、イーサリアムメインネットのデータ帯域により制限されます([データシャーディング](/roadmap/danksharding/)では、この理由により、イーサリアムのデータストレージ容量の向上を提案しています)。 バリディアムでは、すべてのトランザクションデータをオフチェーンで保存し、状態アップデートをメインのイーサリアムチェーンにリレーする際にのみ状態コミットメント(および有効性証明)を送信することでスケーラビリティを達成しています。 しかしバリディアムは、有効性証明を用いることで、その他の純粋にオフチェーンのスケーリングソリューション(プラズマや[サイドチェーン](/developers/docs/scaling/sidechains/))よりも高いセキュリティ保証を提供しています。 バリディアムでは、イーサリアムがオフチェーンのトランザクションを検証する前に処理しなければならないデータ量が軽減されるため、メインネットのスループットを大きく改善できる設計を実現しています。 ### 2. 再帰的証明 {#recursive-proofs} -再帰的な証明とは、他の証明の有効性を証明する有効性証明です。 このような「証明に対する証明」は、最終的にこれまで作成されたすべての証明を証明できる 1 つの最終証明が作成されるまで、複数の証明を再帰的に集約することで実行されます。 再帰的証明は、1 件の有効性証明で検証できるトランザクションの数を増やすため、ブロックチェーンの処理速度におけるスケーラビリティ向上を実現します。 +再帰的な証明とは、他の証明の有効性を証明する有効性証明です。 このような「証明に対する証明」は、最終的にこれまで作成されたすべての証明を証明できる1つの最終証明が作成されるまで、複数の証明を再帰的に集約することで実行されます。 再帰的証明は、1件の有効性証明で検証できるトランザクションの数を増やすため、ブロックチェーンの処理速度におけるスケーラビリティ向上を実現します。 -通常、バリディアムのオペレーターがイーサリアムに提出する有効性証明は、単一のブロック全体を検証します。 これに対し、再帰的証明では、1 件の再帰的証明を用いてバリディアム上の複数のブロックの有効性を同時に確認することができます。これは、再帰的証明のサーキットにおいては、複数のブロック証明を 1 件の最終証明に再帰的に集約できるためです。 オンチェーンの検証者コントラクトがこの再帰的証明を承認すると、その対象である裏付けのブロックすべてがただちに確定します。 +通常、バリディアムのオペレーターがイーサリアムに提出する有効性証明は、単一のブロック全体を検証します。 これに対し、再帰的証明では、1件の再帰的証明を用いてバリディアム上の複数のブロックの有効性を同時に確認することができます。これは、再帰的証明のサーキットにおいては、複数のブロック証明を1件の最終証明に再帰的に集約できるためです。 オンチェーンの検証者コントラクトがこの再帰的証明を承認すると、その対象である裏付けのブロックすべてがただちに確定します。 ## バリディアムの長所と短所 {#pros-and-cons-of-validium} -| 長所 | 短所 | -| -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 有効性証明により、オフチェーンにおけるトランザクションの完全性が確保でき、オペレーターが無効な状態アップデートをファイナライズできなくなる。 | 有効性証明を生成するには特別なハードウェアが必要なため、分散化が低下するリスクがある。 | -| ユーザーがより効率的に資金を利用できる(イーサリアムへの資金引き出しにおいて、遅延が発生しない)。 | 汎用的な計算/スマートコントラクトに対するサポートが限定的であり、開発には特殊な言語が必要である。 | -| 高価値の取引用に用いられる不正証明ベースのシステムを標的とする一部の経済的攻撃に対する脆弱性がない。 | ゼロ知識証明を生成するには高い処理能力が必要であり、低スループットの用途においてはコスト効率が悪い。 | -| calldata をイーサリアムメインネットに送信しないため、ユーザーのガス代が軽減される。 | ユーザーの主観ではファイナリティを得るまでの時間が長い(ゼロ知識証明を生成するのに 10〜30 分が必要)が、紛争による遅延が生じないため、完全なファイナリティはより迅速に得られる。 | -| トランザクションにおけるプライバシーやスケーラビリティが重視される資金取引やブロックチェーンゲームなど、特定のユースケースに適している。 | 所有権に対するマークル証明を生成するには常にオフチェーンのデータが利用可能でなければならないため、ユーザーの資金引き出しが妨害される可能性がある。 | -| オフチェーンにおけるデータの可用性により、より高いスループットとスケーラビリティが実現できる。 | 純粋に暗号論的なセキュリティメカニズムに依存しているゼロ知識ロールアップとは異なり、信頼性の前提と暗号経済的なインセンティブに依存したセキュリティモデルである。 | +| 長所 | 短所 | +| ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| 有効性証明により、オフチェーンにおけるトランザクションの完全性が確保でき、オペレーターが無効な状態アップデートをファイナライズできなくなる。 | 有効性証明を生成するには特別なハードウェアが必要なため、分散化が低下するリスクがある。 | +| ユーザーがより効率的に資金を利用できる(イーサリアムへの資金引き出しにおいて、遅延が発生しない)。 | 汎用的な計算/スマートコントラクトに対するサポートが限定的であり、開発には特殊な言語が必要である。 | +| 高価値の取引用に用いられる不正証明ベースのシステムを標的とする一部の経済的攻撃に対する脆弱性がない。 | ゼロ知識証明を生成するには高い処理能力が必要であり、低スループットの用途においてはコスト効率が悪い。 | +| calldataをイーサリアムメインネットに送信しないため、ユーザーのガス代が軽減される。 | ユーザーの主観ではファイナリティを得るまでの時間が長い(ゼロ知識証明を生成するのに10〜30分が必要)が、紛争による遅延が生じないため、完全なファイナリティはより迅速に得られる。 | +| トランザクションにおけるプライバシーやスケーラビリティが重視される資金取引やブロックチェーンゲームなど、特定のユースケースに適している。 | 所有権に対するマークル証明を生成するには常にオフチェーンのデータが利用可能でなければならないため、ユーザーの資金引き出しが妨害される可能性がある。 | +| オフチェーンにおけるデータの可用性により、より高いスループットとスケーラビリティが実現できる。 | 純粋に暗号論的なセキュリティメカニズムに依存しているゼロ知識ロールアップとは異なり、信頼性の前提と暗号経済的なインセンティブに依存したセキュリティモデルである。 | -### バリディアム/Volitions の活用 {#use-validium-and-volitions} +### バリディアム/Volitionsの活用 {#use-validium-and-volitions} -複数のプロジェクトにより、Dapp に組み込み可能なバリディアムおよび Volitions の実装が提供されています。 +複数のプロジェクトにより、Dappに組み込み可能なバリディアムおよびVolitionsの実装が提供されています。 -**StarkWare StarkEx** - _StarkEx は、有効性証明ベースのイーサリアムレイヤー 2((L2)の スケーリング・ソリューションです。 ゼロ知識ロールアップあるいはバリディアムのいずれかを用いたデータ可用性モードを選択できます。_ +**StarkWare StarkEx** - _StarkExは、有効性証明ベースのイーサリアムレイヤー2((L2)の スケーリング・ソリューションです。 ゼロ知識ロールアップあるいはバリディアムのいずれかを用いたデータ可用性モードを選択できます。_ - [ドキュメント](https://docs.starkware.co/starkex-v4/starkex-deep-dive/data-availability-modes#validium) - [ウェブサイト](https://starkware.co/starkex/) -**Matter Labs zkPorter**- _zkPorter は、ゼロ知識ロールアップとシャーディングを結合したハイブリッド型のアプローチによりデータ化要請を追跡する、レイヤー 2 のスケーリング・プロトコルです。 任意の数のシャードをサポートしており、シャードごとに異なるデータ可用性ポリシーを定めることができます。_ +**Matter Labs zkPorter**- _zkPorterは、ゼロ知識ロールアップとシャーディングを結合したハイブリッド型のアプローチによりデータ化要請を追跡する、レイヤー2のスケーリング・プロトコルです。 任意の数のシャードをサポートしており、シャードごとに異なるデータ可用性ポリシーを定めることができます。_ - [ドキュメント](https://docs.zksync.io/zkevm/#what-is-zkporter) - [ウェブサイト](https://zksync.io/) ## 参考文献 {#further-reading} -- [バリディアムとレイヤー 2 のツー・バイ・ツー:第 99 号](https://www.buildblockchain.tech/newsletter/issues/no-99-validium-and-the-layer-2-two-by-two) +- [バリディアムとレイヤー2のツー・バイ・ツー:第99号](https://www.buildblockchain.tech/newsletter/issues/no-99-validium-and-the-layer-2-two-by-two) - [ゼロ知識ロールアップとバリディアムの比較](https://blog.matter-labs.io/zkrollup-vs-validium-starkex-5614e38bc263) -- [Volition および新たなデータ可用性のアプローチ](https://medium.com/starkware/volition-and-the-emerging-data-availability-spectrum-87e8bfa09bb) -- [ロールアップ、バリディアム、そして Volitions:イーサリアムにおける最新のスケーリングソリューションについて知る](https://www.defipulse.com/blog/rollups-validiums-and-volitions-learn-about-the-hottest-ethereum-scaling-solutions) +- [Volitionおよび新たなデータ可用性のアプローチ](https://medium.com/starkware/volition-and-the-emerging-data-availability-spectrum-87e8bfa09bb) +- [ロールアップ、バリディアム、そしてVolitions:イーサリアムにおける最新のスケーリングソリューションについて知る](https://www.defipulse.com/blog/rollups-validiums-and-volitions-learn-about-the-hottest-ethereum-scaling-solutions) diff --git a/public/content/translations/ja/developers/docs/scaling/zk-rollups/index.md b/public/content/translations/ja/developers/docs/scaling/zk-rollups/index.md index 7a2f24d257b..ecd73e8f859 100644 --- a/public/content/translations/ja/developers/docs/scaling/zk-rollups/index.md +++ b/public/content/translations/ja/developers/docs/scaling/zk-rollups/index.md @@ -4,107 +4,107 @@ description: イーサリアムコミュニティで利用されるスケーリ lang: ja --- -ゼロ知識ロールアップ(ZK ロールアップ)とは、計算および状態保存をオフチェーンで実行することで、イーサリアムメインネットのスループットを向上するための、レイヤー 2 の[スケーリングソリューション](/developers/docs/scaling/)です。 ZK ロールアップは、数千件のトランザクションをバッチ処理した上で、最低限のサマリーデータのみをメインネットに書き込みます。 このサマリーデータには、イーサリアムの状態に対して変更すべき事項の定義と、それらの変更が正しいことを示す暗号学的証明が含まれます。 +ゼロ知識ロールアップ(ZKロールアップ)とは、計算および状態保存をオフチェーンで実行することで、イーサリアムメインネットのスループットを向上するための、レイヤー2の[スケーリングソリューション](/developers/docs/scaling/)です。 ZKロールアップは、数千件のトランザクションをバッチ処理した上で、最低限のサマリーデータのみをメインネットに書き込みます。 このサマリーデータには、イーサリアムの状態に対して変更すべき事項の定義と、それらの変更が正しいことを示す暗号学的証明が含まれます。 ## 前提知識 {#prerequisites} -[イーサリアムのスケーリング](/developers/docs/scaling/)と[レイヤー 2](/layer-2)のページを読んで理解しておくことをお勧めします。 +[イーサリアムのスケーリング](/developers/docs/scaling/)と[レイヤー2](/layer-2)のページを読んで理解しておくことをお勧めします。 ## ゼロ知識ロールアップとは何か? {#what-are-zk-rollups} -**ゼロ知識ロールアップ(ZK ロールアップ)**は、複数のトランザクションをひとつのバッチにまとめて(ロールアップする)、このバッチをオフチェーンで実行します。 計算をオフチェーンで実行することで、ブロックチェーンに書き込む必要があるデータの量を削減することができます。 ZK ロールアップのオペレーターは、個別のトランザクションを送信する代わりに、バッチに含まれるすべてのトランザクションを実行するのに必要な変更のサマリーのみを送信します。 同時に、これらの変更の正しさを証明するために、[有効性証明](/glossary/#validity-proof)を生成します。 この有効性証明は、暗号論的な確実性に基づき、イーサリアムの状態に対する提案された変更が、バッチに含まれるすべてのトランザクションを実行した真の結果であることを証明します。 +**ゼロ知識ロールアップ(ZKロールアップ)**は、複数のトランザクションをひとつのバッチにまとめて(ロールアップする)、このバッチをオフチェーンで実行します。 計算をオフチェーンで実行することで、ブロックチェーンに書き込む必要があるデータの量を削減することができます。 ZKロールアップのオペレーターは、個別のトランザクションを送信する代わりに、バッチに含まれるすべてのトランザクションを実行するのに必要な変更のサマリーのみを送信します。 同時に、これらの変更の正しさを証明するために、[有効性証明](/glossary/#validity-proof)を生成します。 -ZK ロールアップの状態は、イーサリアムネットワーク上でデプロイされたスマートコントラクトにより管理されます。 ZK ロールアップの状態を更新するために、ZK ロールアップのノードは検証のための有効性証明を送信する必要があります。 前述したように、この有効性証明は、ロールアップにより提案された状態の変更が、バッチに含まれるトランザクションを実行した結果と同一であることを暗号論的に保証します。 つまり、ZK ロールアップを用いる場合、[オプティミスティック・ロールアップ](/developers/docs/scaling/optimistic-rollups/)の場合のようにすべてのトランザクションデータをイーサリアムに書き込む必要はなく、有効性証明を提要するだけでイーサリアム上のトランザクションをファイナライズすることができます。 +ZKロールアップの状態は、イーサリアムネットワーク上でデプロイされたスマートコントラクトにより管理されます。 ZKロールアップの状態を更新するために、ZKロールアップのノードは検証のための有効性証明を送信する必要があります。 前述したように、この有効性証明は、ロールアップにより提案された状態の変更が、バッチに含まれるトランザクションを実行した結果と同一であることを暗号論的に保証します。 つまり、ZKロールアップを用いる場合、[オプティミスティック・ロールアップ](/developers/docs/scaling/optimistic-rollups/)の場合のようにすべてのトランザクションデータをイーサリアムに書き込む必要はなく、有効性証明を提要するだけでイーサリアム上のトランザクションをファイナライズすることができます。 -ZK ロールアップのコントラクトが有効性証明が正しいことを確認した時点で出金トランザクションが実行されるため、ZK ロールアップからイーサリアムの資金移動において遅延が発生しません。 一方、オプティミスティック・ロールアップからの資金の引き出しの場合、すべてのユーザーが[不正証明](/glossary/#fraud-proof)を用いて出金トランザクションに対してチャレンジできるようにするための遅延期間が必要になります。 +ZKロールアップのコントラクトが有効性証明が正しいことを確認した時点で出金トランザクションが実行されるため、ZKロールアップからイーサリアムの資金移動において遅延が発生しません。 一方、オプティミスティック・ロールアップからの資金の引き出しの場合、すべてのユーザーが[不正証明](/glossary/#fraud-proof)を用いて出金トランザクションに対してチャレンジできるようにするための遅延期間が必要になります。 -ZK ロールアップでは、トランザクションを`calldata`としてイーサリアムに書き込みます。 `calldata` とは、スマートコントラクトの関数を外部から呼び出す際に含まれるデータが格納される場所を指します。 `calldata` に含まれる情報はブロックチェーン上で公開されるため、すべてのユーザーが独自にロールアップの状態を再構築することができます。 ZK ロールアップでは、圧縮技術を用いてトランザクションデータのサイズを縮小します。例えば、アカウントはアドレスではなくインデックスで表されるため、28 バイト分のデータが節約できます。 ロールアップにおいては、オンチェーンへのデータ公開が大きなコストとなるため、データ圧縮はユーザー費用を引き下げる効果を持ちます。 +ZKロールアップでは、トランザクションを`calldata`としてイーサリアムに書き込みます。 `calldata` とは、スマートコントラクトの関数を外部から呼び出す際に含まれるデータが格納される場所を指します。 `calldata` に含まれる情報はブロックチェーン上で公開されるため、すべてのユーザーが独自にロールアップの状態を再構築することができます。 ZKロールアップでは、圧縮技術を用いてトランザクションデータのサイズを縮小します。例えば、アカウントはアドレスではなくインデックスで表されるため、28バイト分のデータが節約できます。 ロールアップにおいては、オンチェーンへのデータ公開が大きなコストとなるため、データ圧縮はユーザー費用を引き下げる効果を持ちます。 -## ZK ロールアップは、イーサリアムとどのようにやりとりするか? {#zk-rollups-and-ethereum} +## ZKロールアップは、イーサリアムとどのようにやりとりするか? {#zk-rollups-and-ethereum} -ZK ロールアップのチェーンは、イーサリアムブロックチェーン上で動作するオフチェーンのプロトコルであり、イーサリアムのオンチェーンのスマートコントラクトにより管理されます。 ZK ロールアップでは、メインネット外でトランザクションを実行しますが、オフチェーンのトランザクションをまとめたバッチをオンチェーンのロールアップコントラクトに定期的に書き込みます。 このトランザクション記録は、イーサリアムブロックチェーンの場合と同様に改変不可であり、ZK ロールアップのチェーンを形成します。 +ZKロールアップのチェーンは、イーサリアムブロックチェーン上で動作するオフチェーンのプロトコルであり、イーサリアムのオンチェーンのスマートコントラクトにより管理されます。 ZKロールアップでは、メインネット外でトランザクションを実行しますが、オフチェーンのトランザクションをまとめたバッチをオンチェーンのロールアップコントラクトに定期的に書き込みます。 このトランザクション記録は、イーサリアムブロックチェーンの場合と同様に改変不可であり、ZKロールアップのチェーンを形成します。 -ZK ロールアップのコアアーキテクチャは、以下のコンポーネントで構成されます: +ZKロールアップのコアアーキテクチャは、以下のコンポーネントで構成されます: -1. **オンチェーンのコントラクト**: 前述した通り、ZK ロールアップのプロトコルはイーサリアム上で実行されるスマートコントラクトにより管理されます。 これには、ロールアップの各ブロックを保存し、入金状態を追跡し、状態更新を監視するメインのコントラクトが含まれます。 オンチェーンにおけるもう一つのコントラクト(検証者コントラクト)は、ブロック生成者が送信したゼロ知識証明を検証します。 つまり、イーサリアムは ZK ロールアップにおけるベースレイヤー(「レイヤー 1」)の役割を果たします。 +1. **オンチェーンのコントラクト**: 前述した通り、ZKロールアップのプロトコルはイーサリアム上で実行されるスマートコントラクトにより管理されます。 これには、ロールアップの各ブロックを保存し、入金状態を追跡し、状態更新を監視するメインのコントラクトが含まれます。 オンチェーンにおけるもう一つのコントラクト(検証者コントラクト)は、ブロック生成者が送信したゼロ知識証明を検証します。 つまり、イーサリアムはZKロールアップにおけるベースレイヤー(「レイヤー1」)の役割を果たします。 -2. **オフチェーンの仮想マシン(VM)**: ZK ロールアップのプロトコルはイーサリアム上に置かれますが、トランザクションの実行および状態保存は、[EVM](/developers/docs/evm/)とは独立した別個の仮想マシン上で行われます。 このオフチェーンの仮想マシンは、ZK ロールアップ上のトランザクションに対する実行環境であり、ZK ロールアップのプロトコルにおける第 2 層(つまり、「レイヤー 2」)の役割を果たします。 イーサリアムメインネット上で検証された有効性証明により、オフチェーンの VM における状態遷移の正しさが保証されます。 +2. **オフチェーンの仮想マシン(VM)**: ZKロールアップのプロトコルはイーサリアム上に置かれますが、トランザクションの実行および状態保存は、[EVM](/developers/docs/evm/)とは独立した別個の仮想マシン上で行われます。 このオフチェーンの仮想マシンは、ZKロールアップ上のトランザクションに対する実行環境であり、ZKロールアップのプロトコルにおける第2層(つまり、「レイヤー2」)の役割を果たします。 イーサリアムメインネット上で検証された有効性証明により、オフチェーンのVMにおける状態遷移の正しさが保証されます。 -ZK ロールアップは、イーサリアムとは別個に実行されるもののセキュリティについてはイーサリアムに依存するオフチェーンのプロトコルであるため、「ハイブリッド型のスケーリング・ソリューション」であると言えます。 具体的には、イーサリアムネットワークが ZK ロールアップにおける状態更新が有効であることを強制し、ロールアップの状態更新の裏付けとなるデータの可用性を保証します。 この結果、ZK ロールアップは、それ自体がセキュリティ特性の維持に責任を負う[サイドチェーン](/developers/docs/scaling/sidechains/)や、[バリディアム](/developers/docs/scaling/validium/)のように、有効性証明によりイーサリアム上でトランザクションを検証する点は共通しているもののトランザクションデータを別の場所に保存する、純粋にオフチェーンのみを活用したスケーリング・ソリューションと比較すると、大幅に安全性が高いと言えます。 +ZKロールアップは、イーサリアムとは別個に実行されるもののセキュリティについてはイーサリアムに依存するオフチェーンのプロトコルであるため、「ハイブリッド型のスケーリング・ソリューション」であると言えます。 具体的には、イーサリアムネットワークがZKロールアップにおける状態更新が有効であることを強制し、ロールアップの状態更新の裏付けとなるデータの可用性を保証します。 この結果、ZKロールアップは、それ自体がセキュリティ特性の維持に責任を負う[サイドチェーン](/developers/docs/scaling/sidechains/)や、[バリディアム](/developers/docs/scaling/validium/)のように、有効性証明によりイーサリアム上でトランザクションを検証する点は共通しているもののトランザクションデータを別の場所に保存する、純粋にオフチェーンのみを活用したスケーリング・ソリューションと比較すると、大幅に安全性が高いと言えます。 -ZK ロールアップでは、以下の事項につきメインのイーサリアムプロトコルに依存します: +ZKロールアップでは、以下の事項につきメインのイーサリアムプロトコルに依存します: ### データ可用性 {#data-availability} -ZK ロールアップでは、オフチェーンで処理されたすべてのトランザクションの状態データをイーサリアムに書き込みます。 個人または企業のユーザーは、このデータを用いてロールアップの状態を再現し、チェーン自体を検証することができます。 イーサリアムでは、ネットワークのすべての参加者に対し、このデータを`calldata`として提供します。 +ZKロールアップでは、オフチェーンで処理されたすべてのトランザクションの状態データをイーサリアムに書き込みます。 個人または企業のユーザーは、このデータを用いてロールアップの状態を再現し、チェーン自体を検証することができます。 イーサリアムでは、ネットワークのすべての参加者に対し、このデータを`calldata`として提供します。 -ZK ロールアップでは、状態遷移の正しさがすでに有効性証明により検証済みであるため、オンチェーンに書き込む必要があるトランザクションデータの量は多くありません。 それにも関わらず、データをオンチェーンで保存するのが重要である理由は、これにより LC チェーンの状態をパーミッションレスかつ独立して検証できるようになるからであり、これにより、トランザクションをバッチ化して送信するすべてのユーザーは、悪意のオペレーターがチェーンを検閲したり、凍結したりするのを防ぐことができます。 +ZKロールアップでは、状態遷移の正しさがすでに有効性証明により検証済みであるため、オンチェーンに書き込む必要があるトランザクションデータの量は多くありません。 それにも関わらず、データをオンチェーンで保存するのが重要である理由は、これによりLCチェーンの状態をパーミッションレスかつ独立して検証できるようになるからであり、これにより、トランザクションをバッチ化して送信するすべてのユーザーは、悪意のオペレーターがチェーンを検閲したり、凍結したりするのを防ぐことができます。 ユーザーは、ロールアップとのやりとりを実行する場合にオンチェーンでなければなりません。 状態データへのアクセス権限を持たないユーザーは、各自のアカウント残高を照会したり、状態情報に依存する取引(例:出金)を開始することができません。 ### トランザクションのファイナリティ {#transaction-finality} -イーサリアムは、ZK ロールアップに対する決済レイヤーの役割を果たします。つまり、L2 上のトランザクションは、L1 のコントラクトが有効性証明を承認してはじめてファイナライズされます。 これにより、すべてのトランザクションがメインネット上の承認を必要とするため、悪意のオペレーターがチェーンを毀損する(例:ロールアップ上の資金を窃盗する)リスクが除去されます。 イーサリアムはさらに、L1 上でファイナライズされた操作は取消不能であることを保証します。 +イーサリアムは、ZKロールアップに対する決済レイヤーの役割を果たします。つまり、L2上のトランザクションは、L1のコントラクトが有効性証明を承認してはじめてファイナライズされます。 これにより、すべてのトランザクションがメインネット上の承認を必要とするため、悪意のオペレーターがチェーンを毀損する(例:ロールアップ上の資金を窃盗する)リスクが除去されます。 イーサリアムはさらに、L1上でファイナライズされた操作は取消不能であることを保証します。 ### 検閲耐性 {#censorship-resistance} -大部分の ZK ロールアップでは、トンラザクションの実行、バッチの生成、および L1 へのブロック送信を「スーパーノード」(オペレーターと呼ぶ)が担います。 このアプローチは、効率性を向上させる一方で、検閲のリスクを高めるものです。ZK ロールアップのオペレーターが悪意を持つ場合、特定のトランザクションをバッチに含めないことで、それらのトランザクションを行いたいユーザーを検閲できるからです。 +大部分のZKロールアップでは、トンラザクションの実行、バッチの生成、およびL1へのブロック送信を「スーパーノード」(オペレーターと呼ぶ)が担います。 このアプローチは、効率性を向上させる一方で、検閲のリスクを高めるものです。ZKロールアップのオペレーターが悪意を持つ場合、特定のトランザクションをバッチに含めないことで、それらのトランザクションを行いたいユーザーを検閲できるからです。 -ZK ロールアップでは、セキュリティ対策として、ユーザーがオペレーターの検閲を受けていると考える場合はロールアップ上のコントラクトを直接メインネットに送信することを許可しています。 これにより、オペレーターの許可なしで、ZK ロールアップからイーサリアムへの出金を強制実行することができます。 +ZKロールアップでは、セキュリティ対策として、ユーザーがオペレーターの検閲を受けていると考える場合はロールアップ上のコントラクトを直接メインネットに送信することを許可しています。 これにより、オペレーターの許可なしで、ZKロールアップからイーサリアムへの出金を強制実行することができます。 -## ZK ロールアップの仕組みとは? {#how-do-zk-rollups-work} +## ZKロールアップの仕組みとは? {#how-do-zk-rollups-work} ### トランザクション {#transactions} -ZK ロールアップのユーザーは、トランザクションに署名した上で、トランザクションの処理および次のバッチへの追加のために L2 オペレーターに送信します。 場合により、このオペレーターは、トランザクションを実行し、バッチ化した上で L1 に送信する中央集権的なエンティティ(シーケンサーと呼ぶ)の場合があります。 このシステムにおけるシーケンサーは、L2 のブロックを生成し、ロールアップのトランザクションを ZK ロールアップのコントラクトに追加できる唯一のエンティティです。 +ZKロールアップのユーザーは、トランザクションに署名した上で、トランザクションの処理および次のバッチへの追加のためにL2オペレーターに送信します。 場合により、このオペレーターは、トランザクションを実行し、バッチ化した上でL1に送信する中央集権的なエンティティ(シーケンサーと呼ぶ)の場合があります。 このシステムにおけるシーケンサーは、L2のブロックを生成し、ロールアップのトランザクションをZKロールアップのコントラクトに追加できる唯一のエンティティです。 -このアプローチを採用しない ZK ロールアップでは、[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos/)による複数のバリデータがオペレーターの役割をローテーションで担います。 オペレーターに立候補するユーザーは、ロールアップのコントラクトに資金を入金し(ステーキング)、このステークの規模に応じて、次のロールアップ・バッチを生成する役割を与えられる可能性が増減します。 悪意の行動を行ったオペレーターのステークは没収されるため、有効なブロックの送信を促すインセンティブとして機能します。 +このアプローチを採用しないZKロールアップでは、[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos/)による複数のバリデータがオペレーターの役割をローテーションで担います。 オペレーターに立候補するユーザーは、ロールアップのコントラクトに資金を入金し(ステーキング)、このステークの規模に応じて、次のロールアップ・バッチを生成する役割を与えられる可能性が増減します。 悪意の行動を行ったオペレーターのステークは没収されるため、有効なブロックの送信を促すインセンティブとして機能します。 -#### ZK ロールアップにおいてトランザクションデータをイーサリアムに書き込む方法 {#how-zk-rollups-publish-transaction-data-on-ethereum} +#### ZKロールアップにおいてトランザクションデータをイーサリアムに書き込む方法 {#how-zk-rollups-publish-transaction-data-on-ethereum} すでに述べた通り、トランザクションデータは`calldata`としてイーサリアムに書き込まれます。 `calldata`とは、スマートコントラクトにおいて関数に引数を渡すためのデータ領域であり、[メモリ](/developers/docs/smart-contracts/anatomy/#memory)と同様に動作します。 `calldata` はイーサリアムの状態として保存されませんが、イーサリアムチェーンの[履歴ログ](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html?highlight=memory#logs)としてオンチェーン上で永続します。 `calldata` はイーサリアムの状態を変化させないため、オンチェーン上でのデータ保存が安価に実行できます。 -多くの場合、`calldata`におけるキーワードがトランザクションで呼び出されるスマートコントラクトのメソッドを決定し、当該メソッドへの入力を任意のバイト列として保持します。 ZK ロールアップでは、`calldata`を用いて圧縮されたトランザクションデータをオンチェーンに書き込みます。ロールアップのオペレーターの役割は、ロールアップのコントラクトにおいて要求される関数を呼び出し、関数の引数として圧縮データを渡すことにより新規バッチを追加することだけです。 このため、ロールアップにおける手数料の大半はトランザクションデータのオンチェーンの保存において発生するため、ユーザー手数料が軽減されます。 +多くの場合、`calldata`におけるキーワードがトランザクションで呼び出されるスマートコントラクトのメソッドを決定し、当該メソッドへの入力を任意のバイト列として保持します。 ZKロールアップでは、`calldata`を用いて圧縮されたトランザクションデータをオンチェーンに書き込みます。ロールアップのオペレーターの役割は、ロールアップのコントラクトにおいて要求される関数を呼び出し、関数の引数として圧縮データを渡すことにより新規バッチを追加することだけです。 このため、ロールアップにおける手数料の大半はトランザクションデータのオンチェーンの保存において発生するため、ユーザー手数料が軽減されます。 ### ステートコミットメント {#state-commitments} -L2 のアカウントおよび残高が含まれる ZK ロールアップの状態は、[マークルツリー](/whitepaper/#merkle-trees)として表示されます。 マークルツリーのルート(マークルルート)の暗号ハッシュがオンチェーンのコントラクトに保存されるため、ロールアップのプロトコルにより ZK ロールアップの状態変化を追跡することができます。 +L2のアカウントおよび残高が含まれるZKロールアップの状態は、[マークルツリー](/whitepaper/#merkle-trees)として表示されます。 マークルツリーのルート(マークルルート)の暗号ハッシュがオンチェーンのコントラクトに保存されるため、ロールアップのプロトコルによりZKロールアップの状態変化を追跡することができます。 -ロールアップは、一連の新たなトランザクションを実行することで、新しい状態に遷移します。 この状態遷移を開始したオペレーターは、新しい状態ルートを計算し、オンチェーンのコントラクトに送信しなければなりません。 当該バッチの有効性証明が検証者コントラクトにより承認されると、新たなマークルルートが ZK ロールアップにおける正規の状態ルートになります。 +ロールアップは、一連の新たなトランザクションを実行することで、新しい状態に遷移します。 この状態遷移を開始したオペレーターは、新しい状態ルートを計算し、オンチェーンのコントラクトに送信しなければなりません。 当該バッチの有効性証明が検証者コントラクトにより承認されると、新たなマークルルートがZKロールアップにおける正規の状態ルートになります。 -ZK ロールアップのオペレーターは、状態ルートを計算するだけでなく、バッチに含まれるすべてのトランザクションで構成されるマークルツリーのルートであるバッチルートも作成します。 新規バッチが送信されると、ロールアップのコントラクトがバッチルートを保存するため、ユーザーは当該バッチに特定のトランザクション(例:出金リクエスト)が含まれていたかを証明できます。 この場合ユーザーは、トランザクションの詳細、バッチルート、および追加パスを表示する[マークル証明](/developers/tutorials/merkle-proofs-for-offline-data-integrity/)を提供しなければなりません。 +ZKロールアップのオペレーターは、状態ルートを計算するだけでなく、バッチに含まれるすべてのトランザクションで構成されるマークルツリーのルートであるバッチルートも作成します。 新規バッチが送信されると、ロールアップのコントラクトがバッチルートを保存するため、ユーザーは当該バッチに特定のトランザクション(例:出金リクエスト)が含まれていたかを証明できます。 この場合ユーザーは、トランザクションの詳細、バッチルート、および追加パスを表示する[マークル証明](/developers/tutorials/merkle-proofs-for-offline-data-integrity/)を提供しなければなりません。 ### 有効性証明 {#validity-proofs} -ZK ロールアップのオペレーターが L1 のコントラクトに送信する新しい状態ルートは、ロールアップにおける状態更新の結果です。 例えば、アリスがボブに 10 トークンを送信する場合、オペレーターは単にアリスの残高を 10 減らし、ボブの残高を 10 増やします。 オペレーターはその上で、残高変更後のアカウントデータをハッシュ化し、ロールアップのマークルツリーを再構築した上で、新しいマークルルートをオンチェーンのコントラクトに送信します。 +ZKロールアップのオペレーターがL1のコントラクトに送信する新しい状態ルートは、ロールアップにおける状態更新の結果です。 例えば、アリスがボブに10トークンを送信する場合、オペレーターは単にアリスの残高を10減らし、ボブの残高を10増やします。 オペレーターはその上で、残高変更後のアカウントデータをハッシュ化し、ロールアップのマークルツリーを再構築した上で、新しいマークルルートをオンチェーンのコントラクトに送信します。 -しかし、ロールアップのコントラクトは、オペレーターがこの新しいマークルルートがロールアップの状態に対する正しい更新によって生成されたことを証明するまでは、提案された状態コミットメントを自動的に承認しません。 ZK ロールアップのオペレーターは、バッチ化されたトランザクションの正しさを証明する簡潔な暗号学的コミットメントである有効性証明を生成することで、これを証明します。 +しかし、ロールアップのコントラクトは、オペレーターがこの新しいマークルルートがロールアップの状態に対する正しい更新によって生成されたことを証明するまでは、提案された状態コミットメントを自動的に承認しません。 ZKロールアップのオペレーターは、バッチ化されたトランザクションの正しさを証明する簡潔な暗号学的コミットメントである有効性証明を生成することで、これを証明します。 -有効性証明は、ステートメント自体を示さずにその正しさを証明するものであるため、ゼロ知識証明とも呼ばれます。 ZK ロールアップでは、有効性証明を用いることで、トランザクションをイーサリアム上で再実行することなく、オフチェーンの状態遷移の正しさを確認することができるのです。 この有効性証明には、[ZK-SNARK](https://arxiv.org/abs/2202.06877)(ゼロ知識の簡潔かつ非双方向の知識アーギュメント)または[ZK-STARK](https://eprint.iacr.org/2018/046)(ゼロ知識のスケーラブルかつ透明性を持った知識アーギュメント)の 2 種類があります。 +有効性証明は、ステートメント自体を示さずにその正しさを証明するものであるため、ゼロ知識証明とも呼ばれます。 ZKロールアップでは、有効性証明を用いることで、トランザクションをイーサリアム上で再実行することなく、オフチェーンの状態遷移の正しさを確認することができるのです。 この有効性証明には、[ZK-SNARK](https://arxiv.org/abs/2202.06877)(ゼロ知識の簡潔かつ非双方向の知識アーギュメント)または[ZK-STARK](https://eprint.iacr.org/2018/046)(ゼロ知識のスケーラブルかつ透明性を持った知識アーギュメント)の2種類があります。 -SNARK および STARK のいずれも ZK ロールアップにおけるオフチェーンの計算処理の完全性を証明するのに有益ですが、それぞれが独自の機能を持ちます。 +SNARKおよびSTARKのいずれもZKロールアップにおけるオフチェーンの計算処理の完全性を証明するのに有益ですが、それぞれが独自の機能を持ちます。 **ZK-SNARK** -ZK-SNARK のプロトコルが機能するには、共通参照文字列(CRS)を生成する必要があります。この CRS は、有効性証明を証明、検証するための公開パラメータを提供します。 証明システムのセキュリティは、この CRS の設定に依存しています。つまり、公開パラメータが悪意のアクターに所有された場合、虚偽の有効性証明が生成可能になります。 +ZK-SNARKのプロトコルが機能するには、共通参照文字列(CRS)を生成する必要があります。このCRSは、有効性証明を証明、検証するための公開パラメータを提供します。 証明システムのセキュリティは、このCRSの設定に依存しています。つまり、公開パラメータが悪意のアクターに所有された場合、虚偽の有効性証明が生成可能になります。 -一部の ZK ロールアップでは、ZK-SNARK の証明サーキットに対する公開パラメータの生成を信頼された個人ユーザーが参加する[複数当事者による計算セレモニー(MPC)](https://zkproof.org/2021/06/30/setup-ceremonies/amp/)で実行することで、この問題を解消しようとします。 MPC では、各参加者が CRS を構築する際に一定のランダム性(「毒性廃棄物」と呼ぶ)を提供した上で、そのランダム性をただちに破壊しなければなりません。 +一部のZKロールアップでは、ZK-SNARKの証明サーキットに対する公開パラメータの生成を信頼された個人ユーザーが参加する[複数当事者による計算セレモニー(MPC)](https://zkproof.org/2021/06/30/setup-ceremonies/amp/)で実行することで、この問題を解消しようとします。 MPCでは、各参加者がCRSを構築する際に一定のランダム性(「毒性廃棄物」と呼ぶ)を提供した上で、そのランダム性をただちに破壊しなければなりません。 -このような信頼されたユーザーによる関与は、CRS 設定のセキュリティを高めるためのものです。 参加者のうち少なくとも 1 名が正直にインプットを破壊すれば、ZK-SNARK のシステムにおけるセキュリティが保証できます。 しかしこのアプローチでも、システムのセキュリティ保証を毀損しないためには、「参加者は提供したランダム性を消去するはずだ」という信頼が必要になる点は変わりがありません。 +このような信頼されたユーザーによる関与は、CRS設定のセキュリティを高めるためのものです。 参加者のうち少なくとも1名が正直にインプットを破壊すれば、ZK-SNARKのシステムにおけるセキュリティが保証できます。 しかしこのアプローチでも、システムのセキュリティ保証を毀損しないためには、「参加者は提供したランダム性を消去するはずだ」という信頼が必要になる点は変わりがありません。 -ZK-SNARK は、このような信頼の前提という問題を抱えているものの、証明の規模が小さく、一定時間による検証が可能なために広く用いられています。 ZK ロールアップの運用コストの大部分は L1 における有効性証明の検証において発生するため、L2 では、ZK-SNARK を用いることで、メインネット上で迅速かつ安価に検証可能な有効性証明を生成できるのです。 +ZK-SNARKは、このような信頼の前提という問題を抱えているものの、証明の規模が小さく、一定時間による検証が可能なために広く用いられています。 ZKロールアップの運用コストの大部分はL1における有効性証明の検証において発生するため、L2では、ZK-SNARKを用いることで、メインネット上で迅速かつ安価に検証可能な有効性証明を生成できるのです。 **ZK-STARK** -ZK-STARK は、オフチェーンにおける計算につき、そのインプットを示すことなく正しさを証明できるという点では ZK-SNARK と同じです。 しかし、スケーラビリティおよび透明性において、ZK-STARK は ZK-SNARK よりも優れていると評価されています。 +ZK-STARKは、オフチェーンにおける計算につき、そのインプットを示すことなく正しさを証明できるという点ではZK-SNARKと同じです。 しかし、スケーラビリティおよび透明性において、ZK-STARKはZK-SNARKよりも優れていると評価されています。 -ZK-STARK では、共通参照文字列(CRS)の信頼できる設定を必要としないため、「透明性」を持ちます。 ZK-STARK では、有効性証明の生成および検証につき、CRS の代わりに公開的に検証可能なランダム性を用いてパラメータを設定します。 +ZK-STARKでは、共通参照文字列(CRS)の信頼できる設定を必要としないため、「透明性」を持ちます。 ZK-STARKでは、有効性証明の生成および検証につき、CRSの代わりに公開的に検証可能なランダム性を用いてパラメータを設定します。 -ZK-STARK ではさらに、有効性証明を証明、検証するのに必要な時間が、証明を要する計算処理の複雑さに応じて*ほぼ線形的に*増化するため、ZK-SNARK よりもスケーラビリティが高いと言えます。 つまり ZK-SNARK では、証明を要する計算処理の規模に応じて、証明および検証に必要な時間が*線形的*に変化します。 このため ZK-STARK では、大規模なデータセットの証明、検証を ZK-SNARK よりも短時間で完了できるため、大規模なアプリケーションにとってより有益なのです。 +ZK-STARKではさらに、有効性証明を証明、検証するのに必要な時間が、証明を要する計算処理の複雑さに応じて_ほぼ線形的に_増化するため、ZK-SNARKよりもスケーラビリティが高いと言えます。 つまりZK-SNARKでは、証明を要する計算処理の規模に応じて、証明および検証に必要な時間が_線形的_に変化します。 このためZK-STARKでは、大規模なデータセットの証明、検証をZK-SNARKよりも短時間で完了できるため、大規模なアプリケーションにとってより有益なのです。 -ZK-STARK はさらに量子コンピュータに対してもセキュリティを防御できます。一方、ZK-SNARK で用いられている楕円曲線暗号(ECC)は、量子コンピュータによる攻撃に対して脆弱性を持つという意見が支配的です。 ZK-STARK の欠点としては、生成される有効性証明のサイズが大きくなるため、イーサリアム上での検証コストが高くなります。 +ZK-STARKはさらに量子コンピュータに対してもセキュリティを防御できます。一方、ZK-SNARKで用いられている楕円曲線暗号(ECC)は、量子コンピュータによる攻撃に対して脆弱性を持つという意見が支配的です。 ZK-STARKの欠点としては、生成される有効性証明のサイズが大きくなるため、イーサリアム上での検証コストが高くなります。 -#### ZK ロールアップにおいて、有効性証明はどのように機能するか? {#validity-proofs-in-zk-rollups} +#### ZKロールアップにおいて、有効性証明はどのように機能するか? {#validity-proofs-in-zk-rollups} ##### 有効性証明の生成 @@ -115,32 +115,32 @@ ZK-STARK はさらに量子コンピュータに対してもセキュリティ - トランザクションが正しく、ロールアップにおける送信者の公開鍵と一致すること。 - 送信者のノンスが正しいこと、など。 -ZK ロールアップのノードは、トランザクションが一定数に達すると、これらをバッチ化した上で、証明サーキット向けのインプットをコンパイルして簡潔なゼロ知識証明としてコンパイルします。 このゼロ知識証明には、以下が含まれます: +ZKロールアップのノードは、トランザクションが一定数に達すると、これらをバッチ化した上で、証明サーキット向けのインプットをコンパイルして簡潔なゼロ知識証明としてコンパイルします。 このゼロ知識証明には、以下が含まれます: -- バッチに含まれるすべてのトランザクションで構成されるマークルツリー。 +- A Merkle tree root comprising all the transactions in the batch. - 各トランザクションが当該バッチに含まれることを証明するマークル証明。 - トランザクションにおける送信者/受信者ペアのアカウントが、ロールアップのステートツリーに含まれることを証明するマークル証明。 - 各トランザクションに対する状態更新を適用した後の状態ルートの更新により得られる、プロセスの中間における状態ルートのセット(つまり、送信者アカウントの残高減と受信者アカウントの残高増)。 証明サーキットでは、各トランザクションを「ループ」させ、オペレーターがトランザクションを処理する事前に実行したのと同一のチェックを行うことにより、有効性証明を計算します。 証明サーキットではまず、提供されたマークル証明を用いて、送信者アカウントが既存のステートルートに含まれることを確認します。 次に、送信者の残高をマイナスし、ノンスを増やし、変更後のアカウントデータのハッシュをマークル証明と結合させて、新しいマークルルートを生成します。 -このマークルルートは、送信者の残高およびノンスにおける変更という ZK ロールアップの状態に対する唯一の変更を反映しています。 これが可能なのは、アカウントの存在を証明するためのマークル証明が新しいステートルートを導出するために用いられているためです。 +このマークルルートは、送信者の残高およびノンスにおける変更というZKロールアップの状態に対する唯一の変更を反映しています。 これが可能なのは、アカウントの存在を証明するためのマークル証明が新しいステートルートを導出するために用いられているためです。 証明サーキットは、これと同じプロセスを受信者アカウントに対しても実行します。 つまり、(マークル証明を用いて)プロセス中間のステートルートにおいて受信者アカウントが存在することを確認し、残高を増やした上で、アカウントデータを再度ハッシュ化し、マークル証明と結合することで、新しいステートルートを生成します。 -このプロセスを、各トランザクションに対して繰り返します。それぞれの「ループ」処理では、受信者アカウントの変更により新しいステートルートが生成され、受信者アカウントの変更によりさらに次の新しいステートルートが生成されます。 前述したように、このステートルートに対するそれぞれの更新は、ロールアップのステートツリーにおける 1 回の変化を反映したものです。 +このプロセスを、各トランザクションに対して繰り返します。それぞれの「ループ」処理では、受信者アカウントの変更により新しいステートルートが生成され、受信者アカウントの変更によりさらに次の新しいステートルートが生成されます。 前述したように、このステートルートに対するそれぞれの更新は、ロールアップのステートツリーにおける1回の変化を反映したものです。 -ゼロ知識証明サーキットでは、トランザクションバッチの全体を反復的に処理することで、バッチにおける最後のトランザクションが実行された際の最終的なステートルートに至るまでの状態更新のシーケンスの正しさを検証します。 この計算プロセスで得られた最後のマークルルートが、ZK ロールアップにおける最新の正規ステートルートになります。 +ゼロ知識証明サーキットでは、トランザクションバッチの全体を反復的に処理することで、バッチにおける最後のトランザクションが実行された際の最終的なステートルートに至るまでの状態更新のシーケンスの正しさを検証します。 この計算プロセスで得られた最後のマークルルートが、ZKロールアップにおける最新の正規ステートルートになります。 ##### 有効性証明の検証 -証明サーキットにおいて状態更新の正しさが検証されると、L2 のオペレーターは、計算された有効性証明を L1 上の検証者コントラクトに送信します。 検証者コントラクトの検証サーキットでは、この有効性証明の正しさを検証すると同時に、有効性証明の一部である公開インプットについても確認します。 +証明サーキットにおいて状態更新の正しさが検証されると、L2のオペレーターは、計算された有効性証明をL1上の検証者コントラクトに送信します。 検証者コントラクトの検証サーキットでは、この有効性証明の正しさを検証すると同時に、有効性証明の一部である公開インプットについても確認します。 -- **事前のステートルート**: ZK ロールアップの古い状態(つまり、当該バッチに含まれるトランザクションの実行前)を反映した、L2 チェーンにおいて有効である最後の既知のステートルートです。 +- **事前のステートルート**: ZKロールアップの古い状態(つまり、当該バッチに含まれるトランザクションの実行前)を反映した、L2チェーンにおいて有効である最後の既知のステートルートです。 -- **事後のステートルート**: ZK ロールアップの新しい状態(つまり、当該バッチに含まれるトランザクションの実行後)を反映し、L2 チェーンの最新状態であるルートです。 事後のステートルートは、証明サーキットに状態更新を適用することで得られた最終的なルートです。 +- **事後のステートルート**: ZKロールアップの新しい状態(つまり、当該バッチに含まれるトランザクションの実行後)を反映し、L2チェーンの最新状態であるルートです。 事後のステートルートは、証明サーキットに状態更新を適用することで得られた最終的なルートです。 -- **バッチルート**: 当該バッチのマークルルートであり、バッチに*マークル化*を施し、マークルツリーのルートをハッシュ化することで得られます。 +- **バッチルート**: 当該バッチのマークルルートであり、バッチに_マークル化_を施し、マークルツリーのルートをハッシュ化することで得られます。 - **トランザクションにおけるインプット**: 提出されたバッチにおいて実行されたトランザクションに含まれるデータ。 @@ -148,11 +148,11 @@ ZK ロールアップのノードは、トランザクションが一定数に ### 参加と退出 {#entries-and-exits} -ユーザーが ZK ロールアップに参加するには、L1 チェーン上でデプロイされたロールアップのコントラクトにトークンを入金する必要があります。 ロールアップのコントラクトにトランザクションを送信できるのはオペレーターのみであるため、このトランザクションはキュー上で保留されます。 +ユーザーがZKロールアップに参加するには、L1チェーン上でデプロイされたロールアップのコントラクトにトークンを入金する必要があります。 ロールアップのコントラクトにトランザクションを送信できるのはオペレーターのみであるため、このトランザクションはキュー上で保留されます。 -キューに含まれる保留中の入金件数が一定数に達すると、ZK ロールアップのオペレーターが入金トランザクションをロールアップのコントラクトに送信します。 ユーザーの資金がロールアップに入金された時点で、ユーザーはトランザクションをオペレーターに送信し、処理させることで、取引を開始できます。 ユーザーは、各自のアカウントデータをハッシュ化し、ハッシュをロールアップのコントラクトに送信し、さらに現在のステートルートを検証するためのマークル証明を提供することで、ロールアップにおける自らの残高を確認できます。 +キューに含まれる保留中の入金件数が一定数に達すると、ZKロールアップのオペレーターが入金トランザクションをロールアップのコントラクトに送信します。 ユーザーの資金がロールアップに入金された時点で、ユーザーはトランザクションをオペレーターに送信し、処理させることで、取引を開始できます。 ユーザーは、各自のアカウントデータをハッシュ化し、ハッシュをロールアップのコントラクトに送信し、さらに現在のステートルートを検証するためのマークル証明を提供することで、ロールアップにおける自らの残高を確認できます。 -ZK ロールアップから L1 への出金は、簡単に実行できます。 出金トランザクションでは、まずロールアップ上の各自の資金をバーン用の特定のアカウントに送信します。 オペレーターがこのトランザクションを次のバッチに追加した時点で、ユーザーは出金リクエストをオンチェーンのコントラクトに送信できます。 この出金リストには、以下を含める必要があります: +ZKロールアップからL1への出金は、簡単に実行できます。 出金トランザクションでは、まずロールアップ上の各自の資金をバーン用の特定のアカウントに送信します。 オペレーターがこのトランザクションを次のバッチに追加した時点で、ユーザーは出金リクエストをオンチェーンのコントラクトに送信できます。 この出金リストには、以下を含める必要があります: - ユーザーのバーンアカウントへの送金トランザクションが当該バッチに含まれることを証明するマークル証明。 @@ -160,93 +160,97 @@ ZK ロールアップから L1 への出金は、簡単に実行できます。 - バッチルート。 -- 入金資金を受け取る L1 上のアドレス。 +- 入金資金を受け取るL1上のアドレス。 -ロールアップのコントラクトは、このトランザクションデータをハッシュ化し、バッチルートが存在することを確認した上で、マークル証明を用いてこのトランザクションハッシュがバッチルートに含まれることを確認します。 その上で、コントラクトは出金トランザクションを実行し、ユーザーが選択した L1 上のアドレスに資金を送金します。 +ロールアップのコントラクトは、このトランザクションデータをハッシュ化し、バッチルートが存在することを確認した上で、マークル証明を用いてこのトランザクションハッシュがバッチルートに含まれることを確認します。 その上で、コントラクトは出金トランザクションを実行し、ユーザーが選択したL1上のアドレスに資金を送金します。 -## ZK ロールアップと EVM の互換性 {#zk-rollups-and-evm-compatibility} +## ZKロールアップとEVMの互換性 {#zk-rollups-and-evm-compatibility} -オプティミスティック・ロールアップと異なり、ゼロ知識ロールアップはそれ自体が [イーサリアム仮想マシン (EVM)](/developers/docs/evm/) と互換であるわけではありません。 ゼロ知識の証明サーキットにおいて汎用的な EVM の計算を証明するのは、(上記のトークン転送例のような)単純な計算を証明する場合よりも困難であり、多くのリソースが必要になります。 +オプティミスティック・ロールアップと異なり、ゼロ知識ロールアップはそれ自体が [イーサリアム仮想マシン (EVM)](/developers/docs/evm/) と互換であるわけではありません。 ゼロ知識の証明サーキットにおいて汎用的なEVMの計算を証明するのは、(上記のトークン転送例のような)単純な計算を証明する場合よりも困難であり、多くのリソースが必要になります。 -しかし、 [ゼロ知識技術の進歩](https://hackmd.io/@yezhang/S1_KMMbGt#Why-possible-now) により、EVM の計算にゼロ知識証明を用いるアプローチに対する関心が再び高まっています。 これらの取り組みは、ゼロ知識 EVM(zkEVM)の実装を実現することで、プログラム実行の正しさをより効率的に検証できるようにするものです。 ZkEVM は、証明サーキットにおける証明/検証のために EVM の既存オペコードを再作成するもので、これによりスマートコントラクトの実行が可能になります。 +しかし、 [ゼロ知識技術の進歩](https://hackmd.io/@yezhang/S1_KMMbGt#Why-possible-now) により、EVMの計算にゼロ知識証明を用いるアプローチに対する関心が再び高まっています。 これらの取り組みは、ゼロ知識EVM(zkEVM)の実装を実現することで、プログラム実行の正しさをより効率的に検証できるようにするものです。 ZkEVMは、証明サーキットにおける証明/検証のためにEVMの既存オペコードを再作成するもので、これによりスマートコントラクトの実行が可能になります。 -zkEVM では、EVM と同様に、インプットに対する計算を実行した時点で状態が遷移します。 しかし zkEVM では、プログラム実行の各ステップの正しさを検証するためにゼロ知識証明が生成されるという点が異なります。 有効性証明は、仮想マシンの状態(メモリ、スタック、およびストレージ)に関連した操作ならびに計算自体の正しさを検証することができます(つまり、この操作は適切なオペコードを呼び出し、適切に実行されたかを確認できます)。 +zkEVMでは、EVMと同様に、インプットに対する計算を実行した時点で状態が遷移します。 しかしzkEVMでは、プログラム実行の各ステップの正しさを検証するためにゼロ知識証明が生成されるという点が異なります。 有効性証明は、仮想マシンの状態(メモリ、スタック、およびストレージ)に関連した操作ならびに計算自体の正しさを検証することができます(つまり、この操作は適切なオペコードを呼び出し、適切に実行されたかを確認できます)。 -EVM 互換の ZK ロールアップを活用することで、デベロッパはゼロ知識証明がもたらすスケーラビリティとセキュリティ保証を得ることができます。 さらに重要なのは、イーサリアムネイティブのインフラとの互換性が保証されるために、使い慣れた(すでに実戦で検証済みの)ツールや言語を用いて、ZK フレンドリーな Dapp を構築できるという点です。 +EVM互換のZKロールアップを活用することで、デベロッパはゼロ知識証明がもたらすスケーラビリティとセキュリティ保証を得ることができます。 さらに重要なのは、イーサリアムネイティブのインフラとの互換性が保証されるために、使い慣れた(すでに実戦で検証済みの)ツールや言語を用いて、ZKフレンドリーなDappを構築できるという点です。 -## ZK ロールアップにおける手数料の仕組み {#how-do-zk-rollup-fees-work} +## ZKロールアップにおける手数料の仕組み {#how-do-zk-rollup-fees-work} -ZK ロールアップにおけるトランザクション手数料は、イーサリアムメインネットと同じようにガス料金に応じて変化します。 ただし L2 においては、ガス料金の仕組みが異なっており、以下のコストの影響を受けます: +ZKロールアップにおけるトランザクション手数料は、イーサリアムメインネットと同じようにガス料金に応じて変化します。 ただしL2においては、ガス料金の仕組みが異なっており、以下のコストの影響を受けます: -1. **ステートへの書き込み**: イーサリアムのステートに書き込む(つまり、イーサリアムブロックチェーンにトランザクションを送信する)場合、固定コストが発生します。 ZK ロールアップでは、トランザクションをバッチ化し、固定コストを複数のユーザーに分散させることで、ユーザーあたりのコストを引き下げています。 +1. **ステートへの書き込み**: イーサリアムのステートに書き込む(つまり、イーサリアムブロックチェーンにトランザクションを送信する)場合、固定コストが発生します。 ZKロールアップでは、トランザクションをバッチ化し、固定コストを複数のユーザーに分散させることで、ユーザーあたりのコストを引き下げています。 -2. **データの公開**: ZK ロールアップでは、各トランザクションの状態データを`calldata`としてイーサリアムに送信します。 現在、`calldata`のコストは [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) によって管理されています。 `calldata` の非ゼロバイトに対しては 16 ガス、ゼロバイトに対しては 4 ガスのコストが、それぞれ規定されています。 各トランザクションに対して支払われるコストは、オンチェーンで公開される`calldata`の規模に応じて決定されます。 +2. **データの公開**: ZKロールアップでは、各トランザクションの状態データを`calldata`としてイーサリアムに送信します。 現在、`calldata`のコストは [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) によって管理されています。 `calldata` の非ゼロバイトに対しては16ガス、ゼロバイトに対しては4ガスのコストが、それぞれ規定されています。 各トランザクションに対して支払われるコストは、オンチェーンで公開される`calldata`の規模に応じて決定されます。 -3. **L2 オペレーターに対する手数料**: これは、イーサリアムにおけるマイナー手数料の場合と同様に、トランザクションの処理で発生した計算コストの代価としてロールアップのオペレーターに支払う手数料です。 +3. **L2オペレーターに対する手数料**: これは、イーサリアムにおけるマイナー手数料の場合と同様に、トランザクションの処理で発生した計算コストの代価としてロールアップのオペレーターに支払う手数料です。 -4. **有効性証明の生成と検証**: ZK ロールアップのオペレーターは、多くのリソースを用いてトランザクションバッチに対する有効性証明を生成しなければなりません。 メインネットにおけるゼロ知識証明の検証にもガス代が発生します(最大 50 万ガス)。 +4. **有効性証明の生成と検証**: ZKロールアップのオペレーターは、多くのリソースを用いてトランザクションバッチに対する有効性証明を生成しなければなりません。 メインネットにおけるゼロ知識証明の検証にもガス代が発生します(最大50万ガス)。 -ZK ロールアップでは、トランザクションのバッチ化に加えて、トランザクションデータを圧縮することでユーザー手数料を引き下げています。 イーサリアムの ZK ロールアップにおける利用コストは、[リアルタイムで確認できます](https://l2fees.info/)。 +ZKロールアップでは、トランザクションのバッチ化に加えて、トランザクションデータを圧縮することでユーザー手数料を引き下げています。 イーサリアムのZKロールアップにおける利用コストは、[リアルタイムで確認できます](https://l2fees.info/)。 -## ZK ロールアップは、どのようにイーサリアムのスケーラビリティを向上させるか? {#scaling-ethereum-with-zk-rollups} +## ZKロールアップは、どのようにイーサリアムのスケーラビリティを向上させるか? {#scaling-ethereum-with-zk-rollups} ### トランザクションデータの圧縮 {#transaction-data-compression} -ZK ロールアップでは、オフチェーンでの計算を通じてイーサリアム・ベースレイヤーのスループットを向上させますが、実際にスケーラビリティを向上させるのはトランザクションデータを圧縮することによってです。 イーサリアムの [ブロックサイズ](/developers/docs/blocks/#block-size) は、各ブロックが保持できるデータ量を制限しているため、必然的に各ブロックが処理できるトランザクションの数も制限されます。 ZK ロールアップでは、トランザクション関連データを圧縮することで、各ブロックで処理されるトランザクションの数が大きく増えるのです。 +ZKロールアップでは、オフチェーンでの計算を通じてイーサリアム・ベースレイヤーのスループットを向上させますが、実際にスケーラビリティを向上させるのはトランザクションデータを圧縮することによってです。 イーサリアムの [ブロックサイズ](/developers/docs/blocks/#block-size) は、各ブロックが保持できるデータ量を制限しているため、必然的に各ブロックが処理できるトランザクションの数も制限されます。 ZKロールアップでは、トランザクション関連データを圧縮することで、各ブロックで処理されるトランザクションの数が大きく増えるのです。 -ZK ロールアップでは、各トランザクションを検証するためにすべての関連データを書き込む必要がないため、オプティミスティック・ロールアップよりもデータの圧縮度が高いと言えます。 ロールアップにおけるアカウントおよび残高の最新状態を再構築する上で、必要最小限のデータのみを送信すればよいのです。 +ZKロールアップでは、各トランザクションを検証するためにすべての関連データを書き込む必要がないため、オプティミスティック・ロールアップよりもデータの圧縮度が高いと言えます。 ロールアップにおけるアカウントおよび残高の最新状態を再構築する上で、必要最小限のデータのみを送信すればよいのです。 ### 再帰的プルーフ {#recursive-proofs} -ゼロ知識証明の優位性のひとつとして、他の種類の証明を検証するためにも使用できる点が挙げられます。 例えば、ある ZK-SNARK を用いて他の複数の ZK-SNARK を検証することができます。 このような「プルーフに対するプルーフ」を再帰的プルーフと呼び、ZK ロールアップのスループットを劇的に向上させます。 +ゼロ知識証明の優位性のひとつとして、他の種類の証明を検証するためにも使用できる点が挙げられます。 例えば、あるZK-SNARKを用いて他の複数のZK-SNARKを検証することができます。 このような「プルーフに対するプルーフ」を再帰的プルーフと呼び、ZKロールアップのスループットを劇的に向上させます。 -現在のところ、有効性証明はブロックごとに生成され、検証のために L1 上のコントラクトに送信されています。 しかしこの 1 つのブロックのみを検証する有効性証明のアプローチでは、オペレーターが有効性証明を送信する際に 1 つのブロックしかファイナライズできないため、ZK ロールアップにより達成可能なスループットが制限されてしまいます。 +現在のところ、有効性証明はブロックごとに生成され、検証のためにL1上のコントラクトに送信されています。 しかしこの1つのブロックのみを検証する有効性証明のアプローチでは、オペレーターが有効性証明を送信する際に1つのブロックしかファイナライズできないため、ZKロールアップにより達成可能なスループットが制限されてしまいます。 -一方、再帰的プルーフを用いれば、1 つの有効性証明に基づいて複数のブロックをファイナライズすることが可能になります。 このアプローチでは、証明サーキットにおいて複数のブロックに対する証明が集約され、最終的な証明を作成することができるためです。 L2 のオペレーターがこの再規制プルーフを提出し、コントラクトが承認すれば、関連するすべてのブロックが瞬時にファイナライズされます。 再帰的プルーフを用いることで、イーサリアムにおいて一定間隔でファイナライズできる ZK ロールアップのトランザクション数を増やすことができます。 +一方、再帰的プルーフを用いれば、1つの有効性証明に基づいて複数のブロックをファイナライズすることが可能になります。 このアプローチでは、証明サーキットにおいて複数のブロックに対する証明が集約され、最終的な証明を作成することができるためです。 L2のオペレーターがこの再規制プルーフを提出し、コントラクトが承認すれば、関連するすべてのブロックが瞬時にファイナライズされます。 再帰的プルーフを用いることで、イーサリアムにおいて一定間隔でファイナライズできるZKロールアップのトランザクション数を増やすことができます。 -### ZK ロールアップの長所と短所 {#zk-rollups-pros-and-cons} +### ZKロールアップの長所と短所 {#zk-rollups-pros-and-cons} -| 長所 | 短所 | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 有効性証明により、オフチェーンのトランザクションの正しさが保証でき、オペレーターが無効な状態遷移を実行するのを防ぐことができる。 | 有効性証明を計算、検証する際にかなりのコストが発生し、ロールアップにおけるユーザー手数料がかさむ可能性がある。 | -| 有効性証明が L1 上で検証されれば状態更新が承認されるため、トランザクションのファイナリティをより迅速に実現できる。 | ゼロ知識は複雑な関連技術を要するため、EVM 互換の ZK ロールアップ構築は容易ではない。 | -| [オプティミスティック・ロールアップ](/developers/docs/scaling/optimistic-rollups/#optimistic-pros-and-cons)とは異なり、インセンティブに基づく正直なアクターに依存するのではなく、トラストレス性を持つ暗号学的なメカニズムを通じてセキュリティを確保できる。 | 有効性証明の生成には特殊なハードウェアを必要とするため、少数のユーザーがチェーンを中央集権的に管理する傾向が強まる可能性がある。 | -| L1 上でオフチェーンの状態を復元するために必要なデータを保存できるため、セキュリティ、検閲耐性、および分散化が保証される。 | 中央集権的なオペレーター(シーケンサー)がトランザクションの実行順位に影響を及ぼしうる。 | -| ユーザーは L2 からの出金を遅延なく行えるため、資本の効率性が高まる。 | 厳格なハードウェア要件によりチェーンを強制的に進められる参加者数が限定されることで、悪意のオペレーターがロールアップの状態を凍結し、ユーザーを検閲するリスクが高まる。 | -| 生存性の前提に依存しないため、ユーザーは資金を保護するためにチェーンを検証する必要がない。 | 一部の証明システム(ZK-SNARK など)は信頼性に基づく設定が必要であるため、不適切な利用により ZK ロールアップのセキュリティモデルが悪用される可能性がある。 | -| 優れたデータ圧縮機能により、イーサリアム上で`calldata`を公開する費用が軽減され、ユーザーのロールアップ手数料を最小限に抑えられる。 | | +| 長所 | 短所 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- | +| 有効性証明により、オフチェーンのトランザクションの正しさが保証でき、オペレーターが無効な状態遷移を実行するのを防ぐことができる。 | 有効性証明を計算、検証する際にかなりのコストが発生し、ロールアップにおけるユーザー手数料がかさむ可能性がある。 | +| 有効性証明がL1上で検証されれば状態更新が承認されるため、トランザクションのファイナリティをより迅速に実現できる。 | ゼロ知識は複雑な関連技術を要するため、EVM互換のZKロールアップ構築は容易ではない。 | +| [オプティミスティック・ロールアップ](/developers/docs/scaling/optimistic-rollups/#optimistic-pros-and-cons)とは異なり、インセンティブに基づく正直なアクターに依存するのではなく、トラストレス性を持つ暗号学的なメカニズムを通じてセキュリティを確保できる。 | 有効性証明の生成には特殊なハードウェアを必要とするため、少数のユーザーがチェーンを中央集権的に管理する傾向が強まる可能性がある。 | +| L1上でオフチェーンの状態を復元するために必要なデータを保存できるため、セキュリティ、検閲耐性、および分散化が保証される。 | 中央集権的なオペレーター(シーケンサー)がトランザクションの実行順位に影響を及ぼしうる。 | +| ユーザーはL2からの出金を遅延なく行えるため、資本の効率性が高まる。 | 厳格なハードウェア要件によりチェーンを強制的に進められる参加者数が限定されることで、悪意のオペレーターがロールアップの状態を凍結し、ユーザーを検閲するリスクが高まる。 | +| 生存性の前提に依存しないため、ユーザーは資金を保護するためにチェーンを検証する必要がない。 | 一部の証明システム(ZK-SNARKなど)は信頼性に基づく設定が必要であるため、不適切な利用によりZKロールアップのセキュリティモデルが悪用される可能性がある。 | +| 優れたデータ圧縮機能により、イーサリアム上で`calldata`を公開する費用が軽減され、ユーザーのロールアップ手数料を最小限に抑えられる。 | | -### ZK ロールアップに関する動画による説明 {#zk-video} +### ZKロールアップに関する動画による説明 {#zk-video} -Finematics による ZK ロールアップの説明動画をご覧ください: +FinematicsによるZKロールアップの説明動画をご覧ください: ### ゼロ知識ロールアップの活用方法 {#use-zk-rollups} -現在、Dapp に統合可能ないくつかの ZK ロールアップの実装が提供されています: +現在、Dappに統合可能ないくつかのZKロールアップの実装が提供されています: -## zkEVM の開発プロジェクト {#zkevm-projects} +## zkEVMの開発プロジェクト {#zkevm-projects} -現在、zkEVM の開発に取り組んでいるプロジェクトとしては、以下が挙げられます: +現在、zkEVMの開発に取り組んでいるプロジェクトとしては、以下が挙げられます: -- **[ZKSync](https://docs.zksync.io/zkevm/)** - _ZkSync 2.0 は、Matter Labs が独自開発した zkEVM を搭載する EVM 互換の ZK ロールアップです_ +- **[Applied ZKP](https://github.com/privacy-scaling-explorations/zkevm-specs)** - _Applied ZKPは、イーサリアム・ファウンデーションによる資金提供に基づき、EVM互換のZKロールアップならびにイーサリアムブロックに対する有効性証明を生成するメカニズムを開発するプロジェクトです。 -- **[Applied ZKP](https://github.com/privacy-scaling-explorations/zkevm-specs)** - _Applied ZKP は、イーサリアム財団による資金提供に基づき、EVM 互換の ZK ロールアップならびにイーサリアムブロックに対する有効性証明を生成するメカニズムを開発するプロジェクトです。_ +- **[Polygon zkEVM](https://polygon.technology/solutions/polygon-zkevm)** - _イーサリアムメインネット上の分散型ゼロ知識ロールアップであり、ゼロ知識証明による検証が可能なスマートコントラクトなど、イーサリアムのトランザクションを透明性が高い方法で実行するゼロ知識イーサリアム仮想マシン(zkEVM)の開発に取り組んでいます。 -- **[Scroll](https://scroll.io/blog/zkEVM)** - _Scroll は、ネイティブの zkEVM を搭載したイーサリアムのレイヤー 2 ソリューションを開発中のテクノロジー企業です。_ +- **[Scroll](https://scroll.io/blog/zkEVM)** - _Scrollは、ネイティブのzkEVMを搭載したイーサリアムのレイヤー2ソリューションを開発中のテクノロジー企業です。_ -- **[Polygon zkEVM](https://polygon.technology/solutions/polygon-zkevm)** - _イーサリアムメインネット上の分散型ゼロ知識ロールアップであり、ゼロ知識証明による検証が可能なスマートコントラクトなど、イーサリアムのトランザクションを透明性が高い方法で実行するゼロ知識イーサリアム仮想マシン(zkEVM)の開発に取り組んでいます。_ +- **[Taiko](https://taiko.xyz)** - _Taikoは、分散型でイーサリアム等価のゼロ知識ロールアップ([タイプ1のゼロ知識イーサリアム仮想マシン](https://vitalik.ca/general/2022/08/04/zkevm.html))_です。 -## ZK ロールアップの参考文献 {#further-reading-on-zk-rollups} +- **[ZKSync](https://docs.zksync.io/zkevm/)** - _ZkSync Era is an EVM-compatible ZK Rollup built by Matter Labs, powered by its own zkEVM._ + +- **[Starknet](https://starkware.co/starknet/)** - _StarkNet is an EVM-compatible layer 2 scaling solution built by StarkWare._ + +## ZKロールアップの参考文献 {#further-reading-on-zk-rollups} - [ゼロ知識ロールアップとは何か?](https://coinmarketcap.com/alexandria/glossary/zero-knowledge-rollups) - [ゼロ知識ロールアップとは?](https://alchemy.com/blog/zero-knowledge-rollups) -- [STARK と SNARK の相違点](https://consensys.net/blog/blockchain-explained/zero-knowledge-proofs-starks-vs-snarks/) -- [zkEVM とは何か?](https://www.alchemy.com/overviews/zkevm) -- [zkEVM のイントロダクション](https://hackmd.io/@yezhang/S1_KMMbGt) -- [有益な zkEVM 関連リソース](https://github.com/LuozhuZhang/awesome-zkevm) -- [ZK-SNARK の仕組み](https://vitalik.eth.limo/general/2017/02/01/zk_snarks.html) -- [SNARK はどのように実現されているのか?](https://vitalik.eth.limo/general/2021/01/26/snarks.html) +- [STARKとSNARKの相違点](https://consensys.net/blog/blockchain-explained/zero-knowledge-proofs-starks-vs-snarks/) +- [zkEVMとは何か?](https://www.alchemy.com/overviews/zkevm) +- [zkEVMのイントロダクション](https://hackmd.io/@yezhang/S1_KMMbGt) +- [有益なzkEVM関連リソース](https://github.com/LuozhuZhang/awesome-zkevm) +- [ZK-SNARKの仕組み](https://vitalik.ca/general/2017/02/01/zk_snarks.html) +- [SNARKはどのように実現されているのか?](https://vitalik.ca/general/2021/01/26/snarks.html) diff --git a/public/content/translations/ja/developers/docs/smart-contracts/anatomy/index.md b/public/content/translations/ja/developers/docs/smart-contracts/anatomy/index.md index 81d4f8fc7fc..7b4baef7332 100644 --- a/public/content/translations/ja/developers/docs/smart-contracts/anatomy/index.md +++ b/public/content/translations/ja/developers/docs/smart-contracts/anatomy/index.md @@ -8,7 +8,7 @@ lang: ja ## 前提知識 {#prerequisites} -最初に、[スマートコントラクト](/developers/docs/smart-contracts/)を必ずお読みください。 このドキュメントは、JavaScript や Python などのプログラミング言語に精通していることを前提としています。 +最初に、[スマートコントラクト](/developers/docs/smart-contracts/)を必ずお読みください。 このドキュメントは、JavaScriptやPythonなどのプログラミング言語に精通していることを前提としています。 ## データ {#data} @@ -33,7 +33,7 @@ storedData: int128 オブジェクト指向言語でのプログラミングの経験がある場合は、ほとんどの型になじみがあるでしょう。 しかし、イーサリアムの開発が初めての場合、`address`は目新しいかもしれません。 -`address`型は、20 バイトまたは 160 ビットに相当するイーサリアムアドレスを保持します。 先頭が 0x の 16 進数を返します。 +`address`型は、20バイトまたは160ビットに相当するイーサリアムアドレスを保持します。 先頭が0xの16進数を返します。 その他の型には次のものがあります。 @@ -44,19 +44,19 @@ storedData: int128 - 動的サイズのバイト配列 - 有理数リテラルと整数リテラル - 文字列リテラル -- 16 進数リテラル +- 16進数リテラル - 列挙型 詳細については、以下のドキュメントをご覧ください。 -- [Vyper の型を見る](https://vyper.readthedocs.io/en/v0.1.0-beta.6/types.html#value-types) -- [Solidity の型を見る](https://solidity.readthedocs.io/en/latest/types.html#value-types) +- [Vyperの型を見る](https://vyper.readthedocs.io/en/v0.1.0-beta.6/types.html#value-types) +- [Solidityの型を見る](https://solidity.readthedocs.io/en/latest/types.html#value-types) ### メモリ {#memory} コントラクト関数の実行期間にのみ保存される値は、メモリ変数と呼ばれます。 これらはブロックチェーンに永続的に保存されることはないため、低コストで使用できます -EVM がデータ(ストレージ、メモリ、スタック)を格納する方法の詳細については、[Solidity のドキュメント](https://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html?highlight=memory#storage-memory-and-the-stack)をご覧ください。 +EVMがデータ(ストレージ、メモリ、スタック)を格納する方法の詳細については、[Solidityのドキュメント](https://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html?highlight=memory#storage-memory-and-the-stack)をご覧ください。 ### 環境変数 {#environment-variables} @@ -64,28 +64,28 @@ EVM がデータ(ストレージ、メモリ、スタック)を格納する方 例: -| **プロパティ** | **状態変数** | **説明** | -| ----------------- | ------------ | ------------------------------------ | -| `block.timestamp` | uint256 | 現在のブロックエポックタイムスタンプ | -| `msg.sender` | address | メッセージの送信者(現在の呼び出し) | +| **プロパティ** | **状態変数** | **説明** | +| ----------------- | -------- | ------------------ | +| `block.timestamp` | uint256 | 現在のブロックエポックタイムスタンプ | +| `msg.sender` | address | メッセージの送信者(現在の呼び出し) | ## 関数 {#functions} 簡単に言うと、関数は受信トランザクションに応じて情報を取得したり、情報を設定したりすることができます。 -関数呼び出しには、以下の 2 種類があります。 +関数呼び出しには、以下の2種類があります。 -- `internal` - これらは EVM 呼び出しを作成しません。 - - internal 関数と状態変数は、内部(つまり、現在のコントラクト内またはそれから派生したコントラクト内)からのみアクセスできます。 -- `external` - これらは EVM 呼び出しを作成します。 - - external 関数はコントラクトインターフェイスの一部であり、他のコントラクトから呼び出したり、トランザクションを介して呼び出したりすることができます。 external 関数`f`を内部で呼び出すことはできません(つまり、`f()`は動作しませんが、`this.f()`は動作します)。 +- `internal` - これらはEVM呼び出しを作成しません。 + - internal関数と状態変数は、内部(つまり、現在のコントラクト内またはそれから派生したコントラクト内)からのみアクセスできます。 +- `external` - これらはEVM呼び出しを作成します。 + - external関数はコントラクトインターフェイスの一部であり、他のコントラクトから呼び出したり、トランザクションを介して呼び出したりすることができます。 external関数`f`を内部で呼び出すことはできません(つまり、`f()`は動作しませんが、`this.f()`は動作します)。 `public`または`private`にすることもできます。 - `public`関数は、コントラクト内から内部で呼び出すことも、メッセージを介して外部から呼び出すこともできます。 - `private`関数は、それらが定義されているコントラクトからのみ参照できます。派生したコントラクトからは参照できません。 -関数と状態変数はどちらも public または private にすることができます。 +関数と状態変数はどちらもpublicまたはprivateにすることができます。 コントラクトの状態変数を更新するための関数は次のとおりです。 @@ -100,7 +100,7 @@ function update_name(string value) public { - `public`と宣言されており、誰でもアクセスできます。 - `view`が宣言されていないため、コントラクトの状態を変更できます。 -### View 関数 {#view-functions} +### View関数 {#view-functions} これらの関数によって、コントラクトのデータの状態を変更しないことを指定します。 一般的な例としては、「getter」関数があります。例えば、これを使用してユーザーの残高を受け取ることができます。 @@ -133,7 +133,7 @@ def readName() -> string: ### コンストラクタ関数 {#constructor-functions} -`constructor`関数は、コントラクトが最初にデプロイされたときに 1 回だけ実行されます。 多くのクラスベースのプログラミング言語の`constructor`と同様に、これらの関数はしばしば、指定された値に状態変数を初期化します。 +`constructor`関数は、コントラクトが最初にデプロイされたときに1回だけ実行されます。 多くのクラスベースのプログラミング言語の`constructor`と同様に、これらの関数はしばしば、指定された値に状態変数を初期化します。 ```solidity // Solidity example @@ -165,15 +165,15 @@ def __init__(_beneficiary: address, _bidding_time: uint256): - `address.send()` – Solidity - `send(address)` – Vyper -これらの関数により、コントラクトは他のアカウントに ETH を送信することができます。 +これらの関数により、コントラクトは他のアカウントにETHを送信することができます。 ## 関数を書く {#writing-functions} 関数には以下のものが必要です。 - パラメータ変数と型(パラメータを受け取る場合) -- internal/external の宣言 -- pure/view/payable の宣言 +- internal/externalの宣言 +- pure/view/payableの宣言 - 戻り値の型(値を返す場合) ```solidity @@ -207,7 +207,7 @@ contract ExampleDapp { ## 注釈付きの例 {#annotated-examples} -Solidity で書かれた例を以下に示します。 コードを実行したい場合は、[Remix](http://remix.ethereum.org)で操作できます。 +Solidityで書かれた例を以下に示します。 コードを実行したい場合は、[Remix](http://remix.ethereum.org)で操作できます。 ### Hello World {#hello-world} @@ -641,7 +641,7 @@ contract CryptoPizza is IERC721, ERC165 { ## 参考文献 {#further-reading} -スマートコントラクトの全体的な概要については、Solidity と Vyper のドキュメントをご確認ください。 +スマートコントラクトの全体的な概要については、SolidityとVyperのドキュメントをご確認ください。 - [Solidity](https://solidity.readthedocs.io/) - [Vyper](https://vyper.readthedocs.io/) @@ -655,4 +655,4 @@ contract CryptoPizza is IERC721, ERC165 { - [コントラクトのサイズ制限に対処するためのコントラクトのサイズ縮小](/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) _- スマートコントラクトのサイズを小さくするための実用的なヒント_ - [イベントを使用してスマートコントラクトからデータをログに記録](/developers/tutorials/logging-events-smart-contracts/) _- スマートコントラクトのイベントの紹介と、それを使ってデータをログに記録する方法_ -- [Solidity を使用した他のコントラクトとの連携](/developers/tutorials/interact-with-other-contracts-from-solidity/) _- 既存のコントラクトからスマートコントラクトをデプロイし、それを扱う方法_ +- [Solidityを使用した他のコントラクトとの連携](/developers/tutorials/interact-with-other-contracts-from-solidity/) _- 既存のコントラクトからスマートコントラクトをデプロイし、それを扱う方法_ diff --git a/public/content/translations/ja/developers/docs/smart-contracts/compiling/index.md b/public/content/translations/ja/developers/docs/smart-contracts/compiling/index.md index 0d90bad9c78..3e0051bb519 100644 --- a/public/content/translations/ja/developers/docs/smart-contracts/compiling/index.md +++ b/public/content/translations/ja/developers/docs/smart-contracts/compiling/index.md @@ -5,7 +5,7 @@ lang: ja incomplete: true --- -Web アプリとイーサリアム仮想マシン(EVM)が理解できるように、コントラクトをコンパイルする必要があります。 +Webアプリとイーサリアム仮想マシン(EVM)が理解できるように、コントラクトをコンパイルする必要があります。 ## 前提知識 {#prerequisites} @@ -33,15 +33,15 @@ contract Greeter { PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x41 JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0xCFAE3217 EQ PUSH2 0x46 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5B PUSH2 0xD6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x9B JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0x80 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0xC8 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x60 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x48656C6C6F000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP SWAP1 POP SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 SLT 0xec 0xe 0xf5 0xf8 SLT 0xc7 0x2d STATICCALL ADDRESS SHR 0xdb COINBASE 0xb1 BALANCE 0xe8 0xf8 DUP14 0xda 0xad DUP13 LOG1 0x4c 0xb4 0x26 0xc2 DELEGATECALL PUSH7 0x8994D3E002900 ``` -## Web アプリ {#web-applications} +## Webアプリ {#web-applications} コンパイラは、アプリケーションがコントラクトを理解し、コントラクトの関数を呼び出すために必要な**アプリケーションバイナリインターフェイス(ABI)**も生成します。 -ABI は、デプロイされたコントラクトとそのスマートコントラクト関数を記述する JSON ファイルです。 これにより、Web2 と Web3 のギャップを埋めることができます。 +ABIは、デプロイされたコントラクトとそのスマートコントラクト関数を記述するJSONファイルです。 これにより、Web2とWeb3のギャップを埋めることができます。 -[JavaScript クライアントライブラリ](/developers/docs/apis/javascript/)は**ABI**を読み取り、Web アプリのインターフェイスでスマートコントラクトを呼び出すことができます。 +[JavaScriptクライアントライブラリ](/developers/docs/apis/javascript/)は**ABI**を読み取り、Webアプリのインターフェイスでスマートコントラクトを呼び出すことができます。 -以下は、ERC-20 トークンコントラクトの ABI です。 ERC-20 はイーサリアムで取引できるトークンです。 +以下は、ERC-20トークンコントラクトのABIです。 ERC-20はイーサリアムで取引できるトークンです。 ```json [ @@ -270,9 +270,9 @@ ABI は、デプロイされたコントラクトとそのスマートコント ## 参考文献 {#further-reading} -- [ABI 仕様](https://solidity.readthedocs.io/en/v0.7.0/abi-spec.html) _– Solidity_ +- [ABI仕様](https://solidity.readthedocs.io/en/v0.7.0/abi-spec.html) _– Solidity_ ## 関連トピック {#related-topics} -- [JavaScript クライアントライブラリ](/developers/docs/apis/javascript/) +- [JavaScriptクライアントライブラリ](/developers/docs/apis/javascript/) - [イーサリアム仮想マシン(EVM)](/developers/docs/evm/) diff --git a/public/content/translations/ja/developers/docs/smart-contracts/composability/index.md b/public/content/translations/ja/developers/docs/smart-contracts/composability/index.md index a0cd4bd1d2c..16f8782f63f 100644 --- a/public/content/translations/ja/developers/docs/smart-contracts/composability/index.md +++ b/public/content/translations/ja/developers/docs/smart-contracts/composability/index.md @@ -7,7 +7,7 @@ incomplete: true ## 簡単な紹介 {#a-brief-introduction} -スマートコントラクトはイーサリアム上で公開されており、オープン API と考えることができます。 Dapp デベロッパーになるために、独自のスマートコントラクトを書く必要はありません。スマートコントラクトとやり取りする方法を理解するだけで済みます。 例えば、アプリ内のすべてのトークンスワップロジックを処理するために、分散型取引所である[Uniswap](https://uniswap.exchange/swap)の既存のスマートコントラクトを使用できます。ゼロから始める必要はありません。 [v2](https://github.com/Uniswap/uniswap-v2-core/tree/master/contracts)と[v3](https://github.com/Uniswap/uniswap-v3-core/tree/main/contracts)のコントラクトをいくつか確認してみてください。 +スマートコントラクトはイーサリアム上で公開されており、オープンAPIと考えることができます。 Dappデベロッパーになるために、独自のスマートコントラクトを書く必要はありません。スマートコントラクトとやり取りする方法を理解するだけで済みます。 例えば、アプリ内のすべてのトークンスワップロジックを処理するために、分散型取引所である[Uniswap](https://uniswap.exchange/swap)の既存のスマートコントラクトを使用できます。ゼロから始める必要はありません。 [v2](https://github.com/Uniswap/uniswap-v2-core/tree/master/contracts)と[v3](https://github.com/Uniswap/uniswap-v3-core/tree/main/contracts)のコントラクトをいくつか確認してみてください。 ## 構成可能性とは {#what-is-composability} @@ -17,9 +17,9 @@ incomplete: true ## 構成可能性の仕組み {#how-does-composability-work} -イーサリアムのスマートコントラクトはパブリック API のようなものなので、誰でもコントラクトとやり取りしたり、それらを Dapp に統合して機能を追加したりすることができます。 スマートコントラクトの構成は一般的に、モジュール性、自律性、発見性の 3 つの原則に基づいています。 +イーサリアムのスマートコントラクトはパブリックAPIのようなものなので、誰でもコントラクトとやり取りしたり、それらをDappに統合して機能を追加したりすることができます。 スマートコントラクトの構成は一般的に、モジュール性、自律性、発見性の3つの原則に基づいています。 -**1. モジュール性**: 個々のコンポーネントが特定のタスクを実行する能力です。 イーサリアムでは、すべてのスマートコントラクトに特定のユースケースがあります(Uniswap の例に見ることができます)。 +**1. モジュール性**: 個々のコンポーネントが特定のタスクを実行する能力です。 イーサリアムでは、すべてのスマートコントラクトに特定のユースケースがあります(Uniswapの例に見ることができます)。 **2. 自律性**: 構成可能なコンポーネントには、独立して動作できることが求められます。 イーサリアムの各スマートコントラクトは自己実行形式であり、システムの他の部分に依存することなく機能することができます。 @@ -31,7 +31,7 @@ incomplete: true 構成可能性は、[Dapp](/dapps/#what-are-dapps)を作成する際にデベロッパーが行うべき作業を減らします。 [Naval Ravikant 氏が言うように、](https://twitter.com/naval/status/1444366754650656770)「オープンソースは、すべての問題を一度だけ解決すればよいということを意味する」ということです。 -一つの問題を解決するスマートコントラクトがある場合、他のデベロッパーはそれを再利用できるため、同じ問題を解決する必要はありません。 このようにして、デベロッパーは既存のソフトウェアライブラリを利用し、更なる機能を追加して新しい Dapp を作成することができます。 +一つの問題を解決するスマートコントラクトがある場合、他のデベロッパーはそれを再利用できるため、同じ問題を解決する必要はありません。 このようにして、デベロッパーは既存のソフトウェアライブラリを利用し、更なる機能を追加して新しいDappを作成することができます。 ### イノベーションの加速 {#greater-innovation} @@ -39,13 +39,13 @@ incomplete: true ### ユーザーエクスペリエンスの向上 {#better-user-experience} -イーサリアムエコシステムのコンポーネント間の相互運用性は、ユーザーエクスペリエンスを向上させます。 アプリケーション間で通信できない分断されたエコシステムよりも、外部のスマートコントラクトを統合している Dapp の方が、ユーザーに高い機能性を提供できます。 +イーサリアムエコシステムのコンポーネント間の相互運用性は、ユーザーエクスペリエンスを向上させます。 アプリケーション間で通信できない分断されたエコシステムよりも、外部のスマートコントラクトを統合しているDappの方が、ユーザーに高い機能性を提供できます。 ここでは、裁定取引の例を使用して、相互運用性のメリットを説明します。 トークンが`取引所A`で`取引所B`よりも高く取引されている場合、この価格差を利用して利益を上げることができます。 ただし、それができるのは、トランザクション(つまり、`取引所B`からトークンを購入し、`取引所A`でそれを売却すること)に資金を提供するだけの十分な資金がある場合に限ります。 -取引を行うのに十分な資金を持っていないシナリオでは、フラッシュローンが理想的かもしれません。 [フラッシュローン](/defi/#flash-loans)は非常に専門的ですが、基本的な考え方は、*一つ*のトランザクション内で(担保なしに)資産を借りて同じだけ返すということです。 +取引を行うのに十分な資金を持っていないシナリオでは、フラッシュローンが理想的かもしれません。 [フラッシュローン](/defi/#flash-loans)は非常に専門的ですが、基本的な考え方は、_一つ_のトランザクション内で(担保なしに)資産を借りて同じだけ返すということです。 当初の例に戻りましょう。制定取引業者は多額のフラッシュローンを利用して`取引所B`からトークンを購入し、それらを`取引所A`に売却し、資金と利息の払い戻しを受け、利益を確保するまでを同一のトランザクションの中で行うことができます。 この複雑なロジックでは、複数のコントラクトへの呼び出しを組み合わせる必要がありますが、スマートコントラクトに相互運用性がない場合は不可能です。 @@ -53,25 +53,25 @@ incomplete: true ### トークンスワップ {#token-swaps} -ETH でトランザクションフィーを支払う必要がある Dapp を作成する場合、トークンスワップロジックを統合することで、ユーザーが他の ERC-20 トークンで支払えるようにすることができます。 このコードは、コントラクトが呼び出された関数を実行する前に、ユーザーのトークンを ETH に自動的に変換します。 +ETHでトランザクションフィーを支払う必要があるDappを作成する場合、トークンスワップロジックを統合することで、ユーザーが他のERC-20トークンで支払えるようにすることができます。 このコードは、コントラクトが呼び出された関数を実行する前に、ユーザーのトークンをETHに自動的に変換します。 ### ガバナンス {#governance} -[DAO](/dao/)向けにカスタマイズしたガバナンスシステムの構築には、コストと時間がかかることがあります。 代わりに、[Aragon Client](https://client.aragon.org/)のようなオープンソースのガバナンスツールキットを使用して、ガバナンスフレームワークをすばやく作成して DAO を立ち上げることができます。 +[DAO](/dao/)向けにカスタマイズしたガバナンスシステムの構築には、コストと時間がかかることがあります。 代わりに、[Aragon Client](https://client.aragon.org/)のようなオープンソースのガバナンスツールキットを使用して、ガバナンスフレームワークをすばやく作成してDAOを立ち上げることができます。 -### ID 管理 {#identity-management} +### ID管理 {#identity-management} カスタム認証システムを構築したり、集中型プロバイダーに依存したりしなくても、ユーザーの認証を管理する分散型アイデンティティ(DID)ツールを統合できます。 例えば、オープンソースツールキットの[SpluceID](https://www.spruceid.com/)などがあります。このツールキットは「イーサリアムでサインイン」機能を提供し、ユーザーはイーサリアムウォレットを使用してアイデンティティを認証できます。 ## 関連トピック {#related-tutorials} - [コントラクトの構成可能性: イーサリアムスマートコントラクト開発のビルディングブロック](https://www.decentlabs.io/blog/contract-composability-the-building-blocks-of-ethereum-smart-contract-development) -- [create-eth-app を使用した Dapp フロントエンドの始動](/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/) _- create-eth-app を使用して、一般的なスマートコントラクトを使用する、すぐに利用可能なアプリを作成する方法の概要_ +- [create-eth-appを使用したDappフロントエンドの始動](/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/) _- create-eth-appを使用して、一般的なスマートコントラクトを使用する、すぐに利用可能なアプリを作成する方法の概要_ ## 参考文献 {#further-reading} _イーサリアムを学ぶために利用したコミュニティリソースはありますか? もしあればページを編集して追加してください!_ - [構成可能性はイノベーションである](https://future.a16z.com/how-composability-unlocks-crypto-and-everything-else/) -- [構成可能性が Web3 にとって重要な理由](https://hackernoon.com/why-composability-matters-for-web3) +- [構成可能性がWeb3にとって重要な理由](https://hackernoon.com/why-composability-matters-for-web3) - [構成可能性とは](https://blog.aragon.org/what-is-composability/#:~:text=Aragon,connect%20to%20every%20other%20piece.) diff --git a/public/content/translations/ja/developers/docs/smart-contracts/deploying/index.md b/public/content/translations/ja/developers/docs/smart-contracts/deploying/index.md index ace295fa059..6d2819f7105 100644 --- a/public/content/translations/ja/developers/docs/smart-contracts/deploying/index.md +++ b/public/content/translations/ja/developers/docs/smart-contracts/deploying/index.md @@ -21,23 +21,21 @@ lang: ja ### 必要なもの {#what-youll-need} - コントラクトのバイトコード - これは[コンパイル](/developers/docs/smart-contracts/compiling/)によって生成されます。 -- ガス用の ETH - 他のトランザクションと同様にガスリミットを設定しますので、コントラクトのデプロイには、単純な ETH の送金よりも多くのガスが必要であることに注意してください。 +- ガス用のETH - 他のトランザクションと同様にガスリミットを設定しますので、コントラクトのデプロイには、単純なETHの送金よりも多くのガスが必要であることに注意してください。 - デプロイメントのためのスクリプトやプラグイン。 -- [イーサリアムノード](/developers/docs/nodes-and-clients/)へのアクセス。これは、自身のノードを実行するか、公開ノードに接続するか、[Infura](https://www.infura.io/)や[Alchemy](https://docs.alchemy.com/)のような[ノードサービス](/developers/docs/nodes-and-clients/nodes-as-a-service/)を使用して API キーを介するかのいずれかの方法で行います。 +- [イーサリアムノード](/developers/docs/nodes-and-clients/)へのアクセス。これは、自身のノードを実行するか、公開ノードに接続するか、[ノードサービス](/developers/docs/nodes-and-clients/nodes-as-a-service/)を使用してAPIキーを介するかのいずれかの方法で行います。 ### スマートコントラクトをデプロイする手順 {#steps-to-deploy} -実際の手順は、どのツールを利用するかによって変わります。 例えば、[コントラクトのデプロイに関する Hardhat のドキュメント](https://hardhat.org/guides/deploying.html)や、[ネットワークとアプリケーションのデプロイに関する Truffle のドキュメント](https://www.trufflesuite.com/docs/truffle/advanced/networks-and-app-deployment)をご確認ください。 これらは、スマートコントラクトをデプロイするための最も一般的なツールです。このデプロイでは、デプロイの手順を進めていくためのスクリプトを作成します。 - -デプロイされると、コントラクトは他の[アカウント](/developers/docs/accounts/)と同じように、イーサリアムアドレスを持つようになります。 +The specific steps involved will depend on the development framework in question. For example, you can check out [Hardhat's documentation on deploying your contracts](https://hardhat.org/guides/deploying.html) or [Foundry's documentation on deploying and verifying a smart contract](https://book.getfoundry.sh/forge/deploying). Once deployed, your contract will have an Ethereum address like other [accounts](/developers/docs/accounts/) and can be verified using [source code verification tools](/developers/docs/smart-contracts/verifying/#source-code-verification-tools). ## 関連ツール {#related-tools} -**Remix - _Remix IDE では、イーサリアムのようなブロックチェーン上のスマートコントラクトの開発、デプロイ、管理を行うことができます。_** +**Remix - _Remix IDEでは、イーサリアムのようなブロックチェーン上のスマートコントラクトの開発、デプロイ、管理を行うことができます。_** - [Remix](https://remix.ethereum.org) -**Tenderly - _スマートコントラクトの開発、テスト、監視、運用のためのデバッグ、オブザーバビリティ、インフラストラクチャ・ビルディング・ブロックを提供する Web3 開発プラットフォーム_** +**Tenderly - _スマートコントラクトの開発、テスト、監視、運用のためのデバッグ、オブザーバビリティ、インフラストラクチャ・ビルディング・ブロックを提供するWeb3開発プラットフォーム_** - [tenderly.co](https://tenderly.co/) - [ドキュメント](https://docs.tenderly.co/) @@ -51,27 +49,26 @@ lang: ja - [GitHub](https://github.com/nomiclabs/hardhat) - [Discord](https://discord.com/invite/TETZs2KK4k) -**Truffle -** **_開発環境、テストフレームワーク、ビルドパイプライン、およびその他のツール。_** +**サードウェブ - _単一のコマンドを使い、任意のコントラクトを任意のEVM互換チェーンに容易にデプロイ_** -- [trufflesuite.com](https://www.trufflesuite.com/) -- [ネットワークとアプリケーションのデプロイに関するドキュメント](https://www.trufflesuite.com/docs/truffle/advanced/networks-and-app-deployment) -- [GitHub](https://github.com/trufflesuite/truffle) +- [ドキュメント](https://portal.thirdweb.com/deploy/) ## 関連チュートリアル {#related-tutorials} - [最初のスマートコントラクトのデプロイ](/developers/tutorials/deploying-your-first-smart-contract/) _- イーサリアムテストネットワークに最初のスマートコントラクトをデプロイする方法の紹介_ -- [Hello World | スマートコントラクトチュートリアル](/developers/tutorials/hello-world-smart-contract/) _– 容易に理解できるチュートリアルです。基本的なスマートコントラクトを作成し、イーサリアムにデプロイします。_ -- [Solidity を使用した他のコントラクトとの連携](/developers/tutorials/interact-with-other-contracts-from-solidity/) _- 既存のコントラクトからスマートコントラクトをデプロイし、それを扱う方法_ +- [Hello World | スマートコントラクトチュートリアル](/developers/tutorials/hello-world-smart-contract/) _– 基本的なスマートコントラクトの作成と、イーサリアムへのデプロイ方法を学ぶための、わかりやすいチュートリアル_ +- [Solidityを使用した他のコントラクトとの連携](/developers/tutorials/interact-with-other-contracts-from-solidity/) _- 既存のコントラクトからスマートコントラクトをデプロイし、それを扱う方法_ - [コントラクトのサイズを小さくする方法](/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) _- コントラクトコードのサイズをリミットよりも下げて、ガスを節約する方法_ ## 参考文献 {#further-reading} - [https://docs.openzeppelin.com/learn/deploying-and-interacting](https://docs.openzeppelin.com/learn/deploying-and-interacting) - _OpenZeppelin_ -- [Hardhat を使用したコントラクトのデプロイ](https://hardhat.org/guides/deploying.html) - _Nomic Labs_ +- [Hardhatを使用したコントラクトのデプロイ](https://hardhat.org/guides/deploying.html) - _Nomic Labs_ -_イーサリアムを学ぶために利用したコミュニティリソースはありますか? もしあればページを編集して追加してください!_ +_役に立ったコミュニティリソースがあれば、 ぜひこのページに追加してください。_ ## 関連トピック {#related-topics} - [開発フレームワーク](/developers/docs/frameworks/) -- [イーサリアムノードの実行](/developers/docs/nodes-and-clients/run-a-node/) +- [イーサリアムノードの運用](/developers/docs/nodes-and-clients/run-a-node/) +- [Nodes-as-a-service(サービスとしてのノード)](/developers/docs/nodes-and-clients/nodes-as-a-service) diff --git a/public/content/translations/ja/developers/docs/smart-contracts/formal-verification/index.md b/public/content/translations/ja/developers/docs/smart-contracts/formal-verification/index.md index 851b9808cc9..88e894bf98c 100644 --- a/public/content/translations/ja/developers/docs/smart-contracts/formal-verification/index.md +++ b/public/content/translations/ja/developers/docs/smart-contracts/formal-verification/index.md @@ -20,7 +20,7 @@ lang: ja 計算機科学において、 [計算の形式モデル](https://en.wikipedia.org/wiki/Model_of_computation)は計算プロセスを数学的に記述するものです。 プログラムは数学的な関数(方程式)によって抽象化され、関数の入力に対して出力をどう計算するかが形式モデルによって記述されます。 -形式モデルは、プログラムの挙動の分析を評価できる水準での抽象化を可能とします。 形式モデルがあることで*形式仕様*が作成でき、それによって、問題となっているモデルの持つべき望ましいプロパティが記述されます。 +形式モデルは、プログラムの挙動の分析を評価できる水準での抽象化を可能とします。 形式モデルがあることで_形式仕様_が作成でき、それによって、問題となっているモデルの持つべき望ましいプロパティが記述されます。 形式的検証のためのスマートコントラクトのモデル化には、さまざまな技法が用いられます。 たとえば、スマートコントラクトの高水準な挙動を論証するために用いられるモデルがあります。 そのようなモデル化技法では、スマートコントラクトを与えられた入力に基いて計算を実行するブラックボックスとみなします。 @@ -34,7 +34,7 @@ lang: ja 仕様とは、特定のシステムが満たすべき技術的要件のことです。 プログラミングにおいては、仕様はプログラムの実行についてのおおまかな狙い(すなわち、プログラムが何をすべきか)を表します。 -スマートコントラクトの文脈では、形式仕様記述はスマートコントラクトが満たさなければならない要件を形式的に記述したものであり、これを*プロパティ*と呼びます。 プロパティはスマートコントラクトの実行を通しての「不変条件」として記述され、例外なしにあらゆる状況下で真であるべき論理アサーションを表現するものです。 +スマートコントラクトの文脈では、形式仕様記述はスマートコントラクトが満たさなければならない要件を形式的に記述したものであり、これを_プロパティ_と呼びます。 プロパティはスマートコントラクトの実行を通しての「不変条件」として記述され、例外なしにあらゆる状況下で真であるべき論理アサーションを表現するものです。 したがって、形式仕様記述はスマートコントラクトのしかるべき挙動を形式言語で記述したものの集まりである、と考えることができます。 仕様が対象とするのはスマートコントラクトのプロパティで、スマートコントラクトがさまざまな状況下でどのように動作すべきかを表します。 スマートコントラクトがそれらのプロパティ(不変条件) を実行中に破らないことを見極めるのが、 形式的検証の目的です。 @@ -52,11 +52,11 @@ lang: ja その名のとおり、高水準な仕様記述(「モデル指向仕様記述」とも呼ばれます) はプログラムの高水準な挙動を記述するためのものです。 高水準な仕様記述においてスマートコントラクトは[有限状態機械](https://en.wikipedia.org/wiki/Finite-state_machine)(FSM)としてモデル化されます。スマートコントラクトの挙動は処理の実行を伴う状態遷移で表され、モデルの形式的プロパティは時相論理で記述されます。 -[時相論理](https://en.wikipedia.org/wiki/Temporal_logic)は時間という条件の付いた命題(たとえば、「私は*いつも*空腹だ」や「私は*いずれ*空腹になる」)を論証するための規則の集まりです。 形式的検証での時相論理は、状態遷移機械でモデル化されたシステムの正しい挙動に関するアサーションを記述するために使われます。 具体的には、スマートコントラクトがある将来の時点でモデルのどの状態にあるのか、そしてどのように状態間で遷移するのかを時相論理で記述できます。 +[時相論理](https://en.wikipedia.org/wiki/Temporal_logic)は時間という条件の付いた命題(たとえば、「私は_いつも_空腹だ」や「私は_いずれ_空腹になる」)を論証するための規則の集まりです。 形式的検証での時相論理は、状態遷移機械でモデル化されたシステムの正しい挙動に関するアサーションを記述するために使われます。 具体的には、スマートコントラクトがある将来の時点でモデルのどの状態にあるのか、そしてどのように状態間で遷移するのかを時相論理で記述できます。 -高水準な仕様記述は一般に**安全性 (safety)**と**活性 (liveness)**という、スマートコントラクトの時相に関する重要な 2 つのプロパティを捕えることができます。 安全性とはすなわち「何も悪いことが起こらない」ということで、通常は不変条件によって表されます。 安全性は、[デッドロック](https://www.techtarget.com/whatis/definition/deadlock)が起こらないことといった一般的なソフトウェア要件を意味することもあれば、スマートコントラクトのドメイン固有なプロパティ(たとえば関数に対するアクセス制御の不変条件、状態変数の許容値、トークン転送の条件など)を意味することもあります。 +高水準な仕様記述は一般に**安全性 (safety)**と**活性 (liveness)**という、スマートコントラクトの時相に関する重要な2つのプロパティを捕えることができます。 安全性とはすなわち「何も悪いことが起こらない」ということで、通常は不変条件によって表されます。 安全性は、[デッドロック](https://www.techtarget.com/whatis/definition/deadlock)が起こらないことといった一般的なソフトウェア要件を意味することもあれば、スマートコントラクトのドメイン固有なプロパティ(たとえば関数に対するアクセス制御の不変条件、状態変数の許容値、トークン転送の条件など)を意味することもあります。 -例として、*「送金しようとしているトークンの量に対し、送金元の口座残高に不足があってはならない」*という、 ERC-20 トークンのスマートコントラクトで`transfer()`や`transferFrom()`を呼び出す際の安全性の要求仕様を考えます。 この自然言語で書かれたスマートコントラクトの不変条件は数学的な形式仕様記述に翻訳され、その妥当性が厳密に検査されます。 +例として、_「送金しようとしているトークンの量に対し、送金元の口座残高に不足があってはならない」_という、 ERC-20トークンのスマートコントラクトで`transfer()`や`transferFrom()`を呼び出す際の安全性の要求仕様を考えます。 この自然言語で書かれたスマートコントラクトの不変条件は数学的な形式仕様記述に翻訳され、その妥当性が厳密に検査されます。 活性は「何らかの良いことがいずれは起こる」ということを意味し、スマートコントラクトに関しては、するべき処理を滞りなく進められることを示します。 活性の一例として「流動性」が挙げられ、これは、要求に応じてスマートコントラクトが残高を他ユーザーに譲渡できることを意味します。 このプロパティが破られると、[パリティウォレット事件](https://www.cnbc.com/2017/11/08/accidental-bug-may-have-frozen-280-worth-of-ether-on-parity-wallet.html)で起こったように、あるはずの資産が引き出せなくなります。 @@ -64,23 +64,23 @@ lang: ja 高水準な仕様記述では、有限状態モデルから出発してモデルの望ましいプロパティを記述しました。 一方で、低水準な仕様記述(プロパティ指向仕様記述とも呼ばれます)では、プログラム(すなわちスマートコントラクト)を数学的な関数の集まりからなるシステムとしてモデル化し、そのシステムの正しい挙動を記述します。 -簡単に言うと、低水準な仕様記述では*プログラムのトレース* を解析し、それに基づいてスマートコントラクトのプロパティを記述することを目指します。 トレースとは、スマートコントラクトの状態変化を伴った関数の実行シーケンスを指します。したがって、低水準な仕様記述ではスマートコントラクト内部の実行の様子についての要求仕様まで記述できます。 +簡単に言うと、低水準な仕様記述では_プログラムのトレース_ を解析し、それに基づいてスマートコントラクトのプロパティを記述することを目指します。 トレースとは、スマートコントラクトの状態変化を伴った関数の実行シーケンスを指します。したがって、低水準な仕様記述ではスマートコントラクト内部の実行の様子についての要求仕様まで記述できます。 低水準な仕様記述は、ホーア型のプロパティもしくはプログラムの実行フローによって与えられます。 ### ホーア型のプロパティ {#hoare-style-properties} -[ホーア論理](https://en.wikipedia.org/wiki/Hoare_logic)は、スマートコントラクトなどのプログラムの正当性を論証するための形式規則を提供します。 ホーア型のプロパティは、ホーアトリプルと呼ばれる{_P_}_c_{_Q_}という形の式で与えられます。*c*はプログラムで、*P*と*Q*はそれぞれ正式には*事前条件*、*事後条件*と呼ばれる、c の状態についての述語です。 +[ホーア論理](https://en.wikipedia.org/wiki/Hoare_logic)は、スマートコントラクトなどのプログラムの正当性を論証するための形式規則を提供します。 ホーア型のプロパティは、ホーアトリプルと呼ばれる{_P_}_c_{_Q_}という形の式で与えられます。_c_はプログラムで、_P_と_Q_はそれぞれ正式には_事前条件_、_事後条件_と呼ばれる、cの状態についての述語です。 -事前条件は関数を正しく実行するために求められる条件を表しています。スマートコントラクトを呼び出す際には、この事前条件が満たされている必要があります。 事後条件は、関数が正しく実行された場合に成立する条件を表しています。関数呼び出しの後はこの事後条件が真となることが期待されます。 ホーア論理の*不変条件*は、関数の実行中は常に維持されます(すなわち、変化しません)。 +事前条件は関数を正しく実行するために求められる条件を表しています。スマートコントラクトを呼び出す際には、この事前条件が満たされている必要があります。 事後条件は、関数が正しく実行された場合に成立する条件を表しています。関数呼び出しの後はこの事後条件が真となることが期待されます。 ホーア論理の_不変条件_は、関数の実行中は常に維持されます(すなわち、変化しません)。 -ホーア型の仕様記述により、*部分正当性*もしくは*完全正当性*が保証されます。 事前条件が関数実行前に真であり、実行が停止した場合には事後条件も真であるとき、スマートコントラクト関数の実装は「部分正当性を満たし」ます。 完全正当性を証明するには、関数の実行前に事前条件が真であること、実行が終了すること、その際に事後条件が真であることの三つが必要です。 +ホーア型の仕様記述により、_部分正当性_もしくは_完全正当性_が保証されます。 事前条件が関数実行前に真であり、実行が停止した場合には事後条件も真であるとき、スマートコントラクト関数の実装は「部分正当性を満たし」ます。 完全正当性を証明するには、関数の実行前に事前条件が真であること、実行が終了すること、その際に事後条件が真であることの三つが必要です。 プログラムによっては実行が終わるのに時間がかかったり、そもそも終わらなかったりするので、完全正当性の証明は困難となります。 とはいえ、イーサリアムのガスメカニズムが無限ループを防ぐので、実行が終了するかどうかは議論の余地はあれども理論上の問題点です(実行は正常に終了するか、'ガス不足'のエラーで打ち切られます)。 ホーア論理で作成されたスマートコントラクトの仕様記述は、スマートコントラクト内部の関数やループを実行するために述べられた事前条件、事後条件、不変条件を含みます。 事前条件が関数への誤った入力を許容する場合もあり、その際は事後条件でそのような誤った入力があった場合の応答(例外を発生させるなど)が記述されます。 このようにして、ホーア型のプロパティによってスマートコントラクト実装の正当性を保証する際に有効となります。 -多くの形式的検証のフレームワークで、関数の意味的正当性を証明するためにホーア型の仕様記述が使われています。 Solidity の`require`と`assert`ステートメントを使えば、スマートコントラクトのコードにホーア型のプロパティを(アサーションとして) 直接書くこともできます。 +多くの形式的検証のフレームワークで、関数の意味的正当性を証明するためにホーア型の仕様記述が使われています。 Solidityの`require`と`assert`ステートメントを使えば、スマートコントラクトのコードにホーア型のプロパティを(アサーションとして) 直接書くこともできます。 `require`ステートメントは事前条件もしくは不変条件を書くのに用いられ、ユーザーから与えられた入力の有効性を確認するのに使われることが多く、その一方で`assert`ステートメントは安全性のために必要な事後条件を書くのに使われます。 たとえば、 関数への適切なアクセス制御(安全性プロパティの一例) は、`require`ステートメントを使用して、該当する関数を呼び出そうとしているアカウントの識別情報を前提条件チェックすることで実現できます。 同様に、`assert`ステートメントで実行後のスマートコントラクトの状態を確認することで、コントラクト内部の状態変数(たとえば、流通しているトークンの総数など)が許容される値であることを示す不変条件を違反しないが保護することがであることを示す不変条件の違反を防ぐことができます。 @@ -92,7 +92,7 @@ lang: ja 主に、トレースレベルの仕様記述は、スマートコントラクトの内部の実行のパターンを論じる際に用いられます。 トレースレベルでの仕様記述を作成することで、スマートコントラクトに許容される実行パス(すなわち、状態遷移)をアサートできます。 シンボリック実行などの手法を用いれば、形式的モデルで定義されていないパスには実行が進まないことを形式的に検証することができます。 -例として、公開されている関数でトレースレベルのプロパティの記述ができる[DAO](/dao/)コントラクトを見てみましょう。 ここでは、DAO コントラクトによってユーザーが以下の操作を実行できることとします。 +例として、公開されている関数でトレースレベルのプロパティの記述ができる[DAO](/dao/)コントラクトを見てみましょう。 ここでは、DAOコントラクトによってユーザーが以下の操作を実行できることとします。 - 入金 @@ -100,7 +100,7 @@ lang: ja - 提案への投票をしなかった者は返金を要求する -トレースレベルのプロパティの例として、 _「資金を入金しないユーザーは、提案に投票できない」_ または *「提案に投票しないユーザーは、いつでも返金を要求できる」*などが考えられます。 どちらのプロパティも望ましい実行シーケンスをアサートします(入金する*前*に投票することはできず、提案に投票した*後*に払い戻しの要求はできません)。 +トレースレベルのプロパティの例として、 _「資金を入金しないユーザーは、提案に投票できない」_ または _「提案に投票しないユーザーは、いつでも返金を要求できる」_などが考えられます。 どちらのプロパティも望ましい実行シーケンスをアサートします(入金する_前_に投票することはできず、提案に投票した_後_に払い戻しの要求はできません)。 ## スマートコントラクトの形式的検証の技法 {#formal-verification-techniques} @@ -110,9 +110,9 @@ lang: ja モデル検査では、システム(すなわち、スマートコントラクト)を抽象的かつ数学的に表すことと、システムが満たすべきプロパティを[命題論理](https://www.baeldung.com/cs/propositional-logic)に根差した論理式で表すことが求められます。 これにより、モデル検査アルゴリズムの目的は、数学的モデルが与えられた論理式を充足することの証明、と単純化されます。 -形式的検証におけるモデル検査は主として、スマートコントラクトの挙動を時間経過を加味して記述する時間的プロパティの評価に用いられます。 そのような、時間が関係するスマートコントラクトのプロパティには、先に説明した*安全性*と*活性*が含まれます。 +形式的検証におけるモデル検査は主として、スマートコントラクトの挙動を時間経過を加味して記述する時間的プロパティの評価に用いられます。 そのような、時間が関係するスマートコントラクトのプロパティには、先に説明した_安全性_と_活性_が含まれます。 -たとえば、アクセス制御(たとえば、 *スマートコントラクトの所有者に限り`selfdestruct`*を呼び出すことができます)に関するセキュリティプロパティが形式論理で記述できます。 その後、モデル検査のアルゴリズムはスマートコントラクトがこの形式的仕様を満たしているかどうかを検証することができます。 +たとえば、アクセス制御(たとえば、 _スマートコントラクトの所有者に限り`selfdestruct`_を呼び出すことができます)に関するセキュリティプロパティが形式論理で記述できます。 その後、モデル検査のアルゴリズムはスマートコントラクトがこの形式的仕様を満たしているかどうかを検証することができます。 モデル検査では、スマートコントラクトのすべての起こりうる状態を正確に描き、そのうちの到達可能な状態を見つけだそうと試みることで、状態空間の探索をします。 しかし、これは無限の状態数につながる可能性があります(「状態爆発問題」として知られています)。そのため、モデル検査器は抽象化技法によってスマートコントラクトの分析を効率化します。 @@ -120,7 +120,7 @@ lang: ja 定理証明は、スマートコントラクトなどのプログラムの正しさを数学的に論証する手法です。 スマートコントラクトのシステムとその仕様記述を数式(論理式)で書き下す必要があります。 -定理証明で目指すのは、それらの数式が論理的に等価であると検証することです。 「論理的な等価性」(「論理的な双含意」とも呼ばれます)は二つのステートメント間の関係の一種で、片方が真の*時かつその時に限り*もう片方も真となることです。 +定理証明で目指すのは、それらの数式が論理的に等価であると検証することです。 「論理的な等価性」(「論理的な双含意」とも呼ばれます)は二つのステートメント間の関係の一種で、片方が真の_時かつその時に限り_もう片方も真となることです。 スマートコントラクトのモデルに関するステートメントとそのプロパティのステートメントとの間に要求された関係性(論理的等価性)は、証明可能なステートメント(定理と呼ばれます)として定式化されます。 形式的な推論システムにより、自動定理証明器は定理の妥当性を検証することができます。 言い換えれば、定理証明器はスマートコントラクトのモデルが仕様記述に正確に適合していることを、疑いの余地のない形で証明することができます。 @@ -130,13 +130,13 @@ lang: ja ### シンボリック実行 {#symbolic-execution} -シンボリック実行は、関数の実行にあたって*具体的な値*(例えば`x == 5`)の代わりに*シンボリックな値*(例えば`x > 5`)を用いることで、スマートコントラクトの分析を行う手法です。 形式的検証の手法として、シンボリック実行によってスマートコントラクトのコード中のトレースレベルのプロパティを形式的に論証することができます。 +シンボリック実行は、関数の実行にあたって_具体的な値_(例えば`x == 5`)の代わりに_シンボリックな値_(例えば`x > 5`)を用いることで、スマートコントラクトの分析を行う手法です。 形式的検証の手法として、シンボリック実行によってスマートコントラクトのコード中のトレースレベルのプロパティを形式的に論証することができます。 -シンボリック実行では、実行トレースはシンボリックな入力値を含む数式で表され、これを*パス述語*と呼びます。 [SMT ソルバー](https://en.wikipedia.org/wiki/Satisfiability_modulo_theories)はパス述語が「充足可能」(すなわち、論理式を満たす値が存在する)かどうかを検査するのに用いられます。 脆弱性のあるパスが充足可能であれば、SMT ソルバーはそのようなパスへと実行を進めてしまう具体的な値を生成します。 +シンボリック実行では、実行トレースはシンボリックな入力値を含む数式で表され、これを_パス述語_と呼びます。 [SMTソルバー](https://en.wikipedia.org/wiki/Satisfiability_modulo_theories)はパス述語が「充足可能」(すなわち、論理式を満たす値が存在する)かどうかを検査するのに用いられます。 脆弱性のあるパスが充足可能であれば、SMTソルバーはそのようなパスへと実行を進めてしまう具体的な値を生成します。 入力として`uint`の値(`x`)を取り、`x`が`5`より大きく、`10`より小さい場合にリバートするスマートコントラクトの関数を考えます。 通常のテストの手順では、エラーとなる`x`の値を求めるのに、実際にそのような値が見つかる確信のないまま数十(もしくはそれ以上の)テストケースを実行することになります。 -逆に、シンボリック実行のツールは`X > 5 ∧ X < 10`(つまり、`x`は 5 より大きく、かつ、`x`は 10 より小さい)といったシンボリックな値を用いて関数を実行します。 関連するパス述語`x = X > 5 X < 10`は、これを解くために SMT ソルバーに渡されます。 ある値が論理式`x = X > 5 ∧ X < 10`を満たすのであれば、SMT ソルバーはそのような値を計算します。たとえば、`x`の値として`7`を出してくるかもしれません。 +逆に、シンボリック実行のツールは`X > 5 ∧ X < 10`(つまり、`x`は5より大きく、かつ、`x`は10より小さい)といったシンボリックな値を用いて関数を実行します。 関連するパス述語`x = X > 5 X < 10`は、これを解くためにSMTソルバーに渡されます。 ある値が論理式`x = X > 5 ∧ X < 10`を満たすのであれば、SMTソルバーはそのような値を計算します。たとえば、`x`の値として`7`を出してくるかもしれません。 シンボリック実行はプログラムへの入力によって行うもので、到達可能なあらゆる状態を探索するための入力集合は潜在的に無限となるため、これは依然としてテスト技法の一形態です。 ただし、例に示すように、プロパティに反する入力を見付けることについては、シンボリック実行は通常のテスト技法より効果的です。 @@ -170,7 +170,7 @@ function safe_add(uint x, uint y) returns(uint z){ しかし、このアプローチではサンプルに含まれない入力値に関しては正しさを証明することができません。 そのため、スマートコントラクトをテストすることでバグを検出できますが(すなわち、あるコードパスが実行中に望まれる結果を返さないならば)、**バグがないことを疑いの余地のない形で証明することはできません**。 -逆に、形式的検証によって、スマートコントラクトが実行範囲が無限となるような要求を満たすことを、実行すること*なし*に、形式的に証明することができます。 そのためには、スマートコントラクトの正しい挙動の詳細な形式仕様記述を作成し、スマートコントラクトのシステムの形式的(数学的)モデルを開発する必要があります。 そうすれば、形式的な証明手続きによって、スマートコントラクトのモデルとその仕様記述の間に矛盾がないことを確認することができます。 +逆に、形式的検証によって、スマートコントラクトが実行範囲が無限となるような要求を満たすことを、実行すること_なし_に、形式的に証明することができます。 そのためには、スマートコントラクトの正しい挙動の詳細な形式仕様記述を作成し、スマートコントラクトのシステムの形式的(数学的)モデルを開発する必要があります。 そうすれば、形式的な証明手続きによって、スマートコントラクトのモデルとその仕様記述の間に矛盾がないことを確認することができます。 形式的検証により、スマートコントラクトのビジネスロジックが要件を満たしているかどうかを検証するという問題は、証明もしくは反証できる数学的命題となります。 形式的に命題を証明することで、無限にあるテストケースが有限の手順で検証できるようになります。 形式的検証には、スマートコントラクトが仕様記述に対して機能的に正しいこと証明することの、より良い将来性が見込まれます。 @@ -178,11 +178,11 @@ function safe_add(uint x, uint y) returns(uint z){ 検証の対象は、形式的に検証すべきシステムを記述します。 形式的検証は、「組み込みシステム」(大きなシステムの一部を形成する小さく単純なソフトウェア)で最もよく使用されます。 また、少数の規則のみを扱うドメインであれば、ドメイン固有のプロパティを検証するためにツールを変更することも容易であるため、形式的検証が適しています。 -スマートコントラクトは、少なくともある程度は両方の要件を満たしています。 たとえば、イーサリアムのスマートコントラクトはサイズが小さいため、形式的検証が適しています。 同様に、EVM は単純なルールに従っているため、EVM で実行されるプログラムの意味論的なプロパティの仕様記述とその検証も容易になります。 +スマートコントラクトは、少なくともある程度は両方の要件を満たしています。 たとえば、イーサリアムのスマートコントラクトはサイズが小さいため、形式的検証が適しています。 同様に、EVMは単純なルールに従っているため、EVMで実行されるプログラムの意味論的なプロパティの仕様記述とその検証も容易になります。 ### 開発サイクルの短縮 {#faster-development-cycle} -モデル検査やシンボリック実行などの形式的検証の技法は、一般的にスマートコントラクトのコードの定期的な分析よりも効率的です(テストや監査中に実行されます)。 これは、形式的検証ではアサーションをテストするためにシンボリックな値を用いるからで(「ユーザーが _n_ eth 引き出そうとした場合はどうなりますか?」)、 具体的な値を用いる場合(「ユーザーが 5 eth を引き出そうとした場合はどうでしょう?」)とは異なります。 +モデル検査やシンボリック実行などの形式的検証の技法は、一般的にスマートコントラクトのコードの定期的な分析よりも効率的です(テストや監査中に実行されます)。 これは、形式的検証ではアサーションをテストするためにシンボリックな値を用いるからで(「ユーザーが _n_ eth引き出そうとした場合はどうなりますか?」)、 具体的な値を用いる場合(「ユーザーが5 ethを引き出そうとした場合はどうでしょう?」)とは異なります。 シンボリックな入力変数は複数クラスの具体的値をカバーできるため、形式的検証のアプローチでは、より短い時間でより多くのコードカバレッジが期待されます。 形式的検証を効果的に使用することで、開発サイクルを加速させることができます。 @@ -204,7 +204,7 @@ function safe_add(uint x, uint y) returns(uint z){ ### パフォーマンスの問題 {#performance-issues} -形式的検証はパフォーマンス上の問題になります。 例えば、モデル検査とシンボル検査中に発生する状態爆発問題とパス爆発問題により、検証手順に悪影響がありえます。 また、形式的検証ツールは多くの場合に SMT ソルバーやその他の制約ソルバーを内部的に使用しており、多量の計算処理を要します。 +形式的検証はパフォーマンス上の問題になります。 例えば、モデル検査とシンボル検査中に発生する状態爆発問題とパス爆発問題により、検証手順に悪影響がありえます。 また、形式的検証ツールは多くの場合にSMTソルバーやその他の制約ソルバーを内部的に使用しており、多量の計算処理を要します。 プログラムが停止しない可能性([decidability problem](https://en.wikipedia.org/wiki/Decision_problem))もあるため、要求されるプロパティ(論理式として定義される)が満たされるのかどうかも一般には判断できません。 スマートコントラクトのプロパティが正しく記述されていたとしても、証明することが不可能なことがあります。 @@ -212,59 +212,59 @@ function safe_add(uint x, uint y) returns(uint z){ ### 形式的仕様記述のための言語 {#specification-languages} -**Act**: \_\*ストレージの更新、事前条件・事後条件、スマートコントラクトの不変条件を仕様として記述できます。 Act ツールスイートには、Coq、SMT ソルバー、hevm を介してプロパティを証明するための、証明バックエンドが含まれます。\*\* +**Act**: _*ストレージの更新、事前条件・事後条件、スマートコントラクトの不変条件を仕様として記述できます。 Actツールスイートには、Coq、SMTソルバー、hevmを介してプロパティを証明するための、証明バックエンドが含まれます。** - [GitHub](https://github.com/ethereum/act) - [ドキュメント](https://ethereum.github.io/act/) -**Scribble** - \_\*Scribble は、Scribble 仕様言語のコードアノテーションを具体的なアサーションに変換し、仕様記述を検査することができます。\*\* +**Scribble** - _*Scribbleは、Scribble仕様言語のコードアノテーションを具体的なアサーションに変換し、仕様記述を検査することができます。** - [ドキュメント](https://docs.scribble.codes/) -**Dafny** \_\*Dafny はプログラム検証との親和性が高いプログラミング言語で、その高水準なアノテーションを用いることでコードの正しさを論証したり証明したりすることができます。\*\* +**Dafny** _*Dafnyはプログラム検証との親和性が高いプログラミング言語で、その高水準なアノテーションを用いることでコードの正しさを論証したり証明したりすることができます。** - [GitHub](https://github.com/dafny-lang/dafny) ### 正しさを確認するためのプログラム検証器 {#program-verifiers} -**Certora Prover** _Certora Prover は、スマートコントラクトのコードの正しさを検査するための自動形式的検証ツールです。 仕様記述は CVL(Certora Verification Language)で行い、静的解析と制約解析の組み合わせでプロパティ違反を検出します。_ +**Certora Prover** _Certora Proverは、スマートコントラクトのコードの正しさを検査するための自動形式的検証ツールです。 仕様記述はCVL(Certora Verification Language)で行い、静的解析と制約解析の組み合わせでプロパティ違反を検出します。_ - [ウェブサイト](https://www.certora.com/) - [ドキュメント](https://docs.certora.com/en/latest/index.html) -**Solidity SMTChecker** \_\*Solidity SMTChecker は、SMT(Satisfiability Modulo Theories)とホーン節の充足問題に基づく組み込みのモデルチェッカーです。 コンパイル中にスマートコントラクトのソースコードが仕様記述に適合することを確認し、安全性プロパティの違反があるかどうかを静的にチェックします。\*\* +**Solidity SMTChecker** _*Solidity SMTCheckerは、SMT(Satisfiability Modulo Theories)とホーン節の充足問題に基づく組み込みのモデルチェッカーです。 コンパイル中にスマートコントラクトのソースコードが仕様記述に適合することを確認し、安全性プロパティの違反があるかどうかを静的にチェックします。** - [GitHub](https://github.com/ethereum/solidity) -**solc-verify** \_\*solc-verify は Solidity コンパイラの拡張で、アノテーションとモジュラー型のプログラム検証によって自動的に形式的検証を行います。\*\* +**solc-verify** _*solc-verifyはSolidityコンパイラの拡張で、アノテーションとモジュラー型のプログラム検証によって自動的に形式的検証を行います。** - [GitHub](https://github.com/SRI-CSL/solidity) -**KEVM** \_\*KEVM は、K framework で書かれたイーサリアム仮想マシン(EVM)の形式的な意味論です。 KEVM は実行可能であり、到達可能性論理によってある種のプロパティ関連のアサーションの証明に利用できます。\*\* +**KEVM** _*KEVMは、K frameworkで書かれたイーサリアム仮想マシン(EVM)の形式的な意味論です。 KEVMは実行可能であり、到達可能性論理によってある種のプロパティ関連のアサーションの証明に利用できます。** - [GitHub](https://github.com/runtimeverification/evm-semantics) - [ドキュメント](https://jellopaper.org/) ### 定理証明のための論理枠組み {#theorem-provers} -**Isabelle** _証明支援ソフトウェア Isabelle/HOL は、数式を形式言語で表現したり、それらを証明するためのツールで構成されます。 主に数学における証明の形式化とある種の形式的検証に用いられ、コンピュータハードウェアやソフトウェアの正しさの証明やコンピュータ言語やプロトコルの性質の証明などに応用されています。_ +**Isabelle** _証明支援ソフトウェアIsabelle/HOLは、数式を形式言語で表現したり、それらを証明するためのツールで構成されます。 主に数学における証明の形式化とある種の形式的検証に用いられ、コンピュータハードウェアやソフトウェアの正しさの証明やコンピュータ言語やプロトコルの性質の証明などに応用されています。_ - [GitHub](https://github.com/isabelle-prover) - [ドキュメント](https://isabelle.in.tum.de/documentation.html) -**Coq** _Coq は対話型の定理証明器で、機械的に検査されたプログラムの正しさの証明を対話的に作成することができます。_ +**Coq** _Coqは対話型の定理証明器で、機械的に検査されたプログラムの正しさの証明を対話的に作成することができます。_ - [GitHub](https://github.com/coq/coq) - [ドキュメント](https://coq.github.io/doc/v8.13/refman/index.html) ### シンボリック実行に基いてスマートコントラクトが脆弱となるパターンを検出するツール {#symbolic-execution-tools} -**Manticore** \_\*シンボリック実行に基づいた EVM バイトコードの解析ツールです。\*\* +**Manticore** _*シンボリック実行に基づいたEVMバイトコードの解析ツールです。** - [GitHub](https://github.com/trailofbits/manticore) - [ドキュメント](https://github.com/trailofbits/manticore/wiki) -**hevm** \_\*hevm はシンボリック実行のエンジンで、EVM バイトコードの同等性を検査することができます。\*\* +**hevm** _*hevmはシンボリック実行のエンジンで、EVMバイトコードの同等性を検査することができます。** - [GitHub](https://github.com/dapphub/dapptools/tree/master/src/hevm) @@ -278,6 +278,6 @@ function safe_add(uint x, uint y) returns(uint z){ - [スマートコントラクトの形式的検証方法](https://runtimeverification.com/blog/how-formal-verification-of-smart-contracts-works/) - [形式的検証で完璧なスマートコントラクトを実現する方法](https://media.consensys.net/how-formal-verification-can-ensure-flawless-smart-contracts-cbda8ad99bd1) - [イーサリアム・エコシステムにおける形式的検証プロジェクトの概要](https://github.com/leonardoalt/ethereum_formal_verification_overview) -- [イーサリアム 2.0 の入金スマートコントラクトのエンドツーエンドな形式的検証](https://runtimeverification.com/blog/end-to-end-formal-verification-of-ethereum-2-0-deposit-smart-contract/) +- [イーサリアム2.0の入金スマートコントラクトのエンドツーエンドな形式的検証](https://runtimeverification.com/blog/end-to-end-formal-verification-of-ethereum-2-0-deposit-smart-contract/) - [世界一有名なスマートコントラクトの形式的検証](https://www.zellic.io/blog/formal-verification-weth) -- [SMTChecker と形式的検証](https://docs.soliditylang.org/en/v0.8.15/smtchecker.html) +- [SMTCheckerと形式的検証](https://docs.soliditylang.org/en/v0.8.15/smtchecker.html) diff --git a/public/content/translations/ja/developers/docs/smart-contracts/index.md b/public/content/translations/ja/developers/docs/smart-contracts/index.md index cdcbea74aa7..9c557157bef 100644 --- a/public/content/translations/ja/developers/docs/smart-contracts/index.md +++ b/public/content/translations/ja/developers/docs/smart-contracts/index.md @@ -28,7 +28,7 @@ lang: ja このロジックは自動販売機にプログラムされています。 -自動販売機と同様に、スマートコントラクトにはロジックがプログラムされています。 この自動販売機が Solidity で書かれたスマートコントラクトであればどのように見えるか、簡単な例を挙げてみましょう。 +自動販売機と同様に、スマートコントラクトにはロジックがプログラムされています。 この自動販売機がSolidityで書かれたスマートコントラクトであればどのように見えるか、簡単な例を挙げてみましょう。 ```solidity pragma solidity 0.8.7; @@ -66,7 +66,7 @@ contract VendingMachine { ## パーミッションレス {#permissionless} -誰でもスマートコントラクトを作成してネットワークにデプロイできます。 [スマートコントラクト言語](/developers/docs/smart-contracts/languages/)でのコーディング方法を学び、コントラクトをデプロイするのに十分な ETH を持っていればよいのです。 スマートコントラクトのデプロイは技術的にはトランザクションなので、単純な ETH 送金に[ガス](/developers/docs/gas/)を支払う必要があるのと同じように、ガスを支払う必要があります。 ただし、コントラクトのデプロイにかかるガス代は、はるかに高くなります。 +誰でもスマートコントラクトを作成してネットワークにデプロイできます。 [スマートコントラクト言語](/developers/docs/smart-contracts/languages/)でのコーディング方法を学び、コントラクトをデプロイするのに十分なETHを持っていればよいのです。 スマートコントラクトのデプロイは技術的にはトランザクションなので、単純なETH送金に[ガス](/developers/docs/gas/)を支払う必要があるのと同じように、ガスを支払う必要があります。 ただし、コントラクトのデプロイにかかるガス代は、はるかに高くなります。 イーサリアムには以下のような、スマートコントラクトを作成するためのデベロッパーフレンドリーな言語があります。 @@ -79,21 +79,21 @@ contract VendingMachine { ## コンポーザビリティ {#composability} -スマートコントラクトはイーサリアム上で公開されており、オープン API と考えることができます。 つまり、自分のスマートコントラクトの中で他のスマートコントラクトを呼び出し、自分のスマートコントラクトでできることを大幅に拡張することができるのです。 スマートコントラクトは他のスマートコントラクトをデプロイすることもできます。 +スマートコントラクトはイーサリアム上で公開されており、オープンAPIと考えることができます。 つまり、自分のスマートコントラクトの中で他のスマートコントラクトを呼び出し、自分のスマートコントラクトでできることを大幅に拡張することができるのです。 スマートコントラクトは他のスマートコントラクトをデプロイすることもできます。 [スマートコントラクトのコンポーザビリティ](/developers/docs/smart-contracts/composability/)についてもっと詳しく知る ## 制限事項 {#limitations} -スマートコントラクトだけでは、HTTP リクエストを送信できないため、実際のイベントに関する情報を得ることはできません。 これは仕様です。 外部の情報に頼ると、セキュリティや分散化のために重要なコンセンサスが損なわれる可能性があります。 +スマートコントラクトだけでは、オフチェーンソースからデータを取得できないため、実世界のイベントに関する情報を得ることはできません。 そのため、実世界のイベントに反応することはできません。 これは、スマートコントラクトの仕様です。 外部の情報に頼ると、セキュリティや分散化のために重要なコンセンサスが損なわれる可能性があるためです。 -[オラクル](/developers/docs/oracles/)を使用して、この問題を回避する方法があります。 +しかし、ブロックチェーンアプリケーションにとって、オフチェーンデータが使えることは重要です。 そのためソリューションとして、オフチェーンデータを取り込んでスマートコントラクトで利用できるようにするツールである[オラクル](/developers/docs/oracles/)があります。 -スマートコントラクトのもう一つの制約は、コントラクトの最大サイズです。 スマートコントラクトの最大サイズは 24KB です。それ以上の場合はガス不足になります。 これは、[ダイヤモンドパターン](https://eips.ethereum.org/EIPS/eip-2535)を使用して回避することができます。 +スマートコントラクトのもう一つの制約は、コントラクトの最大サイズです。 スマートコントラクトの最大サイズは24KBです。それ以上の場合はガス不足になります。 これは、[ダイヤモンドパターン](https://eips.ethereum.org/EIPS/eip-2535)を使用して回避することができます。 ## マルチシグコントラクト {#multisig} -マルチシグ(複数署名)コントラクトは、トランザクションを実行するために複数の有効な署名を必要とするスマートコントラクトアカウントです。 これは、相当量のイーサやトークンを保持するコントラクトで単一障害点を回避するのに特に便利です。 マルチシグはまた、コントラクトの実行と鍵の管理の責任を複数の当事者間で分担し、取返しのつかない資金損失につながる秘密鍵の紛失を防ぎます。 これらの理由から、簡単な DAO ガバナンスのためにマルチシグコントラクトを利用することができます。 マルチシグでは実行に、許容可能な M 個の署名の内の N 個の署名(N ≤ M、M > 1)が必要です。 `N = 3, M = 5`と`N = 4, M = 7`が一般的に使用されます。 4/7 マルチシグでは、7 つの有効な署名のうちの 4 つが必要です。 これは、3 つの署名が失われても資金が回収可能であることを意味します。 この場合、コントラクトを実行するためには、鍵の保有者の過半数の同意と署名が必要であることも意味します。 +マルチシグ(複数署名)コントラクトは、トランザクションを実行するために複数の有効な署名を必要とするスマートコントラクトアカウントです。 これは、相当量のイーサやトークンを保持するコントラクトで単一障害点を回避するのに特に便利です。 マルチシグはまた、コントラクトの実行と鍵の管理の責任を複数の当事者間で分担し、取返しのつかない資金損失につながる秘密鍵の紛失を防ぎます。 これらの理由から、簡単なDAOガバナンスのためにマルチシグコントラクトを利用することができます。 マルチシグでは実行に、許容可能なM個の署名の内のN個の署名(N ≤ M、M > 1)が必要です。 `N = 3, M = 5`と`N = 4, M = 7`が一般的に使用されます。 4/7マルチシグでは、7つの有効な署名のうちの4つが必要です。 これは、3つの署名が失われても資金が回収可能であることを意味します。 この場合、コントラクトを実行するためには、鍵の保有者の過半数の同意と署名が必要であることも意味します。 ## スマートコントラクト関連情報 {#smart-contract-resources} @@ -103,13 +103,8 @@ contract VendingMachine { - [GitHub](https://github.com/OpenZeppelin/openzeppelin-contracts) - [コミュニティフォーラム](https://forum.openzeppelin.com/c/general/16) -**DappSys -** **_スマートコントラクトのための安全でシンプルかつ柔軟なビルディングブロック。_** - -- [Dappsys](https://dappsys.readthedocs.io/) -- [GitHub](https://github.com/dapphub/dappsys) - ## 参考文献 {#further-reading} -- [スマートコントラクト: 弁護士を不要にするブロックチェーンテクノロジー](https://blockgeeks.com/guides/smart-contracts/) _– Blockgeeks_ -- [スマートコントラクト開発のための最善の方法](https://yos.io/2019/11/10/smart-contract-development-best-practices/) _– 2019 年 11 月 10 日 - Yos Riady_ -- [ クリーンコントラクト - スマートコントラクトのパターンと実践に関するガイド](https://www.wslyvh.com/clean-contracts/) _– 2020 年 7 月 30 日 - wslyvh_ +- [Coinbase: スマートコントラクトとは何か](https://www.coinbase.com/learn/crypto-basics/what-is-a-smart-contract) +- [Chainlink: スマートコントラクトとは何か](https://chain.link/education/smart-contracts) +- [スマートコントラクトの概要を説明するビデオ](https://youtu.be/ZE2HxTmxfrI) diff --git a/public/content/translations/ja/developers/docs/smart-contracts/languages/index.md b/public/content/translations/ja/developers/docs/smart-contracts/languages/index.md index 729d954c736..912bfd54ff7 100644 --- a/public/content/translations/ja/developers/docs/smart-contracts/languages/index.md +++ b/public/content/translations/ja/developers/docs/smart-contracts/languages/index.md @@ -4,20 +4,20 @@ description: 2つの主要なスマートコントラクト言語であるSolidi lang: ja --- -イーサリアムの長所は、比較的デベロッパーフレンドリーな言語を使ってスマートコントラクトを記述できることです。 Python や[中括弧を使ってブロックを表現する言語](https://wikipedia.org/wiki/List_of_programming_languages_by_type#Curly-bracket_languages)を使用している方は、見慣れたような構文を持つ言語を使うことができます。 +イーサリアムの長所は、比較的デベロッパーフレンドリーな言語を使ってスマートコントラクトを記述できることです。 Pythonや[中括弧を使ってブロックを表現する言語](https://wikipedia.org/wiki/List_of_programming_languages_by_type#Curly-bracket_languages)を使用している方は、見慣れたような構文を持つ言語を使うことができます。 -最も活発にメンテナンスされている言語は、以下の 2 つです。 +最も活発にメンテナンスされている言語は、以下の2つです。 - Solidity - Vyper -また、経験豊富なデベロッパーであれば、[イーサリアム仮想マシン](/developers/docs/evm/)用の中間言語である Yul や、Yul を拡張した Yul+を使うのもよいでしょう。 +また、経験豊富なデベロッパーであれば、[イーサリアム仮想マシン](/developers/docs/evm/)用の中間言語であるYulや、Yulを拡張したYul+を使うのもよいでしょう。 -開発中の新しい言語に興味があり、テストに協力したいとお考えの場合は、Fe というまだ登場したばかりのスマートコントラクト言語を試してみることができます。 +開発中の新しい言語に興味があり、テストに協力したいとお考えの場合は、Feというまだ登場したばかりのスマートコントラクト言語を試してみることができます。 ## 前提知識 {#prerequisites} -プログラミング言語、特に JavaScript や Python の知識は、スマートコントラクト言語の違いを理解するのに役立ちます。 また、スマートコントラクトをコンセプトとして理解し、言語比較を深く掘り下げることをお勧めします。 [スマートコントラクトの紹介](/developers/docs/smart-contracts/) +プログラミング言語、特にJavaScriptやPythonの知識は、スマートコントラクト言語の違いを理解するのに役立ちます。 また、スマートコントラクトをコンセプトとして理解し、言語比較を深く掘り下げることをお勧めします。 [スマートコントラクトの紹介](/developers/docs/smart-contracts/) ## Solidity {#solidity} @@ -32,12 +32,12 @@ lang: ja ### 参照すべきリンク {#important-links} - [ドキュメント](https://docs.soliditylang.org/en/latest/) -- [Solidity 言語ポータル](https://soliditylang.org/) +- [Solidity言語ポータル](https://soliditylang.org/) - [Solidity by Example](https://docs.soliditylang.org/en/latest/solidity-by-example.html) - [GitHub](https://github.com/ethereum/solidity/) -- [Solidity Matrix チャットルーム](https://matrix.to/#/#ethereum_solidity:gitter.im)にブリッジされた[Solidity Gitter チャットルーム](https://gitter.im/ethereum/solidity) +- [Solidity Matrixチャットルーム](https://matrix.to/#/#ethereum_solidity:gitter.im)にブリッジされた[Solidity Gitterチャットルーム](https://gitter.im/ethereum/solidity/) - [チートシート](https://reference.auditless.com/cheatsheet) -- [Solidity ブログ](https://blog.soliditylang.org/) +- [Solidityブログ](https://blog.soliditylang.org/) - [Solidity Twitter](https://twitter.com/solidity_lang) ### コントラクトのコード例 {#example-contract} @@ -81,25 +81,25 @@ contract Coin { } ``` -この例は、Solidity のコントラクト構文がどのようなものか理解するのに役立つでしょう。 関数と変数のより詳細な説明については、[ドキュメント](https://docs.soliditylang.org/en/latest/contracts.html)を参照してください。 +この例は、Solidityのコントラクト構文がどのようなものか理解するのに役立つでしょう。 関数と変数のより詳細な説明については、[ドキュメント](https://docs.soliditylang.org/en/latest/contracts.html)を参照してください。 ## Vyper {#vyper} -- Python 的なプログラミング言語 +- Python的なプログラミング言語 - 強い型付け - コンパクトでわかりやすいコンパイラコード - 効率的なバイトコード生成 -- コントラクトの安全性を確保し、監査が容易になることを目的として、意図的に Solidity よりも機能を絞っている。 Vyper は以下をサポートしていない - - modifier 修飾子 +- コントラクトの安全性を確保し、監査が容易になることを目的として、意図的にSolidityよりも機能を絞っている。 Vyperは以下をサポートしていない + - modifier修飾子 - 継承 - インラインアセンブリ - 関数のオーバーロード - オペレータのオーバーロード - 再帰呼び出し - 無限ループ - - 2 進固定小数点 + - 2進固定小数点 -詳細については、[Vyper のドキュメント](https://vyper.readthedocs.io/en/latest/index.html)を参照してください。 +詳細については、[Vyperのドキュメント](https://vyper.readthedocs.io/en/latest/index.html)を参照してください。 ### 参照すべきリンク {#important-links-1} @@ -107,14 +107,14 @@ contract Coin { - [Vyper by Example](https://vyper.readthedocs.io/en/latest/vyper-by-example.html) - [More Vyper by Example](https://vyper-by-example.org/) - [GitHub](https://github.com/vyperlang/vyper) -- [Vyper コミュニティの Discord チャット](https://discord.gg/SdvKC79cJk) +- [VyperコミュニティのDiscordチャット](https://discord.gg/SdvKC79cJk) - [チートシート](https://reference.auditless.com/cheatsheet) -- [スマートコントラクト開発フレームワークと Vyper 用ツール](/developers/docs/programming-languages/python/) -- [VyperPunk - Vyper スマートコントラクトのセキュリティとハッキングを学ぶ](https://github.com/SupremacyTeam/VyperPunk) -- [VyperExamples - Vyper の脆弱性の例](https://www.vyperexamples.com/reentrancy) -- [開発用 Vyper Hub](https://github.com/zcor/vyper-dev) -- [人気を博している Vyper のスマートコントラクトの例](https://github.com/pynchmeister/vyper-greatest-hits/tree/main/contracts) -- [素晴らしい Vyper の厳選されたリソース](https://github.com/spadebuilders/awesome-vyper) +- [スマートコントラクト開発フレームワークとVyper用ツール](/developers/docs/programming-languages/python/) +- [VyperPunk - Vyperスマートコントラクトのセキュリティとハッキングを学ぶ](https://github.com/SupremacyTeam/VyperPunk) +- [VyperExamples - Vyperの脆弱性の例](https://www.vyperexamples.com/reentrancy) +- [開発用Vyper Hub](https://github.com/zcor/vyper-dev) +- [人気を博しているVyperのスマートコントラクトの例](https://github.com/pynchmeister/vyper-greatest-hits/tree/main/contracts) +- [素晴らしいVyperの厳選されたリソース](https://github.com/spadebuilders/awesome-vyper) ### 例 {#example} @@ -203,34 +203,34 @@ def endAuction(): send(self.beneficiary, self.highestBid) ``` -この例は、Vyper のコントラクト構文がどのようなものか理解するのに役立つでしょう。 関数と変数のより詳細な説明については、[ドキュメント](https://vyper.readthedocs.io/en/latest/vyper-by-example.html#simple-open-auction)を参照してください。 +この例は、Vyperのコントラクト構文がどのようなものか理解するのに役立つでしょう。 関数と変数のより詳細な説明については、[ドキュメント](https://vyper.readthedocs.io/en/latest/vyper-by-example.html#simple-open-auction)を参照してください。 -## Yul と Yul+ {#yul} +## YulとYul+ {#yul} -イーサリアムを使い始めたばかりで、スマートコントラクト言語を使ってコードを書いたことがない場合は、Solidity や Vyper を利用することをお勧めします。 Yul や Yul+を検討するのは、スマートコントラクトのセキュリティの最善の方法や、EVM との連携の具体的な内容に精通してからにしてください。 +イーサリアムを使い始めたばかりで、スマートコントラクト言語を使ってコードを書いたことがない場合は、SolidityやVyperを利用することをお勧めします。 YulやYul+を検討するのは、スマートコントラクトのセキュリティの最善の方法や、EVMとの連携の具体的な内容に精通してからにしてください。 **Yul** - イーサリアムのための中間言語 -- [EVM](/developers/docs/evm)および[Ewasm](https://github.com/ewasm)というイーサリアム向けの WebAssembly をサポートしており、両方のプラットフォームで使用可能な共通部分として設計されている -- EVM と eWASM の両方のプラットフォームに同程度のメリットをもたらす、高度な最適化段階を経る対象となる +- [EVM](/developers/docs/evm)および[Ewasm](https://github.com/ewasm)というイーサリアム向けのWebAssemblyをサポートしており、両方のプラットフォームで使用可能な共通部分として設計されている +- EVMとeWASMの両方のプラットフォームに同程度のメリットをもたらす、高度な最適化段階を経る対象となる **Yul+** -- Yul に高効率な拡張機能を施した低レベル言語 +- Yulに高効率な拡張機能を施した低レベル言語 - コントラクトの[オプティミスティック・ロールアップ](/developers/docs/scaling/optimistic-rollups/)のために設計された -- Yul に新しい機能を追加した実験的なアップグレード案として捉えることができる +- Yulに新しい機能を追加した実験的なアップグレード案として捉えることができる ### 参照すべきリンク {#important-links-2} -- [Yul のドキュメント](https://docs.soliditylang.org/en/latest/yul.html) +- [Yulのドキュメント](https://docs.soliditylang.org/en/latest/yul.html) - [Yul+のドキュメント](https://github.com/fuellabs/yulp) - [Yul+ Playground](https://yulp.fuel.sh/) - [Yul+の紹介記事](https://medium.com/@fuellabs/introducing-yul-a-new-low-level-language-for-ethereum-aa64ce89512f) ### コントラクトのコード例 {#example-contract-2} -以下の簡単な例では、べき乗関数を実装しています。 `solc --strict-assembly --bin input.yul`を使用してコンパイルすることができます。 この例は、input.yul に記述されます。 +以下の簡単な例では、べき乗関数を実装しています。 `solc --strict-assembly --bin input.yul`を使用してコンパイルすることができます。 この例は、input.yulに記述されます。 ``` { @@ -251,26 +251,26 @@ def endAuction(): } ``` -スマートコントラクトの経験が豊富な場合は、Yul による[ERC20 の完全な実装](https://solidity.readthedocs.io/en/latest/yul.html#complete-erc20-example)をご覧ください。 +スマートコントラクトの経験が豊富な場合は、Yulによる[ERC20の完全な実装](https://solidity.readthedocs.io/en/latest/yul.html#complete-erc20-example)をご覧ください。 ## Fe {#fe} - イーサリアム仮想マシン(EVM)向けの静的型付け言語 -- Python と Rust の影響を受けている +- PythonとRustの影響を受けている - イーサリアムのエコシステムに不慣れなデベロッパーでも簡単に学習できる言語であることを目標としている -- Fe の開発は未だ初期段階にあり、2021 年 1 月にアルファ版がリリースされた +- Feの開発は未だ初期段階にあり、2021年1月にアルファ版がリリースされた ### 参照すべきリンク {#important-links-3} - [GitHub](https://github.com/ethereum/fe) -- [Fe に関するアナウンス](https://snakecharmers.ethereum.org/fe-a-new-language-for-the-ethereum-ecosystem/) -- [2021 年の Fe のロードマップ](https://notes.ethereum.org/LVhaTF30SJOpkbG1iVw1jg) -- [Fe の Discord チャット](https://discord.com/invite/ywpkAXFjZH) +- [Feに関するアナウンス](https://snakecharmers.ethereum.org/fe-a-new-language-for-the-ethereum-ecosystem/) +- [2021年のFeのロードマップ](https://notes.ethereum.org/LVhaTF30SJOpkbG1iVw1jg) +- [FeのDiscordチャット](https://discord.com/invite/ywpkAXFjZH) - [Twitter](https://twitter.com/official_fe) ### コントラクトのコード例 {#example-contract-3} -Fe で実装されたシンプルなコントラクトのコード例を以下に示します。 +Feで実装されたシンプルなコントラクトのコード例を以下に示します。 ``` type BookMsg = bytes[100] @@ -297,28 +297,28 @@ contract GuestBook: まだどの言語も試していない場合に考慮すべき事項をいくつか紹介します。 -### Solidity の長所 {#solidity-advantages} +### Solidityの長所 {#solidity-advantages} - 初心者向けに、多くのチュートリアルや学習ツールが用意されている。 詳細については、[コーディングで学ぶ](/developers/learning-tools/)セクションを参照 - 優れた開発ツールが利用可能 -- Solidity には大きなデベロッパーコミュニティがあり、質問に対する答えをすぐに見つけることができる +- Solidityには大きなデベロッパーコミュニティがあり、質問に対する答えをすぐに見つけることができる -### Vyper の長所 {#vyper-advatages} +### Vyperの長所 {#vyper-advatages} -- Python デベロッパーが、スマートコントラクトの記述を始めるのに最適な方法である -- Vyper の機能の数は絞られているため、アイデアから素早くプロトタイプを構築可能 -- Vyper は監査が容易で、最大限に人間が読めるようにすることを目指している +- Pythonデベロッパーが、スマートコントラクトの記述を始めるのに最適な方法である +- Vyperの機能の数は絞られているため、アイデアから素早くプロトタイプを構築可能 +- Vyperは監査が容易で、最大限に人間が読めるようにすることを目指している -### Yul と Yul+の長所 {#yul-advantages} +### YulとYul+の長所 {#yul-advantages} - シンプルで機能的な低レベル言語 -- 生の EVM に近づくことができ、コントラクトのガス使用量を最適化するのに役立つ +- 生のEVMに近づくことができ、コントラクトのガス使用量を最適化するのに役立つ ## 言語比較 {#language-comparisons} -コントラクトのライフサイクル、インターフェイス、演算子、データ構造、関数、制御フローなどの基本的な構文の比較については、 [Auditless によるチートシート](https://reference.auditless.com/cheatsheet/)を参照してください。 +コントラクトのライフサイクル、インターフェイス、演算子、データ構造、関数、制御フローなどの基本的な構文の比較については、 [Auditlessによるチートシート](https://reference.auditless.com/cheatsheet/)を参照してください。 ## 参考文献 {#further-reading} -- [OpenZeppelin による Solidity コントラクトライブラリ](https://docs.openzeppelin.com/contracts) +- [OpenZeppelinによるSolidityコントラクトライブラリ](https://docs.openzeppelin.com/contracts) - [Solidity by Example](https://solidity-by-example.org) diff --git a/public/content/translations/ja/developers/docs/smart-contracts/libraries/index.md b/public/content/translations/ja/developers/docs/smart-contracts/libraries/index.md index 0f27ec7541f..f312ae0326c 100644 --- a/public/content/translations/ja/developers/docs/smart-contracts/libraries/index.md +++ b/public/content/translations/ja/developers/docs/smart-contracts/libraries/index.md @@ -12,15 +12,15 @@ lang: ja ## ライブラリの中身 {#whats-in-a-library} -スマートコントラクトライブラリには、通常、2 種類のビルディングブロックがあります。コントラクトに追加できる再利用可能な振る舞いと、さまざまな標準の実装です。 +スマートコントラクトライブラリには、通常、2種類のビルディングブロックがあります。コントラクトに追加できる再利用可能な振る舞いと、さまざまな標準の実装です。 ### 振る舞い {#behaviors} -スマートコントラクトを記述していると、コントラクト内の保護された操作を行うために*管理者*アドレスを割り当てたり、予期せぬ問題が発生した場合に緊急用の*一時停止*ボタンを追加したりと、似たようなパターンを何度も書くことになる可能性があります。 +スマートコントラクトを記述していると、コントラクト内の保護された操作を行うために_管理者_アドレスを割り当てたり、予期せぬ問題が発生した場合に緊急用の_一時停止_ボタンを追加したりと、似たようなパターンを何度も書くことになる可能性があります。 -スマートコントラクトライブラリは通常、Solidity で[ライブラリ](https://solidity.readthedocs.io/en/v0.7.2/contracts.html#libraries)または[継承](https://solidity.readthedocs.io/en/v0.7.2/contracts.html#inheritance)を介して、これらの振る舞いを再利用できる実装を提供します。 +スマートコントラクトライブラリは通常、Solidityで[ライブラリ](https://solidity.readthedocs.io/en/v0.7.2/contracts.html#libraries)または[継承](https://solidity.readthedocs.io/en/v0.7.2/contracts.html#inheritance)を介して、これらの振る舞いを再利用できる実装を提供します。 -例として、[OpenZeppelin のコントラクトライブラリ](https://github.com/OpenZeppelin/openzeppelin-contracts)の[`Ownable contract`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.2.0/contracts/access/Ownable.sol)を簡易にしたバージョンを以下に示します。これは、あるアドレスをコントラクトの所有者として指定し、その所有者のみにメソッドへのアクセスを制限する modifier を提供するコードです。 +例として、[OpenZeppelinのコントラクトライブラリ](https://github.com/OpenZeppelin/openzeppelin-contracts)の[`Ownable contract`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.2.0/contracts/access/Ownable.sol)を簡易にしたバージョンを以下に示します。これは、あるアドレスをコントラクトの所有者として指定し、その所有者のみにメソッドへのアクセスを制限するmodifierを提供するコードです。 ```solidity contract Ownable { @@ -56,13 +56,13 @@ contract MyContract is Ownable { [構成可能性と相互運用性](/developers/docs/smart-contracts/composability/)を促進するために、イーサリアムコミュニティは**ERC**の形式でいくつかの標準を定義しました。 詳細については、 [標準](/developers/docs/standards/)セクションを参照してください。 -ERC をコントラクトの一部として組み込む場合、独自の ERC をロールアウトするよりも、標準の実装を探すことをお勧めします。 最も一般的な ERC の実装は、多くのスマートコントラクトライブラリに含まれています。 例えば、どこにでもある[ERC20 代替可能トークン標準](/developers/tutorials/understand-the-erc-20-token-smart-contract/)は[HQ20](https://github.com/HQ20/contracts/blob/master/contracts/token/README.md)、[DappSys](https://github.com/dapphub/ds-token/)と[OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc20)で見つかります。 さらに、ERC によっては ERC 自体の一部として標準実装を提供することもあります。 +ERCをコントラクトの一部として組み込む場合、独自のERCをロールアウトするよりも、標準の実装を探すことをお勧めします。 最も一般的なERCの実装は、多くのスマートコントラクトライブラリに含まれています。 例えば、どこにでもある[ERC20代替可能トークン標準](/developers/tutorials/understand-the-erc-20-token-smart-contract/)は[HQ20](https://github.com/HQ20/contracts/blob/master/contracts/token/README.md)、[DappSys](https://github.com/dapphub/ds-token/)と[OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc20)で見つかります。 さらに、ERCによってはERC自体の一部として標準実装を提供することもあります。 -特筆すべきは、一部の ERC はスタンドアロンではなく、他の ERC に機能を追加するものであるということです。 例えば、 [ERC2612](https://eips.ethereum.org/EIPS/eip-2612) はユーザビリティを向上させるために ERC20 に拡張機能を追加します。 +特筆すべきは、一部のERCはスタンドアロンではなく、他のERCに機能を追加するものであるということです。 例えば、 [ERC2612](https://eips.ethereum.org/EIPS/eip-2612) はユーザビリティを向上させるためにERC20に拡張機能を追加します。 ## ライブラリの追加方法 {#how-to} -プロジェクトにライブラリを含める具体的な手順については、必ずそのライブラリのドキュメントを参照してください。 複数の Solidity コントラクトライブラリは`npm`を使用してパッケージ化されていますので、`npm install`を実行するだけで済みます。 コントラクトを[コンパイル](/developers/docs/smart-contracts/compiling/)するためのほとんどのツールは、`node_modules`でスマートコントラクトライブラリを調べます。そのため、以下のように指定できます。 +プロジェクトにライブラリを含める具体的な手順については、必ずそのライブラリのドキュメントを参照してください。 複数のSolidityコントラクトライブラリは`npm`を使用してパッケージ化されていますので、`npm install`を実行するだけで済みます。 コントラクトを[コンパイル](/developers/docs/smart-contracts/compiling/)するためのほとんどのツールは、`node_modules`でスマートコントラクトライブラリを調べます。そのため、以下のように指定できます。 ```solidity // This will load the @openzeppelin/contracts library from your node_modules @@ -73,7 +73,7 @@ contract MyNFT is ERC721 { } ``` -使用するメソッドに関係なく、ライブラリを含む場合は[言語](/developers/docs/smart-contracts/languages/)のバージョンを常に気に留めておくようにしてください。 たとえば、Solidity 0.5 でコントラクトを書いている場合は、Solidity 0.6 のライブラリを使用することはできません。 +使用するメソッドに関係なく、ライブラリを含む場合は[言語](/developers/docs/smart-contracts/languages/)のバージョンを常に気に留めておくようにしてください。 たとえば、Solidity 0.5でコントラクトを書いている場合は、Solidity 0.6のライブラリを使用することはできません。 ## ライブラリの利用時 {#when-to-use} @@ -98,15 +98,20 @@ contract MyNFT is ERC721 { - [ドキュメント](https://dappsys.readthedocs.io/) - [GitHub](https://github.com/dapphub/dappsys) -**HQ20 - \*\***_実世界向けの完全な機能を備えた分散アプリケーションの構築を支援する、コントラクト、ライブラリ、サンプルを含む Solidity プロジェクト。_\*\* +**HQ20 - ****_実世界向けの完全な機能を備えた分散アプリケーションの構築を支援する、コントラクト、ライブラリ、サンプルを含むSolidityプロジェクト。_** - [GitHub](https://github.com/HQ20/contracts) +**サードウェブSolidity SDK -** **_カスタムスマートコントラクトを効率的に構築するために必要なツールを提供_** + +- [ドキュメント](https://portal.thirdweb.com/solidity/) +- [GitHub](https://github.com/thirdweb-dev/contracts) + ## 関連トピック {#related-tutorials} -- [イーサリアムデベロッパーのためのセキュリティに関する考慮事項](/developers/docs/smart-contracts/security/) _-スマートコントラクトの構築時のセキュリティに関する考慮事項(ライブラリの使用を含む)_ -- [ERC-20 トークンスマートコントラクトを理解する](/developers/tutorials/understand-the-erc-20-token-smart-contract/) _-複数のライブラリで提供される ERC20 標準のチュートリアル_ +- [イーサリアムデベロッパーのためのセキュリティに関する考慮事項](/developers/docs/smart-contracts/security/) _- スマートコントラクト構築時のセキュリティに関する考慮事項(ライブラリの使用を含む)_ +- [ERC-20トークンスマートコントラクトを理解する](/developers/tutorials/understand-the-erc-20-token-smart-contract/) _- 複数のライブラリで提供されるERC20標準のチュートリアル_ ## さらに学びたい方へ {#further-reading} -_イーサリアムを学ぶために利用したコミュニティリソースはありますか? もしあればページを編集して追加してください!_ +_役に立ったコミュニティリソースがあれば、 ぜひこのページに追加してください。_ diff --git a/public/content/translations/ja/developers/docs/smart-contracts/security/index.md b/public/content/translations/ja/developers/docs/smart-contracts/security/index.md index 92e02f7eb45..d63aeb554d2 100644 --- a/public/content/translations/ja/developers/docs/smart-contracts/security/index.md +++ b/public/content/translations/ja/developers/docs/smart-contracts/security/index.md @@ -6,9 +6,9 @@ lang: ja スマートコントラクトは、非常に柔軟性が高く、大量の値やデータを制御できる能力があり、ブロックチェーン上のコードに基づきイミュータブルな(不変の)ロジックを実行します。 これにより、トラストレスな分散型アプリケーション(Dapp)による活気に満ちたエコシステムが構築され、レガシーシステムと比べて多くの利点をもたらしています。 しかし、これはスマートコントラクトの脆弱性を悪用して利益を得ようとしている攻撃者に機会を与えてしまうことにもなります。 -イーサリアムのようなパブリックブロックチェーンは、スマートコントラクトのセキュリティ確保の問題をさらに複雑にします。 デプロイされたコントラクトのコードは*通常*、セキュリティ上の欠陥にパッチを当てるために変更することはできません。一方、スマートコントラクトから盗まれた資産は追跡が非常に難しく、その不変性により、大抵回収できません。 +イーサリアムのようなパブリックブロックチェーンは、スマートコントラクトのセキュリティ確保の問題をさらに複雑にします。 デプロイされたコントラクトのコードは_通常_、セキュリティ上の欠陥にパッチを当てるために変更することはできません。一方、スマートコントラクトから盗まれた資産は追跡が非常に難しく、その不変性により、大抵回収できません。 -数値は一様ではありませんが、スマートコントラクトのセキュリティ上の欠陥が原因で盗まれたり失われたりした価値の総額は、10 億ドルを超えると推定されています。 これには、[The DAO ハック](https://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/)(現行価格 10 億ドル相当以上の 360 万 ETH の盗難)、[パリティ(Parity)マルチシグウォレットハック](https://www.coindesk.com/30-million-ether-reported-stolen-parity-wallet-breach) (ハッカーによる 3000 万ドルの盗難)、[パリティ(Parity)凍結ウォレット問題](https://www.theguardian.com/technology/2017/nov/08/cryptocurrency-300m-dollars-stolen-bug-ether)(3 億ドル以上の ETH を永遠にロック)などの有名な事件も含まれています。 +数値は一様ではありませんが、スマートコントラクトのセキュリティ上の欠陥が原因で盗まれたり失われたりした価値の総額は、10億ドルを超えると推定されています。 これには、[The DAOハック](https://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/)(現行価格10億ドル相当以上の360万ETHの盗難)、[パリティ(Parity)マルチシグウォレットハック](https://www.coindesk.com/30-million-ether-reported-stolen-parity-wallet-breach) (ハッカーによる3000万ドルの盗難)、[パリティ(Parity)凍結ウォレット問題](https://www.theguardian.com/technology/2017/nov/08/cryptocurrency-300m-dollars-stolen-bug-ether)(3億ドル以上のETHを永遠にロック)などの有名な事件も含まれています。 前述の問題は、デベロッパーに安全で堅牢な回復力のあるスマートコントラクトの構築に労力を費やすことを不可欠にしました。 スマートコントラクトのセキュリティは深刻な課題であり、全てのデベロッパーが学ぶべきことです。 このガイドでは、イーサリアムデベロッパーのためのセキュリティの考慮事項について説明します。さらに、スマートコントラクトのセキュリティ向上に役立つリソースもご紹介します。 @@ -20,13 +20,13 @@ lang: ja ### 1. 適切なアクセス制御設計 {#design-proper-access-controls} -スマートコントラクトでは、`public`または`external`が記述されている関数は、どの外部所有アカウント (EOA) もしくはコントラクトアカウントからでも呼び出すことができます。 他のコントラクトが自分のコントラクトとやり取りできるようにするには、関数に public の可視性を指定する必要があります。 一方で`private`と記述されている関数は、外部アカウントで呼び出すことはできず、スマートコントラクト内の関数でしか呼び出すことはできません。 全てのネットワーク参加者にコントラクト関数へのアクセスを許可してしまうと、特に、細心の注意が求められる操作(例: 新しいトークンのミントなど)を誰でも実行できる場合に、さまざまな問題を引き起こす可能性があります。 +スマートコントラクトでは、`public`または`external`が記述されている関数は、どの外部所有アカウント (EOA) もしくはコントラクトアカウントからでも呼び出すことができます。 他のコントラクトが自分のコントラクトとやり取りできるようにするには、関数にpublicの可視性を指定する必要があります。 一方で`private`と記述されている関数は、外部アカウントで呼び出すことはできず、スマートコントラクト内の関数でしか呼び出すことはできません。 全てのネットワーク参加者にコントラクト関数へのアクセスを許可してしまうと、特に、細心の注意が求められる操作(例: 新しいトークンのミントなど)を誰でも実行できる場合に、さまざまな問題を引き起こす可能性があります。 -スマートコントラクト関数の無許可での使用を防ぐために、安全なアクセス制御の実装が必要です。 アクセス制御メカニズムは、スマートコントラクトの特定の関数を、コントラクトを管理する責任を負うアカウントなどの承認されたエンティティだけが使用できるように制限します。 **Ownable パターン**と**ロールベースアクセス制御**は、スマートコントラクトでアクセス制御を実装する際に有用なパターンです +スマートコントラクト関数の無許可での使用を防ぐために、安全なアクセス制御の実装が必要です。 アクセス制御メカニズムは、スマートコントラクトの特定の関数を、コントラクトを管理する責任を負うアカウントなどの承認されたエンティティだけが使用できるように制限します。 **Ownableパターン**と**ロールベースアクセス制御**は、スマートコントラクトでアクセス制御を実装する際に有用なパターンです -#### Ownable パターン {#ownable-pattern} +#### Ownableパターン {#ownable-pattern} -Ownable パターンでは、コントラクト作成プロセスでアドレスがコントラクトの「オーナー(所有者)」として設定されます。 保護される関数には、`OnlyOwner`修飾子が指定されます。これにより、関数を実行する前にコントラクトが呼び出し元のアドレスのアイデンティティを認証するようになります。 保護された関数に対するコントラクトの所有者以外のアドレスからの呼び出しは、常に取り消されます。これにより、不正なアクセスが防止されます。 +Ownableパターンでは、コントラクト作成プロセスでアドレスがコントラクトの「オーナー(所有者)」として設定されます。 保護される関数には、`OnlyOwner`修飾子が指定されます。これにより、関数を実行する前にコントラクトが呼び出し元のアドレスのアイデンティティを認証するようになります。 保護された関数に対するコントラクトの所有者以外のアドレスからの呼び出しは、常に取り消されます。これにより、不正なアクセスが防止されます。 #### ロールベースアクセス制御 {#role-based-access-control} @@ -36,19 +36,19 @@ Ownable パターンでは、コントラクト作成プロセスでアドレス ##### マルチシグウォレットの使用 -安全なアクセス制御を実装するもう一つのアプローチとして、[マルチシグ(複数署名)アカウント](/developers/docs/smart-contracts/#multisig)でコントラクトを管理することもできます。 通常の EOA と異なり、マルチシグアカウントは複数のエンティティに所有されます。また、トランザクションの実行には最低数のアカウントの署名 (例: 5 つのうち 3 つの署名など) が必要です。 +安全なアクセス制御を実装するもう一つのアプローチとして、[マルチシグ(複数署名)アカウント](/developers/docs/smart-contracts/#multisig)でコントラクトを管理することもできます。 通常のEOAと異なり、マルチシグアカウントは複数のエンティティに所有されます。また、トランザクションの実行には最低数のアカウントの署名 (例: 5つのうち3つの署名など) が必要です。 -アクセス制御でマルチシグ (複数署名) を使用すると、追加のセキュリティレイヤーを導入できます。なぜなら、目的のコントラクトを動作させるには複数の当事者からの同意が必要になるためです。 これは Ownable パターンを使う必要がある場合に特に有用です。これにより、攻撃者や不正な内部関係者が、細心の注意が求められるコントラクト関数を悪意のある目的で操作することをより困難にするためです。 +アクセス制御でマルチシグ (複数署名) を使用すると、追加のセキュリティレイヤーを導入できます。なぜなら、目的のコントラクトを動作させるには複数の当事者からの同意が必要になるためです。 これはOwnableパターンを使う必要がある場合に特に有用です。これにより、攻撃者や不正な内部関係者が、細心の注意が求められるコントラクト関数を悪意のある目的で操作することをより困難にするためです。 -### 2. コントラクト操作の保護に require()、assert()、revert() ステートメントを使用 {#use-require-assert-revert} +### 2. コントラクト操作の保護にrequire()、assert()、revert() ステートメントを使用 {#use-require-assert-revert} -前述のように、スマートコントラクトをいったんブロックチェーンにデプロイすると、誰でもその中の public 関数を呼び出すことができます。 外部アカウントがどのようにコントラクトとやり取りするかを事前に知ることはできないため、デプロイする前に、問題のある操作に対して内部的な防御策を講じることが理想的です。 実行する際、特定の要件を満たさない場合は、`require()`、`assert()`、および`revert()`ステートメントを使用して例外をトリガーし、状態変更を元に戻すことにより、スマートコントラクトで正しい動作を強制できます。 +前述のように、スマートコントラクトをいったんブロックチェーンにデプロイすると、誰でもその中のpublic関数を呼び出すことができます。 外部アカウントがどのようにコントラクトとやり取りするかを事前に知ることはできないため、デプロイする前に、問題のある操作に対して内部的な防御策を講じることが理想的です。 実行する際、特定の要件を満たさない場合は、`require()`、`assert()`、および`revert()`ステートメントを使用して例外をトリガーし、状態変更を元に戻すことにより、スマートコントラクトで正しい動作を強制できます。 **`require()`**: `require`は、関数の開始時に定義され、呼び出された関数が実行される前に、事前に定義された条件を確実に満たすようにします。 `require`ステートメントは、ユーザーの入力の検証、状態変数のチェック、または関数を実行する前に呼び出し元のアカウントのアイデンティティを認証するために使用することができます。 **`assert()`**: `assert()`は、内部エラーの検出や、コード内の「不変条件」の違反をチェックするために使用されます。 不変条件とは、コントラクトの状態に関する論理アサーションであり、すべての関数の実行に対して真 (true) となるべきものです。 不変条件の例としては、トークンコントラクトの最大供給量や残高があげられます。 `assert()` を使用することで、コントラクトが脆弱な状態にならないようにします。もしそうなった場合は、状態変数へのすべての変更がロールバックされます。 -**`revert()`**: `revert()` if-else 文の中で使用することができ、必要な条件を満たさない場合に例外を発生させます。 以下のサンプルコントラクトでは、`revert()`によって関数の実行を保護しています。 +**`revert()`**: `revert()` if-else文の中で使用することができ、必要な条件を満たさない場合に例外を発生させます。 以下のサンプルコントラクトでは、`revert()`によって関数の実行を保護しています。 ``` pragma solidity ^0.8.4; @@ -96,7 +96,7 @@ contract VendingMachine { バグ報奨金プログラムを設けることは、外部コードレビューを実施するためのもう一つのアプローチです。 バク報奨金とは、アプリケーション内の脆弱性を発見した個人 (通常はホワイトハットハッカー) に与えられる金銭的な報酬です。 -バグ報奨金プログラムが適切に機能すれば、ハッカーコミュニティのメンバーは重大な欠陥がないかコードを検査することでインセンティブを得ることができます。 実例としては「無限貨幣バグ」があります。これにより、イーサリアム上で動作している[オプティミズム](https://www.optimism.io/)という[レイヤー 2 プロトコル](/layer-2/)で、攻撃者が無限にイーサ (Ether) を発行できてしまうというものでした。 幸運なことに、ホワイトハットハッカーは[その欠陥](https://www.saurik.com/optimism.html)を発見しチームに通知したため、[その過程で多額の報酬を得ました](https://cryptoslate.com/critical-bug-in-ethereum-l2-optimism-2m-bounty-paid/)。 +バグ報奨金プログラムが適切に機能すれば、ハッカーコミュニティのメンバーは重大な欠陥がないかコードを検査することでインセンティブを得ることができます。 実例としては、「無限貨幣バグ」があります。このバグにより、イーサリアム上で動作している[オプティミズム](https://www.optimism.io/)という[レイヤー2プロトコル](/layer-2/)で、攻撃者が無限にイーサ(Ether)を発行できてしまうというものでした。 幸運なことに、ホワイトハットハッカーは[その欠陥](https://www.saurik.com/optimism.html)を発見しチームに通知したため、[その過程で多額の報酬を得ました](https://cryptoslate.com/critical-bug-in-ethereum-l2-optimism-2m-bounty-paid/)。 バグ報奨金プログラムの報酬額を、危機にさらされている資金の額に比例して設定すると、有効な戦略となります。 「[バグ報奨金スケール](https://medium.com/immunefi/a-defi-security-standard-the-scaling-bug-bounty-9b83dfdc1ba7)」と呼ばれるこのアプローチは、脆弱性を悪用するのではなく、責任をもって開示するように、個人に金銭的なインセンティブを与えるものです。 @@ -104,17 +104,17 @@ contract VendingMachine { 監査やバグ報奨金の制度があるからといって、高品質なコードを書くという責任がなくなるわけではありません。 優れたスマートコントラクトセキュリティは、次の適切な設計と開発プロセスに従うことから始まります。 -- Git などのバージョン管理システムにすべてのコードを保存する +- Gitなどのバージョン管理システムにすべてのコードを保存する - すべてのコードの修正はプルリクエストで行う -- プルリクエストでは、少なくとも 1 人の第三者レビュアーを確保する。プロジェクトを 1 人で進めている場合は、他のデベロッパーを見つけて互いのコードをレビューすることを検討する +- プルリクエストでは、少なくとも1人の第三者レビュアーを確保する。プロジェクトを1人で進めている場合は、他のデベロッパーを見つけて互いのコードをレビューすることを検討する - スマートコントラクトのテスト、コンパイル、デプロイに[開発環境](/developers/docs/frameworks/)を使用する -- Mythril や Slither など、基本的なコード解析ツールを使用してコードを実行する。 これは、各プルリクエストがマージされる前に実行し、出力の違いを比較しておくのが理想的である +- MythrilやSlitherなど、基本的なコード解析ツールを使用してコードを実行する。 これは、各プルリクエストがマージされる前に実行し、出力の違いを比較しておくのが理想的である -- コードがエラーなくコンパイルされ、Solidity コンパイラが警告を発していないことを確認する +- コードがエラーなくコンパイルされ、Solidityコンパイラが警告を発していないことを確認する - [NatSpec](https://solidity.readthedocs.io/en/develop/natspec-format.html)を使用してコードを適切に文書化し、コントラクトのアーキテクチャの詳細を理解しやすい言葉で記述する。 これにより、第三者によるコードの監査やレビューが容易になる @@ -126,7 +126,7 @@ contract VendingMachine { イーサリアムスマートコントラクトは、デフォルトではイミュータブル (不変) ですが、アップグレードパターンを用いることで可変性をある程度獲得することが可能です。 コントラクトのアップグレードは、重大な欠陥によって古いコントラクトが使用できなくなり、新しいロジックをデプロイすることが最も現実的な選択肢となる場合に必要になります。 -コントラクトのアップグレードのメカニズムは様々ですが、「プロキシパターン」はスマートコントラクトのアップグレードでより一般的なアプローチの一つです。 プロキシパターンは、アプリケーションを「状態」と「ロジック」の*2 つの*コントラクトに分割します。 最初のコントラクト (「プロキシコントラクト」と呼ばれる) は、状態変数 (例: ユーザーの残高など) を格納します。一方、2 つ目のコントラクトは (「ロジックコントラクト」と呼ばれる) は、コントラクトの関数を実行するためのコードを保持します。 +コントラクトのアップグレードのメカニズムは様々ですが、「プロキシパターン」はスマートコントラクトのアップグレードでより一般的なアプローチの一つです。 プロキシパターンは、アプリケーションを「状態」と「ロジック」の_2つの_コントラクトに分割します。 最初のコントラクト (「プロキシコントラクト」と呼ばれる) は、状態変数 (例: ユーザーの残高など) を格納します。一方、2つ目のコントラクトは (「ロジックコントラクト」と呼ばれる) は、コントラクトの関数を実行するためのコードを保持します。 アカウントは、プロキシコントラクトとやり取りを行います。プロキシコントラクトは、すべての関数の呼び出しを低レベル呼び出しである[`delegatecall()`](https://docs.soliditylang.org/en/v0.8.16/introduction-to-smart-contracts.html?highlight=delegatecall#delegatecall-callcode-and-libraries)を使ってロジックコントラクトへディスパッチします。 通常のメッセージ呼び出しとは異なり、`delegatecall()`は、 ロジックコントラクトのアドレスで実行されるコードが、呼び出し元コントラクトのコンテキスト内で実行されるようにします。 つまり、ロジックコントラクトは、ロジックのストレージではなく、常にプロキシのストレージに書き込みを行い、元の`msg.sender`や`msg.value`の値は保持されるということです。 @@ -146,7 +146,7 @@ contract VendingMachine { 3. 上記ブール型変数を`true`に設定する緊急停止関数へのアクセス権を持つエンティティ。 悪意のある行為を防ぐために、この関数への呼び出しを信頼できるアドレス (例: コントラクトの所有者など) に制限できます。 -コントラクトが緊急停止を作動させると、特定の関数は呼び出せなくなります。 これは、グローバル変数を参照する modifier を使って、選択対象の関数をラップすることで実現されます。 下記は、コントラクトへのこのパターンの実装を記述した[例](https://github.com/fravoll/solidity-patterns/blob/master/EmergencyStop/EmergencyStop.sol)です。 +コントラクトが緊急停止を作動させると、特定の関数は呼び出せなくなります。 これは、グローバル変数を参照するmodifierを使って、選択対象の関数をラップすることで実現されます。 下記は、コントラクトへのこのパターンの実装を記述した[例](https://github.com/fravoll/solidity-patterns/blob/master/EmergencyStop/EmergencyStop.sol)です。 ```solidity // このコードは、専門的な監査を受けておらず、安全性や正確性を約束するものではありません。 自己責任で利用してくだささい。 @@ -212,15 +212,15 @@ contract EmergencyStop { 分散型ガバナンスは、特にデベロッパーとエンドユーザーの利害が一致することもあり、有益なものになり得ます。 それでもなお、スマートコントラクトのガバナンスメカニズムは、誤って実装された場合に新しいリスクをもたらすことがあります。 起こり得るシナリオは、攻撃者が[フラッシュローン](/defi/#flash-loans)を利用して膨大な投票力(保有トークン数で測定)を獲得し、悪意のある提案を押し通すというものです。 -オンチェーンガバナンスに関連する問題を防ぐ方法の一つとして、[タイムロックの使用](https://blog.openzeppelin.com/protect-your-users-with-smart-contract-timelocks/)が挙げられます。 タイムロックは、特定の時間が経過するまでスマートコントラクトが特定のアクションを実行できないようにするものです。 その他の戦略としては、各トークンがロックされている期間に応じて「投票の重み」を割り当てることや、現在のブロックの代わりに過去の期間 (例: 2 ~ 3 ブロック前) でアドレスの投票力を測定することなどがあります。 どちらの方法も、オンチェーンの投票を思い通りに動かす投票力を短期間で獲得する可能性を減らすことができます。 +オンチェーンガバナンスに関連する問題を防ぐ方法の一つとして、[タイムロックの使用](https://blog.openzeppelin.com/protect-your-users-with-smart-contract-timelocks/)が挙げられます。 タイムロックは、特定の時間が経過するまでスマートコントラクトが特定のアクションを実行できないようにするものです。 その他の戦略としては、各トークンがロックされている期間に応じて「投票の重み」を割り当てることや、現在のブロックの代わりに過去の期間 (例: 2~3ブロック前) でアドレスの投票力を測定することなどがあります。 どちらの方法も、オンチェーンの投票を思い通りに動かす投票力を短期間で獲得する可能性を減らすことができます。 -詳細は、[安全なガバナンスシステムの設計](https://blog.openzeppelin.com/smart-contract-security-guidelines-4-strategies-for-safer-governance-systems/)と[DAO におけるさまざまな投票メカニズム](https://hackernoon.com/governance-is-the-holy-grail-for-daos)をご覧ください。 +詳細は、[安全なガバナンスシステムの設計](https://blog.openzeppelin.com/smart-contract-security-guidelines-4-strategies-for-safer-governance-systems/)と[DAOにおけるさまざまな投票メカニズム](https://hackernoon.com/governance-is-the-holy-grail-for-daos)をご覧ください。 ### 8. コードの複雑さの最小化 {#reduce-code-complexity} -従来のソフトウェアデベロッパーは、ソフトウェア設計に不必要な複雑さを持ち込まないようにするという KISS (Keep It Simple, Stupid) 原則に慣れ親しんでいます。 これは、「複雑なシステムには複雑な障害が発生する」、さらに複雑さによりコストのかかるエラーが発生しやすいという長年の考え方に従ったものです。 +従来のソフトウェアデベロッパーは、ソフトウェア設計に不必要な複雑さを持ち込まないようにするというKISS (Keep It Simple, Stupid) 原則に慣れ親しんでいます。 これは、「複雑なシステムには複雑な障害が発生する」、さらに複雑さによりコストのかかるエラーが発生しやすいという長年の考え方に従ったものです。 -スマートコントラクトが高額の価値を制御する可能性があることを考えると、シンプルさを保ってスマートコントラクトを記述することが特に重要になります。 スマートコントラクトをシンプルに記述するコツは、可能な限り[OpenZeppelin コントラクト](https://docs.openzeppelin.com/contracts/4.x/)のような既存のライブラリを再利用することです。 これらのライブラリは、デベロッパーによって広範な監査とテストが行われているため、新しい機能をゼロから書くことでバグを発生させる可能性を減らすことができます。 +スマートコントラクトが高額の価値を制御する可能性があることを考えると、シンプルさを保ってスマートコントラクトを記述することが特に重要になります。 スマートコントラクトをシンプルに記述するコツは、可能な限り[OpenZeppelinコントラクト](https://docs.openzeppelin.com/contracts/4.x/)のような既存のライブラリを再利用することです。 これらのライブラリは、デベロッパーによって広範な監査とテストが行われているため、新しい機能をゼロから書くことでバグを発生させる可能性を減らすことができます。 別の一般的なアドバイスとしては、小さな関数を記述すること、さらにビジネスロジックを複数のコントラクトに分割してコントラクトをモジュラー型にすることがあります。 よりシンプルなコードを書くことで、スマートコントラクトへの攻撃面を減らすだけでなく、システム全体の正確性を推論しやすくなり、設計エラーの可能性を早期に検出できるようになります。 @@ -228,7 +228,7 @@ contract EmergencyStop { #### 再入可能 (リエントランシー) {#reentrancy} -EVM は同時実行を許可していません。つまり、メッセージ呼び出しに関わる 2 つのコントラクトは同時に実行できません。 外部呼び出しは、呼び出しが戻るまで呼び出し元のコントラクトの実行とメモリを一時停止させます。その時点で外部呼び出しの実行が正常に進みます。 このプロセスは、別のコントラクトへの[制御フロー](https://www.computerhope.com/jargon/c/contflow.htm)の移動として形式的に記述することが可能です。 +EVMは同時実行を許可していません。つまり、メッセージ呼び出しに関わる2つのコントラクトは同時に実行できません。 外部呼び出しは、呼び出しが戻るまで呼び出し元のコントラクトの実行とメモリを一時停止させます。その時点で外部呼び出しの実行が正常に進みます。 このプロセスは、別のコントラクトへの[制御フロー](https://www.computerhope.com/jargon/c/contflow.htm)の移動として形式的に記述することが可能です。 ほとんど場合問題は発生しませんが、信頼できないコントラクトに制御フローを移した場合には、再入可能(リエントランシー)などの問題を引き起こす可能性があります。 元の関数の呼び出しが完了する前に、悪意のあるコントラクトが再び脆弱なコントラクトを呼び出す場合に、再入可能(リエントランシー)攻撃が発生します。 例とともに、このタイプの攻撃を詳しく説明します。 @@ -253,15 +253,15 @@ contract Victim { } ``` -このコントラクトは、ユーザーが以前コントラクトに入金した ETH を引き出せるように、`withdraw()`関数を公開しています。 引き出しを処理する際、コントラクトは次の操作を行います。 +このコントラクトは、ユーザーが以前コントラクトに入金したETHを引き出せるように、`withdraw()`関数を公開しています。 引き出しを処理する際、コントラクトは次の操作を行います。 -1. ユーザーの ETH 残高を確認します。 +1. ユーザーのETH残高を確認します。 2. 呼び出し元のアドレスへ資金を送金します。 -3. 残高を 0 にリセットし、ユーザーからの追加の引き出しを防止します。 +3. 残高を0にリセットし、ユーザーからの追加の引き出しを防止します。 -`Victim`コントラクトの`withdraw()`関数は、「checks-interactions-effects」パターンに従っています。 実行に必要な条件 (つまり、ユーザーの ETH 残高がプラスになっているか) が満たされているかどうかを*確認 (checks) *し、呼び出し元のアドレスに ETH を送金するという*相互作用 (interactions) *を行った後、トランザクションの*結果 (effects) * (つまり、ユーザーの残高を減らす) を適用しているのです。 +`Victim`コントラクトの`withdraw()`関数は、「checks-interactions-effects」パターンに従っています。 実行に必要な条件 (つまり、ユーザーのETH残高がプラスになっているか) が満たされているかどうかを_確認 (checks) _し、呼び出し元のアドレスにETHを送金するという_相互作用 (interactions) _を行った後、トランザクションの_結果 (effects) _ (つまり、ユーザーの残高を減らす) を適用しているのです。 -`withdraw()`が外部所有口座 (EOA) から呼び出された場合、この関数は期待どおりに実行されます。つまり、`msg.sender.call.value()`は呼び出し元に ETH を送金します。 しかし、`msg.sender`が`withdraw()`を呼び出すスマートコントラクトアカウントの場合、`msg.sender.call.value()`を使用して資金を送金すると、そのアドレスに保存されているコードの実行もトリガーすることになります。 +`withdraw()`が外部所有口座 (EOA) から呼び出された場合、この関数は期待どおりに実行されます。つまり、`msg.sender.call.value()`は呼び出し元にETHを送金します。 しかし、`msg.sender`が`withdraw()`を呼び出すスマートコントラクトアカウントの場合、`msg.sender.call.value()`を使用して資金を送金すると、そのアドレスに保存されているコードの実行もトリガーすることになります。 以下がそのコントラクトアドレスにデプロイされているコードだと想像してみてください。 @@ -280,13 +280,13 @@ contract Victim { } ``` -このコントラクトは以下の 3 つのことを行うように設計されています。 +このコントラクトは以下の3つのことを行うように設計されています。 -1. 別のアカウント (攻撃者の EOA の可能性あり) からの入金を受け入れます。 -2. Victim コントラクトへ 1 ETH を入金します。 -3. スマートコントラクトに格納された 1 ETH を引き出します。 +1. 別のアカウント (攻撃者のEOAの可能性あり) からの入金を受け入れます。 +2. Victimコントラクトへ1 ETHを入金します。 +3. スマートコントラクトに格納された1 ETHを引き出します。 -`Attacker`には、入力となる`msg.sender.call.value`からの残りのガスが 4 万以上なら`Victim`内の`withdraw()`を再度呼び出すもう一つの関数があることを除き問題はありません。 これにより、`Attacker`は`Victim`に再入可能になり、最初の`withdraw`の呼び出しが完了する前に、多くの資金を引き出すことができます。 次のようなサイクルになります。 +`Attacker`には、入力となる`msg.sender.call.value`からの残りのガスが4万以上なら`Victim`内の`withdraw()`を再度呼び出すもう一つの関数があることを除き問題はありません。 これにより、`Attacker`は`Victim`に再入可能になり、最初の`withdraw`の呼び出しが完了する前に、多くの資金を引き出すことができます。 次のようなサイクルになります。 ```solidity - 攻撃者のEOAが、1 ETHで「Attacker.beginAttack()」関数を呼び出します。 @@ -301,13 +301,13 @@ contract Victim { - 「Victim」は、最終的に最初のトランザクション(および後続のトランザクション)の結果をステート(状態)に適用するので、「Attacker」の残高は0に設定されます。 ``` -要約すると、関数の実行が完了するまで呼び出し元の残高が 0 にならないため、その後の呼び出しが成功し、呼び出し元が何度も残高を引き出せるようになります。 この種の攻撃は、[2016 年の DAO ハック](https://www.coindesk.com/learn/2016/06/25/understanding-the-dao-attack/)で行われたように、スマートコントラクトから資金を流出させるために使用されます。 [再入可能(リエントランシー)エクスプロイトの公開リスト](https://github.com/pcaversaccio/reentrancy-attacks)が示すように、再入可能攻撃は今日でもスマートコントラクトにとって深刻な問題になっています。 +要約すると、関数の実行が完了するまで呼び出し元の残高が0にならないため、その後の呼び出しが成功し、呼び出し元が何度も残高を引き出せるようになります。 この種の攻撃は、[2016年のDAOハック](https://www.coindesk.com/learn/2016/06/25/understanding-the-dao-attack/)で行われたように、スマートコントラクトから資金を流出させるために使用されます。 [再入可能(リエントランシー)エクスプロイトの公開リスト](https://github.com/pcaversaccio/reentrancy-attacks)が示すように、再入可能攻撃は今日でもスマートコントラクトにとって深刻な問題になっています。 ##### 再入可能 (リエントランシー) 攻撃を防ぐ方法 -再入可能に対処するアプローチとして、[checks-effects-interactions パターン](https://docs.soliditylang.org/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern)に従うことが挙げられます。 このパターンは、次のように関数の実行を順序付けるものです。最初に、実行を進める前に必要な確認を行うコードが来ます。次に、コントラクトの状態を操作するコードが来ます。最後に、他のコントラクトや EOA とやり取りをするコードが来ます。 +再入可能に対処するアプローチとして、[checks-effects-interactionsパターン](https://docs.soliditylang.org/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern)に従うことが挙げられます。 このパターンは、次のように関数の実行を順序付けるものです。最初に、実行を進める前に必要な確認を行うコードが来ます。次に、コントラクトの状態を操作するコードが来ます。最後に、他のコントラクトやEOAとやり取りをするコードが来ます。 -checks-effect-interaction パターンは、以下に示している`Victim`コントラクトの改訂版で使用しています。 +checks-effect-interactionパターンは、以下に示している`Victim`コントラクトの改訂版で使用しています。 ```solidity contract NoLongerAVictim { @@ -320,7 +320,7 @@ contract NoLongerAVictim { } ``` -このコントラクトは、ユーザーの残高を*確認 (check)* し、`withdraw()`関数の*結果 (effects) *を (ユーザーの残高を 0 にすることで) 適用し、_相互作用 (interaction) _ (ユーザーのアドレスに ETH を送金) の実行へと進みます。 これにより、外部呼び出しの前に、コントラクトがストレージを確実にアップデートするようになり、最初の攻撃を可能にする再入可能の条件が排除されます。 `Attacker`コントラクトは依然として、`NoLongerAVictim`を再び呼び出すことができますが、`balances[msg.sender]`が 0 にセットされているので、さらなる引き出しをしてもエラーがスローされます。 +このコントラクトは、ユーザーの残高を_確認 (check)_ し、`withdraw()`関数の_結果 (effects) _を (ユーザーの残高を0にすることで) 適用し、_相互作用 (interaction) _ (ユーザーのアドレスにETHを送金) の実行へと進みます。 これにより、外部呼び出しの前に、コントラクトがストレージを確実にアップデートするようになり、最初の攻撃を可能にする再入可能の条件が排除されます。 `Attacker`コントラクトは依然として、`NoLongerAVictim`を再び呼び出すことができますが、`balances[msg.sender]`が0にセットされているので、さらなる引き出しをしてもエラーがスローされます。 もう一つのオプションは、関数の呼び出しが完了するまで、コントラクトの状態の一部をロックする相互排他ロック (一般的に「ミューテックス」と呼ばれる) を使用することです。 これは、ブール型変数を使って実装されます。関数が実行される前に`true`に設定し、呼び出しが完了した後に`false`に戻します。 以下の例で見られるように、元の呼び出しがまだ処理中であっても、ミューテックスを使うことで再帰的な呼び出しから関数を守ることができます。これにより、効果的に再入可能を防ぐことができます。 @@ -351,11 +351,11 @@ contract MutexPattern { } ``` -また、アカウントに資金を送る「プッシュ型決済」システムではなく、ユーザーがスマートコントラクトから資金を引き出す必要がある[「プル型決済」](https://docs.openzeppelin.com/contracts/4.x/api/security#PullPayment)システムを利用することでも防止可能です。 これにより、不明なアドレスで不注意にコードをトリガーする可能性を取り除けます (特定の DoS 攻撃も防げます) 。 +また、アカウントに資金を送る「プッシュ型決済」システムではなく、ユーザーがスマートコントラクトから資金を引き出す必要がある[「プル型決済」](https://docs.openzeppelin.com/contracts/4.x/api/security#PullPayment)システムを利用することでも防止可能です。 これにより、不明なアドレスで不注意にコードをトリガーする可能性を取り除けます (特定のDoS攻撃も防げます) 。 #### 整数のアンダーフローとオーバーフロー {#integer-underflows-and-overflows} -算術演算の結果が許容値の範囲外になると、整数のオーバーフローが発生します。これにより、表現可能な最小値に「ロールオーバー」します。 例えば、`uint8`は、2^8-1=255 までの値だけを格納できます。 `255`を超える値の算術演算の結果はオーバーフローし、`uint`を`0`にリセットします。これは、車のオドメーターが最大走行距離 (999999) に達すると 0 にリセットされるのと同じです。 +算術演算の結果が許容値の範囲外になると、整数のオーバーフローが発生します。これにより、表現可能な最小値に「ロールオーバー」します。 例えば、`uint8`は、2^8-1=255までの値だけを格納できます。 `255`を超える値の算術演算の結果はオーバーフローし、`uint`を`0`にリセットします。これは、車のオドメーターが最大走行距離 (999999) に達すると0にリセットされるのと同じです。 整数のアンダーフローも同様の理由で発生します。それは算術演算の結果が許容値の範囲を下回った場合です。 例えば、`uint8`で`0`をデクリメントしようと試みると、結果は単純に表現可能な最大値 (`255`) にロールオーバーします。 @@ -414,7 +414,7 @@ contract Attack { function attack() public payable { timeLock.deposit{value: msg.value}(); /* - 「t = 現在のロック時間」ならば、xを以下のようにして求める必要があります。 + 「t = 現在のロック時間」ならば、xを以下のようにして求める必要があります。 x + t = 2**256 = 0 so x = -t 2**256 = type(uint).max + 1 @@ -430,25 +430,25 @@ contract Attack { ##### 整数のアンダーフローとオーバーフローを防ぐ方法 -バージョン 0.8.0 以降の Solidity コンパイラは、整数のアンダーフローとオーバーフローを引き起こすコードを拒否します。 しかし、それよりも低いバージョンのコンパイラでコンパイルされたコントラクトでは、算術演算を実行する関数でチェックを行うか、アンダーフローとオーバーフローをチェックするライブラリ (例: [SafeMath](https://docs.openzeppelin.com/contracts/2.x/api/math)) を使用する必要があります。 +バージョン0.8.0以降のSolidityコンパイラは、整数のアンダーフローとオーバーフローを引き起こすコードを拒否します。 しかし、それよりも低いバージョンのコンパイラでコンパイルされたコントラクトでは、算術演算を実行する関数でチェックを行うか、アンダーフローとオーバーフローをチェックするライブラリ (例: [SafeMath](https://docs.openzeppelin.com/contracts/2.x/api/math)) を使用する必要があります。 -#### オラクル (Oracle) の改ざん {#oracle-manipulation} +#### オラクル(Oracle)の改ざん {#oracle-manipulation} -[オラクル (Oracles) ](/developers/docs/oracles/)は、オフチェーン情報を取得し、スマートコントラクトが使用できるようにオンチェーンに送信します。 オラクルを使用すると、資本市場などのオフチェーンシステムと相互運用するスマートコントラクトを設計して、アプリケーションを大幅に拡張できます。 +[オラクル(Oracles)](/developers/docs/oracles/)は、オフチェーン情報を取得し、スマートコントラクトが使用できるようにオンチェーンに送信します。 オラクルを使用すると、資本市場などのオフチェーンシステムと相互運用するスマートコントラクトを設計して、アプリケーションを大幅に拡張できます。 しかし、オラクルに間違いが含まれており、誤った情報をオンチェーンに送信した場合、スマートコントラクトが誤った入力に基づいて実行され、問題が発生する可能性があります。 これが「オラクルの問題」の根拠であり、ブロックチェーンのオラクルからの情報を確実に正確かつ最新で、タイムリーなものにするということが重要になってきます。 -関連するセキュリティ上の懸念は、分散型取引所(DEX)などのオンチェーンのオラクルを使用して、資産の現在価格を取得することです。 [分散型金融 (DeFi)](/defi/) 業界のレンディング (貸付) プラットフォームは、多くの場合、これを行ってユーザーの担保の価値を判断し、そのユーザーが借りられる金額を決定します。 +関連するセキュリティ上の懸念は、分散型取引所(DEX)などのオンチェーンのオラクルを使用して、資産の現在価格を取得することです。 [分散型金融(DeFi)](/defi/)業界のレンディング(貸付)プラットフォームは、多くの場合、これを行ってユーザーの担保の価値を判断し、そのユーザーが借りられる金額を決定します。 -DEX の価格は正確であることが多く、これは市場の均衡を取り戻す裁定者によるものです。 しかし、特にオンチェーンオラクルが過去の取引パターンに基づいて資産価格を計算する場合 (通常の計算方法) 、改ざんされる可能性があります。 +DEXの価格は正確であることが多く、これは市場の均衡を取り戻す裁定者によるものです。 しかし、特にオンチェーンオラクルが過去の取引パターンに基づいて資産価格を計算する場合(通常の計算方法)、改ざんされる可能性があります。 -例えば、攻撃者は、レンディングコントラクトとやり取りする直前に、フラッシュローンを利用して、資産の現在価格を人為的に吊り上げることができます。 DEX に資産価格を問い合わせると、通常よりも高い価値が返ってくる (攻撃者の大量の「買い注文」が資産の需要を歪めているため) ため、本来よりも多くの借入ができます。 このような「フラッシュローン攻撃」は、DeFi アプリケーション間の価格オラクルへの依存を悪用し、プロトコルに数百万ドルの損失を与えたと言われています。 +例えば、攻撃者は、レンディングコントラクトとやり取りする直前に、フラッシュローンを利用して、資産の現在価格を人為的に吊り上げることができます。 DEXに資産価格を問い合わせると、通常よりも高い価値が返ってくる (攻撃者の大量の「買い注文」が資産の需要を歪めているため) ため、本来よりも多くの借入ができます。 このような「フラッシュローン攻撃」は、DeFiアプリケーション間の価格オラクルへの依存を悪用し、プロトコルに数百万ドルの損失を与えたと言われています。 ##### オラクルの改ざんを防ぐ方法 オラクルの改ざんを回避するための最小要件としては、単一障害点を避けるために複数のソースから情報を照会する分散型オラクルネットワークを使用することです。 ほとんどの場合、分散型オラクルにはオラクルノードに正しい情報を報告するよう促す暗号経済的なインセンティブが組み込まれており、集中型オラクルよりも安全性が高くなっています。 -オンチェーンオラクルに資産価格を照会する場合は、時間加重平均価格(TWAP)メカニズムを実装しているものを使用することを検討してください。 [TWAP オラクル](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles)は、ある資産の価格を 2 つの異なる時点(修正可能)で照会し、得られた平均値に基づいて現在価格を計算します。 長い期間を選択することで、直前に行われた大量の注文が資産価格に影響を与えることができないため、価格の不正操作からプロトコルを保護します。 +オンチェーンオラクルに資産価格を照会する場合は、時間加重平均価格(TWAP)メカニズムを実装しているものを使用することを検討してください。 [TWAPオラクル](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles)は、ある資産の価格を2つの異なる時点(修正可能)で照会し、得られた平均値に基づいて現在価格を計算します。 長い期間を選択することで、直前に行われた大量の注文が資産価格に影響を与えることができないため、価格の不正操作からプロトコルを保護します。 ## デペロッパー向けスマートコントラクト・セキュリティリソース {#smart-contract-security-resources-for-developers} @@ -460,91 +460,93 @@ DEX の価格は正確であることが多く、これは市場の均衡を取 - **[スマートコントラクト監査サービス](/developers/docs/smart-contracts/testing/#smart-contract-auditing-services)** - _イーサリアム開発プロジェクト向けのスマートコントラクト監査サービスを提供する企業のリスト。_ -- **[バグ報奨金プラットフォーム](/developers/docs/smart-contracts/testing/#bug-bounty-platforms)** - _バグ報奨金の調整と、スマートコントラクトの重大な脆弱性の責任ある開示へ報酬を与えるためのプラットフォーム。_ +- **[バグ報奨金プラットフォーム](/developers/docs/smart-contracts/testing/#bug-bounty-platforms)** - _バグ報奨金を調整し、スマートコントラクトの重大な脆弱性を責任を持って開示した人に対して報酬を与えるためのプラットフォーム。_ - **[Fork Checker](https://forkchecker.hashex.org/)** - _フォークされたコントラクトに関する利用可能なすべての情報を確認するための無料のオンラインツール。_ -- **[ABI Encoder](https://abi.hashex.org/)** - _Solidity コントラクトの関数とコンストラクタの引数をエンコードするための無料のオンラインサービス。_ +- **[ABI Encoder](https://abi.hashex.org/)** - _Solidityコントラクトの関数とコンストラクタの引数をエンコードするための無料のオンラインサービス。_ ### スマートコントラクト監視ツール {#smart-contract-monitoring-tools} -- **[OpenZeppelin Defender Sentinels](https://docs.openzeppelin.com/defender/sentinel)** - _スマートコントラクト上のイベント、関数、トランザクションパラメータの自動的な監視と応答を行うツール。_ +- **[OpenZeppelin Defender Sentinels](https://docs.openzeppelin.com/defender/v1/sentinel)** - _スマートコントラクト上のイベント、関数、トランザクションパラメータの自動的な監視と応答を行うツール。_ -- **[Tenderly リアルタイムアラート](https://tenderly.co/alerting/)** - _スマートコントラクトやウォレットに異常なイベントや予期せぬイベントが発生した場合に、通知をリアルタイムに受けとるためのツール。_ +- **[Tenderlyリアルタイムアラート](https://tenderly.co/alerting/)** - _スマートコントラクトやウォレットに異常なイベントや予期せぬイベントが発生した場合に、通知をリアルタイムに受けとるためのツール。_ ### スマートコントラクトのセキュリティ管理ツール {#smart-contract-administration-tools} -- **[OpenZeppelin Defender Admin](https://docs.openzeppelin.com/defender/admin)** - _アクセス制御、アップグレード、一時停止など、スマートコントラクトの管理を行うためのインターフェイス。_ +- **[OpenZeppelin Defender Admin](https://docs.openzeppelin.com/defender/v1/admin)** - _アクセス制御、アップグレード、一時停止など、スマートコントラクトの管理を行うためのインターフェイス。_ -- **[Safe](https://safe.global/)** - _イーサリアム上で動作し、トランザクションが発生する前に最低人数(N 人中の M 人)の承認が必要なスマートコントラクトウォレット。_ +- **[Safe](https://safe.global/)** - _イーサリアム上で動作し、トランザクションが発生する前に最低人数(N人中のM人)の承認が必要なスマートコントラクトウォレット。_ -- **[OpenZeppelin コントラクト](https://docs.openzeppelin.com/contracts/4.x/)** - _コントラクトの所有権、アップグレード、アクセス制御、ガバナンス、一時停止機能など、管理機能を実装するためのコントラクトライブラリ。_ +- **[OpenZeppelinコントラクト](https://docs.openzeppelin.com/contracts/4.x/)** - _コントラクトの所有権、アップグレード、アクセス制御、ガバナンス、一時停止機能など、管理機能を実装するためのコントラクトライブラリ。_ ### スマートコントラクト監査サービス {#smart-contract-auditing-services} -- **[ConsenSys Diligence](https://consensys.net/diligence/)** - _ブロックチェーンエコシステム全体のプロジェクトについて、プロトコルがローンチに適した状態にあり、ユーザーを保護するように構築されていることを確認するスマートコントラクト監査サービス_ +- **[ConsenSys Diligence](https://consensys.net/diligence/)** - _ブロックチェーンエコシステム全体のプロジェクトについて、プロトコルがローンチに適した状態にあり、ユーザーを保護するように構築されていることを確認するスマートコントラクト監査サービス。_ - **[CertiK](https://www.certik.com/)** - _スマートコントラクトとブロックチェーンネットワークに最先端の形式検証技術を使用する先駆的なブロックチェーンセキュリティ企業_ -- **[Trail of Bits](https://www.trailofbits.com/)** - _セキュリティ研究と攻撃者のメンタリティを融合させ、リスクの低減とコードの堅牢化を図るサイバーセキュリティ企業_ +- **[Trail of Bits](https://www.trailofbits.com/)** - _セキュリティ研究と攻撃者のメンタリティを融合させ、リスクの低減とコードの堅牢化を図るサイバーセキュリティ企業。_ -- **[PeckShield](https://peckshield.com/)** - _ブロックチェーンエコシステム全体のセキュリティ、プライバシー、ユーザビリティのための製品やサービスを提供するブロックチェーンセキュリティ企業_ +- **[PeckShield](https://peckshield.com/)** - _ブロックチェーンエコシステム全体のセキュリティ、プライバシー、ユーザビリティのための製品やサービスを提供するブロックチェーンセキュリティ企業。_ -- **[QuantStamp](https://quantstamp.com/)** - _セキュリティおよびリスク評価サービスを通じて、ブロックチェーン技術の主流化を促進する監査サービス_ +- **[QuantStamp](https://quantstamp.com/)** - _セキュリティおよびリスク評価サービスを通じて、ブロックチェーン技術の主流化を促進する監査サービス。_ -- **[OpenZeppelin](https://www.openzeppelin.com/security-audits)** - _分散型システムのセキュリティ監査を提供するスマートコントラクトセキュリティ企業_ +- **[OpenZeppelin](https://www.openzeppelin.com/security-audits)** - _分散型システムのセキュリティ監査を提供するスマートコントラクトセキュリティ企業。_ -- **[Runtime Verification](https://runtimeverification.com/)** - _スマートコントラクトと形式モデルを専門としたセキュリティ企業_ +- **[Runtime Verification](https://runtimeverification.com/)** - _スマートコントラクトと形式モデルを専門としたセキュリティ企業。_ -- **[Hacken](https://hacken.io)** - _ブロックチェーンセキュリティへの 360 度アプローチをもたらすサイバーセキュリティ監査人_ +- **[Hacken](https://hacken.io)** - _ブロックチェーンセキュリティへの360度アプローチをもたらすサイバーセキュリティ監査人。_ -- **[Nethermind](https://nethermind.io/smart-contracts-audits)** - _ Solidity と Cairo の監査サービスにより、イーサリアムと Starknet 全体でスマートコントラクトの整合性とユーザーの安全を確保_ +- **[Nethermind](https://nethermind.io/smart-contracts-audits)** - _ SolidityとCairoの監査サービスにより、イーサリアムとStarknet全体でスマートコントラクトの整合性とユーザーの安全を確保。_ -- **[HashEx](https://hashex.org/)** - _HashEx は、ブロックチェーンとスマート コントラクトの監査に焦点を当てており、暗号通貨のセキュリティを確保するためのスマートコントラクト開発、侵入テスト、ブロックチェーンコンサルティングなどのサービスを提供_ +- **[HashEx](https://hashex.org/)** - _HashExは、ブロックチェーンとスマート コントラクトの監査に焦点を当てており、暗号通貨のセキュリティを確保するためのスマートコントラクト開発、侵入テスト、ブロックチェーンコンサルティングなどのサービスを提供_ + +- **[Code4rena](https://code4rena.com/)** - _スマートコントラクトセキュリティの専門家へ脆弱性の発見にインセンティブを与え、web3をより安全にすることを支援する競争的な監査プラットフォーム。_ ### バグ報奨プログラムプラットフォーム {#bug-bounty-platforms} -- **[Immunefi](https://immunefi.com/)** - _スマートコントラクトと DeFi プロジェクトのバグ報奨プログラムのプラットフォーム。セキュリティ研究者がコードをレビューし、脆弱性を開示し、報酬を得て、暗号資産の安全性を強化_ +- **[Immunefi](https://immunefi.com/)** - _スマートコントラクトとDeFiプロジェクトのバグ報奨プログラムのプラットフォーム。セキュリティ研究者がコードをレビューし、脆弱性を開示し、報酬を得て、暗号資産の安全性を強化。_ - **[HackerOne](https://www.hackerone.com/)** - _企業とペネトレーションテスターやサイバーセキュリティ研究者をつなぐ、脆弱性調整とバグ報奨プログラムのプラットフォーム_ -- **[HackenProof](https://hackenproof.com/)** - _ 暗号プロジェクト(DeFi、スマート コントラクト、ウォレット、CEX など)のエキスパートのバグ報奨金プラットフォーム。セキュリティプロフェッショナルはトリアージサービスを提供し、研究者は検証済みの関連バグレポートに対して報酬を獲得_ +- **[HackenProof](https://hackenproof.com/)** - _ 暗号プロジェクト(DeFi、スマート コントラクト、ウォレット、CEXなど)のエキスパートのバグ報奨金プラットフォーム。セキュリティプロフェッショナルはトリアージサービスを提供し、研究者は検証済みの関連バグレポートに対して報酬を獲得。_ ### 既知のスマートコントラクトの脆弱性とエクスプロイトの公開 {#common-smart-contract-vulnerabilities-and-exploits} -- **[ConsenSys: スマートコントラクトの既知の攻撃](https://consensys.github.io/smart-contract-best-practices/attacks/)** - _コントラクトの最も重要な脆弱性を、ほとんどのケースでサンプルコード付きで初心者にもわかりやすく解説_ +- **[ConsenSys: スマートコントラクトの既知の攻撃](https://consensys.github.io/smart-contract-best-practices/attacks/)** - _コントラクトの最も重要な脆弱性を、ほとんどのケースでサンプルコード付きで初心者にもわかりやすく解説。_ -- **[SWC レジストリ](https://swcregistry.io/)** - _イーサリアムスマートコントラクトに該当する共通の脆弱性(CWE)項目の厳選リスト_ +- **[SWCレジストリ](https://swcregistry.io/)** - _イーサリアムスマートコントラクトに該当する共通の脆弱性(CWE)項目の厳選リスト。_ -- **[Rekt](https://rekt.news/)** - _注目の暗号ハッキングやエクスプロイトを、詳細な事後分析レポートとともに定期的に更新して公開_ +- **[Rekt](https://rekt.news/)** - _注目の暗号ハッキングやエクスプロイトを、詳細な事後分析レポートとともに定期的に更新して公開。_ ### スマートコントラクトのセキュリティ学習課題 {#challenges-for-learning-smart-contract-security} -- **[Awesome BlockSec CTF](https://github.com/blockthreat/blocksec-ctfs)** - _ブロックチェーンセキュリティの机上演習、課題、[Capture The Flag](https://www.webopedia.com/definitions/ctf-event/amp/)コンペやソリューション記事の厳選リスト_ +- **[Awesome BlockSec CTF](https://github.com/blockthreat/blocksec-ctfs)** - _ブロックチェーンセキュリティの机上演習、課題、[Capture The Flag](https://www.webopedia.com/definitions/ctf-event/amp/)コンペやソリューション記事の厳選リスト。_ -- **[Damn Vulnerable DeFi](https://www.damnvulnerabledefi.xyz/)** - _DeFi スマートコントラクトの攻撃的なセキュリティを学び、バグハンティングやセキュリティ監査のスキルを身につけるための机上演習_ +- **[Damn Vulnerable DeFi](https://www.damnvulnerabledefi.xyz/)** - _DeFiスマートコントラクトの攻撃的なセキュリティを学び、バグハンティングやセキュリティ監査のスキルを身につけるための机上演習。_ -- **[Ethernaut](https://ethernaut.openzeppelin.com/)** - _各レベルでスマートコントラクトのハッキングが必要な Web3/Solidity ベースの机上演習_ +- **[Ethernaut](https://ethernaut.openzeppelin.com/)** - _各レベルでスマートコントラクトのハッキングが必要なWeb3/Solidityベースの机上演習_ ### スマートコントラクトのセキュリティのベストプラクティス {#smart-contract-security-best-practices} -- **[ConsenSys: イーサリアムスマートコントラクトのセキュリティのベストプラクティス](https://consensys.github.io/smart-contract-best-practices/)** - _イーサリアムスマートコントラクトのセキュリティのガイドラインの包括的リスト_ +- **[ConsenSys: イーサリアムスマートコントラクトのセキュリティのベストプラクティス](https://consensys.github.io/smart-contract-best-practices/)** - _イーサリアムスマートコントラクトのセキュリティのガイドラインの包括的リスト。_ -- **[Nascent: シンプルセキュリティツールキット](https://github.com/nascentxyz/simple-security-toolkit)** - _スマートコントラクト開発のための、セキュリティを重視した実践的なガイドとチェックリスト集_ +- **[Nascent: シンプルセキュリティツールキット](https://github.com/nascentxyz/simple-security-toolkit)** - _スマートコントラクト開発のための、セキュリティを重視した実践的なガイドとチェックリスト集。_ -- **[Solidity パターン](https://fravoll.github.io/solidity-patterns/)** - _スマート コントラクトプログラミング言語「Solidity」の安全なパターンとベストプラクティスの有用情報のまとめ_ +- **[Solidityパターン](https://fravoll.github.io/solidity-patterns/)** - _スマート コントラクトプログラミング言語「Solidity」の安全なパターンとベストプラクティスの有用情報のまとめ。_ -- **[Solidity ドキュメント: セキュリティ考慮事項](https://docs.soliditylang.org/en/v0.8.16/security-considerations.html)** - _Solidity で安全なスマートコントラクトを記述するためのガイドライン_ +- **[Solidityドキュメント: セキュリティ考慮事項](https://docs.soliditylang.org/en/v0.8.16/security-considerations.html)** - _Solidityで安全なスマートコントラクトを記述するためのガイドライン。_ -- **[スマートコントラクトセキュリティ検証スタンダード](https://github.com/securing/SCSVS)** - _デベロッパー、アーキテクト、セキュリティ評価者、ベンダー向けにスマートコントラクトのセキュリティを標準化するために作成された 14 部構成のチェックリスト_ +- **[スマートコントラクトセキュリティ検証スタンダード](https://github.com/securing/SCSVS)** - _デベロッパー、アーキテクト、セキュリティ評価者、ベンダー向けにスマートコントラクトのセキュリティを標準化するために作成された14部構成のチェックリスト。_ ### スマートコントラクトのセキュリティに関するチュートリアル {#tutorials-on-smart-contract-security} - [安全なスマートコントラクトコードの記述方法](/developers/tutorials/secure-development-workflow/) -- [Slither を使用してスマートコントラクトのバグを見つける方法](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) +- [Slitherを使用してスマートコントラクトのバグを見つける方法](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) -- [Manticore を使用してスマートコントラクトのバグを見つける方法](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/) +- [Manticoreを使用してスマートコントラクトのバグを見つける方法](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/) - [スマートコントラクトのセキュリティガイドライン](/developers/tutorials/smart-contract-security-guidelines/) diff --git a/public/content/translations/ja/developers/docs/smart-contracts/testing/index.md b/public/content/translations/ja/developers/docs/smart-contracts/testing/index.md index 88f43fa6885..8d79007706d 100644 --- a/public/content/translations/ja/developers/docs/smart-contracts/testing/index.md +++ b/public/content/translations/ja/developers/docs/smart-contracts/testing/index.md @@ -1,265 +1,299 @@ --- title: スマートコントラクトのテスト -description: イーサリアムスマートコントラクトをテストするための手法と考慮事項の概要 +description: イーサリアムスマートコントラクトのテスト方法と考察の概要 lang: ja --- -[スマートコントラクト](/developers/docs/smart-contracts/)のテストは、[スマートコントラクトのセキュリティ](/developers/docs/smart-contracts/security/)を向上させる最も重要な対策の 1 つです。 従来のソフトウェアとは異なり、通常、スマートコントラクトは起動後に更新することができないため、イーサリアムネットワークにコントラクトをデプロイする前に厳格なテストを行うことが不可欠です。 +イーサリアムなどのパブリックブロックチェーンは不変で、一度デプロイされたスマートコントラクトのコードを変更するのは困難です。 「バーチャルアップデート」を実行するための[スマートコントラクトアップグレードのパターン](/developers/docs/smart-contracts/upgrading/)が存在するものの、実装は困難で、かつ社会的コンセンサスも必要です。 さらに、アップグレードは、発見された_後に_エラーを修正できるものにすぎません。攻撃者が先に脆弱性を発見した場合、スマートコントラクトは悪用される可能性があります。 -## スマートコントラクトのテストとは {#what-is-smart-contract-testing} - -スマートコントラクトのテストとは、スマートコントラクトの開発サイクルにおいて、そのソースコードの品質を評価するために詳細な分析と評価を行うことを意味します。 スマートコントラクトをテストすることで、バグや脆弱性の特定が容易になり、コストのかかるエクスプロイトにつながるソフトウェアエラーの可能性を低減することができます。 +これらの理由から、メインネットに[デプロイする](/developers/docs/smart-contracts/deploying/)前にスマートコントラクトをテストすることは、 [セキュリティ](/developers/docs/smart-contracts/security/)の最小要件です。 テストでは、さまざまな技術を活用してコードの正確性を評価しますが、必要な機能や目的に合わせて選択しなければなりません。 それでも、さまざまなツールとアプローチを組み合わせたテストスイートを使えば、スマートコントラクトコード深刻度にかかわらず、セキュリティ欠陥を見つけることができます。 -スマートコントラクトのテストには様々な形態があり、それぞれの手法によってメリットがあります。 イーサリアムスマートコントラクトのテスト戦略は、大きく 2 つに分類されます。**自動テスト**と**手動テスト**です。 +## 前提知識 {#prerequisites} -### 自動テスト {#automated-testing} +このページでは、イーサリアムネットワークにデプロイする前に、スマートコントラクトをテストする方法について説明します。 [スマートコントラクト](/developers/docs/smart-contracts/)の知識があることを前提としています。 -自動テストでは、自動化ツールを使って、スマートコントラクトのスクリプトテストを実施します。 この技術は、スマートコントラクトの欠陥を見つけるためにテストを繰り返し実行できる自動化されたソフトウェアに依存しています。 +## スマートコントラクトのテストとは {#what-is-smart-contract-testing} -自動テストは効率的で、使用するリソースも少なく、手動分析よりも高いカバレッジレベルを実現します。 また、自動テストツールにテストデータを設定することで、予測された動作と実際の結果を比較することができます。 +スマートコントラクトのテストとは、スマートコントラクトのコードが意図したとおりに動作することを検証するプロセスです。 テストによって、スマートコントラクトの信頼性、使いやすさ、セキュリティ要件を満たしているかどうかを確認することができます。 -### 手動テスト {#manual-testing} +テストにはさまざまなアプローチがありますが、一般的には、処理することが予想されるデータの小さなサンプルを用いてスマートコントラクトを実行する必要があります。 コントラクトがサンプルデータに対して正しい結果を生成する場合、コントラクトは適切に機能していると判断できます。 テストツールのほとんどは、コントラクトの実行が期待通りであるかどうかを検証するための[テストケース](https://en.m.wikipedia.org/wiki/Test_case)を作成したり実行したりするためのリソースを提供しています。 -手動テストは、人が介在し、テスト手順を手動で実行するものです。 コード監査は、デベロッパーや監査人がコントラクトコードのすべての行に目を通すもので、スマートコントラクトの手動テストの一例です。 +### スマートコントラクトのテストの重要性 {#importance-of-testing-smart-contracts} -スマートコントラクトの手動テストには、かなりのスキルと、時間、費用、労力の投資が必要です。 さらに、手作業によるテストは、時にヒューマンエラーの問題をはらんでいることがあります。 +スマートコントラクトでは、高価値の金融資産を管理することが多いため、小さなプログラミングの間違いが[ユーザーに大損失](https://rekt.news/leaderboard/)を与える可能性があります。実際に、そのような事例は度々発生しています。 Rigorous testing can, however, help you discover defects and issues in a smart contract's code early and fix them before launching on Mainnet. -さらに、手作業によるテストは、時にヒューマンエラーの問題をはらんでいることがあります。 コード監査は、人間の知能を利用して、自動テストでは検出されない可能性のある契約コードの欠陥を見つけます。 +バグが発見された場合、コントラクトをアップグレードすることは可能ですが、アップグレードは複雑で、誤った処理をすると[エラー](https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/)が発生する可能性があります。 また、アップグレードによって、コントラクトの不変性の原則が損なわれ、ユーザーにさらなる信頼が求められることになります。 一方で、統合的なテスト計画を立てることで、スマートコントラクトのセキュリティリスクを軽減し、デプロイ後に複雑なロジックのアップグレードを実行する必要性を減らすことができます。 -スマートコントラクトを手動でテストすることで、コードの外に存在する、しかし影響を及ぼしうる脆弱性を発見することもできます。 例えば、スマートコントラクトの監査では、オフチェーンのコンポーネントとの欠陥のある相互作用に起因する脆弱性を発見することができます。 +## スマートコントラクトのテスト方法 {#methods-for-testing-smart-contracts} -## スマートコントラクトのテストの重要性 {#benefits-of-smart-contract-testing} +Methods for testing Ethereum smart contracts fall under two broad categories: **automated testing** and **manual testing**. 自動テストと手動テストには、それぞれに長所と短所があります。両方を組み合わせることで、コントラクトを解析するための堅牢な計画を立てることができます。 -以下の理由により、スマートコントラクトのテストは重要です。 +### 自動テスト {#automated-testing} -### 1. スマートコントラクトは高価値のアプリケーションである {#smart-contracts-are-high-value-applications} +自動テストでは、スマートコントラクトのコードを実行して、エラーがないか自動的にチェックするツールを使用します。 自動テストの利点は、[スクリプト](https://www.techtarget.com/whatis/definition/script?amp=1)を使用してコントラクトの機能を評価できることです。 スクリプト化されたテストは、人間の介入を最小限に抑え、繰り返し実行するようにスケジュールできるので、手動によるテストよりも効率的です。 -スマートコントラクトは、特に[分散型金融(DeFi)](/defi/)などの業界において価値の高い金融資産や、[非代替性トークン(NFT)](/nft/)などの有価物を扱うことがよくあります。 そのため、スマートコントラクトの些細な脆弱性が、ユーザーにとって回復不能な巨額の損失につながることがしばしばあります。 しかし、包括的なテストにより、スマートコントラクトのコードの誤りを明らかにし、デプロイする前にセキュリティリスクを低減することができます。 +自動テストは、テストが反復的で時間がかかる、手動で実行するのが難しい、人的ミスの影響を受けやすい、重要なコントラクト関数の評価を伴う、などの場合に特に役立ちます。 ただし、自動テストツールには、欠点もあります。例えば、特定のバグを検出できなかったり、多くの[誤検知](https://www.contrastsecurity.com/glossary/false-positive)をしてしまうことがあります。 そのため、スマートコントラクトのテストには、自動テストと手動テストを組み合わせることが望ましいと言えます。 -### 2. スマートコントラクトはイミュータブル(不変)である {#smart-contracts-are-immutable} +### 手動テスト {#manual-testing} -[イーサリアム仮想マシン(EVM)](/developers/docs/evm/)にデプロイされたスマートコントラクトは、デフォルトでイミュータブル(不変)となっています。 従来のデベロッパーは、発売後にソフトウェアのバグを修正することに慣れているかもしれませんが、イーサリアムの開発では、スマートコントラクトがブロックチェーン上で稼働すると、セキュリティ上の欠陥を修正する余地がほとんどなくなります。 +手動テストは、人が直接操作して行うテストです。スマートコントラクトの正確性を解析する際には、テストスイートの各テストケースを順番に実行します。 これは、コントラクト上で複数の個別のテストを同時に実行し、失敗したテストと合格したすべてのテストを表示したレポートを取得できる自動テストとは異なります。 -プロキシパターンなど、スマートコントラクトでアップグレード可能なメカニズムは存在するものの、実装が難しい場合があります。 アップグレードによって不変性が損なわれ、複雑さが生じるだけでなく、しばしば複雑なガバナンスプロセスが要求されます。 +手動テストは、さまざまなテストシナリオを網羅するように作成されたテスト計画書に従って、個人が実行します。 また、手動テストの一環として、複数の個人やグループが一定期間にわたってスマートコントラクトを操作することもあります。 テスターは、コントラクトの実際の動作と期待される動作を比較して、違いがあればバグとしてフラグを立てます。 -ほとんどの場合、アップグレードは最後の手段と考え、必要な場合を除き避けるべきです。 起動前の段階でスマートコントラクトの潜在的な脆弱性や欠陥を検出することで、ロジックのアップグレードの必要性を減らすことができます。 +効果的な手動テストには、スキル、時間、資金、労力などの多くのリソースが必要になります。また、テストの実行中に人的ミスにより、特定のエラーを見逃すことがあります。 しかし、手動テストにもメリットがあります。例えば、人間のテスト担当者(監査人など)は、自動テストツールでは検出が難しいエッジケースを直感的に見つけることができます。 ## スマートコントラクトの自動テスト {#automated-testing-for-smart-contracts} -### 1. 機能テスト {#functional-testing} +### 単体テスト {#unit-testing-for-smart-contracts} -機能テストは、スマートコントラクトの機能を検証し、コード内の各機能が期待通りに動作することを保証するものです。 機能テストでは、スマートコントラクトが特定の条件下でどのように動作すべきかを理解する必要があります。 その後、選択した値で計算を実行し、返された出力と期待される出力を比較することで、各機能をテストすることができます。 +単体テストでは、コントラクトの関数を個別に評価し、各コンポーネントが正しく動作するかを確認します。 優れた単体テストとは、シンプルで短時間で実行でき、テストが失敗した場合に、その原因を明確に示せるものです。 -機能テストには 3 つの手法があります。**単体テスト**、**統合テスト**、**システムテスト**です。 +単体テストは、期待する値が返されるかどうかと、関数の実行後にコントラクトのストレージが適切に更新されるかどうかを確認するのに効果的です。 また、コントラクトのコードベースに変更を加えた後に単体テストを実行し、新しいロジックの追加によってエラーが発生しないことを確認します。 以下は、効果的な単体テストを実行するためのガイドラインです。 -#### 単体テスト +#### スマートコントラクト単体テストのガイドライン {#unit-testing-guidelines} -単体テストは、スマートコントラクトの個々のコンポーネントの正確性をテストするものです。 単体テストはシンプルで、素早く実行でき、テストが失敗した場合に何が悪かったのかを明確にすることができます。 +##### 1. コントラクトのビジネスロジックとワークフローを理解する -スマートコントラクトの開発では、特にコードに新しいロジックを追加する必要がある場合、単体テストは非常に重要です。 各機能の動作を検証し、意図したとおりに実行されることを確認することができます。 +スマートコントラクトが提供する機能を理解し、ユーザーがどのように関数にアクセスして使用しているかを把握しておくと、単体テストを作成しやすくなります。 [ハッピーパステスト](https://en.m.wikipedia.org/wiki/Happy_path)を実行する場合に特に有用です。これは、 コントラクト内の関数が有効なユーザーの入力に対して正しい出力を返すかどうかを判断します。 [オークションコントラクト](https://docs.soliditylang.org/en/v0.8.17/solidity-by-example.html?highlight=Auction%20contract#simple-open-auction)の(要約された)例を用いて、このコンセプトを説明します。 -多くの場合、単体テストを実行するには、_アサーション_(スマートコントラクトの要件を指定する単純で非公式なステートメント)の作成が必要になります。 単体テストでは、それぞれのアサーションをテストし、実行時にそれが正しいかどうかを確認することができます。 +``` +constructor( + uint biddingTime, + address payable beneficiaryAddress + ) { + beneficiary = beneficiaryAddress; + auctionEndTime = block.timestamp + biddingTime; + } -コントラクト関連のアサーションの例としては、以下のものがあります。 +function bid() external payable { -I. 「コントラクトを一時停止できるのは管理者のみ」 + if (block.timestamp > auctionEndTime) + revert AuctionAlreadyEnded(); -ii. 「管理者以外は新しいトークンをミントできない」 + if (msg.value <= highestBid) + revert BidNotHighEnough(highestBid); -iii. 「コントラクトはエラーになると元に戻る」 + if (highestBid != 0) { + pendingReturns[highestBidder] += highestBid; + } + highestBidder = msg.sender; + highestBid = msg.value; + emit HighestBidIncreased(msg.sender, msg.value); + } -#### 統合テスト + function withdraw() external returns (bool) { + uint amount = pendingReturns[msg.sender]; + if (amount > 0) { + pendingReturns[msg.sender] = 0; -統合テストは、テスト階層において単体テストより上位に位置します。 統合テストでは、スマートコントラクトの個々のコンポーネントが一緒にテストされます。 + if (!payable(msg.sender).send(amount)) { + pendingReturns[msg.sender] = amount; + return false; + } + } + return true; + } -このアプローチは、コントラクトの異なる構成要素間、または複数のコントラクトにまたがる相互作用に起因するエラーを検出するものです。 複数の機能を持つ複雑なコントラクトや、他のコントラクトとのインターフェイスを持つコントラクトがある場合は、この手法を使用する必要があります。 +function auctionEnd() external { + if (block.timestamp < auctionEndTime) + revert AuctionNotYetEnded(); + if (ended) + revert AuctionEndAlreadyCalled(); -統合テストは、継承や依存性注入などが適切に動作することを確認するのに便利です。 + ended = true; + emit AuctionEnded(highestBidder, highestBid); -#### システムテスト + beneficiary.transfer(highestBid); + } +} +``` -システムテストは、スマートコントラクトの機能テストの最終段階です。 システムテストは、スマートコントラクトを完全に統合された 1 つの製品として評価し、技術要件で指定されたとおりの性能を発揮するかどうかを確認します。 +このオークションコントラクトは、入札期間中に入札を受け付けるシンプルなものです。 `highestBid`が増えた場合は、以前の最高入札者に入札金が支払われます。また、入札期間が終了すると、`beneficiary`はコントラクトを呼び出して入札金を受け取ります。 -この段階は、ユーザーの視点からスマートコントラクトのエンドツーエンドの流れを確認することだと考えることができます。 スマートコントラクトのシステムテストを行うには、[テストネット](/developers/docs/networks/#ethereum-testnets)や[開発用ネットワーク](/developers/docs/development-networks/)などの本番同様の環境上にデプロイすることが良い方法と言えます。 +このようなコントラクトの単体テストでは、コントラクトとやり取りする際にユーザーが呼び出す可能性のあるさまざまな関数をテストします。 例えば、オークションの進行中にユーザーが入札できるか(すなわち、`bid()`の呼び出しが成功する)かどうかを確認する単体テストや、ユーザーが現在の`highestBid`よりも高い入札ができるかどうかを確認する単体テストなどがあります。 -ここでは、エンドユーザーが試験運用を行い、コントラクトのビジネスロジックや全体的な機能に関する問題を報告することができます。 システムテストが重要なのは、コントラクトがメインの EVM 環境にデプロイされると、コードを変更することができないからです。 +コントラクトの操作上のワークフローを理解しておくと、実行内容が要件を満たしているかどうかを確認する単体テストの作成にも役立ちます。 例えば、オークションコントラクトでは、オークションが終了したとき(つまり、`auctionEndTime`が`block.timestamp`よりも小さいとき)は、ユーザーが入札できないようになっています。 この場合、デベロッパーは、オークション終了時(つまり、`auctionEndTime` > `block.timestamp`の場合)に`bid()`関数の呼び出しが成功するか失敗するかをチェックする単体テストを実行するとよいでしょう。 -### 2. 静的/動的解析 {#static-dynamic-analysis} +##### 2. コントラクトの実行に関するすべての前提条件を評価する -スマートコントラクトのセキュリティ品質を評価するための自動テスト手法として、静的解析と動的解析があります。 しかし、どちらの手法も、コントラクトコードの不具合を発見するために、異なるアプローチを採用しています。 +コントラクトの実行に関する前提を文書化し、それらの前提の妥当性を検証する単体テストを作成することが重要です。 アサーションテストを行うことで、予期しない実行を防ぐことができます。また、スマートコントラクトのセキュリティモデルを破る可能性のある操作について検討する際にも役立ちます。 有用な方法としては、「ユーザーにとって満足のいくテスト」を超えて、間違った入力に対して関数が失敗するかどうかをチェックするネガティブテストを作成することです。 -#### 静的解析 +多くの単体テストフレームワークでは、アサーションの作成ができます。アサーションでは、コントラクトで可能・不可能なことを記述する単純なステートメントを作成します。テストを実行すると、それらのアサーションが維持されているかどうかが確認されます。 上記のオークションコントラクトを開発しているデベロッパーは、ネガティブテストを実行する前に、その挙動について次のようなアサーションを作成できます。 -静的解析は、実行前にスマートコントラクトのソースコードまたはバイトコードを調査します。 つまり、実際にプログラムを実行することなく、コントラクトコードをデバッグすることができるのです。 静的解析ツールは、イーサリアムスマートコントラクトに共通する脆弱性を検出し、最善の方法の遵守を支援します。 +- オークションが終了しているか、まだ開始されていない場合、ユーザーは入札することができないこと。 -#### 動的解析 +- 入札額が許容しきい値を下回った場合、オークションコントラクトを取り消す(リバートする)こと。 -動的解析手法では、スマートコントラクトをランタイム環境で実行し、コードの問題点を特定する必要があります。 動的コードアナライザーは、実行中のコントラクトの振る舞いを観察し、特定された脆弱性やプロパティ違反の詳細なレポートを生成します。 +- 落札に失敗したユーザーの資金が確実に戻ること。 -ファジングは、コントラクトをテストするための動的解析手法の一例です。 ファズテストでは、ファザーがスマートコントラクトに不正なデータを与え、その入力に対してコントラクトがどのように応答するかを監視します。 +**注**: 前提をテストする別の方法としては、特に`require`、`assert`、`if…else`ステートメントなど、コントラクト内の[関数修飾子](https://docs.soliditylang.org/en/v0.8.16/contracts.html#function-modifiers)をトリガーするテストを作成することです。 -ファズテストでは、ファザーがスマートコントラクトに不正なデータを与え、その入力に対してコントラクトがどのように応答するかを監視します。 ユーザーが正しい入力をすることを前提としていますが、必ずしもそうであるとは限らないからです。 +##### 3. コードカバレッジを計測する -スマートコントラクトに誤った入力値を送ると、リソースリークやクラッシュを引き起こしたり、最悪の場合、意図しないコードの実行につながったりするケースがあります。 ファジングキャンペーンでは、このような問題を事前に発見し、脆弱性を排除することが可能です。 +[コードカバレッジ](https://en.m.wikipedia.org/wiki/Code_coverage)は、テストで実行されたコード内の分岐、行、ステートメントの数を追跡する指標です。 テストには、適切なコードカバレッジが必要です。コードカバレッジが不十分だと、「偽陰性」を引き起こす可能性があります。つまり、コントラクトがすべてのテストに合格しても、依然としてコードに脆弱性が存在する可能性が残ってしまいます。 しかし、高いコードカバレッジを記録していれば、スマートコントラクト内のすべてのステートメントや関数が正確であることを十分に検証することができます。 -## スマートコントラクトの手動テスト {#manual-testing-for-smart-contracts} +##### 4. 完成度の高いテストフレームワークを使用する -### 1. コード監査 {#code-audits} +スマートコントラクトの単体テストを実行するツールの品質は、非常に重要です。 理想的なテストフレームワークは、定期的にメンテナンスされ、便利な機能(ログ機能やレポート機能など)を備えているものです。そして、多くのデベロッパーに広く使用され、よく精査されていることも重要です。 -コード監査とは、スマートコントラクトのソースコードを詳細に評価し、起こりうる障害点、セキュリティ上の欠陥、不適切な開発手法を発見することです。 コード監査は自動化することもできますが、ここでは人の手を介したコード解析を指しています。 +Solidityスマートコントラクト用の単体テストフレームワークは、さまざまな言語(主にJavaScript、Python、Rust)で提供されています。 単体テストの実行を始めるには、以下のさまざまなテストフレームワークのガイドを参照してください。 -コード監査では、スマートコントラクトで考えられる攻撃ベクトルをマッピングするために、攻撃者のマインドセットが必要です。 自動監査を行うにしても、ソースコードの一行一行を解析することは、安全なスマートコントラクトを書くための最低条件です。 +- **[Brownieを使った単体テストの実行](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html)** +- **[Foundryを使った単体テストの実行](https://book.getfoundry.sh/forge/writing-tests)** +- **[Waffleを使った単体テストの実行](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-tests)** +- **[Remixを使った単体テストの実行](https://remix-ide.readthedocs.io/en/latest/unittesting.html#write-tests)** +- **[Apeを使った単体テストの実行](https://docs.apeworx.io/ape/stable/userguides/testing.html)** +- **[Hardhatを使った単体テストの実行](https://hardhat.org/hardhat-runner/docs/guides/test-contracts)** -また、スマートコントラクトの安全性をより確実にするために、セキュリティ監査を依頼することも可能です。 監査では、サイバーセキュリティの専門家による広範な解析が行われ、スマートコントラクトの機能を破壊する可能性のある脆弱性やバグを検出することができます。 +### 統合テスト {#integration-testing-for-smart-contracts} -### 2. バグ報奨金 {#bug-bounties} +単体テストでは、コントラクトの関数を個別にデバッグしましたが、統合テストでは、スマートコントラクトのコンポーネント全体を評価します。 統合テストでは、スマートコントラクト間の呼び出しで発生する問題や、同じスマートコントラクト内の異なる関数間のやり取りで発生する問題を検出できます。 例えば、[継承](https://docs.soliditylang.org/en/v0.8.12/contracts.html#inheritance)や依存性注入などの機能が正しく動作するかどうかを確認するのに役立ちます。 -バグ報奨金とは、プログラムのコードに脆弱性やバグを発見し、デベロッパーに報告した個人に与えられる金銭的な報酬のことです。 バグ報奨金は、スマートコントラクトの不具合の発見を他の人に依頼するもので、監査に似ています。 大きな違いは、バグ報奨金プログラムには、デベロッパーコミュニティやハッカーコミュニティからも幅広く参加できるということです。 +統合テストは、コントラクトがモジュラー型アーキテクチャを採用していたり、実行中に他のオンチェーンコントラクトと接続する場合に有用です。 One way of running integration tests is to [fork the blockchain](/glossary/#fork) at a specific height (using a tool like [Forge](https://book.getfoundry.sh/forge/fork-testing) or [Hardhat](https://hardhat.org/hardhat-network/docs/guides/forking-other-networks) and simulate interactions between your contract and deployed contracts. -バグ奨励金プログラムには、独自のスキルや経験を持つ幅広い層の倫理的ハッカーや独立したセキュリティ専門家が多く参加します。 これは、限られた専門知識を持つチームに依存するスマートコントラクト監査にはない利点と言えるでしょう。 +フォークされたブロックチェーンは、メインネットと同様の仕組みで動作し、アカウントに状態と残高が関連付けられています。 しかし、サンドボックス化されたローカル開発環境としてのみ機能します。例えば、トランザクションに実際のETHは必要なく、変更しても実際のイーサリアムプロトコルに影響することはありません。 -## テストと形式検証の比較 {#testing-vs-formal-verification} +### プロパティベースのテスト {#property-based-testing-for-smart-contracts} -テストは、あるデータ入力に対してコントラクトが期待通りの結果を返すことを確認するのに役立ちますが、テストで使用されていない入力に対して同じことを決定的に証明することはできません。 スマートコントラクトのテストは「機能的な正しさ」を保証できません。つまり、入力値や条件の*すべての*セットに対してプログラムが要求通りに動作することを示すことはできないのです。 +プロパティベースのテストは、スマートコントラクトが定義されたプロパティを満たしていることを確認するプロセスです。 プロパティは、コントラクトの行動に関する事実をアサーションします。この事実は、さまざまなシナリオにおいて真であることが期待されるものです。スマートコントラクトプロパティの例としては、「コントラクト内の算術演算は、オーバーフローもアンダーフローもしない」などがあります。 -そのため、デベロッパーはスマートコントラクトの正しさを評価するアプローチに**形式検証**を取り入れることが推奨されています。 形式検証では、[形式手法](https://www.brookings.edu/techstream/formal-methods-as-a-path-toward-better-cybersecurity/)(ソフトウェアを仕様化し検証するための数学的に厳密な技法)を用います。 +プロパティベースのテストを実行する方法には、**静的分析**と**動的分析**の2つの一般的な手法があります。どちらの手法でも、 プログラムのコード(この場合は、スマートコントラクト)が、事前に定義されたプロパティを満たしていることを検証できます。 プロパティベースのテストツールには、予期されるコントラクトプロパティに対する事前定義されたルールが備えてあり、コードがそれらのルールに違反しているかチェックするものや、スマートコントラクトのカスタムプロパティを作成できるものがあります。 -形式検証は、デベロッパーがスマートコントラクトに関連する仮定を形式的に検証するのに役立つため、スマートコントラクトにとって重要であると考えられています。 これは、スマートコントラクトの特性を記述した形式的な仕様を作成し、スマートコントラクトの形式モデルがその仕様に合致していることを検証することで実現されます。 このアプローチにより、スマートコントラクトはビジネスロジックで定義された機能のみを実行し、それ以外の機能は実行しないという信頼性を高めることができます。 +#### 静的解析 {#static-analysis} -[スマートコントラクトのための形式検証の詳細](/developers/docs/smart-contracts/formal-verification) +静的アナライザーは、スマートコントラクトのソースコードを受け取って解析し、コントラクトがプロパティを満たしているかどうかを判断します。 動的解析とは異なり、静的解析では、コントラクトを実行して正確性の解析を行うことはありません。 静的解析は、スマートコントラクトが実行中にたどる可能性のあるすべてのパスを推論します。つまり、ソースコードの構造を調べて、コントラクトの操作がランタイムで何を意味するかを決定します。 -## テストのためのツールとライブラリ {#testing-tools-and-libraries} +コントラクトで静的解析を実行する一般的な手法として、[リンティング](https://www.perforce.com/blog/qac/what-lint-code-and-why-linting-important)と[静的テスト](https://www.techtarget.com/whatis/definition/static-analysis-static-code-analysis)があります。 どちらの手法も、コンパイラによって出力された[抽象構文木](https://en.m.wikipedia.org/wiki/Abstract_syntax_tree)や[制御フローグラフ](https://www.geeksforgeeks.org/software-engineering-control-flow-graph-cfg/amp/)など、コントラクト実行における低レベル表現の解析が必要です。 -### 単体テストツール {#unit-testing-tools} +静的解析は、安全でない構造の使用や構文エラー、コントラクトコード内のコーディング規約違反などの安全性の問題を検出するには有効です。 しかし、より深い脆弱性の検出が不得意であることが知られており、過剰な誤検出が生じる可能性があります。 + +#### 動的解析 {#dynamic-analysis} + +動的解析では、シンボリックな入力(例: [シンボリック実行](https://en.m.wikipedia.org/wiki/Symbolic_execution))または具体的な入力(例: [ファジング](https://owasp.org/www-community/Fuzzing))をスマートコントラクトの関数に生成して、実行トレースが特定のプロパティに違反していないかどうかを確認します。 この方式によるプロパティベースのテストでは、単体テストとは異なり、複数のシナリオのテストケースをカバーし、プログラムがテストケースを生成します。 -**Solidity-Coverage** - _スマートコントラクトのテストに便利な Solidity のコードカバレッジツールです_。 +[ファジング](https://halborn.com/what-is-fuzz-testing-fuzzing/)は、動的解析手法の例の1つでスマートコントラクトの任意のプロパティを検証します。 ファザー(fuzzer)は、定義されたランダムまたは不正なバリエーションの入力値で、ターゲットコントラクト内の関数を呼び出します。 スマートコントラクトがエラー状態 (例: アサーションが失敗した状態など) になると、問題に対してフラグが立てられ、実行によって脆弱なパスに向かう入力がレポートに作成されます。 -- [GitHub](https://github.com/sc-forks/solidity-coverage) +ファジングは、スマートコントラクトの入力検証メカニズムを評価するのに効果的です。なぜなら、予期しない入力を適切に処理しないと、意図しない動作が発生し、悪影響が生じる可能性があるからです。 この方式によるプロパティベースのテストは、以下のような理由から理想的です。 -**Waffle** - _高度なスマートコントラクトの開発とテストのためのフレームワークです(ethers.js をベースとする)_。 +1. **さまざまなシナリオをカバーするテストケースを書くことは難しい**。 プロパティテストでは、振る舞いとその振る舞いをテストするためのデータ範囲を定義するだけです。プログラムは、定義されたプロパティに基づいてテストケースを自動的に生成します。 -- [ドキュメント](https://ethereum-waffle.readthedocs.io/en/latest/) -- [GitHub](https://github.com/TrueFiEng/Waffle) -- [ウェブサイト](https://getwaffle.io/) +2. **テストスイートがプログラム内のすべての実行パスを十分にカバーしていないことがある。**100%のカバレッジであっても、エッジケースを見逃す可能性があります。 -**Remix Tests** - _Solidity スマートコントラクトをテストするためのツールです。 Remix IDE の「Solidity Unit Testing」プラグインで動作します。このプラグインは、コントラクトのテストケースの作成と実行に使用されます。_ +3. **単体テストでは、コントラクトがサンプルデータに対して正しく実行されることを証明できるが、サンプル外の入力に対して正しく実行されるかどうかは未確認のままである。**プロパティテストでは、ターゲットコントラクトを複数のバリエーションで実行します。 指定された入力値を使用して、アサーションの失敗を引き起こす実行トレースを見つけます。 そのため、プロパティテストでは、広範なクラスの入力データに対してコントラクトが正しく実行されることを、より確実に保証することができます。 -- [ドキュメンテーション](https://remix-ide.readthedocs.io/en/latest/unittesting.html) -- [GitHub](https://github.com/ethereum/remix-project/tree/master/libs/remix-tests) +### スマートコントラクトでプロパティベースのテストを実行する際のガイドライン {#running-property-based-tests} -**OpenZeppelin テストヘルパー -** _イーサリアムスマートコントラクトテストのためのアサーションライブラリです。 コントラクトが期待通りに動作することを確認してください。_ +プロパティベースのテストの実行では通常、プロパティの定義(例: [整数オーバーフロー](https://github.com/ConsenSys/mythril/wiki/Integer-Overflow)がないこと)、またはスマートコントラクト検証を行う必要のあるプロパティのコレクションを定義することから始めます。 プロパティテストを作成するときに、プログラムがトランザクションの入力データを生成するために、その値の範囲の定義が必要になることもあります。 -- [GitHub](https://github.com/OpenZeppelin/openzeppelin-test-helpers) -- [ドキュメント](https://docs.openzeppelin.com/test-helpers) +プロパティテストツールは、適切に構成することで、ランダムに生成された入力値を使ってスマートコントラクトの関数を実行することができます。 アサーション違反が発生した場合、評価対象のプロパティに違反する具体的な入力データがレポートに含まれます。 プロパティベースのテストを実行するには、以下のさまざまなツールのガイドを参照してください。 -**Truffle スマートコントラクトテストフレームワーク** - _自動テストフレームワークにより、コントラクトのテストを簡単に行うことができます。_ +- **[Slitherを使ったスマートコントラクト静的解析](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/slither#slither)** +- **[Brownieを使ったプロパティベースのテスト](https://eth-brownie.readthedocs.io/en/stable/tests-hypothesis-property.html)** +- **[Foundryを使ったコントラクトのファジング](https://book.getfoundry.sh/forge/fuzz-testing)** +- **[Echidnaを使ったコントラクトのファジング](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna#echidna-tutorial)** +- **[Manticoreを使ったスマートコントラクトのシンボリック実行](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore#manticore-tutorial)** +- **[Mythrilを使ったスマートコントラクトのシンボリック実行](https://mythril-classic.readthedocs.io/en/master/tutorial.html)** -- [ドキュメント](https://trufflesuite.com/docs/truffle/testing/testing-your-contracts/) -- [ウェブサイト](https://trufflesuite.com/) +## スマートコントラクトの手動テスト {#manual-testing-for-smart-contracts} + +スマートコントラクトの手動テストは、通常、自動テストを行った後の開発サイクルの後半で行われます。 この手動テストでは、スマートコントラクトを完全に統合された1つの製品として評価し、技術要件で指定されたとおりの性能を発揮するかどうかを確認します。 -**ユニットテストフレームワーク Brownie** - _Brownie は、最小限のコードで小さなテストを作成することができ、大規模なプロジェクトでもうまく拡張できる、機能豊富なテストフレームワークである Pytest を利用しています。_ +### ローカルブロックチェーンでのコントラクトのテスト {#testing-on-local-blockchain} -- [ドキュメント](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html) -- [GitHub](https://github.com/eth-brownie/brownie) +ローカルの開発環境で実行される自動テストは、有用なデバッグ情報を提供しますが、実際の環境でスマートコントラクトがどのように動作するかを確認したい場合もあります。 しかし、実際のイーサリアムチェーンにデプロイするとガス代が発生します。また、スマートコントラクトにバグがある場合、ユーザーが実際にお金を失う可能性があることは言うまでもありません。 -**Foundry Tests** - _Foundry 社は、シンプルな単体テスト、ガス最適化チェック、コントラクトファジングを実行できる、高速で柔軟なイーサリアムテストフレームワークである Forge を提供しています。_ +メインネットでテストする代わりに、ローカルのブロックチェーン([開発ネットワーク](/developers/docs/development-networks/)とも呼ばれます)でコントラクトをテストすることをお勧めします。 ローカルブロックチェーンは、イーサリアムブロックチェーンのコピーで、自分のコンピュータのローカル環境で実行できるものです。これにより、イーサリアムの実行レイヤーの動作をシミュレートすることができます。 そのため、トランザクションをプログラムしてコントラクトとやり取りする際に、多額のコストが発生することはありません。 -- [GitHub](https://github.com/foundry-rs/foundry/tree/master/forge) -- [ドキュメント](https://book.getfoundry.sh/forge/) +ローカルのブロックチェーン上でコントラクトを実行するのは、手動で統合テストを行うのに効果的な方法です。 [スマートコントラクトは、柔軟に構成できるようになっています](/developers/docs/smart-contracts/composability/)。これにより、既存のプロトコルと統合できるようになりましたが、複雑なオンチェーンでの相互作用が正しい結果を生み出すかどうかについては、依然として確認する必要があります。 -**Etheno** - _JSON RPC マルチプレクサ、解析ツールラッパー、テスト統合ツールからなるオールインワンのイーサリアムテストツールです。 Etheno は、大規模なマルチコントラクトプロジェクトにおいて、Manticore や Echidna のような分析ツールを設定する複雑さを解消します。_ +[開発用ネットワークの詳細](/developers/docs/development-networks/) -- [GitHub](https://github.com/crytic/etheno) +### テストネットでのスマートコントラクトのテスト {#testing-contracts-on-testnets} -**Woke development and testing framework** - _Python のテスト・デプロイメントスクリプトで、型ヒント、ファザー、デバッグサポート、コードカバレッジ、クロスチェーンテストを備えています。_ +テストネットワークすなわちテストネットは、イーサリアムメインネットとまったく同じ仕様で動作するネットワークです。ただし、テストネットで使用されるイーサ(ETH)は、現実世界で価値がありません。 コントラクトを[テストネット](/developers/docs/networks/#ethereum-testnets)にデプロイすると、資金を失うリスクはありません。また、Dappのフロントエンドなどを介して、誰でもコントラクトとやり取りできるようになります。 -- [ドキュメント](https://ackeeblockchain.com/woke/docs/latest/testing-framework/overview/) -- [GitHub](https://github.com/Ackee-Blockchain/woke) +この方式の手動テストでは、ユーザーの視点からアプリケーションのエンドツーエンドのフローを評価することができます。 テストネットでは、ベータテスターが試験運用を行い、コントラクトのビジネスロジックや全体的な機能に関する問題を報告することもできます。 -### 静的解析ツール {#static-analysis-tools} +テストネットの方がイーサリアム仮想マシンの動作に近いため、ローカルブロックチェーンでテストした後にテストネットにデプロイすることが理想です。 そのため、多くのイーサリアムを使うプロジェクトでは、テストネットにDappをデプロイし、現実世界の条件下でスマートコントラクトの操作を評価するのが一般的です。 -**Mythril** - _Taint 解析、Concolic 解析、制御フローチェックを用いてコントラクトの脆弱性を検出する EVM バイトコード評価ツールです_。 +[イーサリアムテストネットの詳細](/developers/docs/development-networks/#public-beacon-testchains) -- [GitHub](https://github.com/ConsenSys/mythril-classic) -- [ドキュメント](https://mythril-classic.readthedocs.io/en/master/about.html) +## テストと形式検証の比較 {#testing-vs-formal-verification} -**Slither** - _Python ベースの Solidity 静的解析フレームワークで、脆弱性の発見、コード理解の強化、スマートコントラクトのカスタム解析の記述に使用します。_ +テストは、あるデータの入力に対して、コントラクトが期待通りの結果を返すことを確認するのに役立ちますが、テストで使用されていない入力に対して、同じことを確実に証明できるわけではありません。 したがって、スマートコントラクトのテストでは、「機能的な正しさ」を保証できません。つまり、入力値の_すべての_セットに対して、プログラムが要求通りに動作することを保証することはできません。 -- [GitHub](https://github.com/crytic/slither) +形式検証は、プログラムの形式モデルが形式仕様と一致するかどうかを確認することでソフトウェアの正確さを評価するアプローチです。 プログラムを抽象的かつ数学的に表現したものが形式モデルで、プログラムのプロパティ(つまり、プログラムの実行に関する論理的アサーション)を定義したものが形式仕様です。 -**Rattle** - _デプロイされたスマートコントラクトで動作するように設計された EVM バイトコード静的解析フレームワークです。_ +プロパティは、数学用語で記述されるため、システムの形式(数学)モデルが仕様を満たしていることを、論理的な推論規則を使用して検証することができます。 したがって、形式検証ツールは、システムの正確さを「数学的に証明」できると言われています。 -- [GitHub](https://github.com/crytic/rattle) +テストとは異なり、形式検証は、サンプルデータを使わずにスマートコントラクトが_どのような_実行においても、形式仕様を満たしていること(バグがないこと)を検証できます。 これにより、数十の単体テストの実行時間が短縮され、背後にある脆弱性をより効率的に発見できるようになります。 ただし、形式検証手法では、実装の難易度や有用性が多岐に渡ります。 -### 動的解析ツール {#dynamic-analysis-tools} +[スマートコントラクトの形式検証の詳細](/developers/docs/smart-contracts/formal-verification) -**Echidna** - _プロパティベースのテストによりスマートコントラクトの脆弱性を検出する高速なコントラクトファザーです_。 +## テストと監査およびバグ報奨金の比較 {#testing-vs-audits-bug-bounties} -- [GitHub](https://github.com/crytic/echidna/) +上記のように、厳密なテストをしても、コントラクトにバグがないとは言い切れません。 形式検証によるアプローチは、正確性をより強力に保証できますが、現時点では使用が難しく、かなりのコストがかかります。 -**Harvey** - _スマートコントラクトのコードのプロパティ違反を検出するのに便利な自動ファジングツールです。_ +第三者によるコードレビューを受ければ、コントラクトの脆弱性を発見できる可能性が高くなります。 第三者にコントラクトを分析してもらうには、[スマートコントラクトの監査](https://www.immunebytes.com/blog/what-is-a-smart-contract-audit/)および[バグ報奨金](https://medium.com/immunefi/a-defi-security-standard-the-scaling-bug-bounty-9b83dfdc1ba7)のいずれかの方法があります。 -- [ウェブサイト](https://consensys.net/diligence/fuzzing/) +監査は、スマートコントラクトのセキュリティ上の欠陥や不健全な開発プラクティスを探し出す経験豊かな監査人が行います。 監査では、コードベース全体の手動レビューだけでなく、テストや形式検証も行われるのが一般的です。 -**Manticore** - _EVM バイトコード解析のための動的シンボリック実行フレームワーク。_ +一方で、バグ報奨金プログラムでは通常、スマートコントラクトの脆弱性を発見してデベロッパーへ公開する([ホワイトハットハッカー](https://en.wikipedia.org/wiki/White_hat_(computer_security))と呼ばれる)個人に対して、金銭的な報酬が支払われます。 バグ報奨金は、スマートコントラクトの不具合の発見を他の人に依頼するもので、監査に似ています。 -- [GitHub](https://github.com/trailofbits/manticore) -- [ドキュメント](https://github.com/trailofbits/manticore/wiki) +主な違いとしては、バグ報奨金プログラムは、より広範なデベロッパーやハッカーコミュニティを対象としているため、ユニークなスキルや経験を持つ幅広いクラスの倫理的なハッカーや独立したセキュリティ専門家を引きつけることができます。 これは、限られた専門知識を持つチームに依存するスマートコントラクト監査では得られない利点と言えるでしょう。 -### スマートコントラクト監査サービス {#smart-contract-auditing-services} +## テストツールとライブラリ {#testing-tools-and-libraries} -**ConsenSys Diligence** - _スマートコントラクトの監査サービスによって、ブロックチェーンエコシステム全体のプロジェクトについて、プロトコルが起動に適した状態にあり、ユーザーを保護できるように構築されていることを保証します。_ +### 単体テストツール {#unit-testing-tools} -- [ウェブサイト](https://consensys.net/diligence/) +- **[solidity-coverage](https://github.com/sc-forks/solidity-coverage)** - _Solidityで書かれたスマートコントラクトのコードカバレッジツール_ -**CertiK** - _スマートコントラクトとブロックチェーンネットワークに最先端の形式検証技術を使用する先駆的なブロックチェーンセキュリティ企業です。_ +- **[Waffle](https://ethereum-waffle.readthedocs.io/en/latest/)** - _高度なスマートコントラクトの開発とテストのためのフレームワーク(ethers.jsベース)_ -- [ウェブサイト](https://www.certik.com/) +- **[Remixテスト](https://github.com/ethereum/remix-project/tree/master/libs/remix-tests)** - _Solidityスマートコントラクトのテストツール。 Remix IDEの「Solidity Unit Testing」プラグインで動作します。このプラグインは、コントラクトのテストケースの作成と実行に使用します。_ -**Trail of Bits** - _セキュリティ研究と攻撃者の心理を融合させ、リスクの低減とコードの堅牢化を図るサイバーセキュリティ企業です。_ +- **[OpenZeppelinテストヘルパー](https://github.com/OpenZeppelin/openzeppelin-test-helpers)** - _イーサリアムスマートコントラクトのテストに使用できるアサーションライブラリ。 コントラクトが期待通りに動作していることを確認してください。_ -- [ウェブサイト](https://www.trailofbits.com/) +- **[Brownieユニットテストフレームワーク](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html)** - _最小限のコードで小さなテストを作成可能。また、大規模なプロジェクトにも対応するスケーラビリティも持ち合わせており、機能豊富なテストフレームワークであるPytestを利用しています。_ -**PeckShield** - _ブロックチェーンエコシステム全体のセキュリティ、プライバシー、ユーザビリティのための製品やサービスを提供するブロックチェーンセキュリティ企業です。_ +- **[Foundryテスト](https://github.com/foundry-rs/foundry/tree/master/forge)** - _Foundry社は、シンプルな単体テスト、ガス最適化チェック、コントラクトファジングを実行でき、高速で柔軟なイーサリアムテストフレームワークであるForgeを提供しています。_ -- [ウェブサイト](https://peckshield.com/) +- **[Hardhatテスト](https://hardhat.org/hardhat-runner/docs/guides/test-contracts)** - _ethers.js、Mocha、Chaiをベースとしたスマートコントラクトテストにおけるフレームワーク_。 -**QuantStamp** - _セキュリティおよびリスク評価サービスを通じて、ブロックチェーン技術の主流化を促進する監査サービスです_。 +- **[ApeWorx](https://docs.apeworx.io/ape/stable/userguides/testing.html)** - _イーサリアム仮想マシン用のスマートコントラクトでPythonベースの開発およびテストのためのフレームワーク_。 -- [ウェブサイト](https://quantstamp.com/) +### プロパティベースのテストツール {#property-based-testing-tools} -**OpenZeppelin** - _分散型システムのセキュリティ監査を提供するスマートコントラクトセキュリティ企業です。_ +#### 静的解析ツール {#static-analysis-tools} -- [ウェブサイト](https://www.openzeppelin.com/security-audits) +- **[Slither](https://github.com/crytic/slither)** - _PythonベースのSolidity静的解析フレームワークで、脆弱性の発見、コード理解の強化、スマートコントラクトのカスタム解析の記述で使用_。 -**Nethermind** - _Solidity と Cairo の監査サービスにより、イーサリアムと Starknet 全体でスマートコントラクトの整合性とユーザーの安全が確保されます。_ +- **[Ethlint](https://ethlint.readthedocs.io/en/latest/)** - _スマートコントラクトのプログラミング言語であるSolidityのスタイルとセキュリティのベストプラクティスを適用するためのリンター_。 -- [ウェブサイト](https://nethermind.io/smart-contracts-audits) +#### 動的解析ツール {#dynamic-analysis-tools} -### バグ報奨金プラットフォーム {#bug-bounty-platforms} +- **[Echidna](https://github.com/crytic/echidna/)** - _プロパティベースのテストによりスマートコントラクトの脆弱性を検出する高速なコントラクトファザー_。 -**Immunefi** - _スマートコントラクトと DeFi プロジェクトのためのバグ報奨金プラットフォームです。セキュリティ研究者がコードをレビューし、脆弱性を開示し、報酬を得て、暗号をより安全なものにします。_ +- **[Diligence Fuzzing](https://consensys.net/diligence/fuzzing/)** - _スマートコントラクトのコードのプロパティ違反を検出するのに便利な自動ファジングツール_。 -- [ウェブサイト](https://immunefi.com/) +- **[Manticore](https://manticore.readthedocs.io/en/latest/index.html)** - _EVMバイトコード解析のための動的シンボリック実行フレームワーク_。 -**HackerOne** - _企業とペネトレーションテスターやサイバーセキュリティ研究者をつなぐ、脆弱性調整とバグ報奨金のプラットフォームです。_ +- **[Mythril](https://github.com/ConsenSys/mythril-classic)** - _Taint解析、Concolic解析、制御フローチェックを用いてコントラクトの脆弱性を検出するEVMバイトコード評価ツール_。 -- [ウェブサイト](https://www.hackerone.com/) +- **[Diligence Scribble](https://consensys.net/diligence/scribble/)** - _Scribbleは、仕様記述言語およびランタイム検証ツールでスマートコントラクトのプロパティにアノテーションを付けることができます。これにより、Diligence FuzzingやMythXなどのツールを使用してコントラクトを自動的にテストできます。_ ## 関連チュートリアル {#related-tutorials} -- [安定性と Truffle 連続統合設定](/developers/tutorials/solidity-and-truffle-continuous-integration-setup/) _– Travis または Circle CI の Truffle テストと有益なプラグインのセットアップ方法_ -- [製品テストの概要](/developers/tutorials/guide-to-smart-contract-security-tools/) _– 様々な製品テストの概要と比較_ -- [スマートコントラクトのテストに Echidna を使用する方法](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/) -- [Manticore を使用してスマートコントラクトのバグを見つける方法](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/) -- [Slither を使用してスマートコントラクトのバグを見つける方法](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) -- [テスト用 Solidity コントラクトのモックの作成方法](/developers/tutorials/how-to-mock-solidity-contracts-for-testing/) -- [Truffle テストから OpenZeppelin テスト環境に移行する方法](https://docs.openzeppelin.com/test-environment/0.1/migrating-from-truffle) -- [ネットワークにデプロイした後にスマートコントラクトをテストする方法](https://fulldecent.blogspot.com/2019/04/testing-deployed-ethereum-contracts.html) -- [JavaScript で学ぶブロックチェーン、Solidity、フルスタック Web3 開発(YouTube)](https://www.youtube.com/watch?v=gyMwXuJrbJQ) -- [Solidity、ブロックチェーン、スマートコントラクト講座(YouTube)](https://www.youtube.com/watch?v=M576WGiDBdQ) +- [さまざまな製品テストの概要と比較](/developers/tutorials/guide-to-smart-contract-security-tools/) \_ +- [スマートコントラクトのテストにEchidnaを使用する方法](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/) +- [Manticoreを使用してスマートコントラクトのバグを見つける方法](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/) +- [Slitherを使用してスマートコントラクトのバグを見つける方法](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) +- [Solidityコントラクトのテスト用モックの作成方法](/developers/tutorials/how-to-mock-solidity-contracts-for-testing/) +- [How to run unit tests in Solidity using Foundry](https://www.rareskills.io/post/foundry-testing-solidity) ## 参考文献 {#further-reading} -- [イーサリアムスマートコントラクトのテストに関する徹底ガイド](https://iamdefinitelyahuman.medium.com/an-in-depth-guide-to-testing-ethereum-smart-contracts-2e41b2770297) - _Ben Hauser_ -- [イーサリアムスマートコントラクトのテスト方法](https://betterprogramming.pub/how-to-test-ethereum-smart-contracts-35abc8fa199d) - _Alex Roan_ +- [イーサリアムスマートコントラクトのテストに関する詳細ガイド](https://iamdefinitelyahuman.medium.com/an-in-depth-guide-to-testing-ethereum-smart-contracts-2e41b2770297) +- [イーサリアムスマートコントラクトのテスト方法](https://betterprogramming.pub/how-to-test-ethereum-smart-contracts-35abc8fa199d) +- [デベロッパー向けMolochDAOのユニットテストガイド](https://github.com/MolochVentures/moloch/tree/4e786db8a4aa3158287e0935dcbc7b1e43416e38/test#moloch-testing-guide) +- [ロックスターのようにスマートコントラクトをテストする方法](https://forum.openzeppelin.com/t/test-smart-contracts-like-a-rockstar/1001) diff --git a/public/content/translations/ja/developers/docs/smart-contracts/upgrading/index.md b/public/content/translations/ja/developers/docs/smart-contracts/upgrading/index.md new file mode 100644 index 00000000000..bd2dc588ff2 --- /dev/null +++ b/public/content/translations/ja/developers/docs/smart-contracts/upgrading/index.md @@ -0,0 +1,168 @@ +--- +title: スマートコントラクトのアップグレード +description: イーサリアムスマートコントラクトのアップグレードパターンの概要 +lang: ja +--- + +イーサリアムのスマートコントラクトは、イーサリアム仮想マシン(EVM)で実行される自己実行プログラムです。 これらのプログラムは、不変になるように設計されています。そのため、一度デプロイしたコントラクトのビジネスロジックを後から変更することはできません。 + +この不変性は、トラストレス、分散化、スマートコントラクトのセキュリティを実現するために必要ですが、場合によっては欠点になることもあります。 例えば、このコードの不変性により、デベロッパーは脆弱なコントラクトを修正できないことがあります。 + +しかし、スマートコントラクトの改善に向けた研究が進み、いくつかのアップグレードパターンが開発されました。 これらのアップグレードでは、デベロッパーが別のコントラクトにビジネスロジックを配置することで、スマートコントラクトを(不変性を維持しつつ)アップグレードすることができます。 + +## 前提知識 {#prerequisites} + +[スマートコントラクト](/developers/docs/smart-contracts/)、[スマートコントラクトの構造](/developers/docs/smart-contracts/anatomy/)、 [イーサリアム仮想マシン(EVM)](/developers/docs/evm/)について十分に理解している必要があります。 さらに、このガイドでは、読者がスマートコントラクトのプログラミングを理解していることを前提としています。 + +## スマートコントラクトのアップグレードとは {#what-is-a-smart-contract-upgrade} + +スマートコントラクトをアップグレードするには、コントラクトの状態を維持したまま、スビジネスロジックを変更する必要があります。 特にアップグレード可能性と不変性は、スマートコントラクトのコンテキストでは、必ずしも一致するものではありません。 + +イーサリアムネットワーク上のアドレスにデプロイされたプログラムは、変更できません。 しかし、ユーザーがスマートコントラクトとやり取りする際に、実行されるコードは変更することができます。 + +これについては、次の方法を用いて行います。 + +1. 複数のバージョンのスマートコントラクトを作成し、古いコントラクトから新しいコントラクトのインスタンスに状態(データ)を移行する。 + +2. ビジネスロジックおよび状態を保存するセパレートコントラクトを作成する。 + +3. プロキシパターンを使い、不変のプロキシコントラクトから修正可能なロジックコントラクトへの関数の呼び出しを委任する。 + +4. 特定の関数を実行する柔軟なサテライトコントラクトに依存し、インターフェースで接続する不変のメインコントラクトを作成する。 + +5. ダイヤモンドパターンを使い、プロキシコントラクトからロジックコントラクトへの関数の呼び出しを委任する。 + +### アップグレードメカニズム #1: コントラクトマイグレーション {#contract-migration} + +スマートコントラクトのマイグレーションは、バージョン管理に基づいています。バージョン管理とは、同一のソフトウェアの固有の状態を作成・管理する考え方です。 コントラクトマイグレーションでは、従来のスマートコントラクトを新しいインスタンスにデプロイし、ストレージと残高を新しいコントラクトに転送します。 + +新しくデプロイされたコントラクトのストレージは空です。そのため、旧コントラクトからデータを復元して、新しい実装に書き込むことができます。 その後、旧コントラクトとやり取りしたすべてのコントラクトを、新しいコントラクトのアドレスに更新する必要があります。 + +コントラクトマイグレーションの最終ステップは、新しいコントラクトに切り替えてもらうようユーザーを説得することです。 新しいコントラクトでは、不変性が維持されており、ユーザーの残高とアドレスが引き継がれています。 トークンベースのコントラクトの場合は、旧コントラクトの使用を停止し、新しいコントラクトを使用する旨を取引所に通知する必要もあります。 + +コントラクトマイグレーションは、ユーザーとのやり取りを中断することなく、スマートコントラクトをアップグレードできる、比較的簡単で安全な方法です。 ただし、ユーザーのストレージと残高を新しいコントラクトに手動で移行するのに時間がかかり、高額なガス代が発生する可能性があります。 + +[コントラクトマイグレーションの詳細](https://blog.trailofbits.com/2018/10/29/how-contract-migration-works/) + +### アップグレードメカニズム #2: データセパレーション {#data-separation} + +スマートコントラクトのアップグレード方法として、ビジネスロジックとデータストレージを別々のコントラクトに分離する方法があります。 この方法では、ユーザーはロジックコントラクトとやり取りし、データはストレージコントラクトに保存されます。 + +ロジックコントラクトは、アプリケーションとやり取りする際に実行されるコードを含んでいます。 また、ロジックコントラクトは、ストレージコントラクトのアドレスを保持しており、データの取得や設定を処理します。 + +一方で、ストレージコントラクトは、ユーザー残高やアドレスなどのスマートコントラクトに関連する状態を保持します。 ストレージコントラクトは、ロジックコントラクトによって管理されます。また、デプロイ時にロジックコントラクトのアドレスが設定されることに注意してください。 これにより、認可されていないコントラクトがストレージコントラクトを呼び出したり、ストレージコントラクトのデータを更新したりすることを防止できます。 + +デフォルトでは、ストレージコントラクトは不変ですが、ロジックコントラクトは新しい実装に置き換えることで、 ストレージと残高をそのままに保ちつつ、EVMで実行されるコードを変更することができます。 + +このアップグレード方法を使用するには、ストレージコントラクト内のロジックコントラクトのアドレスを更新する必要があります。 また、前述した理由により、ストレージコントラクトのアドレスを使用して、新しいロジックコントラクトを構成する必要があります。 + +データセパレーションパターンは、コントラクトマイグレーションと比較して、簡単に実装できます。 ただし、スマートコントラクトを悪意のあるアップグレードから保護するには、複数のコントラクトを管理し、複雑な認可スキームを実装する必要があります。 + +### アップグレードメカニズム #3: プロキシパターン {#proxy-patterns} + +プロキシパターンでも、ビジネスロジックとデータを別々のコントラクトに保持するために、データセパレーションを使います。 しかし、プロキシパターンでは、コードの実行中に、ストレージコントラクト(プロキシと呼ばれる)がロジックコントラクトを呼び出します。 これは、ロジックコントラクトがストレージコントラクトを呼び出すデータセパレーションとは逆の方法です。 + +プロキシパターンでは、以下の処理が行われます。 + +1. ユーザーは、データを格納するプロキシコントラクトとやり取りします。ただし、プロキシコントラクトにはビジネスロジックは含まれていません。 + +2. プロキシコントラクトでは、ロジックコントラクトのアドレスを格納し、`delegatecall`関数を使って、すべての関数の呼び出しを(ビジネスロジックを持つ)ロジックコントラクトに委任します。 + +3. 呼び出しがロジックコントラクトに転送された後、ロジックコントラクトから返されたデータを取得し、ユーザーに戻します。 + +プロキシパターンを使うには、**delegatecall**関数を理解する必要があります。 基本的に、`delegatecall`は、コントラクトが別のコントラクトを呼び出すことができるオペコードですが、実際のコードは呼び出し元のコントラクトのコンテキストで行われます。 プロキシパターンで`delegatecall`を使用すると、プロキシコントラクトがストレージの読み取りと書き込みを行い、まるで内部関数を呼び出しているかのように、ロジックコントラクトのロジックを実行することになります。 + +[Solidityのドキュメント](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html#delegatecall-callcode-and-libraries)の引用: + +> **delegatecall**という特別な可変メッセージ呼び出しがあります。**delegatecall**は、ターゲットアドレスのコードが、呼び出し側コントラクトのコンテキスト(例: アドレス)で実行されることを除けば、メッセージ呼び出しと同一です。また、`msg.sender`と`msg.value`の値は変わりません。__これは、コントラクトが実行時に、別のアドレスからコードを動的にロードできることを意味します。 つまり、ストレージ、現在のアドレス、残高は呼び出し元のコントラクトを参照しており、 コードのみが呼び出し先のアドレスから取得されます_。 +> +> プロキシコントラクトには、`fallback`関数が組み込まれているため、ユーザーが関数を呼び出すたびに`delegatecall`をが呼び出されていることがわかります。 Solidityプログラミングでは、コントラクトの関数呼び出しが指定した関数と一致しない場合、[フォールバック関数](https://docs.soliditylang.org/en/latest/contracts.html#fallback-function)が実行されます。 +> +> プロキシパターンを機能させるには、プロキシコントラクトがサポートしていない関数の呼び出しを処理する方法を指定したカスタムフォールバック関数を作成する必要があります。 この場合、プロキシのフォールバック関数は、delegatecallを起動し、ユーザーのリクエストを現在のロジックコントラクト実装に切り替えるようにプログラムされます。 +> +> プロキシコントラクトは、デフォルトでは不変ですが、新しいロジックコントラクトを作成することで、ビジネスロジックを更新することができます。 アップグレードを実行するには、プロキシコントラクトが参照しているロジックコントラクトのアドレスを変更する必要があります。 +> +> プロキシコントラクトが新しいロジックコントラクトを参照するように変更することで、ユーザーがプロキシコントラクトの関数を呼び出すときに実行されるコードを変更することができます。 これにより、ユーザーは新しいコントラクトとやり取りする必要がなくなり、コントラクトのロジックをアップグレードすることができます。 +> +> プロキシパターンは、コントラクトのマイグレーションを容易にすることから、アップグレードで広く普及している方法です。 ただし、プロキシパターンの使用は、より複雑なため、不適切に扱うと[関数セレクタークラッシュ](https://medium.com/nomic-foundation-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357)などの重大な欠陥を引き起こす可能性があります。 +> +> [プロキシパターンの詳細](https://blog.openzeppelin.com/proxy-patterns/) +> +> ### アップグレードメカニズム #4: ストラテジパターン {#strategy-pattern} +> +> このテクニックは、[ストラテジパターン](https://en.wikipedia.org/wiki/Strategy_pattern)に基づいています。ストラテジパターンとは、特定の機能を実装するために、他のプログラムとインターフェースするソフトウェアプログラムを作成するよう奨励するものです。 ストラテジパターンをイーサリアム開発に適用すると、他のコントラクトから関数を呼び出すスマートコントラクトを構築することになります。 +> +> この場合、メインコントラクトはコアとなるビジネスロジックを持ちますが、他のスマートコントラクト(「サテライトコントラクト」) のインターフェースで、特定の機能を実行します。 このメインコントラクトには、各サテライトコントラクトのアドレスが格納されており、サテライトコントラクトの実装を切り替えることができます。 +> +> 新しいサテライトコントラクトを構築して、メインコントラクトにその新しいコントラクトアドレスを設定することで、 スマートコントラクトの_ストラテジ_を変更(つまり、新しいロジックを実装)することができます。 +> +> 先ほどのプロキシパターンと似ていますが、ストラテジパターンでは、ユーザーがやり取りするメインコントラクトがビジネスロジックを持っています。これは、プロキシパターンと異なる点です。 このパターンを使用すると、コアインフラストラクチャに影響を与えることなく、スマートコントラクトに限定的な変更を加えることができます。 +> +> このパターンの欠点は、マイナーアップグレードにしか対応できないことです。 また、メインコントラクトが(ハッキングなどにより)侵害された場合は、このアップグレード方法は使用できません。 +> +> ### アップグレードメカニズム #5: ダイヤモンドパターン {#diamond-pattern} +> +> ダイヤモンドパターンは、プロキシパターンの改良版と言えます。 ダイヤモンドパターンでは、ダイヤモンドプロキシコントラクトが、関数呼び出しを複数のロジックコントラクトに委任できることができます。これは、プロキシパターンではできなかったことです。 +> +> ダイヤモンドパターンのロジックコントラクトを_ファセット_と呼びます。 ダイヤモンドパターンを機能させるには、各ファセットアドレスに[関数セレクタ](https://docs.soliditylang.org/en/latest/abi-spec.html#function-selector)をマップするマッピングを、プロキシコントラクト内に作成する必要があります。 +> +> ユーザーが関数を呼び出すと、プロキシコントラクトはマッピングをチェックして、その関数の実行を担当するファセットを見つけます。 次に、(フォールバック関数を使って)`delegatecall`を呼び出します。この呼び出しは、適切なロジックコントラクトにリダイレクトされます。 +> +> このダイヤモンドアップグレードパターンは、従来のプロキシアップグレードパターンに比べて、以下の利点があります。 +> +> 1. コード全体を変更しなくとも、コントラクトの一部をアップグレード可能。 プロキシパターンを使ってアップグレードすると、マイナーアップグレードであっても、新しいロジックコントラクトを最初から作成しなければなりません。 +> +> 2. すべてのスマートコントラクト(プロキシパターンで使用されるロジックコントラクトを含む)には、24KBのサイズ制限がある。この制限は、特に、多くの機能を必要とする複雑なコントラクトで適用されます。 ダイヤモンドパターンを使えば、関数を複数のロジックコントラクトに分割できるため、この問題を簡単に解決できます。 +> +> 3. プロキシパターンは、アクセス制御に対して、一括管理するアプローチを採用。 アップグレード機能にアクセスできるエンティティは、 コントラクト_全体_を変更することができます。 一方、ダイヤモンドパターンを使用することで、モジュールごとにアクセス許可を設定することができます。これにより、エンティティがスマートコントラクト内の特定の機能をアップグレードすることを制限できます。 +> +> [ダイヤモンドパターンの詳細](https://eip2535diamonds.substack.com/p/introduction-to-the-diamond-standard?s=w) +> +> ## スマートコントラクトのアップグレードにおけるメリットとデメリット {#pros-and-cons-of-upgrading-smart-contracts} +> +> + +| メリット | デメリット | +| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| スマートコントラクトのアップグレードにより、デプロイ後に発見された脆弱性を修正しやすくなります。 | スマートコントラクトをアップブレードすると、コードの不変性が失われ、分散化とセキュリティに悪影響を与える可能性があります。 | +| デベロッパーは、ロジックのアップグレードを使い、分散アプリケーションに新しい機能を追加できます。 | ユーザーは、デベロッパーがスマートコントラクトを勝手に変更しないことを信頼しなければなりません。 | +| スマートコントラクトのアップグレードにより、バグを迅速に修正できます。これにより、エンドユーザーの安全性が向上します。 | スマートコントラクトにアップグレード機能をプログラミングすると、より複雑になり、重大な欠陥が発生するリスクが高まります。 | +| コントラクトのアップグレードにより、デベロッパーは、さまざまな機能を試したり、時間とともにDappを改良したりすることができます。 | スマートコントラクトをアップグレードできるため、デベロッパーは、開発段階でデューデリジェンスを行わずに、プロジェクトを早く開始してしまうかもしれません。 | +| | スマートコントラクトがセキュリティが低下したアクセスコントロールや集中化のリスクにさらされることで、悪意のある攻撃者が、認可されていないアップグレードを実行しやすくなる可能性があります。 | + + +## スマートコントラクトのアップグレードにおける考慮事項 {#considerations-for-upgrading-smart-contracts} + +1. 特にプロキシパターン、ストラテジパターン、データセパレーションを使う場合、安全なアクセスコントロール/認可メカニズムを用いて、認可されていないスマートコントラクトへのアップグレードを防止します。 例えば、コントラクトの所有者のみがアップグレード関数を呼び出せるように、アップグレード関数へのアクセスを限定します。 + +2. スマートコントラクトのアップグレードは複雑な作業です。また、脆弱性の侵入を防ぐためには、細心の注意が必要です。 + +3. アップグレードを実行するプロセスを分散化することで、信頼の仮定を軽減します。 可能な戦略としては、[マルチシグウォレットコントラクト](/developers/docs/smart-contracts/#multisig)を用いてアップグレードをコントロールしたり、[DAOメンバー](/dao/)の投票によってアップグレードを承認したりするなどの方法があります。 + +4. コントラクトのアップグレードにコストがかかることに注意します。 例えば、コントラクトのマイグレーション中に、古いコントラクトから新しいコントラクトへ状態(例: ユーザーの残高)をコピーするには、複数のトランザクションが必要になる場合があります。これにより、ガス代が高くなります。 + +5. ユーザーの保護に**タイムロック**の実装を検討します。 タイムロックによって、システムへの変更を強制的に遅延させることができます。 タイムロックとマルチシグによるガバナンスシステムを組み合わせることで、アップグレードをコントロールすることができます。これにより、提案されたアクションが承認に必要なしきい値に達しても、タイムロックで事前に定めた遅延期間が経過するまでは実行されません。 + +タイムロックは、ユーザーが提案された変更(例: ロジックのアップグレードや新しい料金体系など)に同意しない場合、ユーザーに対してシステムから離脱する猶予期間を与える機能です。 タイムロックがないと、ユーザーは、デベロッパーが事前通知なしでスマートコントラクトを勝手に変更しないという信頼に頼らざるを得ません。 タイムロックの欠点としては、脆弱性に対するパッチの適用が遅れる可能性があることです。 + +## リソース {#resources} + +**OpenZeppelinアップグレードプラグイン - _アップグレード可能なスマートコントラクトのデプロイおよび保護するためのツールスイート_** + +- [GitHub](https://github.com/OpenZeppelin/openzeppelin-upgrades) +- [ドキュメント](https://docs.openzeppelin.com/upgrades) + +## チュートリアル {#tutorials} + +- [スマートコントラクトのアップグレード | Patrick CollinsによるYouTubeチュートリアル](https://www.youtube.com/watch?v=bdXJmWajZRY) +- Austin Griffithによる[イーサリアム・スマートコントラクト・マイグレーション・チュートリアル](https://medium.com/coinmonks/ethereum-smart-contract-migration-13f6f12539bd) +- Pranesh A.Sによる[UUPSプロキシパターンを使ったスマートコントラクトのアップグレード](https://blog.logrocket.com/author/praneshas/) +- fangjun.ethによる[Web3チュートリアル: OpenZeppelinを使用したアップグレード可能なスマートコントラクト(プロキシ)の作成](https://dev.to/yakult/tutorial-write-upgradeable-smart-contract-proxy-contract-with-openzeppelin-1916) + +## 参考文献 {#further-reading} + +- [スマートコントラクトの状態のアップグレード](https://blog.openzeppelin.com/the-state-of-smart-contract-upgrades/) | Santiago Palladino +- [Solidityスマートコントラクトのさまざまなアップグレード方法](https://cryptomarketpool.com/multiple-ways-to-upgrade-a-solidity-smart-contract/) - Crypto Market Poolのブログ +- [スマートコントラクトのアップグレードの学習](https://docs.openzeppelin.com/learn/upgrading-smart-contracts) - OpenZeppelinドキュメント +- [Solidityコントラクトのアップグレード可能なプロキシパターン: 透過プロキシとUUPSプロキシの比較](https://mirror.xyz/0xB38709B8198d147cc9Ff9C133838a044d78B064B/M7oTptQkBGXxox-tk9VJjL66E1V8BUF0GF79MMK4YG0) | Naveen Sahu +- [ダイヤモンドアップグレードの動作原理](https://dev.to/mudgen/how-diamond-upgrades-work-417j) | Nick Mudge diff --git a/public/content/translations/ja/developers/docs/smart-contracts/verifying/index.md b/public/content/translations/ja/developers/docs/smart-contracts/verifying/index.md new file mode 100644 index 00000000000..752bbd3ae35 --- /dev/null +++ b/public/content/translations/ja/developers/docs/smart-contracts/verifying/index.md @@ -0,0 +1,107 @@ +--- +title: スマートコントラクトの検証 +description: イーサリアムのスマートコントラクトのソースコード検証の概要 +lang: ja +--- + +[スマートコントラクト](/developers/docs/smart-contracts/) は「トラストレス」なものとして設計されています。つまり、ユーザーはスマートコントラクトとやりとりをする前に、第三者(デベロッパーや企業など)を信頼する必要はありません。 トラストレスであることを確保するためには、ユーザーやその他のデベロッパーがスマートコントラクトのソースコードを検証できるようにする必要があります。 ソースコード検証により、ユーザーとデベロッパーは、公開されたコントラクトコードが、イーサリアムブロックチェーン上のコントラクトアドレスで実行されているのと同じコードであることを確認できます。 + +「ソースコード検証」と「[形式的検証](/developers/docs/smart-contracts/formal-verification/)」を区別することは重要です。 以下で詳述するソースコード検証とは、高級言語(Solidityなど)で書かれたスマートコントラクトのソースコードをコンパイルしたものが、コントラクトアドレスで実行されるバイトコードと一致するかどうかを検証する手法ですが、 形式的検証は、スマートコントラクトの正しさ、つまり、スマートコントラクトが意図したとおりに動作することを検証するものです。 コントラクト検証とは、文脈にもよりますが、一般的にはソースコード検証を指します。 + +## ソースコード検証とは {#what-is-source-code-verification} + +スマートコントラクトを[イーサリアム仮想マシン(EVM)](/developers/docs/evm/)にデプロイする前に、デベロッパーはスマートコントラクトのソースコード([Solidity](/developers/docs/smart-contracts/languages/)もしくは他の高級プログラミング言語で書かれた命令)をバイトコードに[コンパイル](/developers/docs/smart-contracts/compiling/)します。 EVMは高級言語による命令を解釈できないため、EVM内でスマートコントラクトのビジネスロジックを実行するには、ソースコードをバイトコード(すなわち低級のマシン命令)にコンパイルする必要があります。 + +ソースコード検証とは、スマートコントラクトの作成時に使用したソースコードと、実行時にコンパイルされたバイトコードを比較して、違いを検出することです。 公表されたスマートコントラクトのコードと、ブロックチェーン上で実行されるコードが異なる可能性があるため、スマートコントラクトの検証は重要な作業となります。 + +スマートコントラクト検証では、マシンコードを読むことなく、スマートコントラクトが書かれた高級言語を通してスマートコントラクトの挙動を調査することができます。 関数、値、そして通常は変数名とコメントは、コンパイルやデプロイを行っても、元のソースコードと同じままです。 そのため、コードの読解がとても簡単になります。 ソース検証は、コードのドキュメンテーションも規定するため、エンドユーザーはスマートコントラクトが何を行うように設計されているのかを理解することができます。 + +### 全検証とは何か {#full-verification} + +ソースコードには、コメントや変数名など、コンパイル後のバイトコードに影響しない部分があります。 そのため、変数名やコメントが異なるソースコードでも、同じスマートコントラクトを検証することができます。 これを悪用して、ソースコードに嘘のコメントや誤解を招く変数名を与えて、元のソースコードとは別のコードでスマートコントラクトを検証することができます。 + +It is possible to avoid this by appending extra data to the bytecode to serve as a _cryptographic guarantee_ for the exactness of the source code, and as a _fingerprint_ of the compilation information. 必要な情報は、[Solidityのコントラクトメタデータ](https://docs.soliditylang.org/en/v0.8.15/metadata.html)に含まれており、このファイルのハッシュは、コントラクトのバイトコードに追加されます。 この動作は、[メタデータのプレイグラウンド](https://playground.sourcify.dev)で確認できます。 + +メタデータファイルには、ソースファイルとそのハッシュを含む、スマートコントラクトのコンパイルに関する情報が含まれています。 コンパイル設定やソースファイルの1つが1バイトでも変更されると、メタデータファイルも変更されます。 そのため、バイトコードに付加されるメタデータファイルのハッシュも変更されます。 つまり、スマートコントラクトのバイトコードと付加されたメタデータハッシュが、指定されたソースコードおよびコンパイル設定と一致する場合、このソースコードは元のコンパイルで使われたものと完全に一致しており、1バイト単位で変更されていないことを確認できるのです。 + +メタデータハッシュを活用するこのタイプの検証は、**"[全検証](https://docs.sourcify.dev/docs/full-vs-partial-match/)"**(または「完全検証」)と呼ばれます。 一方、メタデータハッシュが一致しない、または検証で考慮されていない場合は「部分一致」と呼ばれ、現在ではこれがより一般的なスマートコントラクト検証の方法です。 全検証をしない場合は、検証されたソースコードに表れない[悪意のあるコードを挿入](https://samczsun.com/hiding-in-plain-sight/)することが可能です。 しかし、ほとんどのデベロッパーは全検証を知らないうえに、コンパイルのメタデータファイルを保持していないため、現実的には部分検証がスマートコントラクト検証の主流となっています。 + +## ソースコード検証が重要な理由 {#importance-of-source-code-verification} + +### トラストレス性 {#trustlessness} + +トラストレス性は、スマートコントラクトと[分散型アプリケーション(dapps)](/developers/docs/dapps/)の最も重要な前提条件です。 スマートコントラクトは「不変」で、変更することはできません。そのため、スマートコントラクトは、デプロイ時にコードで定義されているビジネスロジックのみを実行します。 つまり、デベロッパーや企業は、イーサリアムにデプロイした後に、スマートコントラクトのコードを改ざんすることはできません。 + +スマートコントラクトがトラストレスとなるためには、そのコードが独立した検証のために公開されている必要があります。 しかし、ブロックチェーン上で公開されているスマートコントラクトのコンパイル済みバイトコードは、デベロッパーやユーザーにとって理解するのが難しい低水準言語で書かれています。 + +スマートコントラクトのソースコードを公開することで、信頼を前提とする必要性が減ります。 But this leads to another problem: it is difficult to verify that the published source code matches the contract bytecode. このシナリオでは、ユーザーは、デベロッパーがスマートコントラクトをブロックチェーンにデプロイする前に、ビジネスロジックが変更されていない(つまり、バイトコードが変更されていない)ことを信頼する必要があります。そのため、トラストレス性の価値が失われます。 + +ソースコード検証ツールは、スマートコントラクトのソースコードファイルとアセンブリコードの一致を保証します。 これにより、トラストレスなエコシステムで、ユーザーはやみくもに第三者を信頼することなく、スマートコントラクトに資金を預ける前にコードを検証することができます。 + +### ユーザーの安全性 {#user-safety} + +スマートコントラクトには、通常、高額のコストがかかります。 そのため、より高いセキュリティが求められ、使用前のスマートコントラクトのロジックの検証が必須となります。 問題は、悪意のある開発者がスマートコントラクトに悪意のあるコードを混ぜて、ユーザーを騙す可能性があることです。 検証を行わないと、悪意のあるスマートコントラクトには、ユーザーの安全性を脅かす問題が潜んだままの状態になります。例えば、[バックドア](https://www.trustnodes.com/2018/11/10/concerns-rise-over-backdoored-smart-contracts)や、物議をかもすようなアクセスコントロール機構、悪用されうる脆弱性などです。 + +スマートコントラクトのソースコードファイルを公開すると、監査役など、潜在的な攻撃媒介を評価する者は、スマートコントラクトの評価を容易に行うことができます。 複数の当事者が独自にスマートコントラクトを検証することで、ユーザーはより強力なセキュリティの保証を得ることができます。 + +## イーサリアムのスマートコントラクトコードの検証方法 {#source-code-verification-for-ethereum-smart-contracts} + +[イーサリアムにスマートコントラクトをデプロイする](/developers/docs/smart-contracts/deploying/)には、データペイロード(コンパイル済みバイトコード)を含むトランザクションを、特別なアドレスに送信する必要があります。 データペイロードは、トランザクション内のデータペイロードに付加されるコントラクトインスタンスの[コンストラクタ引数](https://docs.soliditylang.org/en/v0.8.14/contracts.html#constructor)に加えて、ソースコードをコンパイルすることによって生成されます。 コンパイルは決定論的です。つまり、ソースファイルとコンパイル設定(コンパイラのバージョンや最適化など)が同じであれば、常に同じ結果(スマートコントラクトのバイトコード)を生成します。 + +![スマートコントラクトソースコードの検証を説明する図](./source-code-verification.png) + +スマートコントラクトの検証は、大きく分けて次の手順で行われます。 + +1. ソースファイルとコンパイル設定をコンパイラに入力します。 + +2. コンパイラはスマートコントラクトのバイトコードを出力します。 + +3. 指定されたアドレスでデプロイされたスマートコントラクトのバイトコードを取得します。 + +4. デプロイされたバイトコードを再コンパイルされたバイトコードと比較します。 コードが一致すれば、スマートコントラクトが指定されたソースコードとコンパイル設定に基づいて作成されたことが確認できます。 + +5. さらに、バイトコード末尾のメタデータハッシュが一致すれば、完全一致となります。 + +これは検証の単純化された記述であり、 [イミュータブル変数](https://docs.sourcify.dev/docs/immutables/)を持つ場合など、検証できない例外が多いことに注意してください。 + +## ソースコード検証ツール {#source-code-verification-tools} + +スマートコントラクトを検証する従来のプロセスは複雑になりがちです。 そのため、イーサリアムにデプロイされたスマートコントラクトのソースコードを検証するツールが存在します。 これらのツールは、ソースコード検証の大部分を自動化し、ユーザーに有益となるように検証済みのスマートコントラクトをキュレーションします。 + +### Etherscan {#etherscan} + +主に[イーサリアムのブロックチェーンエクスプローラー](/developers/docs/data-and-analytics/block-explorers/)として知られているEtherscanは、スマートコントラクトのデベロッパーやユーザー向けに、[ソースコード検証サービス](https://etherscan.io/verifyContract)も提供しています。 + +Etherscanを使用すると、元のデータペイロード(ソースコード、ライブラリのアドレス、コンパイラの設定、スマートコントラクトのアドレスなど)から、スマートコントラクトのバイトコードを再コンパイルできます。 再コンパイルされたバイトコードがチェーン上のスマートコントラクトのバイトコード(およびコンストラクタのパラメータ)に結び付くと、 [コントラクトが検証されます](https://info.etherscan.com/types-of-contract-verification/)。 + +検証が完了すると、スマートコントラクトのソースコードは「検証済み」のラベルを受け取り、他の人が監査できるようにEtherscanで公開されます。 また、検証済みソースコードを備えたスマートコントラクトのリポジトリである[検証済みコントラクト](https://etherscan.io/contractsVerified/)のセクションにも追加されます。 + +Etherscanはスマートコントラクトを検証するのに最もよく使用されるツールです。 しかし、Etherscanのコントラクト検証には欠点があります。チェーン上のバイトコードの**メタデータハッシュ**と再コンパイルされたバイトコードを比較することができないため、 部分一致しか得られません。 + +[Etherscanでスマートコントラクトを検証する方法の詳細](https://medium.com/etherscan-blog/verifying-contracts-on-etherscan-f995ab772327) + +### Sourcify {#sourcify} + +[Sourcify](https://sourcify.dev/#/verifier)は、オープンソースで分散化された、スマートコントラクトを検証するためのツールです。 ブロックエクスプローラーではなく、 [異なるEVMベースのネットワーク](https://docs.sourcify.dev/docs/chains)でスマートコントラクトを検証するためのものです。 このツールは、他のツールを構築するためのパブリックインフラストラクチャとして機能します。[ABI](/developers/docs/smart-contracts/compiling/#web-applications)やメタデータファイル内で見つけた[NatSpec](https://docs.soliditylang.org/en/v0.8.15/natspec-format.html)コメントを使い、よりヒューマンフレンドリーにコントラクトとやり取りできるようにすることを目指しています。 + +Etherscanと違って、Sourcifyでは、メタデータハッシュとの完全一致をサポートしています。 検証されたコントラクトは、Sourcifyの[パブリックリポジトリ](https://docs.sourcify.dev/docs/repository/)によりHTTPおよび[IPFS](https://docs.ipfs.io/concepts/what-is-ipfs/#what-is-ipfs)で提供されます。IPFSは、分散化された[コンテンツアドレス付](https://web3.storage/docs/concepts/content-addressing/)ストレージです。 添付されたメタデータハッシュがIPFSハッシュであるため、IPFSを通してコントラクトファイルのメタデータを取り出すことができます。 + +さらに、ソースコードファイルのIPFSハッシュもメタデータ内にあるため、IPFSを通してソースコードファイルを取得することもできます。 APIもしくは[UI](https://sourcify.dev/#/verifier)を通して、またはプラグインを使って、メタデータファイルとソースファイルを提供することでコントラクトを検証できます。 また、Sourcifyのモニタリングツールは、新しいブロックでコントラクトの作成をリッスンし、メタデータとソースファイルがIPFSで公開されている場合にコントラクトを検証しようとします。 + +[Sourcifyのコントラクト検証の詳細](https://blog.soliditylang.org/2020/06/25/sourcify-faq/) + +### Tenderly {#tenderly} + +[Tenderlyプラットフォーム](https://tenderly.co/)は、Web3デベロッパー向けにスマートコントラクトのビルド、テスト、モニタリング、操作を提供します。 Tenderlyでは、オブザーバビリティおよびインフラストラクチャのビルディングブロックを持つデバックツールを組み合わせることで、デベロッパーがスマートコントラクトの開発をより迅速に行えるようサポートします。 Tenderlyの機能を完全に有効にするには、デベロッパーはいくつかの方法で[ソースコード検証を実行](https://docs.tenderly.co/monitoring/contract-verification)する必要があります。 + +コントラクトは、公開または非公開で検証できます。 非公開で検証する場合、スマートコントラクトは、作成者(もしくはプロジェクト内の他のメンバー)のみに公開されます。 公開で検証する場合、Tenderlyプラットフォームを使用するすべての人に公開されます。 + +[ダッシュボード](https://docs.tenderly.co/monitoring/smart-contract-verification/verifying-a-smart-contract)、[Tenderly Hardhatプラグイン](https://docs.tenderly.co/monitoring/smart-contract-verification/verifying-contracts-using-the-tenderly-hardhat-plugin)、[CLI](https://docs.tenderly.co/monitoring/smart-contract-verification/verifying-contracts-using-cli)を使ってコントラクトを検証することができます。 + +ダッシュボードを通してコントラクトを検証する場合、Solidityコンパイラによって生成されたソースファイルもしくはメタデータファイル、アドレス/ネットワーク、コンパイラー設定をインポートする必要があります。 + +Tenderly Hardhatプラグインを使うと、少ない労力で検証プロセスをより細かく制御できます。また、自動(コードなし)検証と手動(コードベース)検証のいずれかを選択できます。 + +## 参考文献 {#further-reading} + +- [コントラクトソースコードの検証](https://programtheblockchain.com/posts/2018/01/16/verifying-contract-source-code/) diff --git a/public/content/translations/ja/developers/docs/standards/index.md b/public/content/translations/ja/developers/docs/standards/index.md index f2e48bfc278..5099a1727fe 100644 --- a/public/content/translations/ja/developers/docs/standards/index.md +++ b/public/content/translations/ja/developers/docs/standards/index.md @@ -7,32 +7,32 @@ incomplete: true ## 開発規格の概要 {#standards-overview} -イーサリアムコミュニティでは、([イーサリアムクライアント](/developers/docs/nodes-and-clients/)やウォレットなどの)各種プロジェクトにおける様々な実装間での相互運用性を維持し、スマートコントラクトや Dapp に対してコンポーザビリティを提供するために、多くの規格を定めています。 +イーサリアムコミュニティでは、([イーサリアムクライアント](/developers/docs/nodes-and-clients/)やウォレットなどの)各種プロジェクトにおける様々な実装間での相互運用性を維持し、スマートコントラクトやDappに対してコンポーザビリティを提供するために、多くの規格を定めています。 これらの規格は通常、[イーサリアム改善提案](/eips/)(EIP)として提出された後、コミュニティにおいて[標準プロセス](https://eips.ethereum.org/EIPS/eip-1)に従って議論されます。 -- [EIP とは何か?](/eips/) -- [EIP リスト](https://eips.ethereum.org/) -- [GitHub の EIP レポジトリ](https://github.com/ethereum/EIPs) -- [EIP ディスカッションボード](https://ethereum-magicians.org/c/eips) +- [EIPとは何か?](/eips/) +- [EIPリスト](https://eips.ethereum.org/) +- [GitHubのEIPレポジトリ](https://github.com/ethereum/EIPs) +- [EIPディスカッションボード](https://ethereum-magicians.org/c/eips) - [イーサリアムにおけるガバナンス入門](/governance/) -- [イーサリアムにおけるガバナンスの概説](https://web.archive.org/web/20201107234050/https://blog.bmannconsulting.com/ethereum-governance/) _2019 年 3 月 31 日、ボリス・マン作成。_ -- [イーサリアムにおけるプロトコル開発のガバナンスならびにネットワークアップグレードの調整](https://hudsonjameson.com/2020-03-23-ethereum-protocol-development-governance-and-network-upgrade-coordination/) _2020 年 3 月 23 日、ハドソン・ジェイムソン作成。_ -- [イーサリアム・コアデベロッパー・ミーティングの全プレイリスト](https://www.youtube.com/playlist?list=PLaM7G4Llrb7zfMXCZVEXEABT8OSnd4-7w) _(YouTube のプレイリスト)_ +- [イーサリアムにおけるガバナンスの概説](https://web.archive.org/web/20201107234050/https://blog.bmannconsulting.com/ethereum-governance/) _2019年3月31日、ボリス・マン作成。_ +- [イーサリアムにおけるプロトコル開発のガバナンスならびにネットワークアップグレードの調整](https://hudsonjameson.com/2020-03-23-ethereum-protocol-development-governance-and-network-upgrade-coordination/) _2020年3月23日、ハドソン・ジェイムソン作成。_ +- [イーサリアム・コアデベロッパー・ミーティングの全プレイリスト](https://www.youtube.com/playlist?list=PLaM7G4Llrb7zfMXCZVEXEABT8OSnd4-7w) _(YouTubeのプレイリスト)_ ## 標準規格の種類 {#types-of-standards} -EIP は、以下の 3 種類に分類されます: +EIPは、以下の3種類に分類されます: - スタンダードトラック:すべて/大部分のイーサリアム実装に影響を及ぼす変更について記述します。 - [メタトラック](https://eips.ethereum.org/meta):イーサリアムに関するプロセスについて記述するか、プロセスの変更を提案します。 - [情報トラック](https://eips.ethereum.org/informational):イーサリアムの設計に関する問題点について記述するか、イーサリアムコミュニティに対する全般的なガイドラインや情報を提供します。 -標準トラックはさらに、以下の 4 つのカテゴリーに分類されます: +標準トラックはさらに、以下の4つのカテゴリーに分類されます: - [コア](https://eips.ethereum.org/core):コンセンサスフォークを必要とする改善。 -- [ネットワーク](https://eips.ethereum.org/networking):devp2p ならびにライトイーサリアムのサブプロトコルに関する改善や、Whisper および Swarm ネットワークプロトコル仕様に対する改善提案。 -- [インターフェース](https://eips.ethereum.org/interface):クライアント向け API/RPC の仕様/規格の改善と、メソッドの名称やコントラクトの ABI など、一部の言語レベルにおける規格の改善。 +- [ネットワーク](https://eips.ethereum.org/networking):devp2pならびにライトイーサリアムのサブプロトコルに関する改善や、WhisperおよびSwarmネットワークプロトコル仕様に対する改善提案。 +- [インターフェース](https://eips.ethereum.org/interface):クライアント向けAPI/RPCの仕様/規格の改善と、メソッドの名称やコントラクトのABIなど、一部の言語レベルにおける規格の改善。 - [ERC](https://eips.ethereum.org/erc):アプリケーションレベルにおける規格および慣例。 これらの種類やカテゴリーの詳細については、[EIP-1](https://eips.ethereum.org/EIPS/eip-1#eip-types)を参照してください。 @@ -40,14 +40,14 @@ EIP は、以下の 3 種類に分類されます: ### トークン規格 {#token-standards} - [ERC-20](/developers/docs/standards/tokens/erc-20/) - 投票トークン、ステーキングトークン、通貨トークンなど、代替性トークン (FT) のための標準インタフェースです。 - - [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) - transfer または transferFrom を受信した後の受信者側におけるコードの実行や、承認後における spender コードをサポートする、ERC-20 トークンのトークンインターフェイスを定義します。 -- [ERC-721](/developers/docs/standards/tokens/erc-721/) - アートや楽曲の所有証明などの非代替性トークン (NFT) のための標準インタフェースです。 - - [ERC-2309](https://eips.ethereum.org/EIPS/eip-2309) - ひとつの NFT あるいは連続するトークン識別子を用いた複数の NFT を作成/転送する際に発行される標準イベント。 - - [ERC-4400](https://eips.ethereum.org/EIPS/eip-4400) - EIP-721 コンシューマーロール向けのインターフェース拡張機能。 - - [ERC-4907](https://eips.ethereum.org/EIPS/eip-4907) - ERC-721 トークンに対して、制限付き許可を伴う時間限定ロールを追加します。 -- [ERC-777](/developers/docs/standards/tokens/erc-777/) - **(推奨せず)** ERC-20 を改善したトークン規格です。 + - [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) - transferまたはtransferFromを受信した後の受信者側におけるコードの実行や、承認後におけるspenderコードをサポートする、ERC-20トークンのトークンインターフェイスを定義します。 +- [ERC-721](/developers/docs/standards/tokens/erc-721/) - アートや楽曲に対する所有証明など、非代替性トークン (NFT) を対象とする標準的なインタフェースです。 + - [ERC-2309](https://eips.ethereum.org/EIPS/eip-2309) - ひとつのNFTあるいは連続するトークン識別子を用いた複数のNFTを作成/転送する際に発行される標準イベント。 + - [ERC-4400](https://eips.ethereum.org/EIPS/eip-4400) - EIP-721コンシューマーロール向けのインターフェース拡張機能。 + - [ERC-4907](https://eips.ethereum.org/EIPS/eip-4907) - ERC-721トークンに対して、制限付き許可を伴う時間限定ロールを追加します。 +- [ERC-777](/developers/docs/standards/tokens/erc-777/) - **(推奨せず)** ERC-20を改善したトークン規格です。 - [ERC-1155](/developers/docs/standards/tokens/erc-1155/) - 代替可能および非代替性の両方のトークンに用いることができるトークン規格です。 -- [ERC-4626](/developers/docs/standards/tokens/erc-4626/) - 利回り保管庫のトークン化規格で、利回り保管庫として技術パラメータの最適化と統一がされています。 +- [ERC-4626](/developers/docs/standards/tokens/erc-4626/) - 利回りボールト(保管庫)における技術的なパラメータを最適化、統一することを目指して設計された、トークン化ボールト用の規格です。 [トークン規格](/developers/docs/standards/tokens/)に関する詳細情報。 diff --git a/public/content/translations/ja/developers/docs/standards/tokens/erc-1155/index.md b/public/content/translations/ja/developers/docs/standards/tokens/erc-1155/index.md index b6da43d90b8..424aec64f44 100644 --- a/public/content/translations/ja/developers/docs/standards/tokens/erc-1155/index.md +++ b/public/content/translations/ja/developers/docs/standards/tokens/erc-1155/index.md @@ -10,26 +10,26 @@ lang: ja **マルチトークン規格とは何か?** -この規格は、代替性か非代替性かを問わず、あらゆる種類のトークンを表現し、管理できるスマートコントラクトのインターフェイスを開発するというシンプルな発想に基づいて策定されたものです。 このため、ERC-1155 規格に基づくトークンは、[ERC-20](/developers/docs/standards/tokens/erc-20/)および[ERC-721](/developers/docs/standards/tokens/erc-721/)トークンと同一の機能を提供し、この両方を同時に提供することすら可能です。 このため、ERC-20 および ERC-721 の両規格における機能や効率性が向上し、明らかな実装エラーを訂正することができます。 +この規格は、代替性か非代替性かを問わず、あらゆる種類のトークンを表現し、管理できるスマートコントラクトのインターフェイスを開発するというシンプルな発想に基づいて策定されたものです。 このため、ERC-1155規格に基づくトークンは、[ERC-20](/developers/docs/standards/tokens/erc-20/)および[ERC-721](/developers/docs/standards/tokens/erc-721/)トークンと同一の機能を提供し、この両方を同時に提供することすら可能です。 このため、ERC-20およびERC-721の両規格における機能や効率性が向上し、明らかな実装エラーを訂正することができます。 -ERC-1155 トークンの詳細な説明については、[EIP-1155](https://eips.ethereum.org/EIPS/eip-1155)を参照してください。 +ERC-1155トークンの詳細な説明については、[EIP-1155](https://eips.ethereum.org/EIPS/eip-1155)を参照してください。 ## 前提知識 {#prerequisites} このページをよく理解するには、まず[トークン規格](/developers/docs/standards/tokens/)、[ERC-20](/developers/docs/standards/tokens/erc-20/)、[ERC-721](/developers/docs/standards/tokens/erc-721/)について理解しておく必要があります。 -## ERC-1155 の機能と特長: {#body} +## ERC-1155の機能と特長: {#body} -- [バッチ転送](#batch-transfers):1 回の呼び出しで複数のアセットを転送します。 -- [バッチ残高](#batch-balance):1 回の呼び出しで、複数の資産の残高を取得します。 -- [バッチ承認](#batch-approval):ひとつのアドレスに対するすべてのトークンを承認します。 -- [フック](#recieve-hook):トークンのフックを受け取ります。 -- [NFT に対応](#nft-support):供給トークンの数が 1 の場合、NFT として扱います。 -- [安全な転送ルール](#safe-transfer-rule):セキュアな転送のためのルールセットです。 +- [バッチ転送](#batch_transfers):1回の呼び出しで複数のアセットを転送します。 +- [バッチ残高](#batch_balance):1回の呼び出しで、複数の資産の残高を取得します。 +- [バッチ承認](#batch_approval):ひとつのアドレスに対するすべてのトークンを承認します。 +- [フック](#recieve_hook):トークンのフックを受け取ります。 +- [NFTに対応](#nft_support):供給トークンの数が1の場合、NFTとして扱います。 +- [安全な転送ルール](#safe_transfer_rule):セキュアな転送のためのルールセットです。 ### バッチ転送 {#batch-transfers} -この規格におけるバッチ転送は、通常の ERC-20 の場合とほぼ同様です。 まず、通常の ERC-20 規格における`transferFrom`関数を確認しておきましょう: +この規格におけるバッチ転送は、通常のERC-20の場合とほぼ同様です。 まず、通常のERC-20規格における`transferFrom`関数を確認しておきましょう: ```solidity // ERC-20 @@ -45,17 +45,17 @@ function safeBatchTransferFrom( ) external; ``` -ERC-1155 における唯一の違いは、値を配列として渡し、さらに ID の配列も渡す点です。 例えば、`ids=[3, 6, 13]`、`values=[100, 200, 5]`と指定した場合、以下のような転送が実行されます。 +ERC-1155における唯一の違いは、値を配列として渡し、さらにIDの配列も渡す点です。 例えば、`ids=[3, 6, 13]`、`values=[100, 200, 5]`と指定した場合、以下のような転送が実行されます。 -1. id3 では、`_from`から`_to`に 100 トークンを転送。 -2. id6 では、`_from`から`_to`に 200 トークンを転送。 -3. id13 では、`_from`から`_to`に i5 トークンを転送。 +1. id3では、`_from`から`_to`に100トークンを転送。 +2. id6では、`_from`から`_to`に200トークンを転送。 +3. id13では、`_from`から`_to`にi5トークンを転送。 -ERC-1155 では、`transfer`は存在せず、`transferFrom`のみ利用できます。 通常の`transfer`のように使用するには、 関数を呼び出すアドレスを from address として設定すればよいです。 +ERC-1155では、`transfer`は存在せず、`transferFrom`のみ利用できます。 通常の`transfer`のように使用するには、 関数を呼び出すアドレスをfrom addressとして設定すればよいです。 ### バッチ残高 {#batch-balance} -同様に、ERC-20 における`balanceOf`の呼び出しも、バッチ処理に対応した機能が追加されています。 確認のために、まず ERC-20 の関数を見ておきましょう: +同様に、ERC-20における`balanceOf`の呼び出しも、バッチ処理に対応した機能が追加されています。 確認のために、まずERC-20の関数を見ておきましょう: ```solidity // ERC-20 @@ -68,7 +68,7 @@ function balanceOfBatch( ) external view returns (uint256[] memory); ``` -残高の呼び出しがよりシンプルになり、1 回の呼び出しで複数の残高を取得できるようになりました。 所有者の配列と、その後にトークン ID の配列を指定すればよいです。 +残高の呼び出しがよりシンプルになり、1回の呼び出しで複数の残高を取得できるようになりました。 所有者の配列と、その後にトークンIDの配列を指定すればよいです。 例えば、`_ids=[3, 6, 13]`と`_owners=[0xbeef..., 0x1337..., 0x111111...]`を与えると、戻り値は次のようになります: @@ -95,9 +95,9 @@ function isApprovedForAll( ) external view returns (bool); ``` -承認プロセスは、ERC-20 とは若干異なります。 特定の金額を承認するのではなく、`setApprovalForAll`の関数を通じて承認/非承認を決定するオペレーターを指定します。 +承認プロセスは、ERC-20とは若干異なります。 特定の金額を承認するのではなく、`setApprovalForAll`の関数を通じて承認/非承認を決定するオペレーターを指定します。 -`isApprovedForAll`の関数を使って、現在の承認状態を読み込むことができます。 推測されたとおり、これは All or Nothing 型の操作です。 承認するトークンの数やトークンの種類を指定することはできません。 +`isApprovedForAll`の関数を使って、現在の承認状態を読み込むことができます。 推測されたとおり、これはAll or Nothing型の操作です。 承認するトークンの数やトークンの種類を指定することはできません。 これは、シンプルさを実現するために敢えて採用された設計です。 ひとつのアドレスに対し、すべて承認することだけが可能です。 @@ -113,17 +113,17 @@ function onERC1155BatchReceived( ) external returns(bytes4); ``` -ERC-1155 は、[EIP-165](https://eips.ethereum.org/EIPS/eip-165)に対応しているため、スマートコントラクトに対する受信フックのみ対応しています。 このフック関数は、合い言葉として事前に定義された bytes4 の値(以下の形式を持つ)を返す必要があります。 +ERC-1155は、[EIP-165](https://eips.ethereum.org/EIPS/eip-165)に対応しているため、スマートコントラクトに対する受信フックのみ対応しています。 このフック関数は、合い言葉として事前に定義されたbytes4の値(以下の形式を持つ)を返す必要があります。 ```solidity bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)")) ``` -受信側のコントラクトがこの値を返すと、コントラクトがこの転送を受け入れ、ERC-1155 のトークンに対する処理方法を理解していると見なされます。 これにより、コントラクト内部で未処理のトークンが溜まっていくことがなくなります! +受信側のコントラクトがこの値を返すと、コントラクトがこの転送を受け入れ、ERC-1155のトークンに対する処理方法を理解していると見なされます。 これにより、コントラクト内部で未処理のトークンが溜まっていくことがなくなります! -### NFT のサポート {#nft-support} +### NFTのサポート {#nft-support} -供給されるトークンの数が 1 である場合、このトークンは事実上非代替性トークン(NFT)だと言えます。 ERC-721 規格と同じように、メタデータの URL を定義することが可能です。 この URL は、クライアントによる読み取り/変更が可能です。[こちら](https://eips.ethereum.org/EIPS/eip-1155#metadata)をご覧ください。 +供給されるトークンの数が1である場合、このトークンは事実上非代替性トークン(NFT)だと言えます。 ERC-721規格と同じように、メタデータのURLを定義することが可能です。 このURLは、クライアントによる読み取り/変更が可能です。[こちら](https://eips.ethereum.org/EIPS/eip-1155#metadata)をご覧ください。 ### 安全転送ルール {#safe-transfer-rule} @@ -131,7 +131,7 @@ bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],byt 1. 発信者は、`_from`のトークンを支払う行為に対して承認を受けているか、`_from`と同一でなければなりません。 2. 以下に該当する場合、転送の呼び出しは取り消されます: - 1. `_to`のアドレスが 0 である。 + 1. `_to`のアドレスが0である。 2. `_ids`の長さが`_values`の長さと一致しない。 3. `_ids`におけるトークン(複数可)の保有者(複数可)における残高(複数可)のいずれかが、受信者に送信された`_values`における当該の額(複数可)よりも少ない。 4. その他のエラーが発生した。 @@ -141,6 +141,6 @@ _注記_:フックを含むすべてのバッチ関数は、バッチ処理で ## 参考文献 {#further-reading} - [ERC-1155:マルチトークン規格](https://eips.ethereum.org/EIPS/eip-1155) -- [ERC-1155:Openzeppelin のドキュメンテーション](https://docs.openzeppelin.com/contracts/3.x/erc1155) -- [ERC-1155:GitHub リポジトリ](https://github.com/enjin/erc-1155) +- [ERC-1155:Openzeppelinのドキュメンテーション](https://docs.openzeppelin.com/contracts/3.x/erc1155) +- [ERC-1155:Githubリポジトリ](https://github.com/enjin/erc-1155) - [Alchemy NFT API](https://docs.alchemy.com/alchemy/enhanced-apis/nft-api) diff --git a/public/content/translations/ja/developers/docs/standards/tokens/erc-20/index.md b/public/content/translations/ja/developers/docs/standards/tokens/erc-20/index.md index fff0108d07a..e1bf5524ac2 100644 --- a/public/content/translations/ja/developers/docs/standards/tokens/erc-20/index.md +++ b/public/content/translations/ja/developers/docs/standards/tokens/erc-20/index.md @@ -15,14 +15,14 @@ lang: ja - 宝くじの券。 - 企業の株式などの金融資産。 - 米ドルをはじめとする法定通貨。 -- 金(ゴールド)1 オンス。 +- 金(ゴールド)1オンス。 - 等々。 -イーサリアムにおいてこれほどの威力を持つ機能に対しては、必然的に堅牢な規格が必要です。 これこそ、ERC-20 規格が果たすべき役割なのです! この規格を用いることで、イーサリアム外の製品やサービスと相互運用できるトークンアプリを構築することが可能になります。 +イーサリアムにおいてこれほどの威力を持つ機能に対しては、必然的に堅牢な規格が必要です。 これこそ、ERC-20規格が果たすべき役割なのです! この規格を用いることで、イーサリアム外の製品やサービスと相互運用できるトークンアプリを構築することが可能になります。 -**ERC-20 とは何か?** +**ERC-20とは何か?** -ERC-20 規格は、代替性トークンを扱うための標準規格です。つまりこの規格では、ひとつのトークンが、その種類および値において他のトークンとまったく同じであるというプロパティを持たせることができます。 例えば、ERC-20 トークンは ETH とまったく同様に動作します。つまり、1 トークンは、現在および将来において常に、他のひとつのトークンと同等になります。 +ERC-20規格は、代替性トークンを扱うための標準規格です。つまりこの規格では、ひとつのトークンが、その種類および値において他のトークンとまったく同じであるというプロパティを持たせることができます。 例えば、ERC-20トークンはETHとまったく同様に動作します。つまり、1トークンは、現在および将来において常に、他のひとつのトークンと同等になります。 ## 前提知識 {#prerequisites} @@ -32,16 +32,16 @@ ERC-20 規格は、代替性トークンを扱うための標準規格です。 ## 規格の概要 {#body} -ERC-20(Ethereum Request for Comments 20)は、スマートコントラクト内にトークン API として実装できるトークン規格として、ファビアン・ヴォゲルステラー氏により 2015 年 11 月に提案されました。 +ERC-20(Ethereum Request for Comments 20)は、スマートコントラクト内にトークンAPIとして実装できるトークン規格として、ファビアン・ヴォゲルステラー氏により2015年11月に提案されました。 -ERC-20 は、以下のような機能を提供します: +ERC-20は、以下のような機能を提供します: - トークンを、ひとつのアカウントから他のアカウントに転送する。 - アカウントにおける現在のトークン残高を取得する。 - ネットワーク上で利用可能なトークンの総供給量を取得する。 - 特定のアカウントにおけるトークンにつき、一定額をサードパーティのアカウントが使用できるか否かを承認する。 -以下のメソッドおよびイベントを実装しているスマートコントラクトは ERC-20 トークンコントラクトと呼ぶことができ、デプロイされると、イーサリアム上で発行されたトークンの状況を追跡する責任を負います。 +以下のメソッドおよびイベントを実装しているスマートコントラクトはERC-20トークンコントラクトと呼ぶことができ、デプロイされると、イーサリアム上で発行されたトークンの状況を追跡する責任を負います。 [EIP-20](https://eips.ethereum.org/EIPS/eip-20)から引用: @@ -59,7 +59,7 @@ function approve(address _spender, uint256 _value) public returns (bool success) function allowance(address _owner, address _spender) public view returns (uint256 remaining) ``` -### イベント {#events} +#### イベント {#events} ```solidity event Transfer(address indexed _from, address indexed _to, uint256 _value) @@ -68,11 +68,11 @@ event Approval(address indexed _owner, address indexed _spender, uint256 _value) ### 実例: {#web3py-example} -イーサリアムの ERC-20 トークンコントラクトのコードを詳しく見ることで、これらの規格がイーサリアムのシンプルさを保証する上でどれだけ重要なのかを理解しておきましょう。 ERC-20 トークンを扱うインターフェイスを開発するには、当該コントラクトのアプリケーション・バイナリー・インターフェイス(ABI)を用いればよいです。 理解しやすいように、以下では簡略化した ABI を用いています。 +イーサリアムのERC-20トークンコントラクトのコードを詳しく見ることで、これらの規格がイーサリアムのシンプルさを保証する上でどれだけ重要なのかを理解しておきましょう。 ERC-20トークンを扱うインターフェイスを開発するには、当該コントラクトのアプリケーション・バイナリー・インターフェイス(ABI)を用いればよいです。 理解しやすいように、以下では簡略化したABIを用いています。 #### Web3.py の実例: {#web3py-example} -まず、 Python のライブラリから[Web3.py](https://web3py.readthedocs.io/en/stable/quickstart.html#installation)をインストール済みであることを確認してください: +まず、 Pythonのライブラリから[Web3.py](https://web3py.readthedocs.io/en/stable/quickstart.html#installation)をインストール済みであることを確認してください: ``` pip install web3 @@ -143,6 +143,7 @@ print("Addr Balance:", addr_balance) ## 参考文献 {#further-reading} -- [EIP-20:ERC-20 トークン規格](https://eips.ethereum.org/EIPS/eip-20) +- [EIP-20:ERC-20トークン規格](https://eips.ethereum.org/EIPS/eip-20) - [OpenZeppelin - トークン](https://docs.openzeppelin.com/contracts/3.x/tokens#ERC20) -- [OpenZeppelin - ERC-20 の実装](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol) +- [OpenZeppelin - ERC-20の実装](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol) +- [Alchemy - SolidityにおけるERC20トークンのガイド](https://www.alchemy.com/overviews/erc20-solidity) diff --git a/public/content/translations/ja/developers/docs/standards/tokens/erc-4626/index.md b/public/content/translations/ja/developers/docs/standards/tokens/erc-4626/index.md index d3af1014cc6..e0c02c3dc55 100644 --- a/public/content/translations/ja/developers/docs/standards/tokens/erc-4626/index.md +++ b/public/content/translations/ja/developers/docs/standards/tokens/erc-4626/index.md @@ -6,21 +6,21 @@ lang: ja ## はじめに {#introduction} -ERC-4626 は、利回りボールトの技術的なパラメータを最適化し、統一するための規格です。 この規格は、ボールトに含まれる単一の ERC-20 トークンをどれだけ所有しているかを示すトークン化利回りボールトを作成するための標準 API を提供します。 ERC-4626 はさらに、ERC-20 に基づくトークン化ボールトのオプション拡張機能として、トークンの預入/引出および残高の読み取りといった基本的な機能を提供します。 +ERC-4626は、利回りボールトの技術的なパラメータを最適化し、統一するための規格です。 この規格は、ボールトに含まれる単一のERC-20トークンをどれだけ所有しているかを示すトークン化利回りボールトを作成するための標準APIを提供します。 ERC-4626はさらに、ERC-20に基づくトークン化ボールトのオプション拡張機能として、トークンの預入/引出および残高の読み取りといった基本的な機能を提供します。 -**利回りボールトにおける ERC-4626 の役割** +**利回りボールトにおけるERC-4626の役割** レンディング市場、アグリゲータ、および内部で利回りが得られるトークンは、ユーザーが様々な戦略を駆使して暗号資産トークンから最適な利回りを獲得する上で有益です。 これらの戦略はそれぞれがわずかな違いを持つため、エラーが発生しやすい場合や開発リソースを浪費してしまう場合があります。 -利回りボールトのデベロッパーは、ERC-4626 を活用することで、より一貫性が高く堅牢な実装パターンを実現できるため、アプリケーションとの統合にかかる作業を軽減し、様々なアプリケーションにおいて利回りを獲得できるようにするための別途の取り組みを削減することができます。 +利回りボールトのデベロッパーは、ERC-4626を活用することで、より一貫性が高く堅牢な実装パターンを実現できるため、アプリケーションとの統合にかかる作業を軽減し、様々なアプリケーションにおいて利回りを獲得できるようにするための別途の取り組みを削減することができます。 -ERC-4626 トークンの詳細については、[EIP-4626](https://eips.ethereum.org/EIPS/eip-4626)をご覧ください。 +ERC-4626トークンの詳細については、[EIP-4626](https://eips.ethereum.org/EIPS/eip-4626)をご覧ください。 ## 前提知識 {#prerequisites} この記事をよく理解するには、まず[トークン規格](/developers/docs/standards/tokens/)および[ERC-20](/developers/docs/standards/tokens/erc-20/)に目を通すことをおすすめします。 -## ERC-4626 の機能と特長: {#body} +## ERC-4626の機能と特長: {#body} ### メソッド {#methods} @@ -62,7 +62,7 @@ function convertToAssets(uint256 shares) public view returns (uint256 assets) function maxDeposit(address receiver) public view returns (uint256) ``` -この関数は、`receiver`が 1 回の[`deposit`](#deposit)呼び出しで入金できる原資産の上限を返します。 +この関数は、`receiver`が1回の[`deposit`](#deposit)呼び出しで入金できる原資産の上限を返します。 #### previewDeposit {#previewdeposit} @@ -110,7 +110,7 @@ function mint(uint256 shares, address receiver) public returns (uint256 assets) function maxWithdraw(address owner) public view returns (uint256) ``` -この関数は、1 回の[`withdraw`](#withdraw)呼び出しにより、`owner`残高から引き出し可能な原資産アセットの上限を返します。 +この関数は、1回の[`withdraw`](#withdraw)呼び出しにより、`owner`残高から引き出し可能な原資産アセットの上限を返します。 #### previewWithdraw {#previewwithdraw} @@ -204,4 +204,4 @@ event Withdraw( ## 参考文献 {#further-reading} - [EIP-4626: トークン化ボールト規格](https://eips.ethereum.org/EIPS/eip-4626) -- [ERC-4626: GitHub リポジトリ](https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol) +- [ERC-4626: GitHubリポジトリ](https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol) diff --git a/public/content/translations/ja/developers/docs/standards/tokens/erc-721/index.md b/public/content/translations/ja/developers/docs/standards/tokens/erc-721/index.md index b832109820d..6747d2bdcad 100644 --- a/public/content/translations/ja/developers/docs/standards/tokens/erc-721/index.md +++ b/public/content/translations/ja/developers/docs/standards/tokens/erc-721/index.md @@ -8,13 +8,13 @@ lang: ja **非代替性トークン(NFT)とは** -非代替性トークン(NFT)は、固有の方法で、人や物を識別するために使われます。 この種類のトークンは、収集用のアイテム、アクセスキー、宝くじ、コンサートやスポーツ試合におけるシート番号付チケットなどを発行するプラットフォームに最も適しています。 この特殊なタイプのトークンはすばらしい可能性を秘めているため、専用の規格として ERC-721 を策定しました。 +非代替性トークン(NFT)は、固有の方法で、人や物を識別するために使われます。 この種類のトークンは、収集用のアイテム、アクセスキー、宝くじ、コンサートやスポーツ試合におけるシート番号付チケットなどを発行するプラットフォームに最も適しています。 この特殊なタイプのトークンはすばらしい可能性を秘めているため、専用の規格としてERC-721を策定しました。 -**ERC-721 とは何か?** +**ERC-721とは何か?** -ERC-721 は、NFT に対する標準規格です。つまり、この種類のトークンはそれぞれがユニークな存在であり、発行日、希少性、および外見などの点で、同一のスマートコントラクトで発行される他のトークンとは異なる値を持つことができます。 外見が違うとはどういう意味でしょう? +ERC-721は、NFTに対する標準規格です。つまり、この種類のトークンはそれぞれがユニークな存在であり、発行日、希少性、および外見などの点で、同一のスマートコントラクトで発行される他のトークンとは異なる値を持つことができます。 外見が違うとはどういう意味でしょう? -はい! すべての NFT は、`tokenid`と呼ばれる`unit256`変数を持つため、ERC-721 を伴うコントラクトでは、`contract adress, unit 256 tokenid`のペアはグローバルに固有でなければなりません。 その上で、各 Dapp では、`tokenid`の入力から、ゾンビ、武器、スキル、あるいは可愛い子猫といったクールな画像を出力する「コンバーター」を搭載することができます。 +はい! すべてのNFTは、`tokenid`と呼ばれる`unit256`変数を持つため、ERC-721を伴うコントラクトでは、`contract adress, unit 256 tokenid`のペアはグローバルに固有でなければなりません。 その上で、各Dappでは、`tokenid`の入力から、ゾンビ、武器、スキル、あるいは可愛い子猫といったクールな画像を出力する「コンバーター」を搭載することができます。 ## 前提知識 {#prerequisites} @@ -24,11 +24,11 @@ ERC-721 は、NFT に対する標準規格です。つまり、この種類の ## 規格の概要 {#body} -ERC-721(Ethereum Request for Comments 721)は、ウィリアム・エントリケン氏、ディーター・シャーリー氏、ジェイコブ・エバンス氏、ナスタシア・サックス氏により 2018 年 1 月に提案された、スマートコントラクト内で非代替性トークン(NFT)を取り扱うための API を実装するための規格です。 +ERC-721(Ethereum Request for Comments 721)は、ウィリアム・エントリケン氏、ディーター・シャーリー氏、ジェイコブ・エバンス氏、ナスタシア・サックス氏により2018年1月に提案された、スマートコントラクト内で非代替性トークン(NFT)を取り扱うためのAPIを実装するための規格です。 この規格により、複数アカウント間のトークンの転送、アカウントにおける現在のトークン残高の取得、トークン所有者の取得、およびネットワーク上で供給されているトークン総数の取得といった機能が提供されます。 さらに、特定のアカウントが所有するトークン残高のうち、サードパーティのアカウントが転送可能な上限の設定を承認するなど、その他の機能も提供されています。 -以下のメソッドおよびイベントを実装したスマートコントラクトは ERC-721 非代替性トークン(NFT)コントラクトと呼ばれ、デプロイされると、イーサリアム上で作成されたトークンの状況を追跡する機能を提供します。 +以下のメソッドおよびイベントを実装したスマートコントラクトはERC-721非代替性トークン(NFT)コントラクトと呼ばれ、デプロイされると、イーサリアム上で作成されたトークンの状況を追跡する機能を提供します。 [EIP-721](https://eips.ethereum.org/EIPS/eip-721)から引用: @@ -56,11 +56,11 @@ ERC-721(Ethereum Request for Comments 721)は、ウィリアム・エント ### 例 {#web3py-example} -イーサリアムネットワークにおける ERC-721 トークンコントラクトを詳しく検討することで、ネットワークをシンプルにする上でこれらの規格がいかに重要であるかが理解できるでしょう。 ERC-721 トークンを対象とするインターフェイスを開発するには、コントラクトのアブリケーション・バイナリ・インターフェイス(ABI)があれば十分です。 これからつまずかないように簡略化された ABI を使用した例をお見せします。 +イーサリアムネットワークにおけるERC-721トークンコントラクトを詳しく検討することで、ネットワークをシンプルにする上でこれらの規格がいかに重要であるかが理解できるでしょう。 ERC-721トークンを対象とするインターフェイスを開発するには、コントラクトのアブリケーション・バイナリ・インターフェイス(ABI)があれば十分です。 これからつまずかないように簡略化されたABIを使用した例をお見せします。 -#### Web3.py の例 {#web3py-example} +#### Web3.pyの例 {#web3py-example} -最初に、 Python ライブラリの[Web3.py](https://web3py.readthedocs.io/en/stable/quickstart.html#installation)がインストールされていることを確認してください: +最初に、 Pythonライブラリの[Web3.py](https://web3py.readthedocs.io/en/stable/quickstart.html#installation)がインストールされていることを確認してください: ``` pip install web3 @@ -78,7 +78,7 @@ ck_token_addr = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d" # CryptoKitties acc_address = "0xb1690C08E213a35Ed9bAb7B318DE14420FB57d8C" # CryptoKitties Sales Auction # This is a simplified Contract Application Binary Interface (ABI) of an ERC-721 NFT Contract. -# これらのメソッドのみ提示します: balanceOf(address), name(), ownerOf(tokenId), symbol(), totalSupply() +# It will expose only the methods: balanceOf(address), name(), ownerOf(tokenId), symbol(), totalSupply() simplified_abi = [ { 'inputs': [{'internalType': 'address', 'name': 'owner', 'type': 'address'}], @@ -127,7 +127,7 @@ ck_extra_abi = [ } ] -ck_contract = w3.eth.contract(address=w3.toChecksumAddress(ck_token_addr), abi=simplified_abi+ck_extra_abi) +ck_contract = w3.eth.contract(address=w3.to_checksum_address(ck_token_addr), abi=simplified_abi+ck_extra_abi) name = ck_contract.functions.name().call() symbol = ck_contract.functions.symbol().call() kitties_auctions = ck_contract.functions.balanceOf(acc_address).call() @@ -136,7 +136,7 @@ print(f"{name} [{symbol}] NFTs in Auctions: {kitties_auctions}") pregnant_kitties = ck_contract.functions.pregnantKitties().call() print(f"{name} [{symbol}] NFTs Pregnants: {pregnant_kitties}") -# Transfer Event ABIを使用して、転送されたKittiesの情報を取得する。 +# Using the Transfer Event ABI to get info about transferred Kitties. tx_event_abi = { 'anonymous': False, 'inputs': [ @@ -148,28 +148,28 @@ tx_event_abi = { } # We need the event's signature to filter the logs -event_signature = w3.sha3(text="Transfer(address,address,uint256)").hex() +event_signature = w3.keccak(text="Transfer(address,address,uint256)").hex() -logs = w3.eth.getLogs({ - "fromBlock": w3.eth.blockNumber - 120, - "address": w3.toChecksumAddress(ck_token_addr), +logs = w3.eth.get_logs({ + "fromBlock": w3.eth.block_number - 120, + "address": w3.to_checksum_address(ck_token_addr), "topics": [event_signature] }) # Notes: -# - 120 blocks is the max range for CloudFlare Provider +# - Increase the number of blocks up from 120 if no Transfer event is returned. # - If you didn't find any Transfer event you can also try to get a tokenId at: # https://etherscan.io/address/0x06012c8cf97BEaD5deAe237070F9587f8E7A266d#events # Click to expand the event's logs and copy its "tokenId" argument - recent_tx = [get_event_data(w3.codec, tx_event_abi, log)["args"] for log in logs] -kitty_id = recent_tx[0]['tokenId'] # Paste the "tokenId" here from the link above -is_pregnant = ck_contract.functions.isPregnant(kitty_id).call() -print(f"{name} [{symbol}] NFTs {kitty_id} is pregnant: {is_pregnant}") +if recent_tx: + kitty_id = recent_tx[0]['tokenId'] # Paste the "tokenId" here from the link above + is_pregnant = ck_contract.functions.isPregnant(kitty_id).call() + print(f"{name} [{symbol}] NFTs {kitty_id} is pregnant: {is_pregnant}") ``` -CryptoKitties のコントラクトには、標準的なイベント以外にもいくつか興味深いイベントが含まれています。 +CryptoKittiesのコントラクトには、標準的なイベント以外にもいくつか興味深いイベントが含まれています。 特に、`Pregnant`と `Birth`のイベントについて見てみましょう。 @@ -200,15 +200,15 @@ ck_extra_events_abi = [ # We need the event's signature to filter the logs ck_event_signatures = [ - w3.sha3(text="Pregnant(address,uint256,uint256,uint256)").hex(), - w3.sha3(text="Birth(address,uint256,uint256,uint256,uint256)").hex(), + w3.keccak(text="Pregnant(address,uint256,uint256,uint256)").hex(), + w3.keccak(text="Birth(address,uint256,uint256,uint256,uint256)").hex(), ] # Here is a Pregnant Event: # - https://etherscan.io/tx/0xc97eb514a41004acc447ac9d0d6a27ea6da305ac8b877dff37e49db42e1f8cef#eventlog -pregnant_logs = w3.eth.getLogs({ - "fromBlock": w3.eth.blockNumber - 120, - "address": w3.toChecksumAddress(ck_token_addr), +pregnant_logs = w3.eth.get_logs({ + "fromBlock": w3.eth.block_number - 120, + "address": w3.to_checksum_address(ck_token_addr), "topics": [ck_event_signatures[0]] }) @@ -216,29 +216,29 @@ recent_pregnants = [get_event_data(w3.codec, ck_extra_events_abi[0], log)["args" # Here is a Birth Event: # - https://etherscan.io/tx/0x3978028e08a25bb4c44f7877eb3573b9644309c044bf087e335397f16356340a -birth_logs = w3.eth.getLogs({ - "fromBlock": w3.eth.blockNumber - 120, - "address": w3.toChecksumAddress(ck_token_addr), +birth_logs = w3.eth.get_logs({ + "fromBlock": w3.eth.block_number - 120, + "address": w3.to_checksum_address(ck_token_addr), "topics": [ck_event_signatures[1]] }) recent_births = [get_event_data(w3.codec, ck_extra_events_abi[1], log)["args"] for log in birth_logs] ``` -## 人気が高い NFT の実例: {#popular-nfts} +## 人気が高いNFTの実例: {#popular-nfts} -- [イーサスキャン NFT トラッカー](https://etherscan.io/tokens-nft)は、イーサリアムにおける NFT の取引量ランキングです。 +- [イーサスキャンNFTトラッカー](https://etherscan.io/tokens-nft)は、イーサリアムにおけるNFTの取引量ランキングです。 - [クリプトキティーズ](https://www.cryptokitties.co/)は、クリプトキティーと呼ばれる愛らしい生物を育て、収集するゲームです。 - [ソラーレ](https://sorare.com/)は、グローバルなファンタジーフットボールゲームで、限定アイテムの収集、チームの管理、および試合を通じて賞品を獲得できます。 - [ ENS(イーサリアムネームサービス)](https://ens.domains/)は、安全かつ分散型の方法により、ブロックチェーン内外のリソースにシンプルかつ人間が読み取り可能な名称を付与できるサービスです。 -- [POAP](https://poap.xyz)は、イベント参加や特定アクションの実行を行ったユーザーに対し、無料で NFT を提供できます。 POAP は自由に作成し、配布できます。 +- [POAP](https://poap.xyz)は、イベント参加や特定アクションの実行を行ったユーザーに対し、無料でNFTを提供できます。 POAPは自由に作成し、配布できます。 - [アンストッパブル・ドメインズ](https://unstoppabledomains.com/)は、 サンフランシスコに本社を置く企業で、ブロックチェーン上のドメイン作成業務を行っています。 ブロックチェーン上のドメインは、暗号通貨のアドレスを人間が読み取り可能な名称に置き換えるもので、ウェブサイトに検閲耐性を持たせるために使用できます。 -- [ゴッズ・アンチェインド・カード](https://godsunchained.com/)は、イーサリアムブロックチェーン上の TCG で、NFT を使ってゲーム内アセットに真の所有権を提供しています。 -- [ボアード・エイプ・ヨット・クラブ](https://boredapeyachtclub.com)は、10,000 個の固有 NFT のコレクションであると同時にいわゆるレアな美術作品であり、同クラブの会員証であるトークンでもあります。会員は、初回特典に加えて、コミュニティ活動を行うことでより多くの特典を受け取ることができます。 +- [ゴッズ・アンチェインド・カード](https://godsunchained.com/)は、イーサリアムブロックチェーン上のTCGで、NFTを使ってゲーム内アセットに真の所有権を提供しています。 +- [ボアード・エイプ・ヨット・クラブ](https://boredapeyachtclub.com)は、10,000個の固有NFTのコレクションであると同時にいわゆるレアな美術作品であり、同クラブの会員証であるトークンでもあります。会員は、初回特典に加えて、コミュニティ活動を行うことでより多くの特典を受け取ることができます。 ## 参考文献 {#further-reading} - [EIP-721:ERC-721 非代替性トークン(NFT)規格](https://eips.ethereum.org/EIPS/eip-721) -- [OpenZeppelin - ERC-721 のドキュメンテーション](https://docs.openzeppelin.com/contracts/3.x/erc721) -- [OpenZeppelin - ERC-721 の実装](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol) -- [Alchemy の NFT API](https://docs.alchemy.com/alchemy/enhanced-apis/nft-api) +- [OpenZeppelin - ERC-721のドキュメンテーション](https://docs.openzeppelin.com/contracts/3.x/erc721) +- [OpenZeppelin - ERC-721の実装](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol) +- [AlchemyのNFT API](https://docs.alchemy.com/alchemy/enhanced-apis/nft-api) diff --git a/public/content/translations/ja/developers/docs/standards/tokens/erc-777/index.md b/public/content/translations/ja/developers/docs/standards/tokens/erc-777/index.md index cc7c39678d6..0a9bcf1217f 100644 --- a/public/content/translations/ja/developers/docs/standards/tokens/erc-777/index.md +++ b/public/content/translations/ja/developers/docs/standards/tokens/erc-777/index.md @@ -6,19 +6,19 @@ lang: ja ## 警告 {#warning} -**ERC-777 は、[さまざまな手法の攻撃を受けやすいため](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2620)、適切な実装が困難です。 このため、[ERC-20](/developers/docs/standards/tokens/erc-20/)を使用することをおすすめします。**本ページは、歴史的なアーカイブとして掲載するものです。 +**ERC-777は、[さまざまな手法の攻撃を受けやすいため](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2620)、適切な実装が困難です。 このため、[ERC-20](/developers/docs/standards/tokens/erc-20/)を使用することをおすすめします。**本ページは、歴史的なアーカイブとして掲載するものです。 ## はじめに {#introduction} -ERC-777 は、既存の[ERC-20](/developers/docs/standards/tokens/erc-20/)規格を改善した代替性トークンの規格です。 +ERC-777は、既存の[ERC-20](/developers/docs/standards/tokens/erc-20/)規格を改善した代替性トークンの規格です。 ## 事前に必要な環境 {#prerequisites} 本ページの内容をよく理解するために、まず[ERC-20](/developers/docs/standards/tokens/erc-20/)に目を通すことをおすすめします。 -## ERC-777 は、ERC-20 に対してどのような改善を提案しているか? {#-erc-777-vs-erc-20} +## ERC-777は、ERC-20に対してどのような改善を提案しているか? {#-erc-777-vs-erc-20} -ERC-777 は、ERC-20 に対して以下の改善を提案します。 +ERC-777は、ERC-20に対して以下の改善を提案します。 ### フック {#hooks} @@ -29,16 +29,16 @@ ERC-777 は、ERC-20 に対して以下の改善を提案します。 #### フックの利点: {#why-are-hooks-great} 1. フックを用いることで、トークンをコントラクトに送信する作業とコントラクトに通知する作業をひとつのトランザクションにまとめることができます。[ERC-20](https://eips.ethereum.org/EIPS/eip-20)の場合、これには二重コール(`approve`/`transferFrom`)が必要になります。 -2. 登録フックを持たないコントラクトは、ERC-777 を利用できません。 受信コントラクトがフックを登録していない場合、送信コントラクトはトランザクションを中止します。 これにより、ERC-777 非互換のスマートコントラクトに対する誤転送を防ぐことができます。 +2. 登録フックを持たないコントラクトは、ERC-777を利用できません。 受信コントラクトがフックを登録していない場合、送信コントラクトはトランザクションを中止します。 これにより、ERC-777非互換のスマートコントラクトに対する誤転送を防ぐことができます。 3. フックは、トランザクションを却下することができます。 ### 通貨の最小単位 {#decimals} -ERC-777 はさらに、ERC-20 における`通貨の最小単位`に関する混乱を解消します。 この混乱を解消することで、デベロッパーの利用体験が向上します。 +ERC-777はさらに、ERC-20における`通貨の最小単位`に関する混乱を解消します。 この混乱を解消することで、デベロッパーの利用体験が向上します。 -### ERC-20 との後方互換性 {#backwards-compatibility-with-erc-20} +### ERC-20との後方互換性 {#backwards-compatibility-with-erc-20} -ERC-777 コントラクトとの間は、ERC-20 コントラクトに対する場合と同様のやりとりが可能です。 +ERC-777コントラクトとの間は、ERC-20コントラクトに対する場合と同様のやりとりが可能です。 ## 参考文献 {#further-reading} diff --git a/public/content/translations/ja/developers/docs/standards/tokens/index.md b/public/content/translations/ja/developers/docs/standards/tokens/index.md index b7ee386d2ed..882225b01a7 100644 --- a/public/content/translations/ja/developers/docs/standards/tokens/index.md +++ b/public/content/translations/ja/developers/docs/standards/tokens/index.md @@ -21,16 +21,18 @@ incomplete: true - [ERC-20](/developers/docs/standards/tokens/erc-20/) - 投票用やステーキング用のトークンあるいは仮想通貨など、代替性を持つ(相互に代替可能な)トークンを対象とする標準的なインターフェイスです。 - [ERC-721](/developers/docs/standards/tokens/erc-721/) - アートや楽曲に対する所有証明など、非代替性トークン (NFT) を対象とする標準的なインタフェースです。 - [ERC-777](/developers/docs/standards/tokens/erc-777/) - 通常のトークンに対して、トランザクションのプライバシー向上のためにミキサーコントラクトあるいは秘密鍵を紛失したユーザーを救済できる緊急復旧などの機能を追加できる規格です。 -- [ERC-1155](/developers/docs/standards/tokens/erc-1155/) - より効率的な取引や、トランザクションのバンドル化によるコスト軽減を実現できる規格です。 ユーティリティトークン($BNBや$BAT など)および非代替性トークン(CryptoPunks など)の両方に使用できます。 +- [ERC-1155](/developers/docs/standards/tokens/erc-1155/) - より効率的な取引や、トランザクションのバンドル化によるコスト軽減を実現できる規格です。 ユーティリティトークン($BNBや$BATなど)および非代替性トークン(CryptoPunksなど)の両方に使用できます。 - [ERC-4626](/developers/docs/standards/tokens/erc-4626/) - 利回りボールト(保管庫)における技術的なパラメータを最適化、統一することを目指して設計された、トークン化ボールト用の規格です。 +[ERC](https://eips.ethereum.org/erc)提案の全リスト + ## 参考文献 {#further-reading} -_役に立つコミュニティリソースをご存知の場合は、 このページを編集して追加してください。_ +_役に立ったコミュニティリソースがあれば、 ぜひこのページに追加してください。_ ## 関連トピック {#related-tutorials} - [トークンの統合作業に関するチェックリスト](/developers/tutorials/token-integration-checklist/) _– トークンのやりとりを統合する際に検討すべき事項が列挙されています。_ -- [ERC20 トークンを利用するスマートコントラクトを理解する](/developers/tutorials/understand-the-erc-20-token-smart-contract/) _- イーサリアムのテストネットワーク上ではじめてスマートコントラクトをデプロイする初心者向けの入門ガイドです。_ -- [Solidity のスマートコントラクトで ERC20 トークンを転送、承認する方法](/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/) _– Solidity 言語を用いてトークンのやりとりを行うスマートコントラクトを使用する方法について説明しています。_ -- [ERC721 マーケットの実装に関するハウツーガイド](/developers/tutorials/how-to-implement-an-erc721-market/) _– 分散型の掲示板でトークン化アイテムを出品する方法について説明しています。_ +- [ERC20トークンを利用するスマートコントラクトを理解する](/developers/tutorials/understand-the-erc-20-token-smart-contract/) _- イーサリアムのテストネットワーク上ではじめてスマートコントラクトをデプロイする初心者向けの入門ガイドです。_ +- [SolidityのスマートコントラクトでERC20トークンを転送、承認する方法](/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/) _– Solidity言語を用いてトークンのやりとりを行うスマートコントラクトを使用する方法について説明しています。_ +- [ERC721マーケットの実装に関するハウツーガイド](/developers/tutorials/how-to-implement-an-erc721-market/) _– 分散型の掲示板でトークン化アイテムを出品する方法について説明しています。_ diff --git a/public/content/translations/ja/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md b/public/content/translations/ja/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md index 2d925b2d5c5..66ad2b2d55f 100644 --- a/public/content/translations/ja/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md +++ b/public/content/translations/ja/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md @@ -16,18 +16,18 @@ sourceUrl: https://snakecharmers.ethereum.org/a-developers-guide-to-ethereum-pt- ## 前提条件(ソフト) {#soft-prerequisites} -この投稿は、幅広いデベロッパーに参照していただきたいと考えています。 [ Python ツール](/developers/docs/programming-languages/python/)を使用しますが、これらは概念を伝える手段にすぎませんので、Python デベロッパーでなくても問題ありません。 しかし、ここでは皆さんが Python についての知識があることを前提に話を進めますので、すぐにイーサリアムに特化した部分の説明に移ります。 +この投稿は、幅広いデベロッパーに参照していただきたいと考えています。 [ Pythonツール](/developers/docs/programming-languages/python/)を使用しますが、これらは概念を伝える手段にすぎませんので、Pythonデベロッパーでなくても問題ありません。 しかし、ここでは皆さんがPythonについての知識があることを前提に話を進めますので、すぐにイーサリアムに特化した部分の説明に移ります。 前提知識: -- ターミナルを使用できる -- Python で数行のコードを書いたことがある -- Python バージョン 3.6 以降がマシンにインストールされている([仮想環境](https://realpython.com/effective-python-environment/#virtual-environments)の使用を強くお勧めします) -- Python のパッケージインストーラーである`pip`を使用したことがある これらのうちあてはまらないものがある方、あるいはこの記事にあるコードを実行することがない方でも十分に理解できる内容です。 +- ターミナルを操作できる。 +- Pythonで数行のコードを書いたことがある。 +- Pythonバージョン3.6以降がマシンにインストールされている([仮想環境](https://realpython.com/effective-python-environment/#virtual-environments)の使用を強くお勧めします)。 +- Pythonのパッケージインストーラーである`pip`を使用したことがある。 これらのうちあてはまらないものがある方、あるいはこの記事にあるコードを実行することがない方でも十分に理解できる内容です。 ## ブロックチェーンについて {#blockchains-briefly} -イーサリアムを説明する方法はたくさんありますが、その中心となるのはブロックチェーンです。 ブロックチェーンは一連のブロックで構成されています。まずはその説明から始めましょう。 簡単に言うと、イーサリアムブロックチェーンの各ブロックは、数値などのメタデータとトランザクションのリストにすぎません。 JSON 形式では、次のようになります。 +イーサリアムを説明する方法はたくさんありますが、その中心となるのはブロックチェーンです。 ブロックチェーンは一連のブロックで構成されています。まずはその説明から始めましょう。 簡単に言うと、イーサリアムブロックチェーンの各ブロックは、数値などのメタデータとトランザクションのリストにすぎません。 JSON形式では、次のようになります。 ```json { @@ -41,7 +41,7 @@ sourceUrl: https://snakecharmers.ethereum.org/a-developers-guide-to-ethereum-pt- 各[ブロック](/developers/docs/blocks/)は、その前のブロックを参照します。`parentHash`は、単に前のブロックのハッシュ値です。 -注: イーサリアムはハッシュ関数を定期的に使用して、固定サイズの値(ハッシュ)を生成します。 イーサリアムではハッシュ値が重要な役割を果たしますが、今のところは固有のIDと考えておくとよいでしょう。 + ![ブロックチェーンと各ブロック内のデータを表す図](./blockchain-diagram.png) @@ -53,19 +53,19 @@ _ブロックチェーンは基本的にはリンクリストであり、各ブ ## 新しいパラダイム {#a-new-paradigm} -この新しい分散型技術スタックは、新しいデベロッパーツールを生み出しました。 このようなツールは多くのプログラミング言語に存在しますが、今回は Python を例にとって説明します。 繰り返しになりますが、Python 以外の言語をご使用の場合でも、内容を理解するのはそれほど難しいことではありません。 +この新しい分散型技術スタックは、新しいデベロッパーツールを生み出しました。 このようなツールは多くのプログラミング言語に存在しますが、今回はPythonを例にとって説明します。 繰り返しになりますが、Python以外の言語をご使用の場合でも、内容を理解するのはそれほど難しいことではありません。 -イーサリアムと対話する必要がある Python デベロッパーは、[Web3.py](https://web3py.readthedocs.io/)にアクセスしてください。 Web3.py は、イーサリアムノードへの接続と、そのノードとのデータの送受信を簡単に行えるようにするライブラリです。 +イーサリアムと対話する必要があるPythonデベロッパーは、[Web3.py](https://web3py.readthedocs.io/)にアクセスしてください。 Web3.pyは、イーサリアムノードへの接続と、そのノードとのデータの送受信を簡単に行えるようにするライブラリです。 -注: 「イーサリアムノード」と「イーサリアムクライアント」は同じ意味で使用されます。 どちらもイーサリアムネットワークの参加者が実行するソフトウェアを指します。 このソフトウェアは、ブロックデータの読み取り、新しいブロックがチェーンに追加されたときの更新データの受信、新しいトランザクションのブロードキャストなどを行います。 技術的には、クライアントはソフトウェアを意味し、ノードはソフトウェアを実行しているコンピュータを意味します。 + -[イーサリアムクライアント](/developers/docs/nodes-and-clients/) は、[プロセス間通信(IPC)](https://wikipedia.org/wiki/Inter-process_communication)、HTTP、または WebSocket で接続するように設定できるため、Web3.py でも同じ設定にする必要があります。 Web3.py は、これらの接続オプションを**プロバイダー**として参照します。 Web3.py インスタンスをノードに接続するために、3 つのプロバイダーのいずれかを選択する必要があります。 +[イーサリアムクライアント](/developers/docs/nodes-and-clients/) は、[プロセス間通信(IPC)](https://wikipedia.org/wiki/Inter-process_communication)、HTTP、またはWebSocketで接続するように設定できるため、Web3.pyでも同じ設定にする必要があります。 Web3.pyは、これらの接続オプションを**プロバイダー**として参照します。 Web3.pyインスタンスをノードに接続するために、3つのプロバイダーのいずれかを選択する必要があります。 ![Web3.pyがIPCを使用してアプリケーションをイーサリアムノードに接続する方法を表す図](./web3py-and-nodes.png) -_同じプロトコル(この図ではプロセス間通信(IPC))を介して通信するようにイーサリアムノードと Web3.py を設定します。_ +_同じプロトコル(この図ではプロセス間通信(IPC))を介して通信するようにイーサリアムノードとWeb3.pyを設定します。_ -Web3.py が正しく設定できたら、ブロックチェーンとの対話を開始できます。 参考までに、Web3.py の使用例をいくつか示します。 +Web3.pyが正しく設定できたら、ブロックチェーンとの対話を開始できます。 参考までに、Web3.pyの使用例をいくつか示します。 ```python # read block data: @@ -77,118 +77,120 @@ w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...}) ## インストール {#installation} -このチュートリアルでは、Python インタプリタ内で作業します。 ディレクトリ、ファイル、クラス、関数は作成しません。 +このチュートリアルでは、Pythonインタプリタ内で作業します。 ディレクトリ、ファイル、クラス、関数は作成しません。 -注: 以下の例では、「$」で始まるコマンドはターミナルで実行することを意味しています。 (「$」を入力しないでください。「$」は単に行の始まりを意味します。) + -まず、使いやすい環境となるように[IPython](https://ipython.org/)をインストールしてください。 IPython には、数ある機能の中でも特に便利なタブ補完機能があり、Web3.py での補完の候補を簡単に確認できます。 +まず、使いやすい環境となるように[IPython](https://ipython.org/)をインストールしてください。 IPythonには、数ある機能の中でも特に便利なタブ補完機能があり、Web3.pyでの補完の候補を簡単に確認できます。 ```bash -$ pip install ipython +pip install ipython ``` -Web3.py は`web3`という名前で公開されています。 次のようにしてインストールします。 +Web3.pyは`web3`という名前で公開されています。 次のようにしてインストールします。 ```bash -$ pip install web3 +pip install web3 ``` -あと 1 つ操作が必要です。後でブロックチェーンのシミュレーションを行いますが、それにはさらに数個の依存関係が必要となります。 それらは以下のコマンドでインストールできます。 +あと1つ操作が必要です。後でブロックチェーンのシミュレーションを行いますが、それにはさらに数個の依存関係が必要となります。 それらは以下のコマンドでインストールできます。 ```bash -$ pip install 'web3[tester]' +pip install 'web3[tester]' ``` これで準備完了です。 +注: `web3[tester]`パッケージは、Python 3.10.xxまで対応しています。 + ## サンドボックスの起動 {#spin-up-a-sandbox} -ターミナルで`ipython`を実行し、新しい Python 環境を開きます。 これは、`python`を実行することに相当しますが、より多くの機能を使用できます。 +ターミナルで`ipython`を実行し、新しいPython環境を開きます。 これは、`python`を実行するのと同じですが、より多くの機能を使用できます。 ```bash -$ ipython +ipython ``` -実行している Python と IPython のバージョンに関する情報が出力され、次のような入力待ちの状態になります。 +実行しているPythonとIPythonのバージョンに関する情報が出力され、次のような入力待ちの状態になります。 ```python In [1]: ``` -これは対話型の Python シェルであり、 実質的には、さまざまなものを実行できるサンドボックスです。 ここまで完了したら、いよいよ Web3.py をインポートします。 +これは対話型のPythonシェルであり、 実質的には、さまざまなものを実行できるサンドボックスです。 ここまで完了したら、いよいよWeb3.pyをインポートします。 ```python In [1]: from web3 import Web3 ``` -## Web3 モジュールの紹介 {#introducing-the-web3-module} +## Web3モジュールの紹介 {#introducing-the-web3-module} -[Web3](https://web3py.readthedocs.io/en/stable/overview.html#base-api)モジュールはイーサリアムへの入り口であるだけでなく、便利な関数も提供しています。 いくつか見ていきましょう。 +[Web3](https://web3py.readthedocs.io/en/stable/overview.html#base-api)モジュールは、イーサリアムへの入り口であるだけでなく、便利な関数も提供しています。 その一部をご紹介します。 -イーサリアムのアプリケーションでは、通常、通貨の単位を変換する必要があります。 Web3 のモジュールには、この変換のためだけの[fromWei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.fromWei)や[toWei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toWei)のようなヘルパーメソッドがあります。 +イーサリアムのアプリケーションでは、通常、通貨の単位を変換する必要があります。 Web3のモジュールには、この変換のためだけの[fromWei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.from_wei)や[toWei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.to_wei)のようなヘルパーメソッドがあります。 - + -好きな数字で wei と ETH(ether)を変換してみてください。 なお、ETH と wei の間には、[さまざまな単位の名称があります](https://web3py.readthedocs.io/en/stable/examples.html#converting-currency-denominations)。 その中でよく使われているのは **gwei**です。これは基本的に手数料を意味します。 +好きな数字でweiとETH(ether)を変換してみてください。 なお、ETHとweiの間には、[さまざまな単位の名称があります](https://web3py.readthedocs.io/en/stable/examples.html#converting-currency-denominations)。 その中でよく使われているのは、**gwei**です。これは基本的に手数料を意味します。 ```python -In [2]: Web3.toWei(1, 'ether') +In [2]: Web3.to_wei(1, 'ether') Out[2]: 1000000000000000000 -In [3]: Web3.fromWei(500000000, 'gwei') +In [3]: Web3.from_wei(500000000, 'gwei') Out[3]: Decimal('0.5') ``` -Web3 モジュールのその他のユーティリティメソッドとしては、データ形式のコンバータ(例: [`toHex`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toHex)) 、アドレスヘルパー(例: [`isAddress`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.isAddress)) 、ハッシュ関数(例: [`keccak`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.keccak))が挙げられます。 これらについては、この連載の後半で取り上げます。 利用可能なすべてのメソッドとプロパティを表示するには、`Web3.`と入力し、 ピリオドの後でタブキーを 2 回押して IPython の自動補完機能を利用してください。 +Web3モジュールのその他のユーティリティメソッドとしては、データ形式のコンバータ(例: [`toHex`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toHex)) 、アドレスヘルパー(例: [`isAddress`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.isAddress)) 、ハッシュ関数(例: [`keccak`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.keccak))が挙げられます。 これらについては、この連載の後半で取り上げます。 利用可能なすべてのメソッドとプロパティを表示するには、`Web3`と入力して、 ピリオドの後にタブキーを2回押してください。これにより、IPythonの自動補完機能が起動します。 ## チェーンとの通信 {#talk-to-the-chain} -便利な手法も素晴らしいですが、ブロックチェーンの話に移りましょう。 次のステップでは、Web3.py がイーサリアムノードと通信するように設定します。 ここでは、IPC、HTTP、または WebSocket プロバイダーを使用することができます。 +便利な手法も素晴らしいですが、ブロックチェーンの話に移りましょう。 次のステップでは、Web3.pyがイーサリアムノードと通信できるように設定します。 ここでは、IPC、HTTP、またはWebSocketプロバイダーを使用することができます。 -HTTP プロバイダーを使用した場合の完全なワークフローの例としては、次のようなものがあります(ここでは、この手順は実行しません)。 +HTTPプロバイダーを使用した場合の完全なワークフローの例としては、次のようなものがあります(ここでは、この手順は実行しません)。 - イーサリアムノード([Geth](https://geth.ethereum.org/)など)をダウンロードします。 -- 1 つのターミナルで Geth を起動し、ネットワークの同期を待ちます。 デフォルトの HTTP ポートは`8545`ですが、設定可能です。 -- 次のように`localhost:8545`で、Web3.py を使用して HTTP 経由でノードに接続します。 `w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))` +- 1つのターミナルでGethを起動し、ネットワークの同期を待ちます。 デフォルトのHTTPポートは`8545`ですが、設定可能です。 +- 次のように`localhost:8545`で、Web3.pyを使用してHTTP経由でノードに接続します。 `w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))` - `w3`インスタンスを使用してノードと対話します。 -これは「実際に行われている」方法ですが、同期プロセスには時間がかかるため、開発環境のみが必要な場合は不要です。 Web3.py は、開発環境のみが必要なデベロッパー向けに第 4 のプロバイダーとして**EthereumTesterProvider**を提供しています。 このテストプロバイダーは、制約の少ない権限が適用され、偽の通貨でさまざまなことを試せるようになっている、シミュレートされたイーサリアムノードにつながります。 +これは「実際に行われている」方法ですが、同期プロセスに時間がかかるため、開発環境でのみ使用する場合は不要です。 Web3.pyは、開発環境でのみ使用するデベロッパー向けに、第4のプロバイダーとして**EthereumTesterProvider**を提供しています。 このテストプロバイダーは、制約の少ない権限が適用された、偽の通貨でさまざまなことを試せるようになっている、シミュレートされたイーサリアムノードにつながります。 ![シミュレートされたイーサリアムノードにWeb3.pyアプリケーションをつなげるEthereumTesterProviderを表す図](./ethereumtesterprovider.png) -_EthereumTesterProvider はシミュレートされたノードに接続します。これは、簡単な開発環境で使用する場合に便利です。_ +_EthereumTesterProviderはシミュレートされたノードに接続します。これは、簡単な開発環境で使用する場合に便利です。_ -このシミュレートされたノードは[eth-tester](https://github.com/ethereum/eth-tester)と呼ばれ、前述の`pip install web3[tester]`コマンドでインストールされています。 以下のコマンドで、テストプロバイダーを使用するよう Web3.py を簡単に設定できます。 +このシミュレートされたノードは[eth-tester](https://github.com/ethereum/eth-tester)と呼ばれ、前述の`pip install web3[tester]`コマンドでインストールされています。 以下のコマンドで、テストプロバイダーを使用するようWeb3.pyを簡単に設定できます。 ```python In [4]: w3 = Web3(Web3.EthereumTesterProvider()) ``` -これで「チェーンサーフィン」をする準備ができました! そのような呼び方をする人はいないと思いますが、 そう呼ぶことにしました。 さあ、クイックツアーを始めましょう。 +これで「チェーンサーフィン」をする準備ができました。 そのような呼び方をする人はいないと思いますが、 そう呼ぶことにしました。 さあ、クイックツアーを始めましょう。 ## クイックツアー {#the-quick-tour} 最初に、正常に接続できているかサニティチェックをします。 ```python -In [5]: w3.isConnected() +In [5]: w3.is_connected() Out[5]: True ``` -テスタープロバイダーを使用しているため、これはあまり有用なテストではありませんが、失敗した場合は、`w3`変数をインスタンス化するときに間違った入力をした可能性があります。 内側の括弧、つまり`Web3.EthereumTesterProvider()`が含まれていることを再確認してください。 +テスタープロバイダーを使用しているため、このテストはあまり有用ではありません。失敗した場合は、`w3`変数をインスタンス化するときに入力ミスをした可能性があります。 内側の括弧、つまり`Web3.EthereumTesterProvider()`が含まれていることを再確認してください。 ## ツアー #1: [アカウント](/developers/docs/accounts/) {#tour-stop-1-accounts} -テスタープロバイダーでは便宜上、複数のアカウントが作成されており、テスト用の ETH が入金されています。 +テスタープロバイダーでは便宜上、複数のアカウントが作成されており、テスト用のETHが入金されています。 まず、これらのアカウントの一覧を表示しましょう。 @@ -199,23 +201,23 @@ Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...] ``` -このコマンドを実行すると、`0x`で始まる 10 個の文字列のリストが表示されます。 それぞれが**パブリックアドレス**であり、これらはある意味、当座預金の口座番号のようなものです。 あなた宛てに ETH を送金する人に、これらのアドレスを教えることになります。 +このコマンドを実行すると、`0x`で始まる10個の文字列のリストが表示されます。 それぞれが**パブリックアドレス**であり、これらはある意味、当座預金の口座番号のようなものです。 あなた宛てにETHを送金する人に、これらのアドレスを教えることになります。 -前述のとおり、テスタープロバイダーでは、これらの各アカウントにテスト用の ETH があらかじめ入金されています。 では、最初のアカウントにいくらあるかを調べてみましょう。 +前述のとおり、テスタープロバイダーでは、これらの各アカウントにテスト用のETHがあらかじめ入金されています。 では、最初のアカウントの残高を確認しましょう。 ```python In [7]: w3.eth.get_balance(w3.eth.accounts[0]) Out[7]: 1000000000000000000000000 ``` -なんとたくさんの 0 でしょうか! 満面の笑みで偽の銀行に駆け込む前に、前述した通貨の単位の説明を思い出してください。 ETH の値は、最小単位である wei で表されます。 ETH(ether)に変換すると次のようになります。 +この0の数を見てください! 満面の笑みで偽の銀行に駆け込む前に、前述した通貨の単位の説明を思い出してください。 ETHの値は、最小単位であるweiで表されます。 ETH(ether)に変換すると次のようになります。 ```python -In [8]: w3.fromWei(1000000000000000000000000, 'ether') +In [8]: w3.from_wei(1000000000000000000000000, 'ether') Out[8]: Decimal('1000000') ``` -テスト用とはいえ 100 万 ETH です。依然として素晴らしい額です。 +テスト用とはいえ、100万ETHは依然としてすごい額です。 ## ツアー #2: ブロックデータ {#tour-stop-2-block-data} @@ -234,19 +236,19 @@ Out[9]: AttributeDict({ ブロックに関する多くの情報が返されますが、いくつか注意すべき点があります。 -- テスタープロバイダーを設定した時期がいつであっても、ブロック番号はゼロになります。 実際のイーサリアムネットワーク(新しいブロックが 12 秒ごとに追加される)とは異なり、このシミュレーションは、作業を行うまで待機します。 +- テスタープロバイダーを設定した時期がいつであっても、ブロック番号はゼロになります。 実際のイーサリアムネットワーク(新しいブロックが12秒ごとに追加される)とは異なり、このシミュレーションは、作業を行うまで待機します。 - まだ何も作業を行っていないため、同じ理由で、`transactions`は空のリストになります。 最初のブロックは**空のブロック**であり、チェーンを開始するためだけに使用されています。 - `parentHash`は、単なる一連の空バイトである点に注意してください。 これは、**始まりのブロック**とも呼ばれる、チェーンの最初のブロックであることを意味します。 ## ツアー #3: [トランザクション](/developers/docs/transactions/) {#tour-stop-3-transactions} -保留中のトランザクションが存在するまで、ゼロのブロックで止まっているので、トランザクションを作成してみましょう。 あるアカウントから別のアカウントに、テスト用の ETH(ether)を少し送金します。 +保留中のトランザクションが存在するまで、ゼロのブロックで止まっているので、トランザクションを作成してみましょう。 あるアカウントから別のアカウントに、テスト用のETH(ether)を少し送金します。 ```python In [10]: tx_hash = w3.eth.send_transaction({ 'from': w3.eth.accounts[0], 'to': w3.eth.accounts[1], - 'value': w3.toWei(3, 'ether'), + 'value': w3.to_wei(3, 'ether'), 'gas': 21000 }) ``` @@ -272,9 +274,9 @@ Out[11]: AttributeDict({ }) ``` -`from`、`to`、`value`の各フィールドは、`send_transaction`呼び出し時の入力と一致しなければなりません。 このトランザクションが、ブロック番号 1 の最初のトランザクション(`'transactionIndex': 0`)として含まれていることを確認できることも心強い点です。 +`from`、`to`、`value`の各フィールドは、`send_transaction`呼び出し時の入力と一致しなければなりません。 このトランザクションが、ブロック番号1の最初のトランザクション(`'transactionIndex': 0`)として含まれていることを確認できることも心強い点です。 -さらに、関係する 2 つのアカウントの残高を確認することで、このトランザクションが成功していることを簡単に検証できます。 1 つ目のアカウントから 2 つ目のアカウントへ、3 ETH が移動しているはずです。 +さらに、関係する2つのアカウントの残高を確認することで、このトランザクションが成功していることを簡単に検証できます。 1つ目のアカウントから2つ目のアカウントへ、3 ETHが移動しているはずです。 ```python In [12]: w3.eth.get_balance(w3.eth.accounts[0]) @@ -284,12 +286,12 @@ In [13]: w3.eth.get_balance(w3.eth.accounts[1]) Out[13]: 1000003000000000000000000 ``` -2 つ目のアカウントの残高は正しいようですね! 残高が 1,000,000 ETH から 1,000,003 ETH になっています。 しかし、1 つ目のアカウントはどうなったのでしょうか? 3 ETH より少し多く減っているようです。 残念ながら、人生にはタダというものはなく、イーサリアムのパブリックネットワークを利用するには、そのサポート役であるピアに対価を支払う必要があります。 トランザクションを送信したアカウントから、少額のトランザクションフィーが差し引かれました。このフィーは、消費されたガスの量(ETH 送金では 21000 単位のガス)にベースフィーを掛けたものです。ベースフィーは、ネットワークのアクティビティに加えて、ブロック内にトランザクションを含めるバリデータに送信されるチップによって異なります。 +2つ目のアカウントの残高は、 1,000,000 ETHから1,000,003 ETHに増えているので、正しいようです。 1つ目のアカウントはどうなったのでしょうか? 3 ETHより少し多い金額が失われたようです。 残念ながら、人生にはタダというものはなく、イーサリアムのパブリックネットワークを利用するには、そのサポート役であるピアに対価を支払う必要があります。 トランザクションを送信したアカウントから、少額のトランザクションフィーが差し引かれました。このフィーは、消費されたガスの量(ETH送金では21000単位のガス)にベースフィーを掛けたものです。ベースフィーは、ネットワークのアクティビティに加えて、ブロック内にトランザクションを含めるバリデータに送信されるチップによって異なります。 [ガスの詳細](/developers/docs/gas/#post-london) -注: パブリックネットワークにおいてトランザクションフィーは、ネットワークの需要やどれだけ迅速にトランザクションを処理する必要があるのかによって変動します。 フィー(手数料)の計算方法の内訳に興味がある場合は、ブロックに含まれるトランザクションの仕組みに関する以前の投稿をご覧ください。 + ## ちょっと一息 {#and-breathe} -しばらく続けたので、ここで一息つきたいところです。 イーサリアムの世界はまだまだ続き、この連載の第 2 回へと探索は続きます。 今後のコンセプト: 実際のノードへの接続、スマートコントラクト、トークン。 質問はありますか? 教えてください! 皆様からのご意見は、今後の活動に反映させていきます。 [Twitter](https://twitter.com/wolovim)でリクエストを受け付けています。 +しばらく続けたので、ここで一息つきたいところです。 イーサリアムの世界はまだまだ広く、この連載の第2回ではさらに深く掘り下げていきます。 今後のコンセプトは、実際のノードへの接続、スマートコントラクト、トークンです。 何かご質問があれば、 ぜひお聞かせください。 皆様からのご意見は、今後の活動に反映させていきます。 [Twitter](https://twitter.com/wolovim)でリクエストを受け付けています。 diff --git a/public/content/translations/ja/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md b/public/content/translations/ja/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md index 7460be086cf..a9a4a97b6fb 100644 --- a/public/content/translations/ja/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md +++ b/public/content/translations/ja/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md @@ -16,25 +16,25 @@ sourceUrl: https://soliditydeveloper.com/max-contract-size ## 制限がある理由 {#why-is-there-a-limit} -[2016 年 11 月 22 日](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/)、Spurious Dragon のハードフォークで[EIP-170](https://eips.ethereum.org/EIPS/eip-170)が導入され、24.576 KB のスマートコントラクトのサイズ制限が追加されました。 Solidity デベロッパーにとって、これはコントラクトに機能をどんどん追加していくうちに、ある時点でサイズ制限に達し、デプロイした際に以下のエラーが表示されてしまうということを意味します。 +[2016年11月22日](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/)、Spurious Dragonのハードフォークで[EIP-170](https://eips.ethereum.org/EIPS/eip-170)が導入され、24.576 KBのスマートコントラクトのサイズ制限が追加されました。 Solidityデベロッパーにとって、これはコントラクトに機能をどんどん追加していくうちに、ある時点でサイズ制限に達し、デプロイした際に以下のエラーが表示されてしまうということを意味します。 `Warning: Contract code size exceeds 24576 bytes ( Spurious Dragonで追加された制限). This contract may not be deployable on Mainnet. オプティマイザを有効にすることを検討してください (効率的に実行されます!)、文字列の取り消しをオフにするか、ライブラリを使用します。` -この制限は、サービス拒否(DOS)攻撃を防ぐために導入されました。 コントラクトの呼び出しは、ガスの観点では比較的安価です。 しかし、イーサリアムノードのコントラクト呼び出しの影響は、(ディスクからのコードの読み込み、コードの前処理、マークルプルーフへのデータの追加の対象となる)呼び出されたコントラクトコードのサイズによっては、過度に増加することになります。 攻撃者がリソースをほとんど必要とせずに、他のノードでの大量の処理を生じさせるそうした状況では、DOS 攻撃を受ける可能性が常に存在します。 +この制限は、サービス拒否(DOS)攻撃を防ぐために導入されました。 コントラクトの呼び出しは、ガスの観点では比較的安価です。 しかし、イーサリアムノードのコントラクト呼び出しの影響は、(ディスクからのコードの読み込み、コードの前処理、マークルプルーフへのデータの追加の対象となる)呼び出されたコントラクトコードのサイズによっては、過度に増加することになります。 攻撃者がリソースをほとんど必要とせずに、他のノードでの大量の処理を生じさせるそうした状況では、DOS攻撃を受ける可能性が常に存在します。 -コントラクトコードの固有のサイズ制限が、ブロックのガスリミットとなるため、本来これは問題ではありませんでした。 コントラクトは、コントラクトのバイトコードをすべて含むトランザクション内でデプロイされる必要があることは言うまでもありません。 ブロックに 1 つのトランザクションのみを含めると、そのガスのすべてを使うことができますが、無限ではありません。 [ロンドンアップグレード](/history/#london)以降、ブロックのガスリミットは、ネットワークの需要に応じて 15M ~ 30M 間で変えられるようになりました。 +コントラクトコードの固有のサイズ制限が、ブロックのガスリミットとなるため、本来これは問題ではありませんでした。 コントラクトは、コントラクトのバイトコードをすべて含むトランザクション内でデプロイされる必要があることは言うまでもありません。 ブロックに1つのトランザクションのみを含めると、そのガスのすべてを使うことができますが、無限ではありません。 [ロンドンアップグレード](/history/#london)以降、ブロックのガスリミットは、ネットワークの需要に応じて15M~30M間で変えられるようになりました。 ## サイズ制限への対処 {#taking-on-the-fight} -残念ながら、コントラクトのバイトコードサイズを取得する簡単な方法はありません。 Truffle をご使用の場合は、サイズの取得に役立つ[truffle-contract-size](https://github.com/IoBuilders/truffle-contract-size)プラグインという素晴らしいツールがあります。 +残念ながら、コントラクトのバイトコードサイズを取得する簡単な方法はありません。 Truffleをご使用の場合は、サイズの取得に役立つ[truffle-contract-size](https://github.com/IoBuilders/truffle-contract-size)プラグインという素晴らしいツールがあります。 1. `npm install truffle-contract-size` -2. *truffle-config.js*にプラグインを追加します。`plugins: ["truffle-contract-size"]` +2. _truffle-config.js_にプラグインを追加します。`plugins: ["truffle-contract-size"]` 3. `truffle run contract-size`を実行します。 これにより、変更内容がコントラクトの合計サイズにどのような影響を与えているかを把握することができます。 -次に、いくつかの方法を、効果が大きいものから順に見ていきます。 減量の観点から考えてみましょう。 目標体重(この場合は 24 KB)を達成するための最良の戦略は、まず効果が大きい方法に集中して取り組むことです。 ほとんどの場合、食生活を改善するだけで解決しますが、もう少し何かが必要な場合もあります。 その場合は、運動(中程度の効果)やサプリメント(小さな効果)を加えるとよいでしょう。 +次に、いくつかの方法を、効果が大きいものから順に見ていきます。 減量の観点から考えてみましょう。 目標体重(この場合は24 KB)を達成するための最良の戦略は、まず効果が大きい方法に集中して取り組むことです。 ほとんどの場合、食生活を改善するだけで解決しますが、もう少し何かが必要な場合もあります。 その場合は、運動(中程度の効果)やサプリメント(小さな効果)を加えるとよいでしょう。 ## サイズ削減効果: 大 {#big-impact} @@ -48,7 +48,7 @@ sourceUrl: https://soliditydeveloper.com/max-contract-size ### ライブラリ {#libraries} -機能コードをストレージから移動させる簡単な方法としては、[ライブラリ](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#libraries)の使用が挙げられます。 コンパイル中に直接[コントラクトに追加](https://ethereum.stackexchange.com/questions/12975/are-internal-functions-in-libraries-not-covered-by-linking)されるので、ライブラリ関数を internal で宣言しないでください。 しかし、public 関数を使用する場合、それらは実際には別のライブラリコントラクトに含まれることになります。 ライブラリをより便利に利用するには、[using for](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#using-for)の使用を検討してください。 +機能コードをストレージから移動させる簡単な方法としては、[ライブラリ](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#libraries)の使用が挙げられます。 コンパイル中に直接[コントラクトに追加](https://ethereum.stackexchange.com/questions/12975/are-internal-functions-in-libraries-not-covered-by-linking)されるので、ライブラリ関数をinternalで宣言しないでください。 しかし、public関数を使用する場合、それらは実際には別のライブラリコントラクトに含まれることになります。 ライブラリをより便利に利用するには、[using for](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#using-for)の使用を検討してください。 ### プロキシ {#proxies} @@ -60,8 +60,8 @@ sourceUrl: https://soliditydeveloper.com/max-contract-size これは当然実行すべきことです。 関数はコントラクトサイズをかなり増大させます。 -- **external**: 利便性の理由から、多くの view 関数が頻繁に追加されます。 サイズ制限に達するまでは、追加してもかまいません。 その後で、絶対に必要なもの以外のすべての関数を削除することを真剣に検討します。 -- **internal**: internal 関数や private 関数を削除し、関数が一度だけ呼び出される場合に限り、コードを単にインライン化することもできます。 +- **external**: 利便性の理由から、多くのview関数が頻繁に追加されます。 サイズ制限に達するまでは、追加してもかまいません。 その後で、絶対に必要なもの以外のすべての関数を削除することを真剣に検討します。 +- **internal**: internal関数やprivate関数を削除し、関数が一度だけ呼び出される場合に限り、コードを単にインライン化することもできます。 ### 変数の追加を回避 {#avoid-additional-variables} @@ -95,9 +95,21 @@ require(msg.sender == owner, "Only the owner of this contract can call this func require(msg.sender == owner, "OW1"); ``` +### エラーメッセージのかわりにカスタムエラーを使用 + +[Solidity 0.8.4](https://blog.soliditylang.org/2021/04/21/custom-errors/)で、カスタムエラーが導入されました。 カスタムエラーは、コントラクトのサイズを削減するのに効果的な方法です。なぜなら、(関数と同様に)セレクターとしてABIエンコードされるためです。 + +```solidity +error Unauthorized(); + +if (msg.sender != owner) { + revert Unauthorized(); +} +``` + ### オプティマイザでの低い実行値を検討 {#consider-a-low-run-value-in-the-optimizer} -オプティマイザの設定も変更できます。 デフォルト値の 200 は、関数が 200 回呼び出される場合と同様にバイトコードの最適化を試みることを意味します。 これを 1 に変更すると、通常、各関数を 1 回だけ実行する場合のように最適化するようオプティマイザに指示することになります。 1 回だけの実行向けに最適化された関数は、それ自体のデプロイのために最適化されているということを意味します。 **1 に設定すると関数の実行にかかる[ガス代](/developers/docs/gas/)が高くなる**ことに注意してください。そのため、適していない場合があります。 +オプティマイザの設定も変更できます。 デフォルト値の200は、関数が200回呼び出される場合と同様にバイトコードを最適化しようとしていることを意味します。 これを1に変更すると、通常、各関数を1回だけ実行するケースに最適化するよう、オプティマイザに指示します。 1回だけ実行するように最適化された関数とは、その関数自体のデプロイのために最適化されていることを意味します。 ただし、**1に設定すると関数の実行にかかる[ガス代](/developers/docs/gas/)が高くなる**ことに注意してください。 ## サイズ削減効果: 小 {#small-impact} @@ -132,9 +144,9 @@ function _get(address addr1, address addr2) private view returns(address,address - 外部からのみ呼び出される関数や変数ですか? その場合は、`public`ではなく`external`として宣言します。 - コントラクト内からのみ呼び出される関数または変数ですか? その場合は、`public`ではなく`private`あるいは`internal`として宣言します。 -### modifier の削除 {#remove-modifiers} +### modifierの削除 {#remove-modifiers} -過剰に使用された場合、modifier 修飾子はコントラクトのサイズに大きな影響を与える可能性があります。 それらを削除して代わりに関数を使用することを検討してください。 +modifier修飾子を過剰に使用すると、コントラクトのサイズに大きな影響を与える可能性があります。 そのため、modifierの代わりに関数を使用することを検討してください。 ```solidity modifier checkStuff() {} @@ -148,4 +160,4 @@ function checkStuff() private {} function doSomething() { checkStuff(); } ``` -これらのヒントは、コントラクトのサイズを大幅に削減するのに役立ちます。 繰り返しになりますが、最大の効果を得るためには、可能な限りコントラクトを分割することが重要です。 +これらのヒントを実践することで、コントラクトのサイズを大幅に削減することができます。 繰り返しになりますが、最大の効果を得るためには、可能な限りコントラクトを分割することが重要です。 diff --git a/public/content/translations/ja/developers/tutorials/hello-world-smart-contract/index.md b/public/content/translations/ja/developers/tutorials/hello-world-smart-contract/index.md index a455a5528c8..f9e9836d280 100644 --- a/public/content/translations/ja/developers/tutorials/hello-world-smart-contract/index.md +++ b/public/content/translations/ja/developers/tutorials/hello-world-smart-contract/index.md @@ -13,21 +13,29 @@ lang: ja published: 2021-03-31 --- -このチュートリアルは、ブロックチェーンの開発が初めてで、どこから始めたらよいのか分からない場合や、 スマートコントラクトをデプロイしてやり取りする方法を理解したいだけの場合に、最適なガイドとなります。 このチュートリアルでは、仮想ウォレット([MetaMask](https://metamask.io/))、[Solidity](https://docs.soliditylang.org/en/v0.8.0/)、[Hardhat](https://hardhat.org/)、[Alchemy](https://alchemyapi.io/eth)を使用して、Goerli テストネットワーク上で簡単なスマートコントラクトを作成してデプロイする方法を順を追って説明します(現時点でしっかりと理解できていなくても、心配はご無用です。後ほど説明します)。 +このチュートリアルは、ブロックチェーンの開発が初めてで、どこから始めたらよいのか分からない場合や、 スマートコントラクトをデプロイしてやり取りする方法を理解したいだけの場合に、最適なガイドとなります。 このチュートリアルでは、仮想ウォレット([MetaMask](https://metamask.io/))、[Solidity](https://docs.soliditylang.org/en/v0.8.0/)、[Hardhat](https://hardhat.org/)、[Alchemy](https://alchemyapi.io/eth)を使用して、Goerliテストネットワーク上で簡単なスマートコントラクトを作成してデプロイする方法を順を追って説明します(現時点でしっかりと理解できていなくても、心配はご無用です。後ほど説明します)。 -このチュートリアルの[パート 2](https://docs.alchemy.com/docs/interacting-with-a-smart-contract)では、ここでデプロイしたスマートコントラクトとやり取りする方法について説明します。[パート 3](https://docs.alchemy.com/docs/submitting-your-smart-contract-to-etherscan)では、そのスマートコントラクトを Etherscan で公開する方法について説明します。 +> **警告** +> +> 🚧 非推奨の通知 +> +> このガイドでは、Goerliテストネットワークをスマートコントラクトの作成とデプロイに使用しています。 ただし、イーサリアム・ファウンデーションにより、[Goerliが間もなく廃止予定](https://www.alchemy.com/blog/goerli-faucet-deprecation)であることが発表されました。 +> +> このチュートリアルでは、[Sepolia](https://www.alchemy.com/overviews/sepolia-testnet)および[Sepoliaフォーセット](https://sepoliafaucet.com/)の利用を推奨します。 + +このチュートリアルの[パート2](https://docs.alchemy.com/docs/interacting-with-a-smart-contract)では、ここでデプロイしたスマートコントラクトとやり取りする方法について説明します。[パート3](https://docs.alchemy.com/docs/submitting-your-smart-contract-to-etherscan)では、そのスマートコントラクトをEtherscanで公開する方法について説明します。 質問がある場合は、いつでも[Alchemy Discord](https://discord.gg/gWuC7zB)でお問い合わせください。 -## ステップ 1: イーサリアムネットワークに接続する {#step-1} +## ステップ1: イーサリアムネットワークに接続する {#step-1} -イーサリアムチェーンにリクエストを行う方法はたくさんあります。 簡略化のため、ここでは Alchemy の無料アカウントを使用します。これは独自のノードを実行することなく、イーサリアムチェーンとの通信を可能にするブロックチェーンのデベロッパープラットフォームと API です。 このプラットフォームには、スマートコントラクトのデプロイメントにおいて内部で何が起こっているのかを把握するためにこのチュートリアルで利用する、監視と分析のためのデベロッパーツールも備わっています。 Alchemy のアカウントをお持ちでない場合は、[こちら](https://dashboard.alchemyapi.io/signup)から無料で登録できます。 +イーサリアムチェーンにリクエストを行う方法はたくさんあります。 簡略化のため、ここではAlchemyの無料アカウントを使用します。これは独自のノードを実行することなく、イーサリアムチェーンとの通信を可能にするブロックチェーンのデベロッパープラットフォームとAPIです。 このプラットフォームには、スマートコントラクトのデプロイメントにおいて内部で何が起こっているのかを把握するためにこのチュートリアルで利用する、監視と分析のためのデベロッパーツールも備わっています。 Alchemyのアカウントをお持ちでない場合は、[こちら](https://dashboard.alchemyapi.io/signup)から無料で登録できます。 -## ステップ 2: アプリ(および API キー)を作成する {#step-2} +## ステップ2: アプリ(およびAPI キー)を作成する {#step-2} -Alchemy のアカウントを作成すると、アプリを作成することで API キーを生成できるようになります。 これにより、Goerli テストネットワークへのリクエストが可能になります。 テストネットに詳しくない場合は、[こちらのページ](/developers/docs/networks/)をご覧ください。 +Alchemyのアカウントを作成すると、アプリを作成することでAPIキーを生成できるようになります。 これにより、Goerliテストネットワークへのリクエストが可能になります。 テストネットに詳しくない場合は、[こちらのページ](/developers/docs/networks/)をご覧ください。 -1. ナビゲーションバーの「Apps」にマウスを合わせて、「Create App」をクリックし、Alchemy ダッシュボードの「Create App」ページに移動してください。 +1. ナビゲーションバーの「Apps」にマウスを合わせて、「Create App」をクリックし、Alchemyダッシュボードの「Create App」ページに移動してください。 ![Hello WorldのCreate App](./hello-world-create-app.png) @@ -37,31 +45,31 @@ Alchemy のアカウントを作成すると、アプリを作成することで 3. 「Create app」をクリックして完了です。 アプリが下の表に表示されます。 -## ステップ 3: イーサリアムアカウント(アドレス)を作成する {#step-3} +## ステップ3: イーサリアムアカウント(アドレス)を作成する {#step-3} -トランザクションの送受信には、イーサリアムアカウントが必要です。 このチュートリアルでは、イーサリアムアカウントアドレスを管理するためにブラウザの仮想ウォレットである Metamask を使用します。 [トランザクション](/developers/docs/transactions/)の詳細。 +トランザクションの送受信には、イーサリアムアカウントが必要です。 このチュートリアルでは、イーサリアムアカウントアドレスを管理するためにブラウザの仮想ウォレットであるMetamaskを使用します。 [トランザクション](/developers/docs/transactions/)の詳細。 -Metamask のアカウントは[こちら](https://metamask.io/download.html)から無料でダウンロード、作成できます。 アカウントを作成後、またはすでにアカウントをお持ちの場合は(実際に支払いが発生しないように)右上の「Goerli Test Network」に切り替えてください。 +Metamaskのアカウントは[こちら](https://metamask.io/download.html)から無料でダウンロード、作成できます。 アカウントを作成後、またはすでにアカウントをお持ちの場合は(実際に支払いが発生しないように)右上の「Goerli Test Network」に切り替えてください。 ![MetaMask Ropstenの例](./metamask-ropsten-example.png) -## ステップ 4: フォーセットからイーサ(ETH)を追加する {#step-4} +## ステップ4: フォーセットからイーサ(ETH)を追加する {#step-4} -テストネットワークにスマートコントラクトをデプロイするには、偽の ETH が必要になります。 ETH を取得するには、[Goerli フォーセット](https://goerlifaucet.com/)にアクセスし、Alchemy アカウントでログインしてウォレットアドレスを入力し、「Send Me ETH」をクリックしてください。 ネットワークトラフィックのために偽の ETH を受け取るのに時間がかかる場合があります。 (この記事の執筆時点では、30 分ほどかかりました。) MetaMask アカウントに ETH が表示されるはずです! +テストネットワークにスマートコントラクトをデプロイするには、偽のETHが必要になります。 ETHを取得するには、[Goerliフォーセット](https://goerlifaucet.com/)にアクセスし、Alchemyアカウントでログインしてウォレットアドレスを入力し、「Send Me ETH」をクリックしてください。 ネットワークトラフィックのために偽のETHを受け取るのに時間がかかる場合があります。 (この記事の執筆時点では、30分ほどかかりました。) MetaMaskアカウントにETHが表示されるはずです! -## ステップ 5: 残高を確認する {#step-5} +## ステップ5: 残高を確認する {#step-5} -残高を再確認するために、[eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance)を[Alchemy のコンポーザーツール](https://composer.alchemyapi.io?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D)を使用してリクエストしてみましょう。 このリクエストをすると、ウォレット内の ETH の額が返されます。 MetaMask アカウントアドレスを入力して「Send Request」をクリックすると、次のようなレスポンスが表示されます。 +残高を再確認するために、[eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance)を[Alchemyのコンポーザーツール](https://composer.alchemyapi.io?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D)を使用してリクエストしてみましょう。 このリクエストをすると、ウォレット内のETHの額が返されます。 MetaMaskアカウントアドレスを入力して「Send Request」をクリックすると、次のようなレスポンスが表示されます。 ```json { "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" } ``` -> **注:** この結果の単位は、ETH ではなく wei です。 wei は ETH の最小単位として使われています。 wei から ETH へ変換すると、1 eth = 1018 wei になります。 つまり、0x2B5E3AF16B1880000 を 10 進数に変換すると、5\*10¹⁸ となり、5 ETH に相当します。 -> +> **注:** この結果の単位は、ETHではなくweiです。 weiはETHの最小単位として使われています。 weiからETHへ変換すると、1 eth = 1018 weiになります。 つまり、0x2B5E3AF16B1880000を10進数に変換すると、5\*10¹⁸となり、5 ETHに相当します。 +> > ご安心ください。 偽のお金はすべてそこにあります。 -## ステップ 6: プロジェクトを初期化する {#step-6} +## ステップ6: プロジェクトを初期化する {#step-6} まず、プロジェクトのフォルダを作成する必要があります。 コマンドラインに移動し、次のように入力します。 @@ -70,7 +78,7 @@ mkdir hello-world cd hello-world ``` -プロジェクトフォルダ内に入ったら、`npm init`を使用してプロジェクトを初期化します。 まだ npm がインストールされていない場合は、[こちらの手順](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm)に従ってください(Node.js も必要となりますので、こちらもダウンロードしてください。) +プロジェクトフォルダ内に入ったら、`npm init`を使用してプロジェクトを初期化します。 まだnpmがインストールされていない場合は、[こちらの手順](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm)に従ってください(Node.jsも必要となりますので、こちらもダウンロードしてください。) ``` npm init @@ -103,11 +111,11 @@ About to write to /Users/.../.../.../hello-world/package.json: } ``` -package.json を承認すれば完了です。 +package.jsonを承認すれば完了です。 -## ステップ 7: [Hardhat](https://hardhat.org/getting-started/#overview)をダウンロードする {#step-7} +## ステップ7: [Hardhat](https://hardhat.org/getting-started/#overview)をダウンロードする {#step-7} -Hardhat は、イーサリアムのソフトウェアをコンパイル、デプロイ、テスト、デバッグするための開発環境です。 デベロッパーがライブチェーンにデプロイする前に、スマートコントラクトや分散型アプリケーション(Dapp)をローカルに構築する際に役立ちます。 +Hardhatは、イーサリアムのソフトウェアをコンパイル、デプロイ、テスト、デバッグするための開発環境です。 デベロッパーがライブチェーンにデプロイする前に、スマートコントラクトや分散型アプリケーション(Dapp)をローカルに構築する際に役立ちます。 先ほど作成した`hello-world`プロジェクト内で、以下を実行します。 @@ -117,7 +125,7 @@ npm install --save-dev hardhat [インストール手順](https://hardhat.org/getting-started/#overview)の詳細については、こちらのページをご覧ください。 -## ステップ 8: Hardhat プロジェクトを作成する {#step-8} +## ステップ8: Hardhatプロジェクトを作成する {#step-8} プロジェクトフォルダ内で以下を実行します。 @@ -145,28 +153,28 @@ Create a sample project Quit ``` -`hardhat.config.js`ファイルが生成されます。このファイルでプロジェクトのすべての設定を行います(ステップ 13 で行います)。 +`hardhat.config.js`ファイルが生成されます。このファイルでプロジェクトのすべての設定を行います(ステップ13で行います)。 -## ステップ 9: プロジェクトフォルダを追加する {#step-9} +## ステップ9: プロジェクトフォルダを追加する {#step-9} -プロジェクトを整理するために、2 つの新しいフォルダを作成します。 コマンドラインでプロジェクトのルートディレクトリに移動し、次のように入力します。 +プロジェクトを整理するために、2つの新しいフォルダを作成します。 コマンドラインでプロジェクトのルートディレクトリに移動し、次のように入力します。 ``` mkdir contracts mkdir scripts ``` -- `contracts/`は、Hello World スマートコントラクトのコードファイルを格納する場所です。 +- `contracts/`は、Hello Worldスマートコントラクトのコードファイルを格納する場所です。 - `scripts/`は、コントラクトをデプロイして対話するスクリプトを保持する場所です。 -## ステップ 10: コントラクトを作成する {#step-10} +## ステップ10: コントラクトを作成する {#step-10} -一体いつになったらコードを書くのだろうと疑問をお持ちではないでしょうか 。 このステップ 10 でコードを書いていきましょう。 +一体いつになったらコードを書くのだろうと疑問をお持ちではないでしょうか 。 このステップ10でコードを書いていきましょう。 -お気に入りのエディタで hello-world プロジェクトを開きます(通常は[VScode](https://code.visualstudio.com/)を使用しています)。 スマートコントラクトは、Solidity と呼ばれる言語で記述されています。HelloWorld.sol スマートコントラクトの作成にこの言語を使用します。 +お気に入りのエディタでhello-worldプロジェクトを開きます(通常は[VScode](https://code.visualstudio.com/)を使用しています)。 スマートコントラクトは、Solidityと呼ばれる言語で記述されています。HelloWorld.solスマートコントラクトの作成にこの言語を使用します。 -1. 「contracts」フォルダに移動し、HelloWorld.sol という名前の新規ファイルを作成します。 -2. 以下は、このチュートリアルで使用するイーサリアム・ファウンデーションの Hello World スマートコントラクトのサンプルです。 以下の内容をコピーして、HelloWorld.sol ファイルに貼り付けます。コメントを読んで、このコントラクトが何を行うのかを理解してください。 +1. 「contracts」フォルダに移動し、HelloWorld.solという名前の新規ファイルを作成します。 +2. 以下は、このチュートリアルで使用するイーサリアム・ファウンデーションのHello Worldスマートコントラクトのサンプルです。 以下の内容をコピーして、HelloWorld.solファイルに貼り付けます。コメントを読んで、このコントラクトが何を行うのかを理解してください。 ```solidity // Specifies the version of Solidity, using semantic versioning. @@ -198,28 +206,28 @@ contract HelloWorld { これは、作成時にメッセージを保存し、`update`関数を呼び出すことで更新できる非常にシンプルなスマートコントラクトです。 -## ステップ 11: MetaMask と Alchemy をプロジェクトに接続する {#step-11} +## ステップ11: MetaMaskとAlchemyをプロジェクトに接続する {#step-11} -ここまでで、MetaMask ウォレットと Alchemy アカウントを作成し、スマートコントラクトも作成しました。次はこの 3 つを接続しましょう。 +ここまでで、MetaMaskウォレットとAlchemyアカウントを作成し、スマートコントラクトも作成しました。次はこの3つを接続しましょう。 -仮想ウォレットから送信されるすべてのトランザクションには、固有の秘密鍵を使用した署名が必要です。 この権限をプログラムに提供するため、秘密鍵(および Alchemy API キー)を環境ファイルに安全に保存できます。 +仮想ウォレットから送信されるすべてのトランザクションには、固有の秘密鍵を使用した署名が必要です。 この権限をプログラムに提供するため、秘密鍵(およびAlchemy APIキー)を環境ファイルに安全に保存できます。 -> トランザクションの送信の詳細については、web3 を使用したトランザクションの送信についての[こちらのチュートリアル](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)をご覧ください。 +> トランザクションの送信の詳細については、web3を使用したトランザクションの送信に関する[こちらのチュートリアル](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)をご覧ください。 -まず、プロジェクトディレクトリに dotenv パッケージをインストールします。 +まず、プロジェクトディレクトリにdotenvパッケージをインストールします。 ``` npm install dotenv --save ``` -次に、 `.env`ファイルをプロジェクトのルートディレクトリに作成し、そのファイルに Metamask の秘密鍵と HTTP Alchemy API の URL を追加します。 +次に、 `.env`ファイルをプロジェクトのルートディレクトリに作成し、そのファイルにMetamaskの秘密鍵とHTTP Alchemy APIのURLを追加します。 - 秘密鍵をエクスポートするには、[こちらの手順](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key)に従ってください。 -- HTTP Alchemy API の URL を取得するには、以下を参照してください。 +- HTTP Alchemy APIのURLを取得するには、以下を参照してください。 ![Alchemy APIキーの取得](./get-alchemy-api-key.gif) -Alchemy API の URL をコピーします。 +Alchemy APIのURLをコピーします。 `.env`ファイルは次のようになります。 @@ -228,17 +236,17 @@ API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" PRIVATE_KEY = "your-metamask-private-key" ``` -これらの変数を実際にコードに接続するために、ステップ 13 でこれらの変数を`hardhat.config.js`ファイル内で参照します。 +これらの変数を実際にコードに接続するために、ステップ13でこれらの変数を`hardhat.config.js`ファイル内で参照します。 - + .envファイルをコミットしないでください! .envファイルを誰かと共有したり公開したりしないようにしてください。秘密が漏洩する可能性があります。 バージョン管理ツールを使用している場合は、.envgitignoreファイルに追加します。 -## ステップ 12: Ethers.js をインストールする {#step-12-install-ethersjs} +## ステップ12: Ethers.jsをインストールする {#step-12-install-ethersjs} -Ethers.js は、よりユーザーフレンドリーなメソッドで[標準の JSON-RPC メソッド](/developers/docs/apis/json-rpc/)をラップすることにより、イーサリアムとの対話やリクエストを簡単にするライブラリです。 +Ethers.jsは、よりユーザーフレンドリーなメソッドで[標準のJSON-RPCメソッド](/developers/docs/apis/json-rpc/)をラップすることにより、イーサリアムとの対話やリクエストを簡単にするライブラリです。 -Hardhat は、追加のツールと拡張機能のための[プラグイン](https://hardhat.org/plugins/)の統合を非常に簡単にしてくれます。 コントラクトのデプロイメントに[Ethers プラグイン](https://hardhat.org/plugins/nomiclabs-hardhat-ethers.html)を利用します([Ethers.js](https://github.com/ethers-io/ethers.js/)には、複数の非常にクリーンなコントラクトのデプロイメント方法があります)。 +Hardhatは、追加のツールと拡張機能のための[プラグイン](https://hardhat.org/plugins/)の統合を非常に簡単にしてくれます。 コントラクトのデプロイメントに[Ethersプラグイン](https://hardhat.org/plugins/nomiclabs-hardhat-ethers.html)を利用します([Ethers.js](https://github.com/ethers-io/ethers.js/)には、複数の非常にクリーンなコントラクトのデプロイメント方法があります)。 プロジェクトのホームディレクトリで以下を実行します。 @@ -246,9 +254,9 @@ Hardhat は、追加のツールと拡張機能のための[プラグイン](htt npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0" ``` -次のステップの`hardhat.config.js`でも Ethers(.js)が必要になります。 +次のステップの`hardhat.config.js`でもEthers(.js)が必要になります。 -## ステップ 13: hardhat.config.js を更新する {#step-13-update-hardhatconfigjs} +## ステップ13: hardhat.config.jsを更新する {#step-13-update-hardhatconfigjs} ここまでで、いくつかの依存関係とプラグインを追加しました。次に、`hardhat.config.js`を更新して、プロジェクトがそれらすべてについて認識できるようにする必要があります。 @@ -276,9 +284,9 @@ module.exports = { } ``` -## ステップ 14: コントラクトをコンパイルする {#step-14-compile-our-contracts} +## ステップ14: コントラクトをコンパイルする {#step-14-compile-our-contracts} -ここまででしっかりと動作していることを確認するため、コントラクトをコンパイルしてみましょう。 `compile`タスクは、組み込みの Hardhat タスクの 1 つです。 +ここまででしっかりと動作していることを確認するため、コントラクトをコンパイルしてみましょう。 `compile`タスクは、組み込みのHardhatタスクの1つです。 コマンドラインで以下を実行します。 @@ -288,7 +296,7 @@ npx hardhat compile `SPDX license identifier not provided in source file`という警告が表示される場合がありますが、心配する必要はありません。警告が表示されないのがベストですが、 表示された場合は、いつでも[Alchemy discord](https://discord.gg/u72VCg3)でメッセージを送信できます。 -## ステップ 15: デプロイスクリプトを書く {#step-15-write-our-deploy-scripts} +## ステップ15: デプロイスクリプトを書く {#step-15-write-our-deploy-scripts} コントラクトの作成と設定ファイルの作成が完了したら、いよいよコントラクトのデプロイのためのスクリプトを作成します。 @@ -310,13 +318,13 @@ main() }); ``` -Hardhat がコードの各行で行っている驚くべき内容については、Hardhat の[コントラクトチュートリアル](https://hardhat.org/tutorial/testing-contracts.html#writing-tests)で説明されています。以下では、その説明を採用しています。 +Hardhatがコードの各行で行っている驚くべき内容については、Hardhatの[コントラクトチュートリアル](https://hardhat.org/tutorial/testing-contracts.html#writing-tests)で説明されています。以下では、その説明を採用しています。 ``` const HelloWorld = await ethers.getContractFactory("HelloWorld"); ``` -ethers.js の`ContractFactory`は新しいスマートコントラクトをデプロイするための抽象化であり、ここでの`HelloWorld`は hello world コントラクトのインスタンスのためのファクトリです。 `hardhat-ethers`プラグインを使用する場合、`ContractFactory`および`Contract`インスタンスはデフォルトで最初の署名者に接続されます。 +ethers.jsの`ContractFactory`は新しいスマートコントラクトをデプロイするための抽象化であり、ここでの`HelloWorld`はhello worldコントラクトのインスタンスのためのファクトリです。 `hardhat-ethers`プラグインを使用する場合、`ContractFactory`および`Contract`インスタンスはデフォルトで最初の署名者に接続されます。 ``` const hello_world = await HelloWorld.deploy(); @@ -324,7 +332,7 @@ const hello_world = await HelloWorld.deploy(); `ContractFactory`で`deploy()`を呼び出すとデプロイメントが開始され、`Contract`に解決すべき`Promise`が返されます。 これは、スマートコントラクトの各関数に対するメソッドを持つオブジェクトです。 -## ステップ 16: コントラクトをデプロイする {#step-16-deploy-our-contract} +## ステップ16: コントラクトをデプロイする {#step-16-deploy-our-contract} ようやく、スマートコントラクトをデプロイする準備が整いました。 コマンドラインに移動し、以下を実行します。 @@ -342,16 +350,16 @@ Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 ![EtherscanのContract](./etherscan-contract.png) -`From`アドレスは MetaMask アカウントアドレスと一致する必要があります。To アドレスには「Contract Creation」と表示されますが、トランザクションをクリックすると、`To`フィールドにコントラクトアドレスが表示されます。 +`From`アドレスはMetaMaskアカウントアドレスと一致する必要があります。Toアドレスには「Contract Creation」と表示されますが、トランザクションをクリックすると、`To`フィールドにコントラクトアドレスが表示されます。 ![EtherscanのTransaction](./etherscan-transaction.png) おめでとうございます! イーサリアムチェーンにスマートコントラクトをデプロイできました 🎉 -内部で何が起こっているのかを理解するために、[Alchemy ダッシュボード](https://dashboard.alchemyapi.io/explorer)の Explorer タブに移動してみましょう。 Alchemy のアプリが複数ある場合は、必ずアプリでフィルタリングし、「Hello World」を選択してください。 ![Hello WorldのExplorer](./hello-world-explorer.png) +内部で何が起こっているのかを理解するために、[Alchemyダッシュボード](https://dashboard.alchemyapi.io/explorer)のExplorerタブに移動してみましょう。 Alchemyのアプリが複数ある場合は、必ずアプリでフィルタリングし、「Hello World」を選択してください。 ![Hello WorldのExplorer](./hello-world-explorer.png) -ここでは、`.deploy()`関数を呼び出した際に、Hardhat/Ethers が内部で行った JSON-RPC の呼び出しを見ることができます。 ここで呼び出している 2 つの重要な JSON-RPC は、実際に Goerli チェーン上でコントラクトを書き込むリクエストの[`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction)と、(トランザクションの際の典型的なパターンである)ハッシュを与えられているトランザクションに関する情報を読み取るリクエストの[`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash)です。 トランザクションの送信の詳細については、こちらのチュートリアルの[Web3 を使用したトランザクションの送信](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)をご覧ください。 +ここでは、`.deploy()`関数を呼び出した際に、Hardhat/Ethersが内部で行ったJSON-RPCの呼び出しを見ることができます。 ここで呼び出している2つの重要なJSON-RPCは、実際にGoerliチェーン上でコントラクトを書き込むリクエストの[`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction)と、(トランザクションの際の典型的なパターンである)ハッシュを与えられているトランザクションに関する情報を読み取るリクエストの[`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash)です。 トランザクションの送信の詳細については、こちらのチュートリアルの[Web3を使用したトランザクションの送信](/developers/tutorials/sending-transactions-using-web3-and-alchemy/)をご覧ください。 -こちらのチュートリアルのパート 1 は以上となります。パート 2 では初期メッセージの更新による[スマートコントラクトとの実際のやり取り](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#part-2-interact-with-your-smart-contract)を、パート 3 では[Etherscan へのスマートコントラクトの公開](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#optional-part-3-publish-your-smart-contract-to-etherscan)を行い、やり取りする方法を学びます。 +こちらのチュートリアルのパート1は以上となります。パート2では初期メッセージの更新による[スマートコントラクトとの実際のやり取り](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#part-2-interact-with-your-smart-contract)を、パート3では[Etherscanへのスマートコントラクトの公開](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#optional-part-3-publish-your-smart-contract-to-etherscan)を行い、やり取りする方法を学びます。 -**Alchemy の詳細については、 [ウェブサイト](https://alchemyapi.io/eth)をご覧ください。 アップデートを見逃したくない場合は、 [こちら](https://www.alchemyapi.io/newsletter)でニュースレターを購読してください。 [Twitter](https://twitter.com/alchemyplatform)もあわせてフォローし、[Discord](https://discord.com/invite/u72VCg3)**にもご参加ください。 +**Alchemyの詳細については、 [ウェブサイト](https://alchemyapi.io/eth)をご覧ください。 アップデートを見逃したくない場合は、 [こちら](https://www.alchemyapi.io/newsletter)でニュースレターを購読してください。 [Twitter](https://twitter.com/alchemyplatform)もあわせてフォローし、[Discord](https://discord.com/invite/u72VCg3)**にもご参加ください。 diff --git a/public/content/translations/ja/developers/tutorials/interact-with-other-contracts-from-solidity/index.md b/public/content/translations/ja/developers/tutorials/interact-with-other-contracts-from-solidity/index.md index 737324bd123..de8baa117fa 100644 --- a/public/content/translations/ja/developers/tutorials/interact-with-other-contracts-from-solidity/index.md +++ b/public/content/translations/ja/developers/tutorials/interact-with-other-contracts-from-solidity/index.md @@ -16,7 +16,7 @@ sourceUrl: https://ethereumdev.io/interact-with-other-contracts-from-solidity/ address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" --- -これまでのチュートリアルでは、[最初のスマートコントラクトをデプロイする方法](/developers/tutorials/deploying-your-first-smart-contract/)と、[修飾子によるアクセス制御](https://ethereumdev.io/organize-your-code-and-control-access-to-your-smart-contract-with-modifiers/)や[Solidity でのエラー処理](https://ethereumdev.io/handle-errors-in-solidity-with-require-and-revert/)といったいくつかの機能を追加する方法について学びました。 このチュートリアルでは、既存のコントラクトからスマートコントラクトをデプロイし、それを活用する方法について説明します。 +これまでのチュートリアルでは、[最初のスマートコントラクトをデプロイする方法](/developers/tutorials/deploying-your-first-smart-contract/)と、[修飾子によるアクセス制御](https://ethereumdev.io/organize-your-code-and-control-access-to-your-smart-contract-with-modifiers/)や[Solidityでのエラー処理](https://ethereumdev.io/handle-errors-in-solidity-with-require-and-revert/)といったいくつかの機能を追加する方法について学びました。 このチュートリアルでは、既存のコントラクトからスマートコントラクトをデプロイし、それを活用する方法について説明します。 ここでは、`CounterFactory`という名前のファクトリーを作成することで、誰でも自分の`Counter`スマートコントラクトを所有できるようにするコントラクトを作成します。 初めに、これが`Counter`スマートコントラクトの初期コードです。 @@ -56,7 +56,7 @@ contract Counter { } ``` -ファクトリーのアドレスとコントラクト所有者のアドレスを追跡するために、コントラクトコードを少し変更していることに注意してください。 他のコントラクトからコントラクトコードを呼び出した場合、msg.sender はコントラクトファクトリーのアドレスを参照します。 コントラクトを使用して他のコントラクトとやり取りすることはよくあることなので、これは**理解しておくべき非常に重要なポイント**です。 したがって、複雑なケースでは誰が送信者なのかに注意を払う必要があります。 +ファクトリーのアドレスとコントラクト所有者のアドレスを追跡するために、コントラクトコードを少し変更していることに注意してください。 他のコントラクトからコントラクトコードを呼び出した場合、msg.senderはコントラクトファクトリーのアドレスを参照します。 コントラクトを使用して他のコントラクトとやり取りすることはよくあることなので、これは**理解しておくべき非常に重要なポイント**です。 したがって、複雑なケースでは誰が送信者なのかに注意を払う必要があります。 このために、`onlyFactory`という修飾子も追加しました。この修飾子は、元の呼び出し元をパラメータとして渡すファクトリーのみが、状態変更関数を呼び出せるようにします。 @@ -66,7 +66,7 @@ contract Counter { mapping(address => Counter) _counters; ``` -イーサリアムでは、マッピングは JavaScript のオブジェクトに相当します。これは、型 A のキーを型 B の値にマッピングできます。ここでは、所有者のアドレスをそのカウンターのインスタンスにマッピングしています。 +イーサリアムでは、マッピングはJavaScriptのオブジェクトに相当します。これは、型Aのキーを型Bの値にマッピングできます。ここでは、所有者のアドレスをそのカウンターのインスタンスにマッピングしています。 ユーザーのために新しいカウンターをインスタンス化する場合は、次のようになります。 @@ -77,7 +77,7 @@ mapping(address => Counter) _counters; } ``` -まず、そのユーザーがすでにカウンターを所有しているかどうかを確認します。 もしカウンターを所有していなければ(カウンターの数が 0 ならば)、そのアドレスを`Counter`コンストラクタに渡して新しいカウンターをインスタンス化し、新しく作成したインスタンスをマッピングに割り当てます。 +まず、そのユーザーがすでにカウンターを所有しているかどうかを確認します。 もしカウンターを所有していなければ(カウンターの数が0ならば)、そのアドレスを`Counter`コンストラクタに渡して新しいカウンターをインスタンス化し、新しく作成したインスタンスをマッピングに割り当てます。 特定のカウンターの数を取得する場合は、次のようになります。 @@ -92,7 +92,7 @@ function getMyCount() public view returns (uint256) { } ``` -最初の関数は、指定されたアドレスに Counter コントラクトが存在するかどうかをチェックし、存在する場合にインスタンスから`getCount`メソッドを呼び出します。 2 番目の関数`getMyCount`は、msg.sender を直接`getCount`関数に渡す短い関数です。 +最初の関数は、指定されたアドレスにCounterコントラクトが存在するかどうかをチェックし、存在する場合にインスタンスから`getCount`メソッドを呼び出します。 2番目の関数`getMyCount`は、msg.senderを直接`getCount`関数に渡す短い関数です。 `increment`関数もかなり類似していますが、`Counter`コントラクトに元のトランザクション送信者を渡します。 @@ -103,9 +103,9 @@ function increment() public { } ``` -この関数を何度も呼び出すと、カウンターがオーバーフローする可能性がありますので注意してください。 オーバーフローが発生しないように、できる限り[SafeMath ライブラリ](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/)を使用してください。 +この関数を何度も呼び出すと、カウンターがオーバーフローする可能性がありますので注意してください。 オーバーフローが発生しないように、できる限り[SafeMathライブラリ](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/)を使用してください。 -このコントラクトをデプロイするためには、`CounterFactory`と`Counter`の両方のコードが必要です。 例えば Remix でデプロイする場合、CounterFactory を選択する必要があります。 +このコントラクトをデプロイするためには、`CounterFactory`と`Counter`の両方のコードが必要です。 例えばRemixでデプロイする場合、CounterFactoryを選択する必要があります。 これが完成したコードです。 @@ -170,8 +170,8 @@ contract CounterFactory { } ``` -コンパイル後、Remix のデプロイセクションで、デプロイするファクトリーを選択します。 +コンパイル後、Remixのデプロイセクションで、デプロイするファクトリーを選択します。 ![Remixにデプロイするファクトリーの選択](./counterfactory-deploy.png) -コントラクトファクトリーを使うと、値の変化を確認できます。 もし、別のアドレスからスマートコントラクトを呼び出したい場合は、Remix のアカウントの選択で別のアドレスに変更する必要があります。 +コントラクトファクトリーを使うと、値の変化を確認できます。 もし、別のアドレスからスマートコントラクトを呼び出したい場合は、Remixのアカウントの選択で別のアドレスに変更する必要があります。 diff --git a/public/content/translations/ja/developers/tutorials/nft-minter/index.md b/public/content/translations/ja/developers/tutorials/nft-minter/index.md index 704e20b0dcb..7ae743e9bb1 100644 --- a/public/content/translations/ja/developers/tutorials/nft-minter/index.md +++ b/public/content/translations/ja/developers/tutorials/nft-minter/index.md @@ -14,62 +14,62 @@ lang: ja published: 2021-10-06 --- -Web2 のバックグラウンドを持つデベロッパーの最大の課題の 1 つは、スマートコントラクトをフロントエンドのプロジェクトに接続し、やり取りを行う方法を理解することです。 +Web2のバックグラウンドを持つデベロッパーの最大の課題の1つは、スマートコントラクトをフロントエンドのプロジェクトに接続し、やり取りを行う方法を理解することです。 -ここでは、デジタル資産へのリンク、タイトル、説明を入力できるシンプルな UI を備えた非代替性トークン(NFT)ミンターを構築することで、次の方法を学びます。 +ここでは、デジタル資産へのリンク、タイトル、説明を入力できるシンプルなUIを備えた非代替性トークン(NFT)ミンターを構築することで、次の方法を学びます。 -- フロントエンドのプロジェクト経由で MetaMask に接続する +- フロントエンドのプロジェクト経由でMetaMaskに接続する - フロントエンドからスマートコントラクトメソッドを呼び出す -- MetaMask を使用してトランザクションに署名する +- MetaMaskを使用してトランザクションに署名する -このチュートリアルでは、[React](https://reactjs.org/)をフロントエンドフレームワークとして使用します。 このチュートリアルは Web3 開発に焦点を当てているので、React の基礎についての説明に多くの時間を費やせません。 代わりに、プロジェクトの機能性を高めることに注力します。 +このチュートリアルでは、[React](https://reactjs.org/)をフロントエンドフレームワークとして使用します。 このチュートリアルはWeb3開発に焦点を当てているので、Reactの基礎についての説明に多くの時間を費やせません。 代わりに、プロジェクトの機能性を高めることに注力します。 -前提条件として、React に関する初級レベルの知識を有している必要があります。つまり、コンポーネント、プロパティ(props)、useState および useEffect、基本関数の呼び出しなどの仕組みを理解している必要があります。 これらの中に初めて耳にする用語がある場合は、[React の入門チュートリアル](https://reactjs.org/tutorial/tutorial.html)をご覧ください。 より視覚的な学習を好む方には、Net Ninja による素晴らしい[フルモダン React チュートリアル](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gZD-Tvwfod2gaISzfRiP9d)のビデオシリーズをお勧めします。 +前提条件として、Reactに関する初級レベルの知識を有している必要があります。つまり、コンポーネント、プロパティ(props)、useStateおよびuseEffect、基本関数の呼び出しなどの仕組みを理解している必要があります。 これらの中に初めて耳にする用語がある場合は、[Reactの入門チュートリアル](https://reactjs.org/tutorial/tutorial.html)をご覧ください。 より視覚的な学習を好む方には、Net Ninjaによる素晴らしい[フルモダンReactチュートリアル](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gZD-Tvwfod2gaISzfRiP9d)のビデオシリーズをお勧めします。 -まだ Alchemy アカウントをお持ちでない場合、このチュートリアルを完了したり、ブロックチェーンで何かを構築したりするために必ず必要になりますので、 [こちらから](https://alchemy.com/)無料アカウントに登録してください。 +まだAlchemyアカウントをお持ちでない場合、このチュートリアルを完了したり、ブロックチェーンで何かを構築したりするために必ず必要になりますので、 [こちらから](https://alchemy.com/)無料アカウントに登録してください。 それでは、さっそく始めましょう! ## 非代替性トークン(NFT)作成入門 {#making-nfts-101} -コードを見始める前に、非代替性トークン(NFT)作成の仕組みを理解することが重要です。 それには、次の 2 つのステップがあります。 +コードを見始める前に、非代替性トークン(NFT)作成の仕組みを理解することが重要です。 それには、次の2つのステップがあります。 ### イーサリアムブロックチェーン上で非代替性トークン(NFT)スマートコントラクトを公開 {#publish-nft} -ERC-1155 と ERC-721 の 2 つのスマートコントラクト規格の最大の違いは、ERC-1155 はマルチトークン規格でありバッチ機能を備えているのに対し、ERC-721 はシングルトークン規格であり一度に 1 つのトークンの送信しかサポートしていないことです。 +ERC-1155とERC-721の2つのスマートコントラクト規格の最大の違いは、ERC-1155はマルチトークン規格でありバッチ機能を備えているのに対し、ERC-721はシングルトークン規格であり一度に1つのトークンの送信しかサポートしていないことです。 ### ミント関数の呼び出し {#minting-function} -通常、このミント関数は、パラメータとして 2 つの変数を渡す必要があります。1 つ目は、新しくミントされた非代替性トークン(NFT)を受け取るアドレスを指定する`recipient`です。2 つ目は、非代替性トークン(NFT)のメタデータを記述する JSON ドキュメントに解決される文字列である非代替性トークン(NFT)の`tokenURI`です。 +通常、このミント関数は、パラメータとして2つの変数を渡す必要があります。1つ目は、新しくミントされた非代替性トークン(NFT)を受け取るアドレスを指定する`recipient`です。2つ目は、非代替性トークン(NFT)のメタデータを記述するJSONドキュメントに解決される文字列である非代替性トークン(NFT)の`tokenURI`です。 -非代替性トークン(NFT)のメタデータは、非代替性トークン(NFT)に名前、説明、画像(または別のデジタル資産)、その他の属性などのプロパティを持たせ、非代替性トークン(NFT)を利用できるようにします。 非代替性トークン(NFT)のメタデータが含まれている[tokenURI の例](https://gateway.pinata.cloud/ipfs/QmSvBcb4tjdFpajGJhbFAWeK3JAxCdNQLQtr6ZdiSi42V2)をご覧ください。 +非代替性トークン(NFT)のメタデータは、非代替性トークン(NFT)に名前、説明、画像(または別のデジタル資産)、その他の属性などのプロパティを持たせ、非代替性トークン(NFT)を利用できるようにします。 非代替性トークン(NFT)のメタデータが含まれている[tokenURIの例](https://gateway.pinata.cloud/ipfs/QmSvBcb4tjdFpajGJhbFAWeK3JAxCdNQLQtr6ZdiSi42V2)をご覧ください。 -このチュートリアルでは、React UI を使用して既存の非代替性トークン(NFT)のスマートコントラクトのミント関数を呼び出すパート 2(後半)の方に焦点を当てています。 +このチュートリアルでは、React UIを使用して既存の非代替性トークン(NFT)のスマートコントラクトのミント関数を呼び出すパート2(後半)の方に焦点を当てています。 -このチュートリアルで呼び出す ERC-721 非代替性トークン(NFT)スマートコントラクトへのリンクは、[こちら](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE)です。 この作成方法について知りたい場合は、[非代替性トークン(NFT)の作り方](https://docs.alchemyapi.io/alchemy/tutorials/how-to-create-an-nft)という別のチュートリアルを確認することを強くお勧めします。 +このチュートリアルで呼び出すERC-721非代替性トークン(NFT)スマートコントラクトへのリンクは、[こちら](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE)です。 この作成方法について知りたい場合は、[非代替性トークン(NFT)の作り方](https://docs.alchemyapi.io/alchemy/tutorials/how-to-create-an-nft)という別のチュートリアルを確認することを強くお勧めします。 非代替性トークン(NFT)作成の仕組みを理解したところで、スターターファイルをクローンしましょう。 ## スターターファイルのクローン {#clone-the-starter-files} -最初に、[非代替性トークン(NFT)ミンターチュートリアル(nft-minter-tutorial)の GitHub リポジトリ](https://github.com/alchemyplatform/nft-minter-tutorial)にアクセスし、このプロジェクトのスターターファイルを取得します。 リポジトリをローカル環境にクローンします。 +最初に、[非代替性トークン(NFT)ミンターチュートリアル(nft-minter-tutorial)のGitHubリポジトリ](https://github.com/alchemyplatform/nft-minter-tutorial)にアクセスし、このプロジェクトのスターターファイルを取得します。 リポジトリをローカル環境にクローンします。 -クローンされた`nft-minter-tutorial`リポジトリを開くと、`minter-starter-files`と`nft-minter`という 2 つのフォルダが含まれています。 +クローンされた`nft-minter-tutorial`リポジトリを開くと、`minter-starter-files`と`nft-minter`という2つのフォルダが含まれています。 -- `minter-starter-files`には、このプロジェクトのスターターファイル(基本的には React UI)が含まれています。 このチュートリアルでは、イーサリアムウォレットと非代替性トークン(NFT)スマートコントラクトに接続することで、この UI を利用できるようにする方法を学ぶ際に、**こちらのディレクトリで作業します**。 -- `nft-minter`には、完成したチュートリアル全体が含まれており、**困ったときに\*\***リファレンス\*\*として利用できます。 +- `minter-starter-files`には、このプロジェクトのスターターファイル(基本的にはReact UI)が含まれています。 このチュートリアルでは、イーサリアムウォレットと非代替性トークン(NFT)スマートコントラクトに接続することで、このUIを利用できるようにする方法を学ぶ際に、**こちらのディレクトリで作業します**。 +- `nft-minter`には、完成したチュートリアル全体が含まれており、**困ったときに****リファレンス**として利用できます。 次に、コードエディタで`minter-starter-files`のコピーを開き、`src`フォルダに移動します。 -これから作成するすべてのコードは、`src`フォルダに保存されます。 後ほど`Minter.js`コンポーネントを編集し、追加の javascript ファイルを書くことで、このプロジェクトに Web3 機能を追加します。 +これから作成するすべてのコードは、`src`フォルダに保存されます。 後ほど`Minter.js`コンポーネントを編集し、追加のjavascriptファイルを書くことで、このプロジェクトにWeb3機能を追加します。 -## ステップ 2: スターターファイルの確認 {#step-2-check-out-our-starter-files} +## ステップ2: スターターファイルの確認 {#step-2-check-out-our-starter-files} コーディングを始める前に、スターターファイルで既に提供されるものを確認することが重要です。 -### React プロジェクトの実行 {#get-your-react-project-running} +### Reactプロジェクトの実行 {#get-your-react-project-running} -まずは、ブラウザで React プロジェクトを実行しましょう。 React の素晴らしいところは、一度ブラウザでプロジェクトを実行すると、保存した変更がブラウザでも同時に更新されることです。 +まずは、ブラウザでReactプロジェクトを実行しましょう。 Reactの素晴らしいところは、一度ブラウザでプロジェクトを実行すると、保存した変更がブラウザでも同時に更新されることです。 プロジェクトを実行するには、次のようにターミナルで`minter-starter-files`フォルダのルートディレクトリに移動し、`npm install`を実行してプロジェクトの依存関係をインストールします。 @@ -84,15 +84,15 @@ npm install npm start ``` -これにより、ブラウザで http://localhost:3000/が開き、プロジェクトのフロントエンドが表示されます。 フロントエンドは 3 つのフィールドで構成されており、それぞれ、非代替性トークン(NFT)資産へのリンク、非代替性トークン(NFT)の名前、非代替性トークン(NFT)の説明を入力する場所になっています。 +これにより、ブラウザでhttp://localhost:3000/が開き、プロジェクトのフロントエンドが表示されます。 フロントエンドは3つのフィールドで構成されており、それぞれ、非代替性トークン(NFT)資産へのリンク、非代替性トークン(NFT)の名前、非代替性トークン(NFT)の説明を入力する場所になっています。 「Connect Wallet」や「Mint NFT」ボタンをクリックしても、動作しません。これらの機能は、これからプログラムする必要があります。 :\) -### Minter.js コンポーネント {#minter-js} +### Minter.jsコンポーネント {#minter-js} **注:** `minter-starter-files`フォルダにいることを確認してください。`nft-minter`フォルダではないことを確認します。 -エディタの`src`フォルダに戻り、`Minter.js`ファイルを開きましょう。 このファイルには、これから作業を進めていく主要な React コンポーネントが含まれています。すべての内容を理解することが非常に重要です。 +エディタの`src`フォルダに戻り、`Minter.js`ファイルを開きましょう。 このファイルには、これから作業を進めていく主要なReactコンポーネントが含まれています。すべての内容を理解することが非常に重要です。 このファイルの上部には、特定のイベントの後に更新される状態変数(State Variable)があります。 @@ -105,17 +105,17 @@ const [description, setDescription] = useState("") const [url, setURL] = useState("") ``` -React の状態変数や状態フック(State Hook)を聞いたことがない場合は、 [こちらの](https://reactjs.org/docs/hooks-state.html)ドキュメントをご覧ください。 +Reactの状態変数や状態フック(State Hook)を聞いたことがない場合は、 [こちらの](https://reactjs.org/docs/hooks-state.html)ドキュメントをご覧ください。 それぞれの変数は以下を示します。 - `walletAddress` - ユーザーのウォレットアドレスを格納する文字列 -- `status` - UI の下部に表示するメッセージを含む文字列 +- `status` - UIの下部に表示するメッセージを含む文字列 - `name` - 非代替性トークン(NFT)の名前を格納する文字列 - `description` - 非代替性トークン(NFT)の説明を格納する文字列 - `url` - 非代替性トークン(NFT)のデジタル資産へのリンクを含んだ文字列 -状態変数(State Variable)の後に、`useEffect`、`connectWalletPressed`、`onMintPressed`という 3 つの未実装の関数があります。 これらの関数は、すべて`async`になっています。これは、それぞれの関数で非同期 API 呼び出しを行うためです。 それぞれの関数の名前は、その機能を示しています。 +状態変数(State Variable)の後に、`useEffect`、`connectWalletPressed`、`onMintPressed`という3つの未実装の関数があります。 これらの関数は、すべて`async`になっています。これは、それぞれの関数で非同期API呼び出しを行うためです。 それぞれの関数の名前は、その機能を示しています。 ```javascript useEffect(async () => { @@ -131,13 +131,13 @@ const onMintPressed = async () => { } ``` -- [`useEffect`](https://reactjs.org/docs/hooks-effect.html) - コンポーネントがレンダリングされた後に呼び出される React フックです。 空の配列`[]`の prop が渡される(3 行目を参照)ため、コンポーネントの*最初*のレンダリングでのみ呼び出されます。 ここでは、ウォレットリスナーと別のウォレット関数を呼び出し、ウォレットが接続されているかどうかに応じた UI の更新をします。 -- `connectWalletPressed` - この関数は、ユーザーの MataMask ウォレットを分散型アプリケーション(Dapp)に接続するために呼び出されます。 +- [`useEffect`](https://reactjs.org/docs/hooks-effect.html) - コンポーネントがレンダリングされた後に呼び出されるReactフックです。 空の配列`[]`のpropが渡される(3行目を参照)ため、コンポーネントの_最初_のレンダリングでのみ呼び出されます。 ここでは、ウォレットリスナーと別のウォレット関数を呼び出し、ウォレットが接続されているかどうかに応じたUIの更新をします。 +- `connectWalletPressed` - この関数は、ユーザーのMataMaskウォレットを分散型アプリケーション(Dapp)に接続するために呼び出されます。 - `onMintPressed` - この関数は、ユーザーの非代替性トークン(NFT)をミントするために呼び出されます。 -このファイルの終盤には、コンポーネントの UI があります。 このコードを注意深く読んでいくと、状態変数の`url`、`name`、`description`に対応するテキストフィールドの入力が変更された場合、これらの変数を更新していることが分かります。 +このファイルの終盤には、コンポーネントのUIがあります。 このコードを注意深く読んでいくと、状態変数の`url`、`name`、`description`に対応するテキストフィールドの入力が変更された場合、これらの変数を更新していることが分かります。 -さらに、`walletButton`または`mintButton`という ID を持つボタンがクリックされると、それぞれ`connectWalletPressed`または`onMintPressed`が呼び出されることも分かります。 +さらに、`walletButton`または`mintButton`というIDを持つボタンがクリックされると、それぞれ`connectWalletPressed`または`onMintPressed`が呼び出されることも分かります。 ```javascript //the UI of our component @@ -189,43 +189,43 @@ return ( 最後に、このミンター(Minter)コンポーネントがどこに加えられるかについて説明します。 -他のすべてのコンポーネントのコンテナとして機能する、React のメインコンポーネントである`App.js`ファイルを表示すると、ミンター(Minter)コンポーネントが 7 行目に挿入されていることが分かります。 +他のすべてのコンポーネントのコンテナとして機能する、Reactのメインコンポーネントである`App.js`ファイルを表示すると、ミンター(Minter)コンポーネントが7行目に挿入されていることが分かります。 **このチュートリアルでは、`Minter.js`ファイルの編集と、`src`フォルダへのファイルの追加のみを行います。** これから取り組む内容を理解したところで、イーサリアムウォレットを設定しましょう。 -## イーサリアムウォレットの設定{#set-up-your-ethereum-wallet} +## イーサリアムウォレットの設定 {#set-up-your-ethereum-wallet} ユーザーがスマートコントラクトとやり取りできるようにするには、自分のイーサリアムウォレットを分散型アプリケーション(Dapp)に接続する必要があります。 -### MetaMask をダウンロード {#download-metamask} +### MetaMaskをダウンロード {#download-metamask} -このチュートリアルでは、イーサリアムアカウントアドレスを管理するためにブラウザの仮想ウォレットである Metamask を使用します。 イーサリアムのトランザクションの仕組みの詳細については、[こちらのページ](/developers/docs/transactions/)をご覧ください。 +このチュートリアルでは、イーサリアムアカウントアドレスを管理するためにブラウザの仮想ウォレットであるMetamaskを使用します。 イーサリアムのトランザクションの仕組みの詳細については、[こちらのページ](/developers/docs/transactions/)をご覧ください。 -Metamask のアカウントは[こちら](https://metamask.io/download.html)から無料でダウンロード、作成できます。 アカウントを作成後、またはすでにアカウントをお持ちの場合は、(実際に支払いが発生しないように)右上の「Ropsten Test Network」に切り替えてください。 +Metamaskのアカウントは[こちら](https://metamask.io/download.html)から無料でダウンロード、作成できます。 アカウントを作成後、またはすでにアカウントをお持ちの場合は、(実際に支払いが発生しないように)右上の「Ropsten Test Network」に切り替えてください。 ### フォーセットからイーサ(ETH)を追加 {#add-ether-from-faucet} -非代替性トークン(NFT)をミントする(または、イーサリアムのブロックチェーンのトランザクションに署名する)には、偽の ETH が必要です。 ETH を取得するには、[Ropsten フォーセット](https://faucet.ropsten.be/)にアクセスして、Ropsten アカウントアドレスを入力し、「Send Ropsten ETH」をクリックします。 Metamask アカウントに ETH が表示されるはずです。 +非代替性トークン(NFT)をミントする(または、イーサリアムのブロックチェーンのトランザクションに署名する)には、偽のETHが必要です。 ETHを取得するには、[Ropstenフォーセット](https://faucet.ropsten.be/)にアクセスして、Ropstenアカウントアドレスを入力し、「Send Ropsten ETH」をクリックします。 MetamaskアカウントにETHが表示されるはずです。 ### 残高の確認 {#check-your-balance} -残高を再確認するために、[Alchemy のコンポーザーツール](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D)を使用して[eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance)をリクエストしてみましょう。 このリクエストをすると、ウォレット内の ETH の額が返されます。 MetaMask アカウントアドレスを入力して「Send Request」をクリックすると、次のようなレスポンスが表示されます。 +残高を再確認するために、[Alchemyのコンポーザーツール](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D)を使用して[eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance)をリクエストしてみましょう。 このリクエストをすると、ウォレット内のETHの額が返されます。 MetaMaskアカウントアドレスを入力して「Send Request」をクリックすると、次のようなレスポンスが表示されます。 ```text {"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"} ``` -**注:** この結果の単位は、ETH ではなく wei です。 wei は ETH の最小単位として使われています。 wei から ETH へ変換すると、1 eth = 10¹⁸ wei になります。 つまり、0xde0b6b3a7640000 を 10 進数に変換すると、1\*10¹⁸ となり、1 ETH に相当します。 +**注:** この結果の単位は、ETHではなくweiです。 weiはETHの最小単位として使われています。 weiからETHへ変換すると、1 eth = 10¹⁸ weiになります。 つまり、0xde0b6b3a7640000を10進数に変換すると、1\*10¹⁸となり、1 ETHに相当します。 ふう! これで、偽のお金を手に入れました。 -## MetaMask を UI に接続 {#connect-metamask-to-your-UI} +## MetaMaskをUIに接続 {#connect-metamask-to-your-UI} -MetaMask ウォレットが設定されたので、分散型アプリケーション(Dapp)を接続しましょう。 +MetaMaskウォレットが設定されたので、分散型アプリケーション(Dapp)を接続しましょう。 -[モデルビューコントローラ(MVC)](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)パラダイムを実践したいので、別のファイルを作成し、分散型アプリケーション(Dapp)のロジック、データ、ルールを管理する関数を含めます。次に、それらの関数をフロントエンド(Minter.js コンポーネント)に渡します。 +[モデルビューコントローラ(MVC)](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)パラダイムを実践したいので、別のファイルを作成し、分散型アプリケーション(Dapp)のロジック、データ、ルールを管理する関数を含めます。次に、それらの関数をフロントエンド(Minter.jsコンポーネント)に渡します。 ### `connectWallet`関数 {#connect-wallet-function} @@ -276,24 +276,24 @@ export const connectWallet = async () => { まず、ブラウザで`window.ethereum`が有効になっているかどうかを関数がチェックしています。 -`window.ethereum`は、MetaMask および他のウォレットプロバイダーによって挿入されるグローバル API であり、ウェブサイトがユーザーのイーサリアムアカウントを要求できるようにするものです。 承認されると、ユーザーが接続しているブロックチェーンからデータを読み取ったり、メッセージやトランザクションへの署名をユーザーに提案したりできるようになります。 詳細については、[MetaMask のドキュメント](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents)を参照してください。 +`window.ethereum`は、MetaMaskおよび他のウォレットプロバイダーによって挿入されるグローバルAPIであり、ウェブサイトがユーザーのイーサリアムアカウントを要求できるようにするものです。 承認されると、ユーザーが接続しているブロックチェーンからデータを読み取ったり、メッセージやトランザクションへの署名をユーザーに提案したりできるようになります。 詳細については、[MetaMaskのドキュメント](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents)を参照してください。 -`window.ethereum`が*存在しない*場合は、MeTaMask がインストールされていないことを意味します。 その結果、空の文字列に設定された、返される`address`と、ユーザーが MetaMask をインストールする必要があることを伝える`status`JSX オブジェクトが入った JSON オブジェクトが返されます。 +`window.ethereum`が_存在しない_場合は、MeTaMaskがインストールされていないことを意味します。 その結果、空の文字列に設定された、返される`address`と、ユーザーがMetaMaskをインストールする必要があることを伝える`status`JSXオブジェクトが入ったJSONオブジェクトが返されます。 -**これから記述するほとんどの関数は、状態変数(State Variable)と UI の更新に使用できる JSON オブジェクトを返します。** +**これから記述するほとんどの関数は、状態変数(State Variable)とUIの更新に使用できるJSONオブジェクトを返します。** -`window.ethereum`が*存在*する場合、興味深いことが起こります。 +`window.ethereum`が_存在_する場合、興味深いことが起こります。 -try/catch ループを使用して、`[window.ethereum.request({ method: "eth_requestAccounts" });](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts)`を呼び出すことで、MetaMask への接続を試みます。 この関数を呼び出すと、ブラウザで MetaMask が開き、ユーザーはウォレットを分散型アプリケーション(Dapp)に接続するように求められます。 +try/catchループを使用して、`[window.ethereum.request({ method: "eth_requestAccounts" });](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts)`を呼び出すことで、MetaMaskへの接続を試みます。 この関数を呼び出すと、ブラウザでMetaMaskが開き、ユーザーはウォレットを分散型アプリケーション(Dapp)に接続するように求められます。 -- ユーザーが接続を選んだ場合、`method: "eth_requestAccounts"`は、分散型アプリケーション(Dapp)に接続されているすべてのユーザーのアカウントアドレスを含む配列を返します。 `connectWallet`関数は、配列内の*最初の*`address`と\(9 行目参照\)、ユーザーにスマートコントラクトにメッセージを書き込むように促す`status`メッセージが入った JSON オブジェクトを返します。 -- ユーザーが接続を拒否した場合、JSON オブジェクトには、返される`address`に入る空の文字列と、ユーザーが接続を拒否したことを示す`status`メッセージが入ることになります。 +- ユーザーが接続を選んだ場合、`method: "eth_requestAccounts"`は、分散型アプリケーション(Dapp)に接続されているすべてのユーザーのアカウントアドレスを含む配列を返します。 `connectWallet`関数は、配列内の_最初の_`address`と\(9 行目参照\)、ユーザーにスマートコントラクトにメッセージを書き込むように促す`status`メッセージが入ったJSONオブジェクトを返します。 +- ユーザーが接続を拒否した場合、JSONオブジェクトには、返される`address`に入る空の文字列と、ユーザーが接続を拒否したことを示す`status`メッセージが入ることになります。 -### Minter.js UI コンポーネントに connectWallet 関数を追加 {#add-connect-wallet} +### Minter.js UIコンポーネントにconnectWallet関数を追加 {#add-connect-wallet} `connectWallet`関数を記述したので、 `Minter.js`コンポーネントに接続しましょう。 -まず、`Minter.js`ファイルの上部に`import { connectWallet } from "./utils/interact.js";`を追加して、`Minter.js`ファイルに関数をインポートする必要があります。 `Minter.js`の最初の 11 行は、次のようになります。 +まず、`Minter.js`ファイルの上部に`import { connectWallet } from "./utils/interact.js";`を追加して、`Minter.js`ファイルに関数をインポートする必要があります。 `Minter.js`の最初の11行は、次のようになります。 ```javascript import { useEffect, useState } from "react"; @@ -321,21 +321,21 @@ const connectWalletPressed = async () => { `interact.js`ファイルによって、機能の大部分が`Minter.js`コンポーネントからどのように抽象化されているかに注目してください。 これは、モデルビューコントローラ(M-V-C)パラダイムに準拠しているためです。 -`connectWalletPressed`では、単にインポートされた`connectWallet`関数の await 呼び出しを行っています。さらに、そのレスポンスを使用し、`status`と`walletAddress`変数を状態フックを介して更新しています。 +`connectWalletPressed`では、単にインポートされた`connectWallet`関数のawait呼び出しを行っています。さらに、そのレスポンスを使用し、`status`と`walletAddress`変数を状態フックを介して更新しています。 -それでは、 `Minter.js`と `interact.js`の両方のファイルを保存して、これまでの UI をテストしてみましょう。 +それでは、 `Minter.js`と `interact.js`の両方のファイルを保存して、これまでのUIをテストしてみましょう。 -localhost:3000 でブラウザを開き、ページ右上にある「Connect Wallet」ボタンを押します。 +localhost:3000でブラウザを開き、ページ右上にある「Connect Wallet」ボタンを押します。 -MetaMask がインストールされている場合は、ウォレットを分散型アプリケーション(Dapp)に接続するように求められます。 接続リクエストを承認します。 +MetaMaskがインストールされている場合は、ウォレットを分散型アプリケーション(Dapp)に接続するように求められます。 接続リクエストを承認します。 ウォレットボタンに、接続した自分のアドレスが表示されているはずです。 -次に、ページを更新してみてください。変ですね。 ウォレットボタンによって、すでに接続しているにもかかわらず MetaMask に接続するよう求められます。 +次に、ページを更新してみてください。変ですね。 ウォレットボタンによって、すでに接続しているにもかかわらずMetaMaskに接続するよう求められます。 -でも心配しないでください。 `getCurrentWalletConnected`という関数を実装することで、簡単にこれを修正できます。この関数は、アドレスが分散型アプリケーション(Dapp)にすでに接続されているかどうかを確認し、それに応じて UI を更新します。 +でも心配しないでください。 `getCurrentWalletConnected`という関数を実装することで、簡単にこれを修正できます。この関数は、アドレスが分散型アプリケーション(Dapp)にすでに接続されているかどうかを確認し、それに応じてUIを更新します。 -### getCurrentWalletConnected 関数 {#get-current-wallet} +### getCurrentWalletConnected関数 {#get-current-wallet} `interact.js`ファイルに、以下の`getCurrentWalletConnected`関数を追加します。 @@ -382,9 +382,9 @@ export const getCurrentWalletConnected = async () => { } ``` -このコードは、*非常に*前述の`connectWallet`関数に似ています。 +このコードは、_非常に_前述の`connectWallet`関数に似ています。 -主な違いとしては、ユーザーがウォレットに接続するために MetaMask を開く`eth_requestAccounts`メソッドを呼び出す代わりに、 ここでは`eth_accounts`メソッドを呼び出しています。これは、現在、分散型アプリケーション(Dapp)に接続されている MetaMask のアドレスを含む配列を単に返すだけです。 +主な違いとしては、ユーザーがウォレットに接続するためにMetaMaskを開く`eth_requestAccounts`メソッドを呼び出す代わりに、 ここでは`eth_accounts`メソッドを呼び出しています。これは、現在、分散型アプリケーション(Dapp)に接続されているMetaMaskのアドレスを含む配列を単に返すだけです。 この関数を動作させるため、`Minter.js`コンポーネントの`useEffect`関数で呼び出しましょう。 @@ -412,9 +412,9 @@ useEffect(async () => { このコードを追加したら、ブラウザウィンドウを更新してみてください。 リフレッシュ後も、ボタンには接続されていることが示されており、接続されたウォレットのアドレスのプレビューが表示されているはずです。 -### addWalletListener の実装 {#implement-add-wallet-listener} +### addWalletListenerの実装 {#implement-add-wallet-listener} -分散型アプリケーション(Dapp)ウォレットの設定の最終ステップは、ウォレットリスナーを実装することです。これにより、ユーザーが接続を切断したり、アカウントを切り替えたりした場合など、ウォレットの状態が変更されたときに UI が更新されます。 +分散型アプリケーション(Dapp)ウォレットの設定の最終ステップは、ウォレットリスナーを実装することです。これにより、ユーザーが接続を切断したり、アカウントを切り替えたりした場合など、ウォレットの状態が変更されたときにUIが更新されます。 `Minter.js`ファイルで、次のような`addWalletListener`関数を追加してください。 @@ -445,9 +445,9 @@ function addWalletListener() { ここで何が起きているか、簡単に見ていきましょう。 -- まず、ブラウザで`window.ethereum`が有効になっているか\(すなわち MetaMask がインストールされているか\)を関数がチェックしています。 - - 有効になっていない場合、ユーザーに MetaMask のインストールを求める JSX 文字列を`status`状態変数に設定します。 - - 有効になっている場合、MetaMask ウォレットの状態変更をリッスンしている 3 行目の`window.ethereum.on("accountsChanged")`リスナーを設定します。この状態変更には、ユーザーが追加のアカウントを分散型アプリケーション(Dapp)に接続した場合、アカウントを切り替えた場合、アカウントを切断した場合が含まれます。 少なくとも 1 つのアカウントが接続されていれば、`accounts`配列の最初のアカウントがリスナーから返されたときに、`walletAddress`状態変数が更新されます。 それ以外の場合は、`walletAddress`に空の文字列が設定されます。 +- まず、ブラウザで`window.ethereum`が有効になっているか\(すなわち MetaMaskがインストールされているか\)を関数がチェックしています。 + - 有効になっていない場合、ユーザーにMetaMaskのインストールを求めるJSX文字列を`status`状態変数に設定します。 + - 有効になっている場合、MetaMaskウォレットの状態変更をリッスンしている3行目の`window.ethereum.on("accountsChanged")`リスナーを設定します。この状態変更には、ユーザーが追加のアカウントを分散型アプリケーション(Dapp)に接続した場合、アカウントを切り替えた場合、アカウントを切断した場合が含まれます。 少なくとも1つのアカウントが接続されていれば、`accounts`配列の最初のアカウントがリスナーから返されたときに、`walletAddress`状態変数が更新されます。 それ以外の場合は、`walletAddress`に空の文字列が設定されます。 最後に、`useEffect`関数で次のように呼び出す必要があります。 @@ -467,31 +467,31 @@ useEffect(async () => { このチュートリアルの最初の方で説明した非代替性トークン(NFT)のメタデータを思い出してください。非代替性トークン(NFT)メタデータは、非代替性トークン(NFT)にデジタル資産、名前、説明、その他の属性などのプロパティーを持たせ、非代替性トークン(NFT)を利用できるようにします。 -JSON オブジェクトとしてメタデータを設定し、保存する必要があります。これで、スマートコントラクトの`mintNFT`関数呼び出すときに`tokenURI`パラメータとして渡すことができます。 +JSONオブジェクトとしてメタデータを設定し、保存する必要があります。これで、スマートコントラクトの`mintNFT`関数呼び出すときに`tokenURI`パラメータとして渡すことができます。 -「Link to Asset」、「Name」、「Description」フィールドのテキストは、非代替性トークン(NFT)のメタデータで別々のプロパティになります。 メタデータを JSON オブジェクトとしてフォーマットしますが、この JSON オブジェクトの格納には、以下のような複数のオプションがあります。 +「Link to Asset」、「Name」、「Description」フィールドのテキストは、非代替性トークン(NFT)のメタデータで別々のプロパティになります。 メタデータをJSONオブジェクトとしてフォーマットしますが、このJSONオブジェクトの格納には、以下のような複数のオプションがあります。 - イーサリアムブロックチェーンに格納することができますが、これは非常に高価です。 -- AWS や Firebase などの中央集権型サーバーに保存できます。 しかし、これは分散化の信念に反するものです。 +- AWSやFirebaseなどの中央集権型サーバーに保存できます。 しかし、これは分散化の信念に反するものです。 - 惑星間ファイルシステム(IPFS)という、分散型ファイルシステムでデータを保存、共有するための、分散型プロトコルおよびピアツーピア・ネットワークを使用できます。 このプロトコルは、分散化されており無料のため、最良のオプションです。 -惑星間ファイルシステム(IPFS)にメタデータを保存するには、[Pinata](https://pinata.cloud/)という便利な惑星間ファイルシステム(IPFS) API とツールキットを使用します。 次のステップでは、この方法を具体的に説明します。 +惑星間ファイルシステム(IPFS)にメタデータを保存するには、[Pinata](https://pinata.cloud/)という便利な惑星間ファイルシステム(IPFS) APIとツールキットを使用します。 次のステップでは、この方法を具体的に説明します。 -## メタデータを惑星間ファイルシステム(IPFS)にピン留めする Pintata の使用 {#use-pinata-to-pin-your-metadata-to-IPFS} +## Pinataを使用してメタデータをIPFSに固定化 {#use-pinata-to-pin-your-metadata-to-IPFS} [Pinata](https://pinata.cloud/)アカウントをお持ちでない場合は、[こちら](https://pinata.cloud/signup)から無料のアカウントにサインアップし、メールアドレスとアカウントの認証手順を完了してください。 -### Pinata API キーの作成 {#create-pinata-api-key} +### Pinata APIキーの作成 {#create-pinata-api-key} -[https://pinata.cloud/keys](https://pinata.cloud/keys)ページに移動して、上部にある「New Key」ボタンを選択し、Admin ウィジェットを有効(Enabled)に設定してからキーに名前を付けます。 +[https://pinata.cloud/keys](https://pinata.cloud/keys)ページに移動して、上部にある「New Key」ボタンを選択し、Adminウィジェットを有効(Enabled)に設定してからキーに名前を付けます。 -API 情報を含むポップアップが表示されます。 この情報は、必ず安全な場所に保存してください。 +API情報を含むポップアップが表示されます。 この情報は、必ず安全な場所に保存してください。 キーの設定が完了したので、プロジェクトに追加して使用できるようにしましょう。 -### .env ファイルの作成 {#create-a-env} +### .envファイルの作成 {#create-a-env} -環境ファイルに Pinata キーとシークレットを安全に保存できます。 [dotenv パッケージ](https://www.npmjs.com/package/dotenv)をプロジェクトディレクトリにインストールしましょう。 +環境ファイルにPinataキーとシークレットを安全に保存できます。 [dotenvパッケージ](https://www.npmjs.com/package/dotenv)をプロジェクトディレクトリにインストールしましょう。 ターミナルで\(ローカルホストを実行しているタブとは別の\)新しいタブを開き、`minter-starter-files`フォルダにいることを確認してください。次に、ターミナルで以下のコマンドを実行します。 @@ -507,20 +507,20 @@ vim.env vim\(テキストエディタ\)で `.env`ファイルが開きます。 保存するには、キーボードで「esc」+「:」+「q」をこの順序で押します。 -次に、VSCode で`.env`ファイルに移動し、次のようにして Pinata API キーと API シークレットを追加します。 +次に、VSCodeで`.env`ファイルに移動し、次のようにしてPinata APIキーとAPIシークレットを追加します。 ```text REACT_APP_PINATA_KEY = REACT_APP_PINATA_SECRET = ``` -ファイルを保存します。これで、JSON メタデータを惑星間ファイルシステム(IPFS)にアップロードする関数を書き始める準備が整いました。 +ファイルを保存します。これで、JSONメタデータを惑星間ファイルシステム(IPFS)にアップロードする関数を書き始める準備が整いました。 -### pinJSONToIPFS の実装 {#pin-json-to-ipfs} +### pinJSONToIPFSの実装 {#pin-json-to-ipfs} -幸いにも Pinata では、[惑星間ファイルシステム(IPFS)への JSON データのアップロードに特化した API](https://pinata.cloud/documentation#PinJSONToIPFS)と、少しの変更を加えるだけで使用できる axios のサンプルを備えた便利な JavaScript を使用できます。 +幸いにもPinataでは、[惑星間ファイルシステム(IPFS)へのJSONデータのアップロードに特化したAPI](https://pinata.cloud/documentation#PinJSONToIPFS)と、少しの変更を加えるだけで使用できるaxiosのサンプルを備えた便利なJavaScriptを使用できます。 -`utils`フォルダーに`pinata.js`という別のファイルを作成し、.env ファイルから Pinata のシークレットとキーをインポートしましょう。 +`utils`フォルダーに`pinata.js`という別のファイルを作成し、.envファイルからPinataのシークレットとキーをインポートしましょう。 ```javascript require("dotenv").config() @@ -566,14 +566,14 @@ export const pinJSONToIPFS = async (JSONBody) => { では、このコードは何をしているのでしょうか? -最初に、ブラウザと node.js のための Promise ベースの HTTP クライアントである[axios](https://www.npmjs.com/package/axios)をインポートしています。axios は、Pinata へのリクエストで使用します。 +最初に、ブラウザとnode.jsのためのPromiseベースのHTTPクライアントである[axios](https://www.npmjs.com/package/axios)をインポートしています。axiosは、Pinataへのリクエストで使用します。 -その下に、`pinJSONToIPFS`非同期関数があります。この関数は、`pinJSONToIPFS` API への POST リクエストを行うために、`JSONBody`を入力として取り、Pinata の API キーとシークレットをヘッダーに入れます。 +その下に、`pinJSONToIPFS`非同期関数があります。この関数は、`pinJSONToIPFS` APIへのPOSTリクエストを行うために、`JSONBody`を入力として取り、PinataのAPIキーとシークレットをヘッダーに入れます。 -- POST リクエストが成功した場合、この関数は、true に設定された`success`ブール値と、メタデータがピン留めされた`pinataUrl`が入った JSON オブジェクトを返します。 ここで返された`pinataUrl`は、スマートコントラクトの mint 関数の`tokenURI`の入力として使用されます。 -- POST リクエストが失敗した場合、この関数は、false に設定された`success`ブール値と、エラーを伝える`message`文字列が入った JSON オブジェクトを返します。 +- POSTリクエストが成功した場合、この関数は、trueに設定された`success`ブール値と、メタデータがピン留めされた`pinataUrl`が入ったJSONオブジェクトを返します。 ここで返された`pinataUrl`は、スマートコントラクトのmint関数の`tokenURI`の入力として使用されます。 +- POSTリクエストが失敗した場合、この関数は、falseに設定された`success`ブール値と、エラーを伝える`message`文字列が入ったJSONオブジェクトを返します。 -`connectWallet`関数の戻り値の型と同様に、JSON オブジェクトが返されるので、そのパラメータを状態変数と UI の更新に使用できます。 +`connectWallet`関数の戻り値の型と同様に、JSONオブジェクトが返されるので、そのパラメータを状態変数とUIの更新に使用できます。 ## スマートコントラクトのロード {#load-your-smart-contract} @@ -585,23 +585,23 @@ export const pinJSONToIPFS = async (JSONBody) => { ファイルを詳しく調べてみると、`src`ディレクトリに`contract-abi.json`ファイルがあることが分かります。 アプリケーションバイナリインターフェース(ABI)は、コントラクトが呼び出す関数を指定し、関数が確実に意図しているフォーマットでデータを返すようにするために必要です。 -さらに、イーサリアムブロックチェーンに接続してスマートコントラクトをロードするための、Alchemy API キーと Alchemy Web3 API も必要になります。 +さらに、イーサリアムブロックチェーンに接続してスマートコントラクトをロードするための、Alchemy APIキーとAlchemy Web3 APIも必要になります。 -### Alchemy API キーの作成 {#create-alchemy-api} +### Alchemy APIキーの作成 {#create-alchemy-api} -Alchemy のアカウントをお持ちでない場合は、[こちら](https://alchemy.com/?a=eth-org-nft-minter)から無料で登録できます。 +Alchemyのアカウントをお持ちでない場合は、[こちら](https://alchemy.com/?a=eth-org-nft-minter)から無料で登録できます。 -Alchemy のアカウントを作成した後、アプリを作成することで API キーを生成することができます。 これにより、Ropsten テストネットワークへのリクエストが可能になります。 +Alchemyのアカウントを作成した後、アプリを作成することでAPIキーを生成することができます。 これにより、Ropstenテストネットワークへのリクエストが可能になります。 -ナビゲーションバーの「Apps」にマウスを合わせて、「Create App」をクリックし、Alchemy ダッシュボードの「Create App」ページに移動してください。 +ナビゲーションバーの「Apps」にマウスを合わせて、「Create App」をクリックし、Alchemyダッシュボードの「Create App」ページに移動してください。 アプリに名前を付け(私たちは「My First NFT!」にしました)、簡単な説明を記述し、環境に「Staging」を選択(アプリのブックキーピングに使用)し、ネットワークに「Ropsten」を選択します。 「Create app」をクリックします。 アプリが下の表に表示されます。 -HTTP Alchemy API URL を作成したので、クリップボードにコピーします。 +HTTP Alchemy API URLを作成したので、クリップボードにコピーします。 -それを`.env`ファイルに追加してみましょう。 これで.env ファイル全体は、次のようになります。 +それを`.env`ファイルに追加してみましょう。 これで.envファイル全体は、次のようになります。 ```text REACT_APP_PINATA_KEY = @@ -609,9 +609,9 @@ REACT_APP_PINATA_SECRET = REACT_APP_ALCHEMY_KEY = https://eth-ropsten.alchemyapi.io/v2/ ``` -コントラクトアプリケーションバイナリインターフェース(ABI)と Alchemy API キーが用意できたので、[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)を使用してスマートコントラクトをロードする準備ができました。 +コントラクトアプリケーションバイナリインターフェース(ABI)とAlchemy APIキーが用意できたので、[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)を使用してスマートコントラクトをロードする準備ができました。 -### Alchemy Web3 エンドポイントとコントラクトの設定 {#setup-alchemy-endpoint} +### Alchemy Web3エンドポイントとコントラクトの設定 {#setup-alchemy-endpoint} まず、[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)がインストールされていない場合は、ターミナルで次のようにホームディレクトリである`nft-minter-tutorial`に移動してインストールする必要があります。 @@ -620,7 +620,7 @@ cd .. npm install @alch/alchemy-web3 ``` -次に、`interact.js`ファイルに戻りましょう。 .env ファイルから Alchemy キーがインポートされ、Alchemy Web3 エンドポイントが設定されるように、ファイルの上部に次のコードを追加します。 +次に、`interact.js`ファイルに戻りましょう。 .envファイルからAlchemyキーがインポートされ、Alchemy Web3エンドポイントが設定されるように、ファイルの上部に次のコードを追加します。 ```javascript require("dotenv").config() @@ -629,7 +629,7 @@ const { createAlchemyWeb3 } = require("@alch/alchemy-web3") const web3 = createAlchemyWeb3(alchemyKey) ``` -[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)は、[Web3.js](https://docs.web3js.org/)のラッパーであり、強化された API メソッドや重要なメリットを提供し、Web3 デベロッパーの負担を軽減します。 最小限の設定で使えるように設計されているので、アプリですぐに使用可能です。 +[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3)は、[Web3.js](https://docs.web3js.org/)のラッパーであり、強化されたAPIメソッドや重要なメリットを提供し、Web3デベロッパーの負担を軽減します。 最小限の設定で使えるように設計されているので、アプリですぐに使用可能です。 次に、コントラクトアプリケーションバイナリインターフェース(ABI)とコントラクトアドレスをファイルに追加しましょう。 @@ -643,15 +643,15 @@ const contractABI = require("../contract-abi.json") const contractAddress = "0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE" ``` -これで両方を追加できたので、mint 関数のコーディングを始める準備ができました。 +これで両方を追加できたので、mint関数のコーディングを始める準備ができました。 -## mintNFT 関数の実装 {#implement-the-mintnft-function} +## mintNFT関数の実装 {#implement-the-mintnft-function} `interact.js`ファイル内に、`mintNFT`関数を定義しましょう。この関数は、名前が示すとおりに非代替性トークン(NFT)をミントします。 -多数の非同期呼び出しを\(メタデータを IPFS にピン留めするために Pinata に対して、スマートコントラクトをロードするために Alchemy Web3 に対して、トランザクションに署名するために MetaMask に対して\)行うため、この関数もまた非同期になります。 +多数の非同期呼び出しを\(メタデータをIPFSにピン留めするためにPinataに対して、スマートコントラクトをロードするためにAlchemy Web3に対して、トランザクションに署名するためにMetaMaskに対して\)行うため、この関数もまた非同期になります。 -この関数への 3 つの入力は、デジタル資産の`url`、`name`、`description`になります。 `connectWallet`関数の下に、次の関数シグネチャを追加してください。 +この関数への3つの入力は、デジタル資産の`url`、`name`、`description`になります。 `connectWallet`関数の下に、次の関数シグネチャを追加してください。 ```javascript export const mintNFT = async (url, name, description) => {} @@ -673,11 +673,11 @@ export const mintNFT = async (url, name, description) => { } ``` -基本的に、入力パラメーターのいずれかが空の文字列である場合、false に設定された`success`ブール値と、UI のすべてのフィールドに入力する必要があることを伝える`status`文字列が入った JSON オブジェクトを返します。 +基本的に、入力パラメーターのいずれかが空の文字列である場合、falseに設定された`success`ブール値と、UIのすべてのフィールドに入力する必要があることを伝える`status`文字列が入ったJSONオブジェクトを返します。 -### IPFS にメタデータをアップロード {#upload-metadata-to-ipfs} +### IPFSにメタデータをアップロード {#upload-metadata-to-ipfs} -メタデータが適切にフォーマットされていることを確認したら、次のステップは、それを JSON オブジェクトにラップし、作成した`pinJSONToIPFS`を介して惑星間ファイルシステム(IPFS)にアップロードすることです。 +メタデータが適切にフォーマットされていることを確認したら、次のステップは、それをJSONオブジェクトにラップし、作成した`pinJSONToIPFS`を介して惑星間ファイルシステム(IPFS)にアップロードすることです。 そのためにはまず、`pinJSONToIPFS`関数を`interact.js`ファイルにインポートする必要があります。 `interact.js`の最上部に、次の行を追加してください。 @@ -685,9 +685,9 @@ export const mintNFT = async (url, name, description) => { import { pinJSONToIPFS } from "./pinata.js" ``` -`pinJSONToIPFS`が、JSON 本体を取ることを思い出してください。 そのため、呼び出す前に`url`、`name`、`description`パラメータを JSON オブジェクトにフォーマットする必要があります。 +`pinJSONToIPFS`が、JSON本体を取ることを思い出してください。 そのため、呼び出す前に`url`、`name`、`description`パラメータをJSONオブジェクトにフォーマットする必要があります。 -次のようにコードを更新して、`metadata`という JSON オブジェクトを作成し、この`metadata`パラメータを使用して`pinJSONToIPFS`を呼び出します。 +次のようにコードを更新して、`metadata`というJSONオブジェクトを作成し、この`metadata`パラメータを使用して`pinJSONToIPFS`を呼び出します。 ```javascript export const mintNFT = async (url, name, description) => { @@ -719,9 +719,9 @@ export const mintNFT = async (url, name, description) => { `pinJSONToIPFS(metadata)`の呼び出しのレスポンスを、`pinataResponse`オブジェクトに格納していることに注目してください。 次に、このオブジェクトにエラーがないか解析します。 -エラーがある場合、false に設定された`success`ブール値と、呼び出しが失敗したことを伝える`status`文字列が入った JSON オブジェクトを返します。 それ以外の場合は、`pinataURL`を`pinataResponse`から抽出し、それを`tokenURI`変数として格納します。 +エラーがある場合、falseに設定された`success`ブール値と、呼び出しが失敗したことを伝える`status`文字列が入ったJSONオブジェクトを返します。 それ以外の場合は、`pinataURL`を`pinataResponse`から抽出し、それを`tokenURI`変数として格納します。 -では、ファイルの先頭で初期化した Alchemy Web3 API を使用して、スマートコントラクトをロードしてみましょう。 `mintNFT`関数の下部に次のコードの行を追加して、`window.contract`グローバル変数にコントラクトを設定します。 +では、ファイルの先頭で初期化したAlchemy Web3 APIを使用して、スマートコントラクトをロードしてみましょう。 `mintNFT`関数の下部に次のコードの行を追加して、`window.contract`グローバル変数にコントラクトを設定します。 ```javascript window.contract = await new web3.eth.Contract(contractABI, contractAddress) @@ -763,11 +763,11 @@ try { - まず、トランザクションパラメータを設定します。 - `to`に受取人のアドレス\(スマートコントラクト\)を設定します 。 - - `from`にトランザクションの署名者\(MetaMask に接続されているユーザーのアドレス: `window.ethereum.selectedAddress`\)を指定します。 + - `from`にトランザクションの署名者\(MetaMaskに接続されているユーザーのアドレス: `window.ethereum.selectedAddress`\)を指定します。 - `data`には、スマートコントラクトの`mintNFT`メソッド呼び出しが含まれ、`tokenURI`とユーザーのウォレットのアドレス`window.ethereum.selectedAddress`を入力として受け取ります。 -- 次に、`window.ethereum.request`を await で呼び出して、MetaMask にトランザクションの署名を依頼します。 このリクエストで、eth メソッド\(eth_sendTransaction\)を指定し、`transactionParameters`を渡していることに注目してください。 この時点で、ブラウザで MetaMask が開かれ、ユーザーにトランザクションの署名または拒否を求めます。 - - トランザクションが成功した場合、この関数は、true に設定された`success`ブール値と、Etherscan でトランザクションについての詳細を確認するようユーザーに求める`status`文字列が入った JSON オブジェクトを返します。 - - トランザクションが失敗した場合、この関数は、false に設定された`success`ブール値と、エラーメッセージを伝える`status`文字列が入った JSON オブジェクトを返します。 +- 次に、`window.ethereum.request`をawaitで呼び出して、MetaMaskにトランザクションの署名を依頼します。 このリクエストで、ethメソッド\(eth_sendTransaction\)を指定し、`transactionParameters`を渡していることに注目してください。 この時点で、ブラウザでMetaMaskが開かれ、ユーザーにトランザクションの署名または拒否を求めます。 + - トランザクションが成功した場合、この関数は、trueに設定された`success`ブール値と、Etherscanでトランザクションについての詳細を確認するようユーザーに求める`status`文字列が入ったJSONオブジェクトを返します。 + - トランザクションが失敗した場合、この関数は、falseに設定された`success`ブール値と、エラーメッセージを伝える`status`文字列が入ったJSONオブジェクトを返します。 `mintNFT`関数全体は、次のようになります。 @@ -832,7 +832,7 @@ export const mintNFT = async (url, name, description) => { 巨大な関数でしたね! あとは、`mintNFT`関数を`Minter.js`コンポーネントに接続するだけです。 -## mintNFT を Minter.js フロントエンドに接続 {#connect-our-frontend} +## mintNFTをMinter.jsフロントエンドに接続 {#connect-our-frontend} `Minter.js`ファイルを開いて、上部の`import { connectWallet, getCurrentWalletConnected } from "./utils/interact.js";`の行を次のように更新してください。 @@ -844,7 +844,7 @@ import { } from "./utils/interact.js" ``` -最後に、次のように`onMintPressed`関数を実装し、インポートした`mintNFT`関数を await で呼び出します。さらに、`status`状態変数を更新し、トランザクションが成功したか失敗したかを反映させるようにします。 +最後に、次のように`onMintPressed`関数を実装し、インポートした`mintNFT`関数をawaitで呼び出します。さらに、`status`状態変数を更新し、トランザクションが成功したか失敗したかを反映させるようにします。 ```javascript const onMintPressed = async () => { @@ -855,7 +855,7 @@ const onMintPressed = async () => { ## 稼働中のウェブサイトに非代替性トークン(NFT)をデプロイ {#deploy-your-NFT} -プロジェクトを稼働させてユーザーが使える準備ができましたでしょうか? 稼働しているウェブサイトへ Minter をデプロイする[チュートリアル](https://docs.alchemy.com/alchemy/tutorials/nft-minter/how-do-i-deploy-nfts-online)をご覧ください。 +プロジェクトを稼働させてユーザーが使える準備ができましたでしょうか? 稼働しているウェブサイトへMinterをデプロイする[チュートリアル](https://docs.alchemy.com/alchemy/tutorials/nft-minter/how-do-i-deploy-nfts-online)をご覧ください。 次は最後のステップです。 @@ -865,9 +865,9 @@ const onMintPressed = async () => { 要約すると、非代替性トークン(NFT)ミンターを構築することで次の方法を学ぶことが出来ました。 -- フロントエンドのプロジェクト経由で MetaMask へアクセス +- フロントエンドのプロジェクト経由でMetaMaskへアクセス - フロントエンドからスマートコントラクトメソッドの呼び出し -- MetaMask を使ったトランザクションの署名 +- MetaMaskを使ったトランザクションの署名 ウォレットに分散型アプリケーション(Dapp)を介してミントされた非代替性トークン(NFT)を表示する方法については、[ウォレットに非代替性トークン(NFT)を表示する方法](https://docs.alchemyapi.io/alchemy/tutorials/how-to-write-and-deploy-a-nft-smart-contract/how-to-view-your-nft-in-your-wallet)という簡単なチュートリアルをご覧ください。 diff --git a/public/content/translations/ja/developers/tutorials/reverse-engineering-a-contract/index.md b/public/content/translations/ja/developers/tutorials/reverse-engineering-a-contract/index.md index 92ccdf1d41f..3ea4449370e 100644 --- a/public/content/translations/ja/developers/tutorials/reverse-engineering-a-contract/index.md +++ b/public/content/translations/ja/developers/tutorials/reverse-engineering-a-contract/index.md @@ -12,7 +12,7 @@ published: 2021-12-30 ## はじめに {#introduction} -*ブロックチェーン上に秘密はありません。*ブロックチェーン上で起こる全てのことは、一貫性があり、検証可能で、公開されています。 理想的には、[コントラクトは Etherscan で公開され、検証されたソースコードであるべきです](https://etherscan.io/address/0xb8901acb165ed027e32754e0ffe830802919727f#code)。 しかし、[必ずしもそうとは限りません](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#code)。 この記事では、ソースコード([`0x2510c039cc3b061d79e564b38836da87e31b342f`](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f))を見ることなくコントラクトをリバースエンジニアリングする方法を学びます。 +_ブロックチェーン上に秘密はありません。_ブロックチェーン上で起こる全てのことは、一貫性があり、検証可能で、公開されています。 理想的には、[コントラクトはEtherscanで公開され、検証されたソースコードであるべきです](https://etherscan.io/address/0xb8901acb165ed027e32754e0ffe830802919727f#code)。 しかし、[必ずしもそうとは限りません](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#code)。 この記事では、ソースコード([`0x2510c039cc3b061d79e564b38836da87e31b342f`](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f))を見ることなくコントラクトをリバースエンジニアリングする方法を学びます。 リバースコンパイラを使用しても、必ず[利用可能な結果](https://etherscan.io/bytecode-decompiler?a=0x2510c039cc3b061d79e564b38836da87e31b342f)が生成されるわけではありません。 この記事では、手動でリバースエンジニアリングを実行し、[オペコード](https://github.com/wolflo/evm-opcodes)からコントラクトを理解する方法を学びます。また、デコンパイラによる結果を理解する方法も学びます。 @@ -20,137 +20,137 @@ published: 2021-12-30 ## 実行可能コードの準備 {#prepare-the-executable-code} -Etherscan にアクセスするとコントラクトのオペコードを入手できます。「**Contract**」タブをクリックし、次に「**Switch to Opcodes View**」をクリックしてください。 これで一行ずつオペコートが表示されます。 +Etherscanにアクセスするとコントラクトのオペコードを入手できます。「**Contract**」タブをクリックし、次に「**Switch to Opcodes View**」をクリックしてください。 これで一行ずつオペコートが表示されます。 ![Etherscanでのオペコードの表示](opcode-view.png) -ジャンプ (JUMP) を理解するには、コード内のオペコードの場所を理解する必要があります。 そのための 1 つの方法は、Google スプレッドシートを開き、オペコードを C 列に貼り付けることです。[既に準備されているこのスプレッドシートをコピーすれば、次のステップをスキップできます](https://docs.google.com/spreadsheets/d/1tKmTJiNjUwHbW64wCKOSJxHjmh0bAUapt6btUYE7kDA/edit?usp=sharing)。 +ジャンプ (JUMP) を理解するには、コード内のオペコードの場所を理解する必要があります。 そのための1つの方法は、Googleスプレッドシートを開き、オペコードをC列に貼り付けることです。[既に準備されているこのスプレッドシートをコピーすれば、次のステップをスキップできます](https://docs.google.com/spreadsheets/d/1tKmTJiNjUwHbW64wCKOSJxHjmh0bAUapt6btUYE7kDA/edit?usp=sharing)。 -次のステップは、正しいコードの位置を取得することです。これで、ジャンプを理解できるようになります。 オペコードのサイズを B 列に、場所(16 進数)を A 列に配置します。`B1`セルに以下の関数を入力し、それを B 列の残りの部分にコードの最終行までコピーアンドペーストします。 これを行った後、B 列を非表示にできます。 +次のステップは、正しいコードの位置を取得することです。これで、ジャンプを理解できるようになります。 オペコードのサイズをB列に、場所(16進数)をA列に配置します。`B1`セルに以下の関数を入力し、それをB列の残りの部分にコードの最終行までコピーアンドペーストします。 これを行った後、B列を非表示にできます。 ``` =1+IF(REGEXMATCH(C1,"PUSH"),REGEXEXTRACT(C1,"PUSH(\d+)"),0) ``` -この関数は、まず 1 バイトをオペコード自体に追加し、次に`PUSH`を探します。 PUSH は特殊なオペコードであり、プッシュされる値用に追加のバイトを保持する必要があります。 オペコードが`PUSH`の場合、バイト数を抽出して加算します。 +この関数は、まず1バイトをオペコード自体に追加し、次に`PUSH`を探します。 PUSHは特殊なオペコードであり、プッシュされる値用に追加のバイトを保持する必要があります。 オペコードが`PUSH`の場合、バイト数を抽出して加算します。 -`A1`に最初のオフセットである 0 を配置します。 次に`A2`に下記の関数を配置し、A 列の残りの部分にコピーアンドペーストします。 +`A1`に最初のオフセットである0を配置します。 次に`A2`に下記の関数を配置し、A列の残りの部分にコピーアンドペーストします。 ``` =dec2hex(hex2dec(A1)+B1) ``` -ジャンプ(`JUMP`と`JUMPI`)の前にプッシュされる値は 16 進数で渡されるため、この関数で 16 進数の値を得る必要があります。 +ジャンプ(`JUMP`と`JUMPI`)の前にプッシュされる値は16進数で渡されるため、この関数で16進数の値を得る必要があります。 ## エントリーポイント(0x00) {#the-entry-point-0x00} コントラクトは、必ず最初のバイトから実行されます。 以下は、コードの冒頭部分です。 -| オフセット | オペコード | スタック(オペコードの後) | -| ---------: | ------------ | ------------------------ | -| 0 | PUSH1 0x80 | 0x80 | -| 2 | PUSH1 0x40 | 0x40, 0x80 | -| 4 | MSTORE | なし | -| 5 | PUSH1 0x04 | 0x04 | -| 7 | CALLDATASIZE | CALLDATASIZE 0x04 | -| 8 | LT | CALLDATASIZE<4 | -| 9 | PUSH2 0x005e | 0x5E CALLDATASIZE<4 | -| C | JUMPI | なし | +| オフセット | オペコード | スタック(オペコードの後) | +| -----:| ------------ | ------------------- | +| 0 | PUSH1 0x80 | 0x80 | +| 2 | PUSH1 0x40 | 0x40, 0x80 | +| 4 | MSTORE | なし | +| 5 | PUSH1 0x04 | 0x04 | +| 7 | CALLDATASIZE | CALLDATASIZE 0x04 | +| 8 | LT | CALLDATASIZE<4 | +| 9 | PUSH2 0x005e | 0x5E CALLDATASIZE<4 | +| C | JUMPI | なし | -このコードは、次の 2 つのことをしています。 +このコードは、次の2つのことをしています。 -1. メモリロケーションの 0x40~0x5F へ、32 バイト値として 0x80 を書き込みます(0x5F に 0x80 が格納され、0x40 ~ 0x5E はすべてゼロになります)。 -2. コールデータサイズ(CALLDATASIZE)を読み取ります。 通常、イーサリアムコントラクトのコールデータは、[アプリケーションバイナリインターフェース(ABI)](https://docs.soliditylang.org/en/v0.8.10/abi-spec.html)に従います。アプリケーションバイナリインターフェース(ABI)では、最低でも 4 バイトが関数セレクタに必要です。 コールデータのサイズが 4 未満の場合、0x5E へジャンプします。 +1. メモリロケーションの0x40~0x5Fへ、32バイト値として0x80を書き込みます(0x5Fに0x80が格納され、0x40~0x5Eはすべてゼロになります)。 +2. コールデータサイズ(CALLDATASIZE)を読み取ります。 通常、イーサリアムコントラクトのコールデータは、[アプリケーションバイナリインターフェース(ABI)](https://docs.soliditylang.org/en/v0.8.10/abi-spec.html)に従います。アプリケーションバイナリインターフェース(ABI)では、最低でも4バイトが関数セレクタに必要です。 コールデータのサイズが4未満の場合、0x5Eへジャンプします。 ![この部分のフローチャート](flowchart-entry.png) -### 0x5E のハンドラ(非アプリケーションバイナリインターフェース(ABI)コールデータの処理) {#the-handler-at-0x5e-for-non-abi-call-data} +### 0x5Eのハンドラ(非アプリケーションバイナリインターフェース(ABI)コールデータの処理) {#the-handler-at-0x5e-for-non-abi-call-data} -| オフセット | オペコード | -| ---------: | ------------ | -| 5E | JUMPDEST | -| 5F | CALLDATASIZE | -| 60 | PUSH2 0x007c | -| 63 | JUMPI | +| オフセット | オペコード | +| -----:| ------------ | +| 5E | JUMPDEST | +| 5F | CALLDATASIZE | +| 60 | PUSH2 0x007c | +| 63 | JUMPI | -このスニペットは、`JUMPDEST`で始まります。 イーサリアム仮想マシン(EVM)プログラムは、`JUMPDEST`ではないオペコードにジャンプした場合に例外を投げます。 次に、CALLDATASIZE を確認し、それが「true」の場合(ゼロではない場合)、0x7C にジャンプします。 これについては後述します。 +このスニペットは、`JUMPDEST`で始まります。 イーサリアム仮想マシン(EVM)プログラムは、`JUMPDEST`ではないオペコードにジャンプした場合に例外を投げます。 次に、CALLDATASIZEを確認し、それが「true」の場合(ゼロではない場合)、0x7Cにジャンプします。 これについては後述します。 -| オフセット | オペコード | スタック(オペコードの後) | -| ---------: | ---------- | ---------------------------------------------------------------------------------------------- | -| 64 | CALLVALUE | [Wei](/glossary/#wei)が呼び出しによって提供されます。 Solidity で`msg.value`が呼び出されます。 | -| 65 | PUSH1 0x06 | 6 CALLVALUE | -| 67 | PUSH1 0x00 | 0 6 CALLVALUE | -| 69 | DUP3 | CALLVALUE 0 6 CALLVALUE | -| 6A | DUP3 | 6 CALLVALUE 0 6 CALLVALUE | -| 6B | SLOAD | Storage[6] CALLVALUE 0 6 CALLVALUE | +| オフセット | オペコード | スタック(オペコードの後) | +| -----:| ---------- | --------------------------------------------------------------------- | +| 64 | CALLVALUE | 呼び出しによって[Wei](/glossary/#wei)が提供されます。 Solidityでは、`msg.value`が呼び出されます。 | +| 65 | PUSH1 0x06 | 6 CALLVALUE | +| 67 | PUSH1 0x00 | 0 6 CALLVALUE | +| 69 | DUP3 | CALLVALUE 0 6 CALLVALUE | +| 6A | DUP3 | 6 CALLVALUE 0 6 CALLVALUE | +| 6B | SLOAD | Storage[6] CALLVALUE 0 6 CALLVALUE | -コールデータがない場合、Storage[6]の値を読み取ります。 この Storage[6] の値はまだわかりませんが、コールデータなしで受信したコントラクトのトランザクションを探すことはできます。 コールデータなしで(つまりメソッドなしで)ETH を送金するだけのトランザクションの場合、Etherscan に`Transfer`メソッドがあります。 実際、[コントラクトが受信した最初のトランザクション](https://etherscan.io/tx/0xeec75287a583c36bcc7ca87685ab41603494516a0f5986d18de96c8e630762e7)は、送金(transfer)です。 +コールデータがない場合、Storage[6]の値を読み取ります。 このStorage[6] の値はまだわかりませんが、コールデータなしで受信したコントラクトのトランザクションを探すことはできます。 コールデータなしで(つまりメソッドなしで)ETHを送金するだけのトランザクションの場合、Etherscanに`Transfer`メソッドがあります。 実際、[コントラクトが受信した最初のトランザクション](https://etherscan.io/tx/0xeec75287a583c36bcc7ca87685ab41603494516a0f5986d18de96c8e630762e7)は、送金(transfer)です。 -このトランザクションを調べるには、「**Click to show more**」をクリックします。コールデータ(Input Data と表示される)が実際に空(`0x`)であることが分かります。 また、値が 1.559ETH であることに留意してください。これに関しては、後述します。 +このトランザクションを調べるには、「**Click to show more**」をクリックします。コールデータ(Input Dataと表示される)が実際に空(`0x`)であることが分かります。 また、値が1.559ETHであることに留意してください。これに関しては、後述します。 ![コールデータが空](calldata-empty.png) -次に「**State**」タブをクリックし、リバースエンジニアリングしているコントラクト(0x2510...)を展開します。 トランザクション中に `Storage[6]` が変更されたことが分かります。「Hex」から「**Number**」に変更すると、次のコントラクトの値に応じて wei に変換された値、1,559,000,000,000,000,000 になります(分かりやすくするためにコンマを追加しています) 。 +次に「**State**」タブをクリックし、リバースエンジニアリングしているコントラクト(0x2510...)を展開します。 トランザクション中に `Storage[6]` が変更されたことが分かります。「Hex」から「**Number**」に変更すると、次のコントラクトの値に応じてweiに変換された値、1,559,000,000,000,000,000になります(分かりやすくするためにコンマを追加しています) 。 ![Storage[6]の変化](storage6.png) -[同時期の他の`Transfer`トランザクション](https://etherscan.io/tx/0xf708d306de39c422472f43cb975d97b66fd5d6a6863db627067167cbf93d84d1#statechange)によって引き起こされた状態変更を確認すると、`Storage[6]`がしばらくの間、コントラクトの値を追跡していたことが分かります。 これを今から`Value*`と呼びます。 アスタリスク (`*`) は、この変数が何をするかまだ*分からない*ことを思い起こさせます。しかし、コントラクトの値を追跡するだけのものではありません。`ADDRESS BALANCE`を使用してアカウント残高を取得できる場合には、非常に高価なストレージを使う必要がないからです。 最初のオペコードは、コントラクト自体のアドレスをプッシュ(PUSH)します。 2 番目のオペコードは、スタックの上部にあるアドレスを読み込み、そのアドレスの残高で置き換えます。 +[同時期の他の`Transfer`トランザクション](https://etherscan.io/tx/0xf708d306de39c422472f43cb975d97b66fd5d6a6863db627067167cbf93d84d1#statechange)によって引き起こされた状態変更を確認すると、`Storage[6]`がしばらくの間、コントラクトの値を追跡していたことが分かります。 これを今から`Value*`と呼びます。 アスタリスク (`*`) は、この変数が何をするかまだ_分からない_ことを思い起こさせます。しかし、コントラクトの値を追跡するだけのものではありません。`ADDRESS BALANCE`を使用してアカウント残高を取得できる場合には、非常に高価なストレージを使う必要がないからです。 最初のオペコードは、コントラクト自体のアドレスをプッシュ(PUSH)します。 2番目のオペコードは、スタックの上部にあるアドレスを読み込み、そのアドレスの残高で置き換えます。 -| オフセット | オペコード | スタック | -| ---------: | ------------ | ------------------------------------------- | -| 6C | PUSH2 0x0075 | 0x75 Value\* CALLVALUE 0 6 CALLVALUE | -| 6F | SWAP2 | CALLVALUE Value\* 0x75 0 6 CALLVALUE | -| 70 | SWAP1 | Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 71 | PUSH2 0x01a7 | 0x01A7 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 74 | JUMP | | +| オフセット | オペコード | スタック | +| -----:| ------------ | --------------------------------------------- | +| 6C | PUSH2 0x0075 | 0x75 Value\* CALLVALUE 0 6 CALLVALUE | +| 6F | SWAP2 | CALLVALUE Value\* 0x75 0 6 CALLVALUE | +| 70 | SWAP1 | Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 71 | PUSH2 0x01a7 | 0x01A7 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 74 | JUMP | | ジャンプ先(JUMPDEST)でも、このコードのトレースを続けます。 -| オフセット | オペコード | スタック | -| ---------: | ---------- | ----------------------------------------------------------- | -| 1A7 | JUMPDEST | Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1A8 | PUSH1 0x00 | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1AA | DUP3 | CALLVALUE 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1AB | NOT | 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| オフセット | オペコード | スタック | +| -----:| ---------- | ------------------------------------------------------------- | +| 1A7 | JUMPDEST | Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1A8 | PUSH1 0x00 | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AA | DUP3 | CALLVALUE 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AB | NOT | 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -`NOT`は、ビットごとの NOT であるため、コール値内の全てのビット値を反転します。 +`NOT`は、ビットごとのNOTであるため、コール値内の全てのビット値を反転します。 -| オフセット | オペコード | スタック | -| ---------: | ------------ | --------------------------------------------------------------------------- | -| 1AC | DUP3 | Value\* 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1AD | GT | Value\*>2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1AE | ISZERO | Value\*<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1AF | PUSH2 0x01df | 0x01DF Value\*<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1B2 | JUMPI | | +| オフセット | オペコード | スタック | +| -----:| ------------ | ------------------------------------------------------------------------------- | +| 1AC | DUP3 | Value\* 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AD | GT | Value\*>2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AE | ISZERO | Value\*<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AF | PUSH2 0x01df | 0x01DF Value\*<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1B2 | JUMPI | | -`Value*`の値が、2^256-CALLVALUE-1 以下の場合にジャンプ(JUMP)します。 これは、オーバーフローを防ぐためのロジックに見えます。 実際に、オフセット 0X01DE でいくつかの無意味な操作(例: 削除される寸前にメモリへの書き込み)をした後、オーバーフローが検出されると、標準の動作としてコントラクトが元に戻されます。 +`Value*`の値が、2^256-CALLVALUE-1以下の場合にジャンプ(JUMP)します。 これは、オーバーフローを防ぐためのロジックに見えます。 実際に、オフセット0X01DEでいくつかの無意味な操作(例: 削除される寸前にメモリへの書き込み)をした後、オーバーフローが検出されると、標準の動作としてコントラクトが元に戻されます。 -このようなオーバーフローが発生する可能性は、非常に低いことに留意してください。これは、コール値に`Value*`を加えたものが、2^256 wei(約 10^59 ETH)と同等になる必要があるためです。 [ETH の総供給量は、この記事の執筆時点で 2 億未満です](https://etherscan.io/stat/supply)。 +このようなオーバーフローが発生する可能性は、非常に低いことに留意してください。これは、コール値に`Value*`を加えたものが、2^256 wei(約10^59 ETH)と同等になる必要があるためです。 [ETHの総供給量は、この記事の執筆時点で2億未満です](https://etherscan.io/stat/supply)。 -| オフセット | オペコード | スタック | -| ---------: | ---------- | ----------------------------------------- | -| 1DF | JUMPDEST | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1E0 | POP | Value\* CALLVALUE 0x75 0 6 CALLVALUE | -| 1E1 | ADD | Value\*+CALLVALUE 0x75 0 6 CALLVALUE | -| 1E2 | SWAP1 | 0x75 Value\*+CALLVALUE 0 6 CALLVALUE | -| 1E3 | JUMP | | +| オフセット | オペコード | スタック | +| -----:| -------- | ------------------------------------------- | +| 1DF | JUMPDEST | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1E0 | POP | Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1E1 | ADD | Value\*+CALLVALUE 0x75 0 6 CALLVALUE | +| 1E2 | SWAP1 | 0x75 Value\*+CALLVALUE 0 6 CALLVALUE | +| 1E3 | JUMP | | -ここに到達した場合、`Value* + CALLVALUE`を取得して、オフセット 0x75 へジャンプします。 +ここに到達した場合、`Value* + CALLVALUE`を取得して、オフセット0x75へジャンプします。 -| オフセット | オペコード | スタック | -| ---------: | ---------- | ------------------------------- | -| 75 | JUMPDEST | Value\*+CALLVALUE 0 6 CALLVALUE | -| 76 | SWAP1 | 0 Value\*+CALLVALUE 6 CALLVALUE | -| 77 | SWAP2 | 6 Value\*+CALLVALUE 0 CALLVALUE | -| 78 | SSTORE | 0 CALLVALUE | +| オフセット | オペコード | スタック | +| -----:| -------- | --------------------------------- | +| 75 | JUMPDEST | Value\*+CALLVALUE 0 6 CALLVALUE | +| 76 | SWAP1 | 0 Value\*+CALLVALUE 6 CALLVALUE | +| 77 | SWAP2 | 6 Value\*+CALLVALUE 0 CALLVALUE | +| 78 | SSTORE | 0 CALLVALUE | ここに到達した場合(コールデータが空である必要があります)、`Value*`にコール値を加えます。 これは、`Transfer`トランザクションが行うことと一致しています。 | オフセット | オペコード | -| ---------: | ---------- | -| 79 | POP | -| 7A | POP | -| 7B | STOP | +| -----:| ----- | +| 79 | POP | +| 7A | POP | +| 7B | STOP | 最後に、スタックをクリアし(任意)、トランザクションが正常に終了したことを通知します。 @@ -158,393 +158,393 @@ Etherscan にアクセスするとコントラクトのオペコードを入手 ![エントリポイントフローチャート](flowchart-entry.png) -## 0x7C のハンドラ {#the-handler-at-0x7c} +## 0x7Cのハンドラ {#the-handler-at-0x7c} 意図的にこのハンドラが何をするか見出しに入れませんでした。 特定のコントラクトの動作を教えるのではなく、どのようにコントラクトをリバースエンジニアリングするかを学ぶのがポイントだからです。 同じ方法で、コードを追って何をするか学ぶことができます。 ここへ到達するのは、次のような場合です。 -- (オフセット 0x63 から)1 バイト、2 バイトまたは 3 バイトのコールデータががある場合 -- (オフセット 0x42 と 0x5D から)メソッドのシグネチャが不明な場合 +- (オフセット0x63から)1バイト、2バイトまたは3バイトのコールデータががある場合 +- (オフセット0x42と0x5Dから)メソッドのシグネチャが不明な場合 -| オフセット | オペコード | スタック | -| ---------: | ------------ | -------------------- | -| 7C | JUMPDEST | | -| 7D | PUSH1 0x00 | 0x00 | -| 7F | PUSH2 0x009d | 0x9D 0x00 | -| 82 | PUSH1 0x03 | 0x03 0x9D 0x00 | -| 84 | SLOAD | Storage[3] 0x9D 0x00 | +| オフセット | オペコード | スタック | +| -----:| ------------ | -------------------- | +| 7C | JUMPDEST | | +| 7D | PUSH1 0x00 | 0x00 | +| 7F | PUSH2 0x009d | 0x9D 0x00 | +| 82 | PUSH1 0x03 | 0x03 0x9D 0x00 | +| 84 | SLOAD | Storage[3] 0x9D 0x00 | これは別のストレージセルです。このセルはどのトランザクションにも見つからなかったので、これが何を意味しているのか理解するのは困難です。 しかし、以下のコードがこれを明確にします。 -| オフセット | オペコード | スタック | -| ---------: | ------------------------------------------------- | ------------------------------- | -| 85 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xff....ff Storage[3] 0x9D 0x00 | -| 9A | AND | Storage[3]-as-address 0x9D 0x00 | +| オフセット | オペコード | スタック | +| -----:| ------------------------------------------------- | ------------------------------- | +| 85 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xff....ff Storage[3] 0x9D 0x00 | +| 9A | AND | Storage[3]-as-address 0x9D 0x00 | -これらのオペコードは、Storage[3]から読み取った値を 160 ビットに切り捨てています。これは、イーサリアムアドレスの長さです。 +これらのオペコードは、Storage[3]から読み取った値を160ビットに切り捨てています。これは、イーサリアムアドレスの長さです。 -| オフセット | オペコード | スタック | -| ---------: | ---------- | ------------------------------- | -| 9B | SWAP1 | 0x9D Storage[3]-as-address 0x00 | -| 9C | JUMP | Storage[3]-as-address 0x00 | +| オフセット | オペコード | スタック | +| -----:| ----- | ------------------------------- | +| 9B | SWAP1 | 0x9D Storage[3]-as-address 0x00 | +| 9C | JUMP | Storage[3]-as-address 0x00 | 次のオペコードに進むため、このジャンプ(JUMP)は不要です。 このコードは、ガス効率が良くありません。 -| オフセット | オペコード | スタック | -| ---------: | ---------- | ------------------------------- | -| 9D | JUMPDEST | Storage[3]-as-address 0x00 | -| 9E | SWAP1 | 0x00 Storage[3]-as-address | -| 9F | POP | Storage[3]-as-address | -| A0 | PUSH1 0x40 | 0x40 Storage[3]-as-address | -| A2 | MLOAD | Mem[0x40] Storage[3]-as-address | - -コードの最初で、Mem[0x40]を 0x80 に設定しました。 その後の 0x40 を確かめると変更していないことが分かります。つまり、これは 0x80 であると推測できます。 - -| オフセット | オペコード | スタック | -| ---------: | ------------ | ------------------------------------------------- | -| A3 | CALLDATASIZE | CALLDATASIZE 0x80 Storage[3]-as-address | -| A4 | PUSH1 0x00 | 0x00 CALLDATASIZE 0x80 Storage[3]-as-address | -| A6 | DUP3 | 0x80 0x00 CALLDATASIZE 0x80 Storage[3]-as-address | -| A7 | CALLDATACOPY | 0x80 Storage[3]-as-address | - -0x80 から始まるすべてのコールデータ(CALLDATA)をメモリにコピーします。 - -| オフセット | オペコード | スタック | -| ---------: | ------------- | -------------------------------------------------------------------------------- | -| A8 | PUSH1 0x00 | 0x00 0x80 Storage[3]-as-address | -| AA | DUP1 | 0x00 0x00 0x80 Storage[3]-as-address | -| AB | CALLDATASIZE | CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | -| AC | DUP4 | 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | -| AD | DUP6 | Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | -| AE | GAS | GAS Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | -| AF | DELEGATE_CALL | | +| オフセット | オペコード | スタック | +| -----:| ---------- | ------------------------------- | +| 9D | JUMPDEST | Storage[3]-as-address 0x00 | +| 9E | SWAP1 | 0x00 Storage[3]-as-address | +| 9F | POP | Storage[3]-as-address | +| A0 | PUSH1 0x40 | 0x40 Storage[3]-as-address | +| A2 | MLOAD | Mem[0x40] Storage[3]-as-address | + +コードの最初で、Mem[0x40]を0x80に設定しました。 その後の0x40を確かめると変更していないことが分かります。つまり、これは0x80であると推測できます。 + +| オフセット | オペコード | スタック | +| -----:| ------------ | ------------------------------------------------- | +| A3 | CALLDATASIZE | CALLDATASIZE 0x80 Storage[3]-as-address | +| A4 | PUSH1 0x00 | 0x00 CALLDATASIZE 0x80 Storage[3]-as-address | +| A6 | DUP3 | 0x80 0x00 CALLDATASIZE 0x80 Storage[3]-as-address | +| A7 | CALLDATACOPY | 0x80 Storage[3]-as-address | + +0x80から始まるすべてのコールデータ(CALLDATA)をメモリにコピーします。 + +| オフセット | オペコード | スタック | +| -----:| ------------- | -------------------------------------------------------------------------------- | +| A8 | PUSH1 0x00 | 0x00 0x80 Storage[3]-as-address | +| AA | DUP1 | 0x00 0x00 0x80 Storage[3]-as-address | +| AB | CALLDATASIZE | CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AC | DUP4 | 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AD | DUP6 | Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AE | GAS | GAS Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AF | DELEGATE_CALL | | これで、かなり明確になりました。 このコントラクトは、[プロキシ](https://blog.openzeppelin.com/proxy-patterns/)として機能しており、Storage[3] 内のアドレスを呼び出して、実際の作業をしています。 `DELEGATE_CALL`は、別のコントラクトを呼び出しますが、同じストレージ内に留まります。 つまり、委任されたコントラクト(現在のコントラクトがこのコントラクトのプロキシとなります)が、同じストレージスペースにアクセスします。 コール(呼び出し)のパラメータは次の通りです。 - _ガス_: 残りのガス - _呼び出されたアドレス_: Storage[3]-as-address -- _コールデータ_: 元のコールデータを配置する、0x80 から始まる CALLDATASIZE バイト +- _コールデータ_: 元のコールデータを配置する、0x80から始まるCALLDATASIZEバイト - _リターンデータ_: なし(0x00 - 0x00)。リターンデータは他の方法で取得(以下を参照) -| オフセット | オペコード | スタック | -| ---------: | -------------- | --------------------------------------------------------------------------------------------- | -| B0 | RETURNDATASIZE | RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B1 | DUP1 | RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B2 | PUSH1 0x00 | 0x00 RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B4 | DUP5 | 0x80 0x00 RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B5 | RETURNDATACOPY | RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| オフセット | オペコード | スタック | +| -----:| -------------- | --------------------------------------------------------------------------------------------- | +| B0 | RETURNDATASIZE | RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B1 | DUP1 | RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B2 | PUSH1 0x00 | 0x00 RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B4 | DUP5 | 0x80 0x00 RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B5 | RETURNDATACOPY | RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -ここでは、すべてのリターンデータを 0x80 から始まるメモリバッファにコピーします。 +ここでは、すべてのリターンデータを0x80から始まるメモリバッファにコピーします。 -| オフセット | オペコード | スタック | -| ---------: | ------------ | ---------------------------------------------------------------------------------------------------------------------------- | -| B6 | DUP2 | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B7 | DUP1 | (((call success/failure))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B8 | ISZERO | (((did the call fail))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| B9 | PUSH2 0x00c0 | 0xC0 (((did the call fail))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| BC | JUMPI | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| BD | DUP2 | RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| BE | DUP5 | 0x80 RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| BF | RETURN | | +| オフセット | オペコード | スタック | +| -----:| ------------ | ---------------------------------------------------------------------------------------------------------------------------- | +| B6 | DUP2 | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B7 | DUP1 | (((call success/failure))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B8 | ISZERO | (((did the call fail))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B9 | PUSH2 0x00c0 | 0xC0 (((did the call fail))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BC | JUMPI | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BD | DUP2 | RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BE | DUP5 | 0x80 RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BF | RETURN | | -リターンデータをバッファ(0x80 ~ 0x80+RETURNDATASIZE)にコピーする呼び出しの後、その呼び出しが成功した場合は、そのバッファを正確に返します(`RETURN`します)。 +リターンデータをバッファ(0x80~0x80+RETURNDATASIZE)にコピーする呼び出しの後、その呼び出しが成功した場合は、そのバッファを正確に返します(`RETURN`します)。 -### DELEGATECALL の失敗 {#delegatecall-failed} +### DELEGATECALLの失敗 {#delegatecall-failed} -0xC0 に到達した場合は、現在のコントラクトが呼び出したコントラクトが、元に戻された(REVERT された)ことを意味します。 現在のコントラクトはこのコントラクトの単なるプロキシであるため、現在のコントラクトも同じデータを返して、元に戻す(REVERT する)必要があります。 +0xC0に到達した場合は、現在のコントラクトが呼び出したコントラクトが、元に戻された(REVERTされた)ことを意味します。 現在のコントラクトはこのコントラクトの単なるプロキシであるため、現在のコントラクトも同じデータを返して、元に戻す(REVERTする)必要があります。 -| オフセット | オペコード | スタック | -| ---------: | ---------- | ------------------------------------------------------------------------------------------------------------------- | -| C0 | JUMPDEST | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| C1 | DUP2 | RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| C2 | DUP5 | 0x80 RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | -| C3 | REVERT | | +| オフセット | オペコード | スタック | +| -----:| -------- | ------------------------------------------------------------------------------------------------------------------- | +| C0 | JUMPDEST | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| C1 | DUP2 | RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| C2 | DUP5 | 0x80 RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| C3 | REVERT | | -そのため、前に`RETURN`で使用した同じバッファ(0x80 ~ 0x80+RETURNDATASIZE)を元に戻します(`REVERT`します)。 +そのため、前に`RETURN`で使用した同じバッファ(0x80~0x80+RETURNDATASIZE)を元に戻します(`REVERT`します)。 ![プロキシするための呼び出しのフローチャート](flowchart-proxy.png) ## アプリケーションバイナリインターフェース(ABI)呼び出し {#abi-calls} -コールデータのサイズが 4 バイト以上である場合、有効なアプリケーションバイナリインターフェース(ABI)呼び出しである可能性があります。 +コールデータのサイズが4バイト以上である場合、有効なアプリケーションバイナリインターフェース(ABI)呼び出しである可能性があります。 -| オフセット | オペコード | スタック | -| ---------: | ------------ | ------------------------------------------------- | -| D | PUSH1 0x00 | 0x00 | -| F | CALLDATALOAD | (((First word (256 bits) of the call data))) | -| 10 | PUSH1 0xe0 | 0xE0 (((First word (256 bits) of the call data))) | -| 12 | SHR | (((first 32 bits (4 bytes) of the call data))) | +| オフセット | オペコード | スタック | +| -----:| ------------ | ------------------------------------------------- | +| D | PUSH1 0x00 | 0x00 | +| F | CALLDATALOAD | (((First word (256 bits) of the call data))) | +| 10 | PUSH1 0xe0 | 0xE0 (((First word (256 bits) of the call data))) | +| 12 | SHR | (((first 32 bits (4 bytes) of the call data))) | -Etherscan では、`1C`が未知のオペコードとなっていますが、これは[Etherscan でこの機能が作成された後に追加された](https://eips.ethereum.org/EIPS/eip-145)ため、まだ反映がされていないのが理由です。 [最新のオペコードテーブル](https://github.com/wolflo/evm-opcodes)では、これが右シフトであることが示されています +Etherscanでは、`1C`が未知のオペコードとなっていますが、これは[Etherscanでこの機能が作成された後に追加された](https://eips.ethereum.org/EIPS/eip-145)ため、まだ反映がされていないのが理由です。 An [up to date opcode table](https://github.com/wolflo/evm-opcodes) shows us that this is shift right -| オフセット | オペコード | スタック | -| ---------: | ---------------- | -------------------------------------------------------------------------------------------------------- | -| 13 | DUP1 | (((first 32 bits (4 bytes) of the call data))) (((first 32 bits (4 bytes) of the call data))) | -| 14 | PUSH4 0x3cd8045e | 0x3CD8045E (((first 32 bits (4 bytes) of the call data))) (((first 32 bits (4 bytes) of the call data))) | -| 19 | GT | 0x3CD8045E>first-32-bits-of-the-call-data (((first 32 bits (4 bytes) of the call data))) | -| 1A | PUSH2 0x0043 | 0x43 0x3CD8045E>first-32-bits-of-the-call-data (((first 32 bits (4 bytes) of the call data))) | -| 1D | JUMPI | (((first 32 bits (4 bytes) of the call data))) | +| オフセット | オペコード | スタック | +| -----:| ---------------- | -------------------------------------------------------------------------------------------------------- | +| 13 | DUP1 | (((first 32 bits (4 bytes) of the call data))) (((first 32 bits (4 bytes) of the call data))) | +| 14 | PUSH4 0x3cd8045e | 0x3CD8045E (((first 32 bits (4 bytes) of the call data))) (((first 32 bits (4 bytes) of the call data))) | +| 19 | GT | 0x3CD8045E>first-32-bits-of-the-call-data (((first 32 bits (4 bytes) of the call data))) | +| 1A | PUSH2 0x0043 | 0x43 0x3CD8045E>first-32-bits-of-the-call-data (((first 32 bits (4 bytes) of the call data))) | +| 1D | JUMPI | (((first 32 bits (4 bytes) of the call data))) | -このようにメソッドシグネチャのマッチングテストを 2 つに分割することで、平均的にテストの半分を節約できます。 その直後のコードと 0x43 のコードは、コールデータの最初の 32 ビットの複製(`DUP1`)、プッシュ(`PUSH4 (((method signature>`)、`EQ`を実行し等式を判定、メソッドシグネチャがマッチした場合は`JUMPI`、という同じパターンをたどります。 以下に、メソッドシグネチャ、そのアドレス、既知の場合は[対応するメソッド定義](https://www.4byte.directory/)を示します。 +このようにメソッドシグネチャのマッチングテストを2つに分割することで、平均的にテストの半分を節約できます。 その直後のコードと0x43のコードは、コールデータの最初の32ビットの複製(`DUP1`)、プッシュ(`PUSH4 (((method signature>`)、`EQ`を実行し等式を判定、メソッドシグネチャがマッチした場合は`JUMPI`、という同じパターンをたどります。 以下に、メソッドシグネチャ、そのアドレス、既知の場合は[対応するメソッド定義](https://www.4byte.directory/)を示します。 -| メソッド | メソッドシグネチャ | ジャンプ先のオフセット | -| -------------------------------------------------------------------------------------- | ------------------ | ---------------------- | -| [splitter()](https://www.4byte.directory/signatures/?bytes4_signature=0x3cd8045e) | 0x3cd8045e | 0x0103 | -| ??? | 0x81e580d3 | 0x0138 | -| [currentWindow()](https://www.4byte.directory/signatures/?bytes4_signature=0xba0bafb4) | 0xba0bafb4 | 0x0158 | -| ??? | 0x1f135823 | 0x00C4 | -| [merkleRoot()](https://www.4byte.directory/signatures/?bytes4_signature=0x2eb4a7ab) | 0x2eb4a7ab | 0x00ED | +| メソッド | メソッドシグネチャ | ジャンプ先のオフセット | +| -------------------------------------------------------------------------------------- | ---------- | ----------- | +| [splitter()](https://www.4byte.directory/signatures/?bytes4_signature=0x3cd8045e) | 0x3cd8045e | 0x0103 | +| ??? | 0x81e580d3 | 0x0138 | +| [currentWindow()](https://www.4byte.directory/signatures/?bytes4_signature=0xba0bafb4) | 0xba0bafb4 | 0x0158 | +| ??? | 0x1f135823 | 0x00C4 | +| [merkleRoot()](https://www.4byte.directory/signatures/?bytes4_signature=0x2eb4a7ab) | 0x2eb4a7ab | 0x00ED | -一致するものが見つからない場合、そのコードは、現在のコントラクトがプロキシとなっているコントラクトに一致するものがあることを期待して、[0x7C のプロキシハンドラ](#the-handler-at-0x7c)へジャンプします。 +一致するものが見つからない場合、そのコードは、現在のコントラクトがプロキシとなっているコントラクトに一致するものがあることを期待して、[0x7Cのプロキシハンドラ](#the-handler-at-0x7c)へジャンプします。 ![アプリケーションバイナリインターフェース(ABI)呼び出しのフローチャート](flowchart-abi.png) ## splitter() {#splitter} -| オフセット | オペコード | スタック | -| ---------: | ------------ | ----------------------------- | -| 103 | JUMPDEST | | -| 104 | CALLVALUE | CALLVALUE | -| 105 | DUP1 | CALLVALUE CALLVALUE | -| 106 | ISZERO | CALLVALUE==0 CALLVALUE | -| 107 | PUSH2 0x010f | 0x010F CALLVALUE==0 CALLVALUE | -| 10A | JUMPI | CALLVALUE | -| 10B | PUSH1 0x00 | 0x00 CALLVALUE | -| 10D | DUP1 | 0x00 0x00 CALLVALUE | -| 10E | REVERT | | - -この関数が最初に行うことは、呼び出しが ETH を送金していないことを確認することです。 この関数は、[`payable`](https://solidity-by-example.org/payable/)ではありません。 誰かが ETH を送金してきた場合は、何かの間違いです。ETH を戻せなくなる前に元に戻す(`REVERT`する)必要があります。 - -| オフセット | オペコード | スタック | -| ---------: | ------------------------------------------------- | --------------------------------------------------------------------------- | -| 10F | JUMPDEST | | -| 110 | POP | | -| 111 | PUSH1 0x03 | 0x03 | -| 113 | SLOAD | (((Storage[3] a.k.a the contract for which we are a proxy))) | -| 114 | PUSH1 0x40 | 0x40 (((Storage[3] a.k.a the contract for which we are a proxy))) | -| 116 | MLOAD | 0x80 (((Storage[3] a.k.a the contract for which we are a proxy))) | -| 117 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xFF...FF 0x80 (((Storage[3] a.k.a the contract for which we are a proxy))) | -| 12C | SWAP1 | 0x80 0xFF...FF (((Storage[3] a.k.a the contract for which we are a proxy))) | -| 12D | SWAP2 | (((Storage[3] a.k.a the contract for which we are a proxy))) 0xFF...FF 0x80 | -| 12E | AND | ProxyAddr 0x80 | -| 12F | DUP2 | 0x80 ProxyAddr 0x80 | -| 130 | MSTORE | 0x80 | - -0x80 にはプロキシアドレスが含まれるようになりました。 - -| オフセット | オペコード | スタック | -| ---------: | ------------ | --------- | -| 131 | PUSH1 0x20 | 0x20 0x80 | -| 133 | ADD | 0xA0 | -| 134 | PUSH2 0x00e4 | 0xE4 0xA0 | -| 137 | JUMP | 0xA0 | - -### E4 のコード {#the-e4-code} - -これらの行を見るのは初めてですが、他のメソッドと共有されています(以下を参照)。 スタック X の値を呼び出します。`splitter()`で、この X の値が 0xA0 であることを覚えておいてください。 - -| オフセット | オペコード | スタック | -| ---------: | ---------- | ----------- | -| E4 | JUMPDEST | X | -| E5 | PUSH1 0x40 | 0x40 X | -| E7 | MLOAD | 0x80 X | -| E8 | DUP1 | 0x80 0x80 X | -| E9 | SWAP2 | X 0x80 0x80 | -| EA | SUB | X-0x80 0x80 | -| EB | SWAP1 | 0x80 X-0x80 | -| EC | RETURN | | - -したがって、このコードは、スタック(X)内のメモリのポインターを受け取ります。これにより、コントラクトが 0x80 ~ X までのバッファを返します(`RETURN`します)。 - -`splitter()`の場合、これは現在のコントラクトがプロキシとなっているアドレスを返します。 `RETURN`は、0x80 ~ 0x9F のバッファを返します。これは、このデータを書き込んだ場所です(上記のオフセット 0x130)。 +| オフセット | オペコード | スタック | +| -----:| ------------ | ----------------------------- | +| 103 | JUMPDEST | | +| 104 | CALLVALUE | CALLVALUE | +| 105 | DUP1 | CALLVALUE CALLVALUE | +| 106 | ISZERO | CALLVALUE==0 CALLVALUE | +| 107 | PUSH2 0x010f | 0x010F CALLVALUE==0 CALLVALUE | +| 10A | JUMPI | CALLVALUE | +| 10B | PUSH1 0x00 | 0x00 CALLVALUE | +| 10D | DUP1 | 0x00 0x00 CALLVALUE | +| 10E | REVERT | | + +この関数が最初に行うことは、呼び出しがETHを送金していないことを確認することです。 この関数は、[`payable`](https://solidity-by-example.org/payable/)ではありません。 誰かがETHを送金してきた場合は、何かの間違いです。ETHを戻せなくなる前に元に戻す(`REVERT`する)必要があります。 + +| オフセット | オペコード | スタック | +| -----:| ------------------------------------------------- | --------------------------------------------------------------------------- | +| 10F | JUMPDEST | | +| 110 | POP | | +| 111 | PUSH1 0x03 | 0x03 | +| 113 | SLOAD | (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 114 | PUSH1 0x40 | 0x40 (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 116 | MLOAD | 0x80 (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 117 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xFF...FF 0x80 (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 12C | SWAP1 | 0x80 0xFF...FF (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 12D | SWAP2 | (((Storage[3] a.k.a the contract for which we are a proxy))) 0xFF...FF 0x80 | +| 12E | AND | ProxyAddr 0x80 | +| 12F | DUP2 | 0x80 ProxyAddr 0x80 | +| 130 | MSTORE | 0x80 | + +0x80にはプロキシアドレスが含まれるようになりました。 + +| オフセット | オペコード | スタック | +| -----:| ------------ | --------- | +| 131 | PUSH1 0x20 | 0x20 0x80 | +| 133 | ADD | 0xA0 | +| 134 | PUSH2 0x00e4 | 0xE4 0xA0 | +| 137 | JUMP | 0xA0 | + +### E4のコード {#the-e4-code} + +これらの行を見るのは初めてですが、他のメソッドと共有されています(以下を参照)。 スタックXの値を呼び出します。`splitter()`で、このXの値が0xA0であることを覚えておいてください。 + +| オフセット | オペコード | スタック | +| -----:| ---------- | ----------- | +| E4 | JUMPDEST | X | +| E5 | PUSH1 0x40 | 0x40 X | +| E7 | MLOAD | 0x80 X | +| E8 | DUP1 | 0x80 0x80 X | +| E9 | SWAP2 | X 0x80 0x80 | +| EA | SUB | X-0x80 0x80 | +| EB | SWAP1 | 0x80 X-0x80 | +| EC | RETURN | | + +したがって、このコードは、スタック(X)内のメモリのポインターを受け取ります。これにより、コントラクトが0x80~Xまでのバッファを返します(`RETURN`します)。 + +`splitter()`の場合、これは現在のコントラクトがプロキシとなっているアドレスを返します。 `RETURN`は、0x80~0x9Fのバッファを返します。これは、このデータを書き込んだ場所です(上記のオフセット0x130)。 ## currentWindow() {#currentwindow} -オフセット 0x158 ~ 0x163 のコードは、`splitter()`の 0x103 ~ 0x10E で見たものと(`JUMPI`の宛先以外は)同一であるため、`currentWindow()`も同様に`payable`ではないことが分かります。 +オフセット0x158~0x163のコードは、`splitter()`の0x103~0x10Eで見たものと(`JUMPI`の宛先以外は)同一であるため、`currentWindow()`も同様に`payable`ではないことが分かります。 -| オフセット | オペコード | スタック | -| ---------: | ------------ | -------------------- | -| 164 | JUMPDEST | | -| 165 | POP | | -| 166 | PUSH2 0x00da | 0xDA | -| 169 | PUSH1 0x01 | 0x01 0xDA | -| 16B | SLOAD | Storage[1] 0xDA | -| 16C | DUP2 | 0xDA Storage[1] 0xDA | -| 16D | JUMP | Storage[1] 0xDA | +| オフセット | オペコード | スタック | +| -----:| ------------ | -------------------- | +| 164 | JUMPDEST | | +| 165 | POP | | +| 166 | PUSH2 0x00da | 0xDA | +| 169 | PUSH1 0x01 | 0x01 0xDA | +| 16B | SLOAD | Storage[1] 0xDA | +| 16C | DUP2 | 0xDA Storage[1] 0xDA | +| 16D | JUMP | Storage[1] 0xDA | -### DA のコード {#the-da-code} +### DAのコード {#the-da-code} -このコードもまた他のメソッドと共有されます。 スタック Y の値を呼び出します。`currentWindow()`で、この Y の値が Storage[1]であることを覚えておいてください。 +このコードもまた他のメソッドと共有されます。 スタックYの値を呼び出します。`currentWindow()`で、このYの値がStorage[1]であることを覚えておいてください。 -| オフセット | オペコード | スタック | -| ---------: | ---------- | ---------------- | -| DA | JUMPDEST | Y 0xDA | -| DB | PUSH1 0x40 | 0x40 Y 0xDA | -| DD | MLOAD | 0x80 Y 0xDA | -| DE | SWAP1 | Y 0x80 0xDA | -| DF | DUP2 | 0x80 Y 0x80 0xDA | -| E0 | MSTORE | 0x80 0xDA | +| オフセット | オペコード | スタック | +| -----:| ---------- | ---------------- | +| DA | JUMPDEST | Y 0xDA | +| DB | PUSH1 0x40 | 0x40 Y 0xDA | +| DD | MLOAD | 0x80 Y 0xDA | +| DE | SWAP1 | Y 0x80 0xDA | +| DF | DUP2 | 0x80 Y 0x80 0xDA | +| E0 | MSTORE | 0x80 0xDA | -0x80 ~ 0x9F に Y を書き込みます。 +0x80~0x9FにYを書き込みます。 -| オフセット | オペコード | スタック | -| ---------: | ---------- | -------------- | -| E1 | PUSH1 0x20 | 0x20 0x80 0xDA | -| E3 | ADD | 0xA0 0xDA | +| オフセット | オペコード | スタック | +| -----:| ---------- | -------------- | +| E1 | PUSH1 0x20 | 0x20 0x80 0xDA | +| E3 | ADD | 0xA0 0xDA | -残りはすでに、[上記](#the-e4-code)で説明されています。 0xDA にジャンプして、スタックの先頭(Y)を 0x80 ~ 0x9F に書き込み、その値を返します。 `currentWindow()`の場合、Storage[1]を返します。 +残りはすでに、[上記](#the-e4-code)で説明されています。 0xDAにジャンプして、スタックの先頭(Y)を0x80~0x9Fに書き込み、その値を返します。 `currentWindow()`の場合、Storage[1]を返します。 ## merkleRoot() {#merkleroot} -オフセット 0xED ~ 0xF8 のコードは、`splitter()`の 0x103 ~ 0x10E で見たものと(`JUMPI`の宛先以外は)同一であるため、`merkleRoot()`も同様に`payable`ではないことが分かります。 +オフセット0xED~0xF8のコードは、`splitter()`の0x103~0x10Eで見たものと(`JUMPI`の宛先以外は)同一であるため、`merkleRoot()`も同様に`payable`ではないことが分かります。 -| オフセット | オペコード | スタック | -| ---------: | ------------ | -------------------- | -| F9 | JUMPDEST | | -| FA | POP | | -| FB | PUSH2 0x00da | 0xDA | -| FE | PUSH1 0x00 | 0x00 0xDA | -| 100 | SLOAD | Storage[0] 0xDA | -| 101 | DUP2 | 0xDA Storage[0] 0xDA | -| 102 | JUMP | Storage[0] 0xDA | +| オフセット | オペコード | スタック | +| -----:| ------------ | -------------------- | +| F9 | JUMPDEST | | +| FA | POP | | +| FB | PUSH2 0x00da | 0xDA | +| FE | PUSH1 0x00 | 0x00 0xDA | +| 100 | SLOAD | Storage[0] 0xDA | +| 101 | DUP2 | 0xDA Storage[0] 0xDA | +| 102 | JUMP | Storage[0] 0xDA | ジャンプ(JUMP)の後に何が起こるかは、[すでに分かっています](#the-da-code)。 つまり、`merkleRoot()`は、Storage[0]を返します。 ## 0x81e580d3 {#0x81e580d3} -オフセット 0x138 ~ 0x143 のコードは、`splitter()`の 0x103 ~ 0x10E で見たものと(`JUMPI`の宛先以外は)同一であるため、この関数も同様に`payable`ではないことが分かりります。 - -| オフセット | オペコード | スタック | -| ---------: | ------------ | ------------------------------------------------------------ | -| 144 | JUMPDEST | | -| 145 | POP | | -| 146 | PUSH2 0x00da | 0xDA | -| 149 | PUSH2 0x0153 | 0x0153 0xDA | -| 14C | CALLDATASIZE | CALLDATASIZE 0x0153 0xDA | -| 14D | PUSH1 0x04 | 0x04 CALLDATASIZE 0x0153 0xDA | -| 14F | PUSH2 0x018f | 0x018F 0x04 CALLDATASIZE 0x0153 0xDA | -| 152 | JUMP | 0x04 CALLDATASIZE 0x0153 0xDA | -| 18F | JUMPDEST | 0x04 CALLDATASIZE 0x0153 0xDA | -| 190 | PUSH1 0x00 | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 192 | PUSH1 0x20 | 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 194 | DUP3 | 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 195 | DUP5 | CALLDATASIZE 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 196 | SUB | CALLDATASIZE-4 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 197 | SLT | CALLDATASIZE-4<32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 198 | ISZERO | CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 199 | PUSH2 0x01a0 | 0x01A0 CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 19C | JUMPI | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | - -この関数は、コールデータに少なくとも 32 バイト(1 ワード)を必要とするようです。 - -| オフセット | オペコード | スタック | -| ---------: | ---------- | -------------------------------------------- | -| 19D | DUP1 | 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 19E | DUP2 | 0x00 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 19F | REVERT | | +オフセット0x138~0x143のコードは、`splitter()`の0x103~0x10Eで見たものと(`JUMPI`の宛先以外は)同一であるため、この関数も同様に`payable`ではないことが分かりります。 + +| オフセット | オペコード | スタック | +| -----:| ------------ | ------------------------------------------------------------ | +| 144 | JUMPDEST | | +| 145 | POP | | +| 146 | PUSH2 0x00da | 0xDA | +| 149 | PUSH2 0x0153 | 0x0153 0xDA | +| 14C | CALLDATASIZE | CALLDATASIZE 0x0153 0xDA | +| 14D | PUSH1 0x04 | 0x04 CALLDATASIZE 0x0153 0xDA | +| 14F | PUSH2 0x018f | 0x018F 0x04 CALLDATASIZE 0x0153 0xDA | +| 152 | JUMP | 0x04 CALLDATASIZE 0x0153 0xDA | +| 18F | JUMPDEST | 0x04 CALLDATASIZE 0x0153 0xDA | +| 190 | PUSH1 0x00 | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 192 | PUSH1 0x20 | 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 194 | DUP3 | 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 195 | DUP5 | CALLDATASIZE 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 196 | SUB | CALLDATASIZE-4 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 197 | SLT | CALLDATASIZE-4<32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 198 | ISZERO | CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 199 | PUSH2 0x01a0 | 0x01A0 CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 19C | JUMPI | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | + +この関数は、コールデータに少なくとも32バイト(1ワード)を必要とするようです。 + +| オフセット | オペコード | スタック | +| -----:| ------ | -------------------------------------------- | +| 19D | DUP1 | 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 19E | DUP2 | 0x00 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 19F | REVERT | | コールデータを取得しなかった場合、トランザクションはリターンデータなしで元に戻されます。 -この関数が、必要なコールデータを*取得した*場合、何が起こるか見ていきましょう。 - -| オフセット | オペコード | スタック | -| ---------: | ------------ | ---------------------------------------- | -| 1A0 | JUMPDEST | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | -| 1A1 | POP | 0x04 CALLDATASIZE 0x0153 0xDA | -| 1A2 | CALLDATALOAD | calldataload(4) CALLDATASIZE 0x0153 0xDA | - -`calldataload(4)`は、メソッドシグネチャの*後にある*コールデータの最初のワードです。 - -| オフセット | オペコード | スタック | -| ---------: | ------------ | ---------------------------------------------------------------------------- | -| 1A3 | SWAP2 | 0x0153 CALLDATASIZE calldataload(4) 0xDA | -| 1A4 | SWAP1 | CALLDATASIZE 0x0153 calldataload(4) 0xDA | -| 1A5 | POP | 0x0153 calldataload(4) 0xDA | -| 1A6 | JUMP | calldataload(4) 0xDA | -| 153 | JUMPDEST | calldataload(4) 0xDA | -| 154 | PUSH2 0x016e | 0x016E calldataload(4) 0xDA | -| 157 | JUMP | calldataload(4) 0xDA | -| 16E | JUMPDEST | calldataload(4) 0xDA | -| 16F | PUSH1 0x04 | 0x04 calldataload(4) 0xDA | -| 171 | DUP2 | calldataload(4) 0x04 calldataload(4) 0xDA | -| 172 | DUP2 | 0x04 calldataload(4) 0x04 calldataload(4) 0xDA | -| 173 | SLOAD | Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA | -| 174 | DUP2 | calldataload(4) Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA | -| 175 | LT | calldataload(4))`、もう一つが`isClaimed()`であり、エアドロップコントラクトのように見えます。 ここからは、オペコードごとに調べる代わりに、[デコンパイラ](https://etherscan.io/bytecode-decompiler?a=0x2f81e57ff4f4d83b40a9f719fd892d8e806e0761)を使用します。デコンパイラは、このコントラクトの 3 つの関数について利用可能な結果を生成します。 他の関数のリバースエンジニアリングは、読者の演習として残しておきます。 +残りのメソッドの1つが`claim()`、もう一つが`isClaimed()`であり、エアドロップコントラクトのように見えます。 ここからは、オペコードごとに調べる代わりに、[デコンパイラ](https://etherscan.io/bytecode-decompiler?a=0x2f81e57ff4f4d83b40a9f719fd892d8e806e0761)を使用します。デコンパイラは、このコントラクトの3つの関数について利用可能な結果を生成します。 他の関数のリバースエンジニアリングは、読者の演習として残しておきます。 ### scaleAmountByPercentage {#scaleamountbypercentage} @@ -592,7 +592,7 @@ def unknown8ffb5c97(uint256 _param1, uint256 _param2) payable: return (_param1 * _param2 / 100 * 10^6) ``` -最初の`require`では、コールデータ内に 2 つのパラメータにとって十分なサイズ、つまり関数シグネチャの 4 バイトに加え少なくとも 64 バイトあるかどうかをテストしています。 そうでない場合、問題があるのは明らかです。 +最初の`require`では、コールデータ内に2つのパラメータにとって十分なサイズ、つまり関数シグネチャの4バイトに加え少なくとも64バイトあるかどうかをテストしています。 そうでない場合、問題があるのは明らかです。 `if`文は、`_param1`がゼロでないこと、さらに`_param1 * _param2`が負でないことを確認していると思われます。 これは、オーバー(アンダー)フローを防止している可能性があります。 @@ -611,7 +611,7 @@ def unknown2e7ba6ef(uint256 _param1, uint256 _param2, uint256 _param3, array _pa revert with 0, 'cannot claim for a future window' ``` -ここでは、重要事項が 2 つあります。 +ここでは、重要事項が2つあります。 - `_param2`は、`uint256`として宣言されているが、実際にはアドレスである - `_param1`は、請求対象のウィンドウであり、`currentWindow`であるか、前のウィンドウである必要がある @@ -650,7 +650,7 @@ def unknown2e7ba6ef(uint256 _param1, uint256 _param2, uint256 _param3, array _pa gas 30000 wei ``` -これは、コントラクトが自身の ETH を別のアドレス(コントラクトまたは外部所有アカウント)に送金する方法です。 送金する金額の値で呼び出します。 これは ETH のエアドロップであると思われます。 +これは、コントラクトが自身のETHを別のアドレス(コントラクトまたは外部所有アカウント)に送金する方法です。 送金する金額の値で呼び出します。 これはETHのエアドロップであると思われます。 ```python if not return_data.size: @@ -660,22 +660,22 @@ def unknown2e7ba6ef(uint256 _param1, uint256 _param2, uint256 _param3, array _pa value unknown81e580d3[_param1] * _param3 / 100 * 10^6 wei ``` -下の 2 行は、Storage[2] も呼び出すコントラクトであることを示しています。 [コンストラクタのトランザクションを見ると](https://etherscan.io/tx/0xa1ea0549fb349eb7d3aff90e1d6ce7469fdfdcd59a2fd9b8d1f5e420c0d05b58#statechange)、このコントラクトは[0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2)であり、[ソースコードが Etherscan にアップロードされている](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code)ラップドイーサ(WETH)コントラクトであることが分かります。 +下の2行は、Storage[2] も呼び出すコントラクトであることを示しています。 [コンストラクタのトランザクションを見ると](https://etherscan.io/tx/0xa1ea0549fb349eb7d3aff90e1d6ce7469fdfdcd59a2fd9b8d1f5e420c0d05b58#statechange)、このコントラクトは[0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2)であり、[ソースコードがEtherscanにアップロードされている](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code)ラップドイーサ(WETH)コントラクトであることが分かります。 -このコントラクトは、`_param2`に ETH を送金しようとしていると思われます。 送金できれば問題ありません。 送金できない場合は、[ラップドイーサ(WETH)](https://weth.io/)を送金しようとします。 `_param2`が外部所有アカウント(EOA)である場合、必ず ETH を受け取ることができますが、コントラクトは ETH の受け取りを拒否することができます。 しかし、ラップドイーサ(WETH)は ERC-20 であるため、コントラクトは受け取りを拒否できません。 +このコントラクトは、`_param2`にETHを送金しようとしていると思われます。 送金できれば問題ありません。 送金できない場合は、[ラップドイーサ(WETH)](https://weth.io/)を送金しようとします。 `_param2`が外部所有アカウント(EOA)である場合、必ずETHを受け取ることができますが、コントラクトはETHの受け取りを拒否することができます。 しかし、ラップドイーサ(WETH)はERC-20であるため、コントラクトは受け取りを拒否できません。 ```python ... log 0xdbd5389f: addr(_param2), unknown81e580d3[_param1] * _param3 / 100 * 10^6, bool(ext_call.success) ``` -関数の最後に、ログエントリが生成されていることがわかります。 [生成されたログエントリを確認し](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#events)、`0xdbd5...`で始まるトピックでフィルタリングします。 [そのようなエントリを生成したトランザクションの 1 つをクリックすると](https://etherscan.io/tx/0xe7d3b7e00f645af17dfbbd010478ef4af235896c65b6548def1fe95b3b7d2274)、実際に請求のように見えることがわかります。アカウントは、リバースエンジニアリングしているコントラクトにメッセージを送信し、代わりに ETH を取得しています。 +関数の最後に、ログエントリが生成されていることがわかります。 [生成されたログエントリを確認し](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#events)、`0xdbd5...`で始まるトピックでフィルタリングします。 [そのようなエントリを生成したトランザクションの1つをクリックすると](https://etherscan.io/tx/0xe7d3b7e00f645af17dfbbd010478ef4af235896c65b6548def1fe95b3b7d2274)、実際に請求のように見えることがわかります。アカウントは、リバースエンジニアリングしているコントラクトにメッセージを送信し、代わりにETHを取得しています。 ![請求トランザクション](claim-tx.png) ### 1e7df9d3 {#1e7df9d3} -この関数は、上記の[`claim`](#claim)と非常に似ています。 この関数はマークルプルーフも同様に確認し、ETH を最初に送金しようと試み、同じタイプのログエントリを生成します。 +この関数は、上記の[`claim`](#claim)と非常に似ています。 この関数はマークルプルーフも同様に確認し、ETHを最初に送金しようと試み、同じタイプのログエントリを生成します。 ```python def unknown1e7df9d3(uint256 _param1, uint256 _param2, array _param3) payable: diff --git a/public/content/translations/ja/developers/tutorials/run-node-raspberry-pi/index.md b/public/content/translations/ja/developers/tutorials/run-node-raspberry-pi/index.md index bb2d6d722a6..d892d0f9b91 100644 --- a/public/content/translations/ja/developers/tutorials/run-node-raspberry-pi/index.md +++ b/public/content/translations/ja/developers/tutorials/run-node-raspberry-pi/index.md @@ -14,34 +14,34 @@ source: Ethereum on ARM sourceUrl: https://ethereum-on-arm-documentation.readthedocs.io/en/latest/ --- -**Ethereum on Arm は、Raspberry Pi をイーサリアムノードにするカスタム Linux イメージです。** +**Ethereum on Armは、Raspberry PiをイーサリアムノードにするカスタムLinuxイメージです。** -Ethereum on Arm を使用して Raspberry Pi をイーサリアムノードにする場合、次のハードウェアが推奨されます。 +Ethereum on Armを使用してRaspberry Piをイーサリアムノードにする場合、次のハードウェアが推奨されます。 -- Raspberry 4 (モデル B 8 GB)、Odroid M1 または Rock 5B (8 GB / 16 GB RAM)ボード -- マイクロ SD カード(最小構成: 16 GB、クラス 10) -- 2 TB SSD 最小 USB 3.0 ディスクまたは USB-SATA ケース付き SSD +- Raspberry 4 (モデル B 8 GB)、Odroid M1またはRock 5B (8 GB / 16 GB RAM)ボード +- マイクロSDカード(最小構成: 16 GB、クラス10) +- 2 TB SSD最小USB 3.0ディスクまたはUSB-SATAケース付きSSD - 電源 - イーサネットケーブル - ポートフォワーディング機能(詳細はクライアントを参照してください) - ヒートシンクとファンが付属しているケース -- USB キーボード、モニター、HDMI ケーブル(マイクロ HDMI) (オプション) +- USBキーボード、モニター、HDMIケーブル(マイクロHDMI) (オプション) -## Ethereum on Arm を実行する理由 {#why-run-ethereum-on-arm} +## Ethereum on Armを実行する理由 {#why-run-ethereum-on-arm} -ARM ボードは価格が非常に手頃で、柔軟性の高い、小型のコンピュータです。 このボードは、イーサリアムノードを実行するのに適しています。手ごろな価格で、ノードだけにリソースを使うように設定が可能であり、効率的で電力消費量が少なく、物理的にも小さいので家に置いても邪魔にならないからです。 また、ノードを立ち上げるのも簡単です。Raspberry Pi のマイクロ SD カードは、ビルド済みイメージを簡単に書き込めるので、ソフトウェアのダウンロードやビルドが不要です。 +ARMボードは価格が非常に手頃で、柔軟性の高い、小型のコンピュータです。 このボードは、イーサリアムノードを実行するのに適しています。手ごろな価格で、ノードだけにリソースを使うように設定が可能であり、効率的で電力消費量が少なく、物理的にも小さいので家に置いても邪魔にならないからです。 また、ノードを立ち上げるのも簡単です。Raspberry PiのマイクロSDカードは、ビルド済みイメージを簡単に書き込めるので、ソフトウェアのダウンロードやビルドが不要です。 ## 動作方法 {#how-does-it-work} -ビルド済みイメージを Raspberry Pi のメモリーカードに書き込みます。 このイメージには、イーサリアムノードを実行するために必要なすべてが含まれています。 この書き込まれたカードがあれば、ユーザーは Raspberry Pi の電源を入れるだけで済みます。 ノードを実行するのに必要なすべてのプロセスは自動で開始します。 メモリーカードに Linux ベースのオペレーティングシステム(OS)が含まれており、その上でシステムレベルのプロセスが自動的に実行され、ARM ボードがイーサリアムノードになります。 +ビルド済みイメージをRaspberry Piのメモリーカードに書き込みます。 このイメージには、イーサリアムノードを実行するために必要なすべてが含まれています。 この書き込まれたカードがあれば、ユーザーはRaspberry Piの電源を入れるだけで済みます。 ノードを実行するのに必要なすべてのプロセスは自動で開始します。 メモリーカードにLinuxベースのオペレーティングシステム(OS)が含まれており、その上でシステムレベルのプロセスが自動的に実行され、ARMボードがイーサリアムノードになります。 -イーサリアムは、Raspberry Pi の Linux OS としてよく知られている「Raspbian」では実行できません。Raspbian は、依然として 32 ビットのアーキテクチャを使用しており、これによるメモリの問題が発生します。さらに、コンセンサスクライアントは、32 ビットバイナリをサポートしていません。 これを克服するために、Ethereum on Arm チームは、「Armbian」と呼ばれるネイティブの 64 ビット OS に移行しました。 +イーサリアムは、Raspberry PiのLinux OSとしてよく知られている「Raspbian」では実行できません。Raspbianは、依然として32ビットのアーキテクチャを使用しており、これによるメモリの問題が発生します。さらに、コンセンサスクライアントは、32ビットバイナリをサポートしていません。 これを克服するために、Ethereum on Armチームは、「Armbian」と呼ばれるネイティブの64ビットOSに移行しました。 -**このイメージは、必要なステップのすべてを行います**。環境のセットアップ、SSD ディスクのフォーマット、イーサリアムソフトウェアのインストールと実行だけでなくブロックチェーンの同期も開始します。 +**このイメージは、必要なステップのすべてを行います**。環境のセットアップ、SSDディスクのフォーマット、イーサリアムソフトウェアのインストールと実行だけでなくブロックチェーンの同期も開始します。 ## 実行クライアントとコンセンサスクライアントに関する注意事項 {#note-on-execution-and-consensus-clients} -Ethereum on Arm のイメージには、ビルド済みの実行クライアントとコンセンサスクライアントがサービスとして組み込まれています。 イーサリアムノードでは、両方のクライアントが同期されて実行される必要があります。 ここでユーザーがすべきことは、イメージをダウンロードして書き込んだ後、サービスを開始するだけです。 イメージには、次の実行クライアントが入っています。 +Ethereum on Armのイメージには、ビルド済みの実行クライアントとコンセンサスクライアントがサービスとして組み込まれています。 イーサリアムノードでは、両方のクライアントが同期されて実行される必要があります。 ここでユーザーがすべきことは、イメージをダウンロードして書き込んだ後、サービスを開始するだけです。 イメージには、次の実行クライアントが入っています。 - Geth - Nethermind @@ -54,13 +54,13 @@ Ethereum on Arm のイメージには、ビルド済みの実行クライアン - プリズム - テク -使いたい実行クライアントとコンセンサスクライアントを各 1 つずつ選びます。すべての実行クライアントは、すべてのコンセンサスクライアントと連携可能です。 クライアントを選択しなかった場合、デフォルトで Geth とライトハウスになります。ボードに電源を入れると、これらのクライアントが自動的に実行されます。 Geth がピアを見つけて接続できるように、ルーターで 30303 ポートを開く必要があります。 +使いたい実行クライアントとコンセンサスクライアントを各1つずつ選びます。すべての実行クライアントは、すべてのコンセンサスクライアントと連携可能です。 クライアントを選択しなかった場合、デフォルトでGethとライトハウスになります。ボードに電源を入れると、これらのクライアントが自動的に実行されます。 Gethがピアを見つけて接続できるように、ルーターで30303ポートを開く必要があります。 ## イメージのダウンロード {#downloading-the-image} -Raspberry Pi 4 のイーサリアムイメージは、「プラグ・アンド・プレイ」イメージです。実行クライアントとコンセンサスクライアントのインストールとセットアップが自動的に行われ、それらが互いに通信し、イーサリアムネットワークに接続するように設定されます。 ユーザーがすべきことは、単純なコマンドを使用してプロセスを開始するだけです。 +Raspberry Pi 4のイーサリアムイメージは、「プラグ・アンド・プレイ」イメージです。実行クライアントとコンセンサスクライアントのインストールとセットアップが自動的に行われ、それらが互いに通信し、イーサリアムネットワークに接続するように設定されます。 ユーザーがすべきことは、単純なコマンドを使用してプロセスを開始するだけです。 -[Ethereum on Arm](https://ethereumonarm-my.sharepoint.com/:u:/p/dlosada/Ec_VmUvr80VFjf3RYSU-NzkBmj2JOteDECj8Bibde929Gw?download=1)から Raspberry Pi イメージをダウンロードし、次のように SHA256 ハッシュを確認してください。 +[Ethereum on Arm](https://ethereumonarm-my.sharepoint.com/:u:/p/dlosada/Ec_VmUvr80VFjf3RYSU-NzkBmj2JOteDECj8Bibde929Gw?download=1)からRaspberry Piイメージをダウンロードし、次のようにSHA256ハッシュを確認してください。 ```sh # ダウンロードしたイメージがあるディレクトリで以下を実行します。 @@ -69,11 +69,11 @@ shasum -a 256 ethonarm_22.04.00.img.zip fb497e8f8a7388b62d6e1efbc406b9558bee7ef46ec7e53083630029c117444f ``` -Rock 5B と Odroid M1 ボードのイメージは、Ethereum-on-Arm の[ダウンロードページ](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/quick-guide/download-and-install.html)から入手可能です。 +Rock 5BとOdroid M1ボードのイメージは、Ethereum-on-Armの[ダウンロードページ](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/quick-guide/download-and-install.html)から入手可能です。 -## マイクロ SD への書き込み {#flashing-the-microsd} +## マイクロSDへの書き込み {#flashing-the-microsd} -Raspberry Pi で使用するマイクロ SD カードは、まずデスクトップパソコンかノートパソコンに挿入して書き込む必要があります。 以下のターミナルコマンドで、ダウンロードしたイメージを SD カードに書き込みます。 +Raspberry Piで使用するマイクロSDカードは、まずデスクトップパソコンかノートパソコンに挿入して書き込む必要があります。 以下のターミナルコマンドで、ダウンロードしたイメージをSDカードに書き込みます。 ```shell # マイクロSDカード名の確認 @@ -82,34 +82,34 @@ sudo fdisk -l >> sdxxx ``` -SD カード名を正しく取得することは、非常に重要です。次に使うコマンドに`dd`があり、これはイメージを書き込む前にカードの内容を完全に削除するからです。 zip イメージがあるディレクトリに移動して続行します。 +SDカード名を正しく取得することは、非常に重要です。次に使うコマンドに`dd`があり、これはイメージを書き込む前にカードの内容を完全に削除するからです。 zipイメージがあるディレクトリに移動して続行します。 ```shell -# zip展開とイメージの書き込み +# unzip and flash image unzip ethonarm_22.04.00.img.zip -sudo dd bs=1M if=ethonarm_kiln_22.04.00.img of=/dev/mmcblk0 conv=fdatasync status=progress +sudo dd bs=1M if=ethonarm_22.04.00.img of=/dev/ conv=fdatasync status=progress ``` -これでカードに書きこまれたので、Raspberry Pi に挿入できます。 +これでカードに書きこまれたので、Raspberry Piに挿入できます。 ## ノードの開始 {#start-the-node} -SD カードを挿入した Raspberry Pi に、SSD とイーサネットケーブルを接続し、電源を入れてください。 OS が起動し、クライアントソフトウェアのインストールやビルドなど、Raspberry Pi をイーサリアムノードにする事前設定処理が自動的に開始します。 この処理には 10 ~ 15 分を要します。 +SDカードを挿入したRaspberry Piに、SSDとイーサネットケーブルを接続し、電源を入れてください。 OSが起動し、クライアントソフトウェアのインストールやビルドなど、Raspberry Piをイーサリアムノードにする事前設定処理が自動的に開始します。 この処理には10~15分を要します。 -自動インストールおよび設定が完了したら、モニターとキーボードがボードに接続されているならば直接ターミナルを使うか、SSH 接続でデバイスへログインしてください。 `ethereum`アカウントを使用してログインします。このアカウントは、ノードの開始に必要なパーミッションを持っています。 +自動インストールおよび設定が完了したら、モニターとキーボードがボードに接続されているならば直接ターミナルを使うか、SSH接続でデバイスへログインしてください。 `ethereum`アカウントを使用してログインします。このアカウントは、ノードの開始に必要なパーミッションを持っています。 ```shell User: ethereum Password: ethereum ``` -デフォルトの実行クライアントである Geth が自動的に開始します。 次のターミナルコマンドを使用してログをチェックすることで、開始を確認できます。 +デフォルトの実行クライアントであるGethが自動的に開始します。 次のターミナルコマンドを使用してログをチェックすることで、開始を確認できます。 ```sh sudo journalctl -u geth -f ``` -コンセンサスクライアントは、明示的に開始する必要があります。 開始するには、まずルーターの 9000 ポートを開き、ライトハウスがピアを見つけて接続できるようにします。 次にライトハウスサービスを有効にして開始します。 +コンセンサスクライアントは、明示的に開始する必要があります。 開始するには、まずルーターの9000ポートを開き、ライトハウスがピアを見つけて接続できるようにします。 次にライトハウスサービスを有効にして開始します。 ```sh sudo systemctl enable lighthouse-beacon @@ -124,15 +124,15 @@ sudo journalctl -u lighthouse-beacon チェックポイント同期を使用するため、コンセンサスクライアントは数分で同期されることに注意してください。 実行クライアントは、同期により時間がかかります。数時間かかる場合もあります。さらに、コンセンサスクライアントの同期が完了するまで、同期を開始しません(これは、実行クライアントが、同期されたコンセンサスクライアントが提供する同期先のターゲットを必要とするためです)。 -Geth とライトハウスのサービスが開始し同期されると、Raspberry Pi がイーサリアムノードになります。 イーサリアムネットワークとのやり取りを行うには、8545 ポートで Geth クライアントに接続し、Geth の Javascript コンソールを使うことが最も一般的な方法です。 また、Curl などのリクエストツールを使用して、JSON オブジェクトとしてフォーマットされたコマンドを送信することもできます。 詳細は、[Geth のドキュメント](https://geth.ethereum.org/)をご覧ください。 +Gethとライトハウスのサービスが開始し同期されると、Raspberry Piがイーサリアムノードになります。 イーサリアムネットワークとのやり取りを行うには、8545ポートでGethクライアントに接続し、GethのJavascriptコンソールを使うことが最も一般的な方法です。 また、Curlなどのリクエストツールを使用して、JSONオブジェクトとしてフォーマットされたコマンドを送信することもできます。 詳細は、[Gethのドキュメント](https://geth.ethereum.org/)をご覧ください。 -Geth は、ブラウザで表示できる Grafana ダッシュボードに、メトリクスをレポートするように事前設定されています。 この機能を使用してノードの健全性を監視したい上級ユーザーは、`ipaddress:3000`にアクセスして`user: admin`と`passwd: ethereum`を入力してください。 +Gethは、ブラウザで表示できるGrafanaダッシュボードに、メトリクスをレポートするように事前設定されています。 この機能を使用してノードの健全性を監視したい上級ユーザーは、`ipaddress:3000`にアクセスして`user: admin`と`passwd: ethereum`を入力してください。 ## バリデータ {#validators} -バリデータは、コンセンサスクライアントにオプションで追加することもできます。 バリデータソフトウェアを使用すると、ノードが積極的にコンセンサスに参加し、暗号経済のセキュリティをネットワークに提供できるようになります。 この作業の報酬として ETH を受け取れます。 バリデータを実行するには、まず 32 ETH を持っている必要があり、これをデポジットコントラクトに預け入れる必要があります。 **長期的なコミットメントとなるため、この ETH はまだ引き出すことはできません。** 預け入れは、[ランチパッド](https://launchpad.ethereum.org/)のステップバイステップガイドに従って行うことができます。 この作業は、デスクトップパソコンまたはノートパソコンで行いますが、キーは生成しないでください。キーは Raspberry Pi で直接生成します。 +バリデータは、コンセンサスクライアントにオプションで追加することもできます。 バリデータソフトウェアを使用すると、ノードが積極的にコンセンサスに参加し、暗号経済のセキュリティをネットワークに提供できるようになります。 この作業の報酬としてETHを受け取れます。 バリデータを実行するには、まず32 ETHを持っている必要があり、これをデポジットコントラクトに預け入れる必要があります。 **長期的なコミットメントとなるため、このETHはまだ引き出すことはできません。** 預け入れは、[ランチパッド](https://launchpad.ethereum.org/)のステップバイステップガイドに従って行うことができます。 この作業は、デスクトップパソコンまたはノートパソコンで行いますが、キーは生成しないでください。キーはRaspberry Piで直接生成します。 -Raspberry Pi のターミナルを開き、以下のコマンドを実行して、デポジットキーを生成してください。 +Raspberry Piのターミナルを開き、以下のコマンドを実行して、デポジットキーを生成してください。 ``` sudo apt-get update @@ -140,11 +140,11 @@ sudo apt-get install staking-deposit-cli cd && deposit new-mnemonic --num_validators 1 ``` -ニーモニックフレーズを安全に保管してください。 上記コマンドで、ノードのキーストアに 2 つのファイルが生成されました。これらは、バリデータキーとデポジットデータファイルです。 デポジットデータは、ランチパッドにアップロードする必要があるため、Raspberry Pi からデスクトップパソコンまたはノートパソコンにコピーする必要があります。 これは、ssh 接続や他のコピー/ペーストの手法を用いて行えます。 +ニーモニックフレーズを安全に保管してください。 上記コマンドで、ノードのキーストアに2つのファイルが生成されました。これらは、バリデータキーとデポジットデータファイルです。 デポジットデータは、ランチパッドにアップロードする必要があるため、Raspberry Piからデスクトップパソコンまたはノートパソコンにコピーする必要があります。 これは、ssh接続や他のコピー/ペーストの手法を用いて行えます。 ランチパッドを実行しているコンピューターでデポジットデータファイルが利用可能になったら、これをランチパッド画面の「`+`」にドラッグ・アンド・ドロップすることができます。 画面の指示に従って、デポジットコントラクトにトランザクションを送信してください。 -Raspberry Pi に戻ると、バリデータが開始可能になります。 これには、バリデータキーのインポート、報酬を受け取るためのアドレスの設定、事前設定されたバリデータプロセスの開始が必要になります。 以下は、ライトハウス向けの例です。その他のコンセンサス クライアント向けの手順については、[Ethereum on Arm のドキュメント](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/)を参照してください。 +Raspberry Piに戻ると、バリデータが開始可能になります。 これには、バリデータキーのインポート、報酬を受け取るためのアドレスの設定、事前設定されたバリデータプロセスの開始が必要になります。 以下は、ライトハウス向けの例です。その他のコンセンサス クライアント向けの手順については、[Ethereum on Armのドキュメント](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/)を参照してください。 ```shell # バリデータキーのインポート @@ -157,15 +157,15 @@ sudo sed -i 's/' /etc/ethereum/lighthouse-validator.conf sudo systemctl start lighthouse-validator ``` -おめでとうございます。これでフルイーサリアムノードとバリデータが、Raspberry Pi で実行されました。 +おめでとうございます。これでフルイーサリアムノードとバリデータが、Raspberry Piで実行されました。 ## 詳細情報 {#more-details} -このページでは、Raspberry Pi を使用して Geth およびライトハウスのノードとバリデータを設定する方法の概要について説明しました。 さらに詳細な手順は、[Ethereum on Arm](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/index.html)のウェブサイトでご覧いただけます。 +このページでは、Raspberry Piを使用してGethおよびライトハウスのノードとバリデータを設定する方法の概要について説明しました。 さらに詳細な手順は、[Ethereum on Arm](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/index.html)のウェブサイトでご覧いただけます。 ## フィードバックご協力のお願い {#feedback-appreciated} -Raspberry Pi は多くのユーザーが利用しており、イーサリアムネットワークの健全性に非常に良い影響を与えてきました。 このチュートリアルを深く掘り下げていき、テストネットで実行してみてください。また、Ethereum on Arm の GitHub ページの確認、フィードバックの提供、問題提起、プルリクエストの作成による、テクノロジーの進歩とドキュメント化推進へのご協力をお願いします。 +Raspberry Piは多くのユーザーが利用しており、イーサリアムネットワークの健全性に非常に良い影響を与えてきました。 このチュートリアルを深く掘り下げていき、テストネットで実行してみてください。また、Ethereum on ArmのGitHubページの確認、フィードバックの提供、問題提起、プルリクエストの作成による、テクノロジーの進歩とドキュメント化推進へのご協力をお願いします。 ## 参考文献 {#references} diff --git a/public/content/translations/ja/developers/tutorials/send-token-etherjs/index.md b/public/content/translations/ja/developers/tutorials/send-token-etherjs/index.md new file mode 100644 index 00000000000..c160a581043 --- /dev/null +++ b/public/content/translations/ja/developers/tutorials/send-token-etherjs/index.md @@ -0,0 +1,212 @@ +--- +title: ethers.jsを使用したトークンの送信 +description: ethers.jsを使用してトークンを送信するための初心者向けのガイド +author: Kim YongJun +tags: + - "ETHERS.JS" + - "ERC-20" + - "トークン" +skill: beginner +lang: ja +published: 2021-04-06 +--- + +## ethers.js(5.0)を使用したトークンの送信 {#send-token} + +### このチュートリアルでは、次の処理を行う方法について学びます。 {#you-learn-about} + +- ethers.jsのインポート +- トークンの転送 +- ネットワークの混雑状況に応じたガス代の設定 + +### はじめに {#to-get-started} + +まず、ethers.jsというライブラリをjavascriptにインポートする必要があります。これには、ethers.js 5.0も含まれます。 + +### インストール {#install-ethersjs} + +```shell +/home/ricmoo> npm install --save ethers +``` + +ブラウザでES6を使用するには次のようにします。 + +```html + +``` + +ブラウザでES3(UMD)を使用するには次のようにします。 + +```html + +``` + +### パラメータ {#param} + +1. **`contract_address`**: トークンのコントラクトアドレス(転送したいトークンがイーサでない場合は、コントラクトアドレスが必要となります) +2. **`send_token_amount`**: 受取人に送る量 +3. **`to_address`**: 受取人のアドレス +4. **`send_account`**: 送信者のアドレス +5. **`private_key`**: トランザクションに署名し、実際にトークンを転送するための送信者の秘密鍵 + +## 注意 {#notice} + +`signTransaction(tx)`は、`sendTransaction()`の内部で実行されるため削除されました。 + +## 送信の手順 {#procedure} + +### 1. ネットワーク(testnet)に接続する {#connect-to-network} + +#### プロバイダー(Infura)の設定 {#set-provider} + +テストネットのRopstenに接続します。 + +```javascript +window.ethersProvider = new ethers.providers.InfuraProvider("ropsten") +``` + +### 2. ウォレットを作成する {#create-wallet} + +```javascript +let wallet = new ethers.Wallet(private_key) +``` + +### 3. ウォレットをネットに接続する {#connect-wallet-to-net} + +```javascript +let walletSigner = wallet.connect(window.ethersProvider) +``` + +### 4. 現在のガス代を取得する {#get-gas} + +```javascript +window.ethersProvider.getGasPrice() // gasPrice +``` + +### 5. トランザクションを定義する {#define-transaction} + +以下で定義されている変数は、`send_token()`に依存します。 + +### トランザクションのパラメータ {#transaction-params} + +1. **`send_account`**: トークン送信者のアドレス +2. **`to_address`**: トークンの受取人のアドレス +3. **`send_token_amount`**: 送信するトークンの量 +4. **`gas_limit`**: ガスリミット +5. **`gas_price`**: ガス代 + +[使い方については以下をご覧ください。](#how-to-use) + +```javascript +const tx = { + from: send_account, + to: to_address, + value: ethers.utils.parseEther(send_token_amount), + nonce: window.ethersProvider.getTransactionCount(send_account, "latest"), + gasLimit: ethers.utils.hexlify(gas_limit), // 100000 + gasPrice: gas_price, +} +``` + +### 6. 転送する {#transfer} + +```javascript +walletSigner.sendTransaction(tx).then((transaction) => { + console.dir(transaction) + alert("Send finished!") +}) +``` + +## 使い方 {#how-to-use} + +```javascript +let private_key = + "41559d28e936dc92104ff30691519693fc753ffbee6251a611b9aa1878f12a4d" +let send_token_amount = "1" +let to_address = "0x4c10D2734Fb76D3236E522509181CC3Ba8DE0e80" +let send_address = "0xda27a282B5B6c5229699891CfA6b900A716539E6" +let gas_limit = "0x100000" +let wallet = new ethers.Wallet(private_key) +let walletSigner = wallet.connect(window.ethersProvider) +let contract_address = "" +window.ethersProvider = new ethers.providers.InfuraProvider("ropsten") + +send_token( + contract_address, + send_token_amount, + to_address, + send_address, + private_key +) +``` + +### 成功しました! {#success} + +![トランザクションが成功したときのイメージ](./successful-transaction.png) + +## send_token() {#send-token-method} + +```javascript +function send_token( + contract_address, + send_token_amount, + to_address, + send_account, + private_key +) { + let wallet = new ethers.Wallet(private_key) + let walletSigner = wallet.connect(window.ethersProvider) + + window.ethersProvider.getGasPrice().then((currentGasPrice) => { + let gas_price = ethers.utils.hexlify(parseInt(currentGasPrice)) + console.log(`gas_price: ${gas_price}`) + + if (contract_address) { + // general token send + let contract = new ethers.Contract( + contract_address, + send_abi, + walletSigner + ) + + // How many tokens? + let numberOfTokens = ethers.utils.parseUnits(send_token_amount, 18) + console.log(`numberOfTokens: ${numberOfTokens}`) + + // Send tokens + contract.transfer(to_address, numberOfTokens).then((transferResult) => { + console.dir(transferResult) + alert("sent token") + }) + } // ether send + else { + const tx = { + from: send_account, + to: to_address, + value: ethers.utils.parseEther(send_token_amount), + nonce: window.ethersProvider.getTransactionCount( + send_account, + "latest" + ), + gasLimit: ethers.utils.hexlify(gas_limit), // 100000 + gasPrice: gas_price, + } + console.dir(tx) + try { + walletSigner.sendTransaction(tx).then((transaction) => { + console.dir(transaction) + alert("Send finished!") + }) + } catch (error) { + alert("failed to send!!") + } + } + }) +} +``` diff --git a/public/content/translations/ja/developers/tutorials/the-graph-fixing-web3-data-querying/index.md b/public/content/translations/ja/developers/tutorials/the-graph-fixing-web3-data-querying/index.md index ef4a3ea6511..7aace3323b9 100644 --- a/public/content/translations/ja/developers/tutorials/the-graph-fixing-web3-data-querying/index.md +++ b/public/content/translations/ja/developers/tutorials/the-graph-fixing-web3-data-querying/index.md @@ -16,9 +16,9 @@ source: soliditydeveloper.com sourceUrl: https://soliditydeveloper.com/thegraph --- -今回は、The Graph について詳しく見ていきます。The Grash は昨年、分散型アプリケーション(Dapp)を開発するために欠かせない標準スタックの一部となりました。 まずは、従来のやり方から見ていきましょう。 +今回は、The Graphについて詳しく見ていきます。The Grashは昨年、分散型アプリケーション(Dapp)を開発するために欠かせない標準スタックの一部となりました。 まずは、従来のやり方から見ていきましょう。 -## The Graph を使わない例 {#without-the-graph} +## The Graphを使わない例 {#without-the-graph} それでは、説明のために簡単な例から始めます。 私たちは皆、ゲームが好きなので、ユーザーが賭けをする次の簡単なゲームを考えてみましょう。 @@ -52,7 +52,7 @@ contract Game { 2. `totalGamesPlayerLost`の取得 3. `BetPlaced`イベントのサブスクライブ -右に示したように[Web3 イベント](https://docs.web3js.org/api/web3/class/Contract#events)をリッスンできますが、多くのケースを処理する必要があります。 +右に示したように[Web3イベント](https://docs.web3js.org/api/web3/class/Contract#events)をリッスンできますが、多くのケースを処理する必要があります。 ```solidity GameContract.events.BetPlaced({ @@ -83,29 +83,29 @@ GameContract.events.BetPlaced({ では、より良い解決策を見ていきましょう。 -## GraphQL の紹介 {#let-me-introduce-to-you-graphql} +## GraphQLの紹介 {#let-me-introduce-to-you-graphql} -最初に GraphQL について説明します。GraphQL は、もともとフェイスブック社によって設計され、実装されました。 従来の Rest API モデルについては、ご存知かもしれません。 では、今度は次のように必要なデータを正確に取得できるクエリを作成できると想像してみてください。 +最初にGraphQLについて説明します。GraphQLは、もともとフェイスブック社によって設計され、実装されました。 従来のRest APIモデルについては、ご存知かもしれません。 では、今度は次のように必要なデータを正確に取得できるクエリを作成できると想像してみてください。 ![GraphQL APIとREST APIの比較](./graphql.jpg) -2 つの画像は、GraphQL の本質をほぼ捉えています。 右のクエリーでは、必要なデータを正確に定義できるので、1 回のリクエストで必要なものだけを取得できます。 GraphQL サーバーは必要とされるすべてのデータの取得を処理できるので、フロントエンドのコンシューマ側にとっては極めて使いやすいツールとなっています。 ご興味があれば、サーバーが具体的にどのようにクエリを処理するかについて[わかりやすい説明](https://www.apollographql.com/blog/graphql-explained-5844742f195e/)をご覧ください。 +2つの画像は、GraphQLの本質をほぼ捉えています。 右のクエリーでは、必要なデータを正確に定義できるので、1回のリクエストで必要なものだけを取得できます。 GraphQLサーバーは必要とされるすべてのデータの取得を処理できるので、フロントエンドのコンシューマ側にとっては極めて使いやすいツールとなっています。 ご興味があれば、サーバーが具体的にどのようにクエリを処理するかについて[わかりやすい説明](https://www.apollographql.com/blog/graphql-explained-5844742f195e/)をご覧ください。 -この知識をもとに、ブロックチェーン空間と The Graph の世界に入って行きましょう。 +この知識をもとに、ブロックチェーン空間とThe Graphの世界に入って行きましょう。 -## The Graph とは {#what-is-the-graph} +## The Graphとは {#what-is-the-graph} -ブロックチェーンは、分散型データベースですが、通常のデータベースとは対照的に、データベースに対するクエリ言語がありません。 データを取得することにおいては、苦痛を伴うか不可能かのどちらかです。 The Graph は、ブロックチェーンデータのインデックス作成とクエリを行うための分散型プロトコルです。 ご想像の通り The Graph は、GraphQL をクエリ言語として使用しています。 +ブロックチェーンは、分散型データベースですが、通常のデータベースとは対照的に、データベースに対するクエリ言語がありません。 データを取得することにおいては、苦痛を伴うか不可能かのどちらかです。 The Graphは、ブロックチェーンデータのインデックス作成とクエリを行うための分散型プロトコルです。 ご想像の通りThe Graphは、GraphQLをクエリ言語として使用しています。 ![The Graph](./thegraph.png) -何かを理解するには例を見るのが最善なので、先ほどの GameContract で The Graph を使ってみましょう。 +何かを理解するには例を見るのが最善なので、先ほどのGameContractでThe Graphを使ってみましょう。 ## サブグラフの作成方法 {#how-to-create-a-subgraph} -サブグラフは、データにインデックスを作成する方法を定義するものです。 定義には、次の 3 つのコンポーネントが必要です。 +サブグラフは、データにインデックスを作成する方法を定義するものです。 定義には、次の3つのコンポーネントが必要です。 1. マニフェスト(`subgraph.yaml`) 2. スキーマ(`schema.graphql`) @@ -120,11 +120,11 @@ GameContract.events.BetPlaced({ - 関数呼び出しやブロックなど、その他に何をリッスンするか - 呼び出されるマッピング関数 (後述の`mapping.ts`を参照) -マニフェストには複数のコントラクトとハンドラを定義できます。 典型的な設定では、Truffle または Hardhat プロジェクト内にサブグラフフォルダと独自のリポジトリがあります。 それにより、簡単にアプリケーションバイナリインターフェース(ABI)を参照することができます。 +マニフェストには複数のコントラクトとハンドラを定義できます。 典型的な設定では、TruffleまたはHardhatプロジェクト内にサブグラフフォルダと独自のリポジトリがあります。 それにより、簡単にアプリケーションバイナリインターフェース(ABI)を参照することができます。 -便利さの観点から、Mustache のようなテンプレートツールを使用することもできます。 `subgraph.template.yaml`を作成し、最新のデプロイメントに基づいたアドレスを挿入します。 より高度な設定例については、[Aave サブグラフリポジトリ](https://github.com/aave/aave-protocol/tree/master/thegraph)の例をご覧ください。 +便利さの観点から、Mustacheのようなテンプレートツールを使用することもできます。 `subgraph.template.yaml`を作成し、最新のデプロイメントに基づいたアドレスを挿入します。 より高度な設定例については、[Aaveサブグラフリポジトリ](https://github.com/aave/aave-protocol/tree/master/thegraph)の例をご覧ください。 -完全なドキュメントは、こちらをご覧ください。https://thegraph.com/docs/define-a-subgraph#the-subgraph-manifest +ドキュメント全文については、[こちら](https://thegraph.com/docs/en/developing/creating-a-subgraph/#the-subgraph-manifest)をご覧ください。 ```yaml specVersion: 0.0.1 @@ -157,17 +157,17 @@ dataSources: ### スキーマ(`schema.graphql`) {#schema} -スキーマは、GraphQL のデータ定義です。 必要なエンティティとタイプを定義することができます。 The Graph でサポートされているタイプは、次のとおりです。 +スキーマは、GraphQLのデータ定義です。 必要なエンティティとタイプを定義することができます。 The Graphでサポートされているタイプは、次のとおりです。 - バイト型 -- ID 型 +- ID型 - 文字列型 - ブール型 - 整数型 -- BigInt 型 -- BigDecimal 型 +- BigInt型 +- BigDecimal型 -リレーションシップを定義するために、エンティティをタイプとして使用することもできます。 この例では、プレイヤーと賭け(Bet)で 1 対多のリレーションシップを定義します。 「!」 は、空の値を取れないこと意味します。 完全なドキュメントは、こちらをご覧ください。https://thegraph.com/docs/define-a-subgraph#the-graphql-schema +リレーションシップを定義するために、エンティティをタイプとして使用することもできます。 この例では、プレイヤーと賭け(Bet)で1対多のリレーションシップを定義します。 「!」 は、空の値を取れないこと意味します。 完全なドキュメントは、[こちら](https://thegraph.com/docs/en/developing/creating-a-subgraph/#the-subgraph-manifest)をご覧ください。 ```graphql type Bet @entity { @@ -188,15 +188,15 @@ type Player @entity { ### マッピング(`mapping.ts`) {#mapping} -The Graph のマッピングファイルは、受信したイベントをエンティティに変換する関数を定義します。 Typescript のサブセットである AssemblyScript で書きます。 これは、より効率化され、よりポータブル化されたマッピングの実行を実現するため、WebAssembly(WASM)にコンパイルされます。 +The Graphのマッピングファイルは、受信したイベントをエンティティに変換する関数を定義します。 TypescriptのサブセットであるAssemblyScriptで書きます。 これは、より効率化され、よりポータブル化されたマッピングの実行を実現するため、WebAssembly(WASM)にコンパイルされます。 -各関数を`subgraph.yaml`ファイルに定義する必要があります。この例では、`handleNewBet`の一つだけが必要です。 まず、id として送信者アドレスから Player エンティティを読み込もうとします。 存在しない場合は、新しいエンティティを作成して開始値を入れます。 +各関数を`subgraph.yaml`ファイルに定義する必要があります。この例では、`handleNewBet`の一つだけが必要です。 まず、idとして送信者アドレスからPlayerエンティティを読み込もうとします。 存在しない場合は、新しいエンティティを作成して開始値を入れます。 -次に、Bet エンティティを作成します。 id は、`event.transaction.hash.toHex() + "-" + event.logIndex.toString()`になり、常に一意の値になります。 誰かがスマートコントラクトを介して 1 つのトランザクションで placeBet 関数を複数回呼び出す可能性があるため、ハッシュのみの使用では十分ではありません。 +次に、Betエンティティを作成します。 idは、`event.transaction.hash.toHex() + "-" + event.logIndex.toString()`になり、常に一意の値になります。 誰かがスマートコントラクトを介して1つのトランザクションでplaceBet関数を複数回呼び出す可能性があるため、ハッシュのみの使用では十分ではありません。 -最後に、すべてのデータで Player エンティティを更新します。 配列を直接プッシュすることはできませんが、ここに示すように更新する必要があります。 bet を参照するために id を使用します。 エンティティを保存するには、`.save()`が最後に必要です。 +最後に、すべてのデータでPlayerエンティティを更新します。 配列を直接プッシュすることはできませんが、ここに示すように更新する必要があります。 betを参照するためにidを使用します。 エンティティを保存するには、`.save()`が最後に必要です。 -完全なドキュメントは、こちらをご覧ください。https://thegraph.com/docs/define-a-subgraph#writing-mappings マッピングファイルにログの出力を追加できます。詳細は[こちら](https://thegraph.com/docs/assemblyscript-api#api-reference)をご覧ください。 +ドキュメント全文については、こちらをご覧ください。https://thegraph.com/docs/en/developing/creating-a-subgraph/#writing-mappings マッピングファイルにログの出力を追加できます。詳細は[こちら](https://thegraph.com/docs/assemblyscript-api#api-reference)をご覧ください。 ```typescript import { Bet, Player } from "../generated/schema" @@ -240,7 +240,7 @@ export function handleNewBet(event: PlacedBet): void { ## フロントエンドでの使用 {#using-it-in-the-frontend} -Apollo Boost などを使うと、The Graph を React(または Apollo-Vue)の分散型アプリケーション(Dapp)に簡単に統合できます。 特に React フックと Apollo を使用する場合は、コンポーネントに単一の GraphQL クエリを記述するのと同じくらいデータの取得が簡単です。 典型的な設定は次のようになります。 +Apollo Boostなどを使うと、The GraphをReact(またはApollo-Vue)の分散型アプリケーション(Dapp)に簡単に統合できます。 特にReactフックとApolloを使用する場合は、コンポーネントに単一のGraphQLクエリを記述するのと同じくらいデータの取得が簡単です。 典型的な設定は次のようになります。 ```javascript // See all subgraphs: https://thegraph.com/explorer/ @@ -262,7 +262,7 @@ ReactDOM.render( - 現在のユーザーの敗北数 - 過去の賭けのタイムスタンプのリスト -GraphQL サーバーへの単一リクエストですべて取得できます。 +GraphQLサーバーへの単一リクエストですべて取得できます。 ```javascript const myGraphQlQuery = gql` @@ -287,30 +287,27 @@ React.useEffect(() => { ![マジック](./magic.jpg) -しかし、最後のパズルの 1 つが欠けています。それがサーバーについてです。 自分のノードでサーバーを実行することも、ホストサービスを使用することもできます。 +しかし、最後のパズルの1つが欠けています。それがサーバーについてです。 自分のノードでサーバーを実行することも、ホストサービスを使用することもできます。 -## The Graph サーバー {#the-graph-server} +## The Graphサーバー {#the-graph-server} ### Graph エクスプローラー: ホストサービス {#graph-explorer-the-hosted-service} -最も簡単な方法は、ホストサービスを利用することです。 [こちらの手順](https://thegraph.com/docs/deploy-a-subgraph)に従ってサブグラフをデプロイします。 エクスプローラー(https://thegraph.com/explorer/)では、さまざまなプロジェクト向けに既存のサブグラフを探せます。 +最も簡単な方法は、ホストサービスを利用することです。 [こちらの手順](https://thegraph.com/docs/en/deploying/deploying-a-subgraph-to-hosted/)に従ってサブグラフをデプロイしてください。 [エクスプローラー](https://thegraph.com/explorer/)では、さまざまなプロジェクト向けに既存のサブグラフを探すことができます。 ![The Graphエクスプローラー](./thegraph-explorer.png) ### 自分のノードで実行 {#running-your-own-node} -もう一つの方法として、次のように自分のノードで実行することもできます。 https://github.com/graphprotocol/graph-node#quick-start これにより、ホストサービスでサポートされていないネットワークで使用することができます。 現在サポートされいるネットワークは、Mainnet、Kovan、Rinkeby、Ropsten、Goerli、PoA-Core、xDAI、Sokol です。 +自分のノードでも実行できます。 実行方法については、[こちら](https://github.com/graphprotocol/graph-node#quick-start)のドキュメントをご覧ください。 これにより、ホストサービスでサポートされていないネットワークでも使用できます。 現在サポートしているネットワークについては、[こちら](https://thegraph.com/docs/en/developing/supported-networks/)をご覧ください。 ## 非中央集権型の未来 {#the-decentralized-future} -GraphQL は、新しく受信するイベントのストリームもサポートしています。 The Graph では、完全にはサポートされていませんが、近々リリースされる予定です。 +GraphQLは、新しく受信するイベントのストリームもサポートしています。 これらの機能は、現在オープンベータ版の[Substreams](https://thegraph.com/docs/en/substreams/)を通して、グラフ上でサポートされています。 -このサービスに欠けている側面の一つは、分散化です。 The Graph は、最終的に完全に分散化されたプロトコルになる予定です。 この計画を詳細に説明する次の 2 つの素晴らしい記事をご覧ください。 +[2021](https://thegraph.com/blog/mainnet-migration/)年に、The Graphは分散型インデックスネットワークへの移行を開始しました。 分散型インデックスネットワークのアーキテクチャの詳細については、[こちら](https://thegraph.com/docs/en/network/explorer/)をご覧ください。 -- https://thegraph.com/blog/the-graph-network-in-depth-part-1 -- https://thegraph.com/blog/the-graph-network-in-depth-part-2 - -次の 2 つの重要な点があります。 +次の2つの重要な点があります。 1. ユーザーは、クエリのインデックス作成者に料金を支払う。 2. インデックス作成者は、グラフトークン(GRT)をステーキングする。 diff --git a/public/content/translations/ja/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md b/public/content/translations/ja/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md index 25fab467a5f..4cdf617692d 100644 --- a/public/content/translations/ja/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md +++ b/public/content/translations/ja/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md @@ -15,16 +15,16 @@ sourceUrl: https://ethereumdev.io/transfers-and-approval-or-erc20-tokens-from-a- address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" --- -前回のチュートリアルでは、イーサリアムブロックチェーン上の[Solidity で描かれた ERC-20 トークンの構造](/developers/tutorials/understand-the-erc-20-token-smart-contract/)について学びました。 この記事では、Solidity 言語で書かれたトークンとやり取りするためのスマートコントラクトの使い方について説明します。 +前回のチュートリアルでは、イーサリアムブロックチェーン上の[Solidityで描かれたERC-20トークンの構造](/developers/tutorials/understand-the-erc-20-token-smart-contract/)について学びました。 この記事では、Solidity言語で書かれたトークンとやり取りするためのスマートコントラクトの使い方について説明します。 -このスマートコントラクトのために、私たちは新しくデプロイされた[ERC-20 トークン](/developers/docs/standards/tokens/erc-20/)でイーサリアムを取引できる、ダミーの分散型取引所を実際に作成します。 +このスマートコントラクトのために、新しくデプロイされた[ERC-20トークン](/developers/docs/standards/tokens/erc-20/)でイーサを取引できる、ダミーの分散型取引所を実際に作成します。 このチュートリアルでは、前のチュートリアルで書いたコードをベースとして使います。 この分散型取引所(DEX)では、コントラクトのインスタンスをコンストラクタでインスタンス化し、以下の操作を実行します。 - トークンをイーサ(ETH)に交換 - イーサ(ETH)をトークンに交換 -次のシンプルな ERC20 コードベースを追加することで、分散型取引所コードを開始します。 +次のシンプルなERC20コードベースを追加することで、分散型取引所コードを開始します。 ```solidity pragma solidity ^0.8.0; @@ -104,7 +104,7 @@ contract ERC20Basic is IERC20 { ``` -次の新しい分散型取引所(DEX)スマートコントラクトは 、ERC-20 をデプロイし、供給されたすべてを取得します。 +次の新しい分散型取引所(DEX)スマートコントラクトは 、ERC-20をデプロイし、供給されたすべてを取得します。 ```solidity contract DEX { @@ -129,18 +129,18 @@ contract DEX { } ``` -これで分散型取引所(DEX)ができました。また、すべてのトークンリザーブが利用可能になりました。 コントラクトには、次の 2 つの関数があります。 +これで分散型取引所(DEX)ができました。また、すべてのトークンリザーブが利用可能になりました。 コントラクトには、次の2つの関数があります。 - `buy`: ユーザーはイーサ(ETH)を送ってトークンに交換できます - `sell`: ユーザーはトークンを送信してイーサ(ETH)を取り戻すことができます -## buy 関数 {#the-buy-function} +## buy関数 {#the-buy-function} -buy 関数をコーディングしてみましょう。 まず、メッセージに含まれるイーサ(ETH)の量を確認し、コントラクトが十分なトークンを所有していることと、そのメッセージにいくつかのイーサ(ETH)が含まれていることを検証する必要があります。 コントラクトが十分なトークンを所有している場合、ユーザーにその分のトークンを送信し、 `Bought` イベントを発行します。 +buy関数をコーディングしてみましょう。 まず、メッセージに含まれるイーサ(ETH)の量を確認し、コントラクトが十分なトークンを所有していることと、そのメッセージにいくつかのイーサ(ETH)が含まれていることを検証する必要があります。 コントラクトが十分なトークンを所有している場合、ユーザーにその分のトークンを送信し、 `Bought` イベントを発行します。 -require 関数の呼び出しがエラーだった場合に、送信されたイーサ(ETH)は直接元に戻され、ユーザーに返されることに注意してください。 +require関数の呼び出しがエラーだった場合に、送信されたイーサ(ETH)は直接元に戻され、ユーザーに返されることに注意してください。 -ここではシンプルに、1 トークンと 1Wei を交換します。 +ここではシンプルに、1トークンと1Weiを交換します。 ```solidity function buy() payable public { @@ -153,13 +153,13 @@ function buy() payable public { } ``` -購入が成功した場合、トランザクションには`Transfer`と`Bought`の 2 つのイベントが表示されます。 +購入が成功した場合、トランザクションには`Transfer`と`Bought`の2つのイベントが表示されます。 ![トランザクション内の2つのイベント: TransferとBought](./transfer-and-bought-events.png) -## sell 関数 {#the-sell-function} +## sell関数 {#the-sell-function} -売却を行う関数は事前に approve 関数を呼び出し、ユーザーがその金額を承認することを要求します。 転送を承認するには、分散型取引所(DEX)によってインスタンス化された ERC20Basic トークンがユーザーによって呼び出される必要があります。 これは、まず分散型取引所(DEX)コントラクトの`token()`関数を呼び出し、分散型取引所(DEX)が`token`という ERC20Basic コントラクトをデプロイしたアドレスを取得することで実現できます。 次に、セッション内にそのコントラクトのインスタンスを作成し、その`approve`関数を呼び出します。 次に、分散型取引所(DEX)の`sell`関数を呼び出すことで、トークンをイーサ(ETH)に交換できます。 例えば、インタラクティブ・ブラウニー(interactive brownie)セッションでは、次のようになります。 +売却を行う関数は事前にapprove関数を呼び出し、ユーザーがその金額を承認することを要求します。 転送を承認するには、分散型取引所(DEX)によってインスタンス化されたERC20Basicトークンがユーザーによって呼び出される必要があります。 これは、まず分散型取引所(DEX)コントラクトの`token()`関数を呼び出し、分散型取引所(DEX)が`token`というERC20Basicコントラクトをデプロイしたアドレスを取得することで実現できます。 次に、セッション内にそのコントラクトのインスタンスを作成し、その`approve`関数を呼び出します。 次に、分散型取引所(DEX)の`sell`関数を呼び出すことで、トークンをイーサ(ETH)に交換できます。 例えば、インタラクティブ・ブラウニー(interactive brownie)セッションでは、次のようになります。 ```python #### Python in interactive brownie console... @@ -183,7 +183,7 @@ token.approve(dex.address, 3e18, {'from':account2}) ``` -その後、sell 関数が呼び出されたときに、呼び出し元のアドレスからコントラクトアドレスへの転送が成功したかどうかを確認し、その後イーサ(ETH)を呼び出し元のアドレスに送信します。 +その後、sell関数が呼び出されたときに、呼び出し元のアドレスからコントラクトアドレスへの転送が成功したかどうかを確認し、その後イーサ(ETH)を呼び出し元のアドレスに送信します。 ```solidity function sell(uint256 amount) public { @@ -196,15 +196,15 @@ function sell(uint256 amount) public { } ``` -すべてがうまくいけば、トランザクションに 2 つのイベント(`Transfer` と `Sold`)が表示され、トークンの残高とイーサリアムの残高が更新されるはずです。 +すべてがうまくいけば、トランザクションに2つのイベント(`Transfer` と `Sold`)が表示され、トークンの残高とイーサの残高が更新されるはずです。 ![トランザクション内の2つのイベント: TransferとSold](./transfer-and-sold-events.png) -このチュートリアルでは、残高と ERC-20 トークンの割当量を確認する方法と、インターフェースを使用して ERC20 スマートコントラクトの`Transfer`と`TransferFrom`を呼び出す方法について説明しました。 +このチュートリアルでは、残高とERC-20トークンの割当量を確認する方法と、インターフェースを使用してERC20スマートコントラクトの`Transfer`と`TransferFrom`を呼び出す方法について説明しました。 -一度トランザクションが作成されると、コントラクト用に作成されている[待機してトランザクションについての詳細を取得する](https://ethereumdev.io/waiting-for-a-transaction-to-be-mined-on-ethereum-with-js/)ための JavaScript チュートリアルや、アプリケーションバイナリインターフェース(ABI)があれば、[トークン転送や他のイベントによって発行されるイベントをデコードするチュートリアル](https://ethereumdev.io/how-to-decode-event-logs-in-javascript-using-abi-decoder/)を参照することで情報を取得できます。 +一度トランザクションが作成されると、コントラクト用に作成されている[待機してトランザクションについての詳細を取得する](https://ethereumdev.io/waiting-for-a-transaction-to-be-mined-on-ethereum-with-js/)ためのJavaScriptチュートリアルや、アプリケーションバイナリインターフェース(ABI)があれば、[トークン転送や他のイベントによって発行されるイベントをデコードするチュートリアル](https://ethereumdev.io/how-to-decode-event-logs-in-javascript-using-abi-decoder/)を参照することで情報を取得できます。 チュートリアルの完全なコードは、次のようになります。 diff --git a/public/content/translations/ja/developers/tutorials/yellow-paper-evm/index.md b/public/content/translations/ja/developers/tutorials/yellow-paper-evm/index.md new file mode 100644 index 00000000000..f4a03f03ae3 --- /dev/null +++ b/public/content/translations/ja/developers/tutorials/yellow-paper-evm/index.md @@ -0,0 +1,264 @@ +--- +title: イエローペーパーにおけるEVM仕様の理解 +description: イーサリアムの正式な仕様であるイエローペーパーでのイーサリアム仮想マシン(EVM)についての説明を理解する。 +author: "qbzzt" +tags: + - "イーサリアム仮想マシン(EVM)" +skill: intermediate +lang: ja +published: 2022-05-15 +--- + +[イエローペーパー](https://ethereum.github.io/yellowpaper/paper.pdf)は、イーサリアムの正式な仕様です。 [EIPプロセス](/eips/)によって修正される場合を除き、すべての動作方式が正確に記されています。 数学の論文形式で書かれており、プログラマーには馴染みのない専門用語が含まれています。 この論文を通して、論文の読み方を学び、他の関連する数学論文も読めるようにしましょう。 + +## 解説するイエローペーパーについて {#which-yellow-paper} + +イーサリアムに関する他のものと同じように、イエローペーパーも時間の経過とともに進化しています。 特定のバージョンを参照できるように、[執筆時のバージョン](yellow-paper-berlin.pdf)をアップロードしています。 このドキュメントで使用するセクション番号、ページ番号、数式番号は、そのバージョンを参照しています。 ドキュメントを読む際は、アップロードされたイエローペーパーを別のウィンドウで開いておくと便利です。 + +### EVMを解説する理由 {#why-the-evm} + +イーサリアムの開発が始まったときに書かれたオリジナルのイエローペーパーでは、 コンセンサスメカニズムのベースとなったオリジナルのプルーフ・オブ・ワークについて記述されていました。 しかし、イーサリアムでは、2022年9月にプルーフ・オブ・ワークを止め、プルーフ・オブ・ステークをベースとしたコンセンサスを使い始めました。 このチュートリアルでは、イエローペーパーにおけるイーサリアム仮想マシンの定義部について解説します。 プルーフ・オブ・ステークへの移行後も、EVMは変更されていないことが解説する理由です。ただし、DIFFICULTY オペコードの戻り値は変更されています。 + +## 9 実行モデル {#9-execution-model} + +このセクション(p. 12-14)には、EVMの定義のほとんどが記述されています。 + +_システム状態_とは、システムを実行するため必要なすべての情報を指します。 典型的なコンピュータでは、これはメモリやレジスタの内容などです。 + +[チューリングマシン](https://en.wikipedia.org/wiki/Turing_machine)は、計算モデルです。 チューリングマシンは、コンピュータを本質的に単純化したもので、通常のコンピュータと同じ計算を実行する能力があることが証明されています。つまり、コンピュータが計算できるものはすべてチューリングマシンでも計算でき、またその逆も同様です。 このモデルは、さまざまな定理で何が計算可能で何が計算不可能であるかを証明するのに役立ちます。 + +[チューリング完全](https://en.wikipedia.org/wiki/Turing_completeness)とは、チューリングマシンと同じ計算を実行できるコンピュータのことを指します。 チューリングマシンは無限ループができますが、EVMではガスがなくなると無限ループができません。そのため、EVMは準チューリング完全であるといわれています。 + +## 9.1 基本事項 {#91-basics} + +このセクションでは、EVMの基本事項と、EVMと他の計算モデルとの比較について説明しています。 + +[スタックマシン](https://en.wikipedia.org/wiki/Stack_machine)は、中間データをレジスタではなく[**スタック**](https://en.wikipedia.org/wiki/Stack_(abstract_data_type))に格納するコンピュータです。 これは、仮想マシンで好まれるアーキテクチャです。なぜなら、実装が簡単で、バグやセキュリティの脆弱性が発生する可能性を大幅に低くできるためです。 スタック内のメモリは、256ビットのワードに分割されます。 256ビットが選ばれた理由としては、Kecck-256ハッシュや楕円曲線計算など、イーサリアムの中核となる暗号操作に都合が良いためです。 スタックの最大サイズは、1024バイトです。 オペコード実行時、通常、スタックからパラメータを取得します。 `POP`(スタックの先頭のアイテムの削除)、`DUP_N`(スタックのN番目のアイテムの複製)など、スタック内の要素を再構成するための専用オペコードがあります。 + +EVMには、 実行中にデータを保存するために使用される**メモリ**と呼ばれる揮発性スペースもあります。 このメモリは、32バイトのワードで構成されます。 すべてのメモリのロケーションは、ゼロで初期化されます。 次の[Yul](https://docs.soliditylang.org/en/latest/yul.html)コードを実行してメモリにワードを追加すると、32バイトのメモリのワード内にある空スペースがパディングによってゼロで埋められます。つまり、ロケーション0~29、0x60~30、0xA7~31にゼロが含まれる1つのワードが作成されます。 + +```yul +mstore(0, 0x60A7) +``` + +EVMは、メモリとやり取りをする3つのオペコードを提供しています。そのうちの1つが`mstore`で、ワードをメモリにロードします。 他の2つは、1バイトをメモリにロードする`mstore8`、ワードをメモリからスタックに移動する`mload`です。 + +EVMには、システム状態の一部として保持される独自の不揮発性**ストレージ**モデルもあります。このメモリは、(ワードアドレス可能なスタック内のバイト配列とは違い)ワードの配列で構成されます。 このストレージは、コントラクトが永続データを保存する場所です。コントラクトは、自分のストレージとしかやり取りできません。 ストレージは、キーと値のマッピングで構成されます。 + +イエローペーパーのこのセクションでは言及されていませんが、メモリに4番目のタイプがあることを知っておくといいでしょう。 **Calldata**は、トランザクションの`data`パラメータで渡された値を保存するために使用される、バイトアドレス可能な読み取り専用のメモリです。 EVMには、`calldata`を管理する専用のオペコードがあります。 `calldatasize`は、そのデータのサイズを返します。 `calldataload`は、そのデータをスタックにロードします。 `calldatacopy`は、そのデータをメモリにコピーします。 + +標準の[フォンノイマン型アーキテクチャ](https://en.wikipedia.org/wiki/Von_Neumann_architecture)では、コードとデータが同じメモリに保存されます。 しかし、EVMでは、セキュリティ上の理由からこの標準に準拠していません。なぜなら、揮発性メモリを共有すると、プログラムのコードが変更される可能性があるからです。 そのため、コードはストレージに保存されます。 + +コードがメモリから実行されるのは、次の2つのケースだけです。 + +- コントラクトが他のコントラクトを作成する場合([`CREATE`](https://www.evm.codes/#f0) または[`CREATE2`](https://www.evm.codes/#f5)を使用)、コントラクトにあるコンストラクタのコードはメモリから取得されます。 +- _あらゆる_コントラクトの作成において、コンストラクタのコードが実行され、メモリから実際のコントラクトのコードが返されます。 + +例外実行とは、現在のコントラクトの実行を停止させる例外を意味します。 + +## 9.2 フィーの概要 {#92-fees-overview} + +このセクションでは、ガス代の計算方法について説明しています。 次の3つのコストがあります。 + +### オペコードコスト {#opcode-cost} + +特定のオペコードで発生する固有のコストです。 この値を取得するには、付録H(ページ28)の式(327)の下部でオペコードのコストグループを見つけます。そして、式(324)でコストグループを見つけます。 ここには、コスト関数があります。ほとんどのケースにおいて、付録G(ページ27)のパラメータを使用します。 + +例えば、オペコード[`CALLDATACOPY`](https://www.evm.codes/#37)は、_Wcopy_グループのメンバーです。 このグループにおけるオペコードのコストは、_Gverylow+Gcopy×⌈μs[2]÷32⌉_となります。 付録Gを見ると、両方の定数が3であることがわかり、この式は、_3+3×⌈μs[2]÷32⌉_です。 + +また、_⌈μs[2]÷32⌉_という式を解読する必要があります。 一番外側の部分の _⌈ \ ⌉_は、天井関数です。この関数に値を指定すると、その値以上の最小の整数を返します。 例えば、_⌈2.5⌉ = ⌈3⌉ = 3_となります。 この式の内側部分は、_μs[2]÷32_です。 ページ3のセクション3(慣習)を参照してください。_μ_は、マシンの状態を表します。 マシンの状態は、ページ13のセクション9.4.1で定義されています。 そのセクションによると、マシンの状態パラメータの1つは、スタックの_s_になります。 したがって、_μs[2]_ は、スタックの2番目のロケーションにあるということです。 こちらの[オペコード](https://www.evm.codes/#37)では、スタック内のロケーション#2に、データのサイズ(バイト単位)が格納されています。 グループWの他のオペコードcopyである[`CODECOPY`](https://www.evm.codes/#39)と[`RETURNDATACOPY`](https://www.evm.codes/#3e)も、同じロケーションにデータのサイズを格納しています。 したがって、_⌈μs[2]÷32⌉_ は、コピーされるデータを保存するために必要になる32バイトのワード数です。 以上から、[`CALLDATACOPY`](https://www.evm.codes/#37)に固有のコストは、3ガスにコピーされるデータのワードごとに3ガスを加えたものになります。 + +### 実行コスト {#running-cost} + +呼び出すコードの実行コスト。 + +- [`CREATE`](https://www.evm.codes/#f0)および[`CREATE2`](https://www.evm.codes/#f5)の場合は、新しいコントラクトのコンストラクタ +- [`CALL`](https://www.evm.codes/#f1)、[`CALLCODE`](https://www.evm.codes/#f2)、[`STATICCALL`](https://www.evm.codes/#fa)、[`DELEGATECALL`](https://www.evm.codes/#f4)の場合は、呼び出すコントラクト + +### メモリーコストの拡張 {#expanding-memory-cost} + +(必要な場合の)メモリ拡張におけるコストについて。 + +この値は、式324で_Cmemi')-Cmemi)_として記述されています。 セクション9.4.1をもう一度見てみましょう。_μi_は、メモリ内のワード数であることがわかります。 そのため_μi_は、オペコードの前のメモリ内のワード数となります。また、_μi '_は、オペコード後のメモリ内のワード数を表します。 + +関数_Cmem_は、式326で次のように定義されます。_Cmem (a) = Gmemory × a + ⌊a2 ÷ 512⌋_ _⌊x⌋_は、床関数を表します。これは値を指定すると、その値以下の最大の整数を返す関数です。 例えば、 _⌊2.5⌋ = ⌊2⌋ = 2_となります。 _a < √512_のときは、 _a2 < 512_となり、この床関数の結果はゼロとなります。 そのため、最初の22ワード(704 バイト)については、必要なメモリワード数に応じてコストが線形的に増加します。 そのワード数を超えると、_⌊a2 ÷ 512⌋_が正になります。 必要なメモリが大きい場合、ガスコストがメモリ量の2乗に比例します。 + +これらの要素は、_固有_のガス代にのみ影響を与えることに**注意してください**。フィーマーケットやバリデータへのチップは、エンドユーザーが支払う必要がある金額を決定する要素であり、この式には含まれていません。この式は、EVMで特定の操作を実行するための直接コストのみを表しています。 + +[ガスについての詳細](/developers/docs/gas/) + +## 9.3 実行環境 {#93-execution-env} + +実行環境は、_I_で表します。これは、ブロックチェーンの状態やEVMの以外の情報を含みます。 + +| パラメータ | データにアクセスするためのオペコード | データにアクセスするためのSolidityのコード | +| --------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------ | +| _Ia_ | [`ADDRESS`](https://www.evm.codes/#30) | `address(this)` | +| _Io_ | [`ORIGIN`](https://www.evm.codes/#32) | `tx.origin` | +| _Ip_ | [`GASPRICE`](https://www.evm.codes/#3a) | `tx.gasprice` | +| _Id_ | [`CALLDATALOAD`](https://www.evm.codes/#35)など | `msg.data` | +| _Is_ | [`CALLER`](https://www.evm.codes/#33) | `msg.sender` | +| _Iv_ | [`CALLVALUE`](https://www.evm.codes/#34) | `msg.value` | +| _Ib_ | [`CODECOPY`](https://www.evm.codes/#39) | `address(this).code` | +| _IH_ | ブロックヘッダーフィールド、[`NUMBER`](https://www.evm.codes/#43)や[`DIFFICULTY`](https://www.evm.codes/#44)など | `block.number`, `block.difficulty`など | +| _Ie_ | コントラクト間のコールのコールスタックの深さ(コントラクトの作成を含む) | | +| _Iw_ | EVMの状態の変更を許可されているか、もしくは静的に実行されているか | | + +セクション9の続きを理解するには、次にある他のパラメータのいくつかを理解する必要があります。 + +| パラメータ | 定義されているセクション | 説明 | +| ----- | ------------- | ------------------------------------------------------------------------------------------------ | +| _σ_ | 2(2ページ目, 数式1) | ブロックチェーンの状態 | +| _g_ | 9.3(13ページ目) | ガスの残量 | +| _A_ | 6.1(8ページ目) | 発生したサブ状態(トランザクション終了時にスケジュールされた変更) | +| _o_ | 9.3(13ページ目) | 出力 - 内部トランザクションの場合に返される結果(あるコントラクトが別のコントラクトを呼び出すとき)およびビュー関数の呼び出し(情報を求めるだけなので、トランザクションを待つ必要がない場合) | + +## 9.4 実行の概要 {#94-execution-overview} + +それでは準備が整ったので、ようやくEVMがどのように機能するかについての説明を開始します。 + +式137~142は、EVMを実行するための次の初期条件を示しています。 + +| Symbol | 初期値 | 説明 | +| ---------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _μg_ | _g_ | ガスの残量 | +| _μpc_ | _0_ | プログラムカウンタ、実行する次の命令が格納されたアドレス | +| _μm_ | _(0, 0, ...)_ | メモリ、ゼロで初期化 | +| _μi_ | _0_ | 使用される最上位のメモリ位置 | +| _μs_ | _()_ | スタック、初期値は空 | +| _μo_ | _∅_ | 戻りデータ([`RETURN`](https://www.evm.codes/#f3)または[`REVERT`](https://www.evm.codes/#fd))もしくは戻りデータ無し([`STOP`](https://www.evm.codes/#00)または[`SELFDESTRUCT`](https://www.evm.codes/#ff))で止めない限り、戻りデータは空の出力 | + +式143では、実行中の各時点で4つ状態が発生する可能性があること、そしてそれらをどのように処理するかを示しています。 + +1. `Z(σ,μ,A,I)` Zは関数を表しており、操作によって無効な状態遷移が発生するかどうかをテストします([例外による停止](#942-Exceptional-halting)を参照)。 Trueと評価された場合、変更が行われていないため、新しい状態は古い状態と同じです (ガスがバーンされることは除く) 。 +2. 実行されているオペコードが[`REVERT`](https://www.evm.codes/#fd)の場合は、ガスが失われ、新しい状態と古い状態は同一になります。 +3. 一連の演算が終了すると、[`RETURN`](https://www.evm.codes/#f3)で示されるように、状態は新しい状態に更新されます。 +4. 終了条件1~3のいずれでもない場合は、実行を続けます。 + +## 9.4.1 マシンの状態 {#941-machine-state} + +このセクションでは、マシンの状態について詳しく説明します。 ここでは、_w_が現在のオペコードであることを規定しています。 _μpc_がコードの長さを示す_||Ib|| 未満の場合_、そのバイト(_Ibpc]_)は、オペコードです。 それ以外の場合、オペコードは[`STOP`](https://www.evm.codes/#00)と定義されています。 + +[スタックマシン](https://en.wikipedia.org/wiki/Stack_machine)であるため、ポップアウトされたアイテムの数(_δ_)と各オペコードによってプッシュインされたアイテムの数(_α_)を追跡する必要があります。 + +## 9.4.2 例外による停止 {#942-exceptional-halt} + +このセクションでは、異常終了がいつ発生するかを規定する_Z_関数を定義しています。 これは [Boolean](https://en.wikipedia.org/wiki/Boolean_data_type)関数であり、[論理和では_∨_](https://en.wikipedia.org/wiki/Logical_disjunction)を使用します。また、[論理積では_∧_](https://en.wikipedia.org/wiki/Logical_conjunction)を使用します。 + +次のいずれかの条件が真になる場合、例外による停止をします。 + +- **_μg < C(σ,μ,A,I)_** セクション9.2に書かれているように、_C_はガスのコストを規定する関数です。 次のオペコードを実施するのに十分なガスが残っていない場合の条件です。 + +- **_δw=∅_** オペコードに対してポップされるアイテムの数が未定義の場合、オペコード自体も未定義となります。 + +- **_|| μs || < δw_** スタックのアンダーフロー。現在のオペコードに対してスタック内に十分なアイテムがありません。 + +- **_w = JUMP ∧ μs[0]∉D(Ib)_** オペコードが[`JUMP`](https://www.evm.codes/#56)で、またアドレスが[`JUMPDEST`](https://www.evm.codes/#5b)でない場合です。 ジャンプは、ジャンプ先が[`JUMPDEST`](https://www.evm.codes/#5b)のとき_のみ_有効です。 + +- **_w = JUMPI ∧ μs[1]≠0 ∧ μs[0] ∉ D(Ib)_** オペコードが [`JUMPI`](https://www.evm.codes/#57)であり、条件が真(ゼロ以外)であるため、ジャンプが発生しますが、[`JUMPDEST`](https://www.evm.codes/#5b)がアドレスではありません。 ジャンプは、ジャンプ先が[`JUMPDEST`](https://www.evm.codes/#5b)のとき_のみ_有効です。 + +- **_w = RETURNDATACOPY ∧ μs[1]+μs[2]>|| μo ||_** オペコードは、[`RETURNDATACOPY`](https://www.evm.codes/#3e)です。 このオペコードでは、スタックの要素_μs[1]_は、戻り値データのバッファ内からの読み取り位置です。そしてスタックの要素 _μs[2]_はデータの長さです。 この条件は、戻りデータのバッファの末尾を超えて読み取ろうとしたときに発生します。 コールデータやコード自体には類似した条件がないことに注意してください。 これらのバッファの末尾を超えて読み取ろうとすると、ゼロが返されるだけです。 + +- **_|| μs || - δw + αw > 1024_** + + スタックオーバーフロー オペコードの実行で1024を超えるアイテムのスタックが生成された場合は、中断されます。 + +- **_¬Iw ∧ W(w,μ)_** 静的に実行しようとしていますか? ([¬は否定を表します](https://en.wikipedia.org/wiki/Negation) 。また、ブロックチェーンの状態を変更できる場合_Iw_が真になります) そのような場合、状態の変更操作を試行しようとしてもできません。 + + 関数_W(w,μ)_は、この後に式150にて定義されています。 次の条件が真の場合、_W(w,μ)_が真になります。 + + - **_w ∈ {CREATE, CREATE2, SSTORE, SELFDESTRUCT}_** これらのオペコードは、新しいコントラクトの作成、値の保存、現在のコントラクトの破棄によって状態を変更します。 + + - **_LOG0≤w ∧ w≤LOG4_** 静的に呼び出した場合、ログエントリは出力されません。 [`LOG0` (A0)](https://www.evm.codes/#a0)から[`LOG4` (A4)](https://www.evm.codes/#a4)の間における範囲内に全てのログオペコードがあります。 ログオペコードの後にある数字は、ログエントリに含まれるトピックの数を規定しています。 + - **_w=CALL ∧ μs[2]≠0_** 静的な場合、他のコントラクトは呼び出せますが、ETHの送金はできません。 + +- **_w = SSTORE ∧ μg ≤ Gcallstipend_** Gcallstipend(付録Gで2300で定義)以上のガスがなければ、[`SSTORE`](https://www.evm.codes/#55)を実行することはできません。 + +## 9.4.3 ジャンプ先の有効性 {#943-jump-dest-valid} + +ここでは、[`JUMPDEST`](https://www.evm.codes/#5b)オペコードについて形式的に定義します。 バイト値0x5Bを単純に見つけることはできません。なぜなら、バイト値0x5Bは、PUSH内にある可能性があるためです(つまり、オペコードではなくデータ)。 + +式(153)では、関数_N(i,w)_を定義します。 最初のパラメータ _i_ は、オペコードのロケーションです。 2番目のパラメータ_w_は、そのオペコードです。 _w∈[PUSH1, PUSH32]_の場合、オペコードがPUSHであることを意味します(角括弧は端点を含む範囲を定義しています)。 この場合では、次のオペコードが_i+2+(w−PUSH1)_になります。 [`PUSH1`](https://www.evm.codes/#60)では、2バイト(PUSH自体と1バイトの値)進む必要があります。[`PUSH2`](https://www.evm.codes/#61)では、2バイトの値であるため、3バイト進める必要があります。 他のすべてのEVMオペコードの長さは1バイトであるため、その他のすべてのケースにおいては_N(i,w)=i+1_となります。 + +この関数は、式(152)で_DJ(c,i)_と定義され、コード_c_内のすべての有効なジャンプ先の[集合](https://en.wikipedia.org/wiki/Set_(mathematics))で、オペコードのロケーション_i_から始まります。 この関数は、再帰的に定義されています。 _i≥||c||_では、コードが終了していることを意味します。 そのため、これ以上のジャンプ先は存在しないので、空集合を返すだけです。 + +それ以外の場合は、次のオペコードに移動し、そこから始まる集合を取得することで、コードの残りの部分を調べます。 現在のオペコードが_c[i]_であるため、次のオペコードのロケーションは、_N(i,c[i])_になります。 したがって、_DJ(c,N(i,c[i]))_は、次のオペコードから始まる有効なジャンプ先の集合です。 現在のオペコードが`JUMPDEST`でなければ、その集合を返すだけです。 `JUMPDEST`であれば、結果の集合にそれを含めて返します。 + +## 9.4.4 通常停止 {#944-normal-halt} + +停止関数である_H_は、3つの型の値を返すことができます。 + +- 停止オペコードでない場合は、空のセットである_∅_を返します。 慣例により、この値はブール型の偽(false)として解釈されます。 +- 出力を生成しない停止オペコードの場合、([`STOP`](https://www.evm.codes/#00)または[`SELFDESTRUCT`](https://www.evm.codes/#ff))、サイズがゼロバイトのシーケンスを戻り値として返します。 これは空のセットとは、大きく異なることに注意してください。 この値は、EVMが実際に停止し、読み取る戻りデータがないことを意味します。 +- 出力を生成する停止オペコードがある場合([`RETURN`](https://www.evm.codes/#f3)または [`REVERT`](https://www.evm.codes/#fd))、そのオペコードで指定されたバイトのシーケンスを返します。 このシーケンスはメモリから取り出され、スタックの先頭の値(_μs[0]_)が最初のバイトであり、その後の値(_μs[1]_)は長さです。 + +## H.2 命令セット {#h2-instruction-set} + +EVMに関する最後のサブセクション9.5に進む前に、命令自体について考察してみましょう。 付録H.2で定義されており、ページ29から開始しています。 特定のオペコードでは、規定されていないものはすべて同じままであることが求められます。 変化する変数は、\'と規定されています。 + +例として、[`ADD`](https://www.evm.codes/#01)オペコードを見ていきます。 + +| 値 | Mnemonic | δ | α | 説明 | +| ----:| -------- | - | - | --------------------------------------------------------- | +| 0x01 | ADD | 2 | 1 | 加算演算 | +| | | | | _μ′s[0] ≡ μs[0] + μs[1]_ | + +_δ_は、スタックからポップする値の個数です。 この場合は、先頭にある2つの値を加算するので、2になります。 + +_α_は、プッシュバックする値の個数です。 この場合は、合計で1になります。 + +なぜなら、新しいスタックの先頭(_μ′s[0]_)は、古いスタックの先頭(_μs[0]_)とその次の古い値(_μs[1]_)の合計となるためです。 + +この記事では、すべてのオペコードを網羅するのではなく、新規性のあるオペコードのみを説明します。 + +| 値 | Mnemonic | δ | α | 説明 | +| ----:| --------- | - | - | ---------------------------------------------------------------------------------------------------------- | +| 0x20 | KECCAK256 | 2 | 1 | Keccak-256ハッシュの計算 | +| | | | | _μ′s[0] ≡ KEC(μms[0] . 。 。 (μs[0] + μs[1] − 1)])_ | +| | | | | _μ′i ≡ M(μis[0],μs[1])_ | + +これはメモリにアクセスする最初のオペコードです(この場合は、読み取り専用)。 ただし、現在のメモリの制限を超えて拡張される可能性があるため、_μi_を更新する必要があります。ページ29の式328に定義されている_M_関数を使ってこの更新を行っています。 + +| 値 | Mnemonic | δ | α | 説明 | +| ----:| -------- | - | - | ---------------- | +| 0x31 | BALANCE | 1 | 1 | 指定されたアカウントの残高を取得 | +| | | | | ... | + +残高を知る必要のあるアドレスは、_μs[0] mod 2160_ です。 スタックの最上位がアドレスなのは、アドレスは160ビットしかないためです。値を[modulo](https://en.wikipedia.org/wiki/Modulo_operation) 2160で計算します。 + +_σ[μs[0] mod 2160] ≠ ∅_の場合、このアドレスに関する情報が存在します。 その場合、_σ[μs[0] mod 2160]b_は、そのアドレスの残高です。 _σ[μs[0] mod 2160] = ∅_ の場合、このアドレスは初期化されておらず、残高はゼロです。 アカウント情報フィールドのリストは、4ページ目のセクション4.1に記載されています。 + +2つ目の数式、_A'a ≡ Aa ∪ {μs[0] mod 2160}_は、ウォームストレージ(最近アクセスされ、キャッシュされる可能性が高いストレージ)とコールドストレージ(アクセスされておらず、取得コストが高く低速な可能性が高いストレージ)とのアクセスのコストの差に関連しています。 _Aa_は、トランザクションによって以前アクセスされたアドレスのリストです。このリストは、8ページ目のセクション6.1に定義されているように、アクセスするコストが安くなっています。 この件についての詳細は、[EIP-2929](https://eips.ethereum.org/EIPS/eip-2929)をご覧ください。 + +| 値 | Mnemonic | δ | α | 説明 | +| ----:| -------- | -- | -- | --------------------------------------- | +| 0x8F | DUP16 | 16 | 17 | 16番目のスタックアイテムを複製 | +| | | | | _μ′s[0] ≡ μs[15]_ | + +スタックアイテムを使用するには、ポップする必要があることに注意してください。つまり、そのアイテム上にあるすべてのスタックアイテムもポップする必要があります。 [`DUP`](https://www.evm.codes/#8f)および[`SWAP`](https://www.evm.codes/#9f)の場合は、最大で16個の値をポップして、その後にプッシュしなければならなりません。 + +## 9.5 実行サイクル {#95-exec-cycle} + +すべてのパーツが揃ったので、ようやくEVMの実行サイクルがどのように文書化されているのかを理解できます。 + +数式(155)は、次の状態を示しています。 + +- _σ_(グローバルブロックチェーンの状態) +- _μ_(EVMの状態) +- _A_(サブ状態、トランザクション終了時に発生する変更) +- _I_(実行環境) + +新たな状態は、_(σ', μ', A', I')_となります。 + +数式(156)~(158)は、スタックとオペコード(_μs_)によるスタックの変化を定義しています。 数式(159)は、ガスの変化(_μg_)です。 数式(160)は、プログラムカウンタ(_μpc_)の変化です。 最後に、数式(161)~(164)は、オペコードによって明示的に変更されない限り、他のパラメータが同じままであることを明記しています。 + +以上より、EVMが完全に定義されました。 + +## まとめ {#conclusion} + +数学的表記法は正確であるため、イエローペーパーでは、イーサリアムのあらゆる詳細が記述されています。 ただし、次のような欠点があります。 + +- 人間のみが理解できるため、[コンプライアンステスト](https://github.com/ethereum/tests)は、手作業によって記述する必要があります。 +- プログラマーはコンピュータのコードは理解できますが、 数学的な表記法については、理解できない人もいます。 + +このような理由から、新たな[コンセンサスレイヤーの仕様](https://github.com/ethereum/consensus-specs/blob/dev/tests/core/pyspec/README.md)は、 Pythonで記述されています。 [こちらに](https://ethereum.github.io/execution-specs)Pythonで書かれた実行レイヤーの仕様がありますが、完全ではありません。 イエローペーパー全体がPythonもしくは同様の言語に翻訳されるまで、イエローペーパーは使われ続けます。そのため、イエローペーパーを読めるようにしておくと便利です。 diff --git a/public/content/translations/ja/eips/index.md b/public/content/translations/ja/eips/index.md index 3c45b49f031..cc02dcc1b14 100644 --- a/public/content/translations/ja/eips/index.md +++ b/public/content/translations/ja/eips/index.md @@ -6,27 +6,27 @@ lang: ja # イーサリアム改善提案(EIP)入門 {#introduction-to-ethereum-improvement-proposals} -## EIP とは {#what-are-eips} +## EIPとは {#what-are-eips} -[イーサリアム改善提案(EIP)](https://eips.ethereum.org/)は、イーサリアムの新しい機能やプロセスに関する提案を規定する標準規格です。 EIP には、技術仕様の変更案が含まれており、コミュニティの 「信頼できる情報源」として機能します。 イーサリアムのネットワークアップグレードとアプリケーションの標準規格は、EIP プロセスでの議論を通じて開発されます。 +[イーサリアム改善提案(EIP)](https://eips.ethereum.org/)は、イーサリアムの新しい機能やプロセスに関する提案を規定する標準規格です。 EIPには、技術仕様の変更案が含まれており、コミュニティの 「信頼できる情報源」として機能します。 イーサリアムのネットワークアップグレードとアプリケーションの標準規格は、EIPプロセスでの議論を通じて開発されます。 -イーサリアムコミュニティ内の誰でも EIP を作成することができます。 EIP を書くためのガイドラインは [EIP-1](https://eips.ethereum.org/EIPS/eip-1)に記載されています。 EIP には、主に簡潔な技術仕様と提案の背景を提出する必要があります。 EIP の作成者は、コミュニティ内でコンセンサスを得て、提案に対する別の意見を文書化します。 適格な EIP を提出する上での技術的な障壁が高いため、これまでは通常アプリケーションまたはプロトコルのデベロッパーが EIP を提案しています。 +イーサリアムコミュニティ内の誰でもEIPを作成することができます。 EIPを書くためのガイドラインは [EIP-1](https://eips.ethereum.org/EIPS/eip-1)に記載されています。 EIPには、主に簡潔な技術仕様と提案の背景を提出する必要があります。 EIPの作成者は、コミュニティ内でコンセンサスを得て、提案に対する別の意見を文書化します。 適格なEIPを提出する上での技術的な障壁が高いため、これまでは通常アプリケーションまたはプロトコルのデベロッパーがEIPを提案しています。 -## EIP の重要性 {#why-do-eips-matter} +## EIPの重要性 {#why-do-eips-matter} -EIP は、イーサリアムで変更がどのように行われ、文書化されるかにおいて、中心的な役割を果たします。 EIP は変更を提案・議論し、採用する方法です。 [EIP には複数の種類](https://eips.ethereum.org/EIPS/eip-1#eip-types)があります。[EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)のようにコンセンサスに影響を与えてネットワークのアップグレードを要求する下位レベルのプロトコル変更を目的としたコア EIP、 [EIP-20](https://eips.ethereum.org/EIPS/eip-20)や[EIP-721](https://eips.ethereum.org/EIPS/eip-721)などのアプリケーション標準を目的とした ERC などがあります。 +EIPは、イーサリアムで変更がどのように行われ、文書化されるかにおいて、中心的な役割を果たします。 EIPは変更を提案・議論し、採用する方法です。 [EIPには複数の種類](https://eips.ethereum.org/EIPS/eip-1#eip-types)があります。[EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)のようにコンセンサスに影響を与えてネットワークのアップグレードを要求する下位レベルのプロトコル変更を目的としたコアEIP、 [EIP-20](https://eips.ethereum.org/EIPS/eip-20)や[EIP-721](https://eips.ethereum.org/EIPS/eip-721)などのアプリケーション標準を目的としたERCなどがあります。 -すべてのネットワークアップグレードは、複数の EIP で構成され、これらはネットワーク上の各[イーサリアムクライアント](/learn/#clients-and-nodes)に実装される必要があります。 これは、イーサリアムメインネット上の他のクライアントとコンセンサス状態を維持するには、クライアントデベロッパーは必ず必要な EIP をすべて実装しなければならないということを意味します。 +すべてのネットワークアップグレードは、複数のEIPで構成され、これらはネットワーク上の各[イーサリアムクライアント](/learn/#clients-and-nodes)に実装される必要があります。 これは、イーサリアムメインネット上の他のクライアントとコンセンサス状態を維持するには、クライアントデベロッパーは必ず必要なEIPをすべて実装しなければならないということを意味します。 -変更の技術仕様の提供に加えて、EIP ではイーサリアムでガバナンスが行われます。誰でも自由に提案でき、コミュニティの様々な利害関係者が議論し、提案を標準規格として採用するべきか、ネットワークアップグレードに含めるべきかを判断します。 コア以外の EIP はすべてのアプリケーションで導入される必要はない一方で(例えば EIP-20 を実装していない代替トークンを作成可能など)、コア EIP は広く導入されなければならず(同一ネットワークを構成するには、全ノードをアップグレードする必要があるため) 、コア EIP は非コア EIP よりもコミュニティでの広範なコンセンサスを必要とします。 +変更の技術仕様の提供に加えて、EIPではイーサリアムでガバナンスが行われます。誰でも自由に提案でき、コミュニティの様々な利害関係者が議論し、提案を標準規格として採用するべきか、ネットワークアップグレードに含めるべきかを判断します。 コア以外のEIPはすべてのアプリケーションで導入される必要はない一方で(例えばEIP-20を実装していない代替トークンを作成可能など)、コアEIPは広く導入されなければならず(同一ネットワークを構成するには、全ノードをアップグレードする必要があるため) 、コアEIPは非コアEIPよりもコミュニティでの広範なコンセンサスを必要とします。 -## EIP の歴史 {#history-of-eips} +## EIPの歴史 {#history-of-eips} -[イーサリアム改善提案改善提案(EIP) Github リポジトリ](https://github.com/ethereum/EIPs)は 2015 年 10 月に作成されました。 EIP プロセスは、[Bitcoin 改善提案(BIP)](https://github.com/bitcoin/bips)に基づいており、この BIP 自体[Python 改善提案 (PEP)](https://www.python.org/dev/peps/)に準じています。 +[イーサリアム改善提案改善提案(EIP) Githubリポジトリ](https://github.com/ethereum/EIPs)は2015年10月に作成されました。 EIPプロセスは、[Bitcoin改善提案(BIP)](https://github.com/bitcoin/bips)に基づいており、このBIP自体[Python改善提案 (PEP)](https://www.python.org/dev/peps/)に準じています。 -EIP 編集者は、技術的な健全性、フォーマットの問題、正しいスペル、文法、およびコードスタイルについての EIP のレビューを担当します。 Martin Becze、Vitalik Buterin、Gavin Wood など数名が、2015 年から 2016 年まで初代の EIP 編集者でした。 +EIP編集者は、技術的な健全性、フォーマットの問題、正しいスペル、文法、およびコードスタイルについてのEIPのレビューを担当します。 Martin Becze、Vitalik Buterin、Gavin Woodなど数名が、2015年から2016年まで初代のEIP編集者でした。 -現在の EIP 編集者は次のとおりです +現在のEIP編集者は次のとおりです - Alex Beregszaszi (@axic) - Gavin John (@Pandapip1) @@ -34,7 +34,7 @@ EIP 編集者は、技術的な健全性、フォーマットの問題、正し - Matt Garnett (@lightclient) - Sam Wilson (@SamWilsn) -EIP 名誉編集者は次のとおりです +EIP名誉編集者は次のとおりです - Casey Detrio (@cdetrio) - Hudson Jameson (@Souptacular) @@ -44,23 +44,23 @@ EIP 名誉編集者は次のとおりです - Nick Savers (@nicksavers) - Vitalik Buterin (@vbuterin) -EIP 編集者になりたい方は、[EIP-5069](https://eips.ethereum.org/EIPS/eip-5069)をご確認ください。 +EIP編集者になりたい方は、[EIP-5069](https://eips.ethereum.org/EIPS/eip-5069)をご確認ください。 -EIP 編集者は、提案が EIP になる準備ができているかを決定し、EIP 作成者が提案を進めるのを支援します。 [イーサリアムキャットハーダーズ(Ethereum Cat Herders)](https://www.ethereumcatherders.com/)は、EIP 編集者とコミュニティ間のミーティング開催をサポートします([EIPIP](https://github.com/ethereum-cat-herders/EIPIP)を参照)。 +EIP編集者は、提案がEIPになる準備ができているかを決定し、EIP作成者が提案を進めるのを支援します。 [イーサリアムキャットハーダーズ(Ethereum Cat Herders)](https://www.ethereumcatherders.com/)は、EIP編集者とコミュニティ間のミーティング開催をサポートします([EIPIP](https://github.com/ethereum-cat-herders/EIPIP)を参照)。 図表を含む完全な標準化プロセスは、[EIP-1](https://eips.ethereum.org/EIPS/eip-1)に記載されています。 ## 詳細 {#learn-more} -EIP の詳細についてご興味がある場合は、 [EIP ウェブサイト](https://eips.ethereum.org/)や[EIP-1](https://eips.ethereum.org/EIPS/eip-1)をご覧ください。 下記は役立つ情報のリンクです。 +EIPの詳細についてご興味がある場合は、 [EIPウェブサイト](https://eips.ethereum.org/)や[EIP-1](https://eips.ethereum.org/EIPS/eip-1)をご覧ください。 下記は役立つ情報のリンクです。 -- [全 EIP リスト](https://eips.ethereum.org/all) -- [全 EIP タイプの説明](https://eips.ethereum.org/EIPS/eip-1#eip-types) -- [全 EIP ステータスの説明](https://eips.ethereum.org/EIPS/eip-1#eip-process) +- [全EIPリスト](https://eips.ethereum.org/all) +- [全EIPタイプの説明](https://eips.ethereum.org/EIPS/eip-1#eip-types) +- [全EIPステータスの説明](https://eips.ethereum.org/EIPS/eip-1#eip-process) -## EIP への参加 {#participate} +## EIPへの参加 {#participate} -誰でも EIP を作成できます。 提案を提出する前に、EIP のプロセスと書き方を概説した[EIP-1](https://eips.ethereum.org/EIPS/eip-1)をお読みください。また、草案を提出する前に、まずコミュニティと議論する場所である[イーサリアム・マジシャンズ](https://ethereum-magicians.org/) でフィードバックを募ってください。 +誰でもEIPを作成できます。 提案を提出する前に、EIPのプロセスと書き方を概説した[EIP-1](https://eips.ethereum.org/EIPS/eip-1)をお読みください。また、草案を提出する前に、まずコミュニティと議論する場所である[イーサリアム・マジシャンズ](https://ethereum-magicians.org/) でフィードバックを募ってください。 ## 参考文献 {#references} diff --git a/public/content/translations/ja/roadmap/account-abstraction/index.md b/public/content/translations/ja/roadmap/account-abstraction/index.md index eb2fb8d7d30..d472a9a81e9 100644 --- a/public/content/translations/ja/roadmap/account-abstraction/index.md +++ b/public/content/translations/ja/roadmap/account-abstraction/index.md @@ -10,9 +10,9 @@ summaryPoints: # アカウント抽象化 {#account-abstraction} -ユーザーは、**[外部所有アカウント(EOA)](/glossary/#eoa)**を使用してイーサリアムとやりとりします。 EOA は、トランザクションを開始したり、スマートコントラクトを実行したりするための唯一の方法です。 ユーザーとイーサリアムのやり取りは、EOA により制限されています。 例えば、EOA では、トランザクションのバッチ処理が困難になり、ユーザーはガス代を支払うための ETH 残高を常に保持する必要があります。 +ユーザーは、**[外部所有アカウント(EOA)](/glossary/#eoa)**を使用してイーサリアムとやりとりします。 EOAは、トランザクションを開始したり、スマートコントラクトを実行したりするための唯一の方法です。 ユーザーとイーサリアムのやり取りは、EOAにより制限されています。 例えば、EOAでは、トランザクションのバッチ処理が困難になり、ユーザーはガス代を支払うためのETH残高を常に保持する必要があります。 -アカウント抽象化は、ユーザーがアカウントに対してセキュリティを強化したり、ユーザーエクスペリエンスを柔軟にプログラムできるようにすることで、これらの問題を解決する方法です。 [EOA をアップグレード](https://eips.ethereum.org/EIPS/eip-3074)してスマートコントラクトから制御できるようにするか、[スマートコントラクトをアップグレード](https://eips.ethereum.org/EIPS/eip-2938)してトランザクションを開始できるようにすることで実現します。 上記のオプションのいずれにおいても、イーサリアムプロトコルを変更する必要があります。 さらに、既存のプロトコルと並行して実行する[第二の独立したトランザクションシステム](https://eips.ethereum.org/EIPS/eip-4337)追加する方法もあります。 どの方法であっても、結果としてスマートコントラクトウォレットを介してイーサリアムにアクセスします。これは、既存のプロトコルの一部を利用しても、アドオンのトランザクションネットワークを介しても、ネイティブにサポートされます。 +アカウント抽象化は、ユーザーがアカウントに対してセキュリティを強化したり、ユーザーエクスペリエンスを柔軟にプログラムできるようにすることで、これらの問題を解決する方法です。 [EOAをアップグレード](https://eips.ethereum.org/EIPS/eip-3074)してスマートコントラクトから制御できるようにするか、[スマートコントラクトをアップグレード](https://eips.ethereum.org/EIPS/eip-2938)してトランザクションを開始できるようにすることで実現します。 上記のオプションのいずれにおいても、イーサリアムプロトコルを変更する必要があります。 さらに、既存のプロトコルと並行して実行する[第二の独立したトランザクションシステム](https://eips.ethereum.org/EIPS/eip-4337)追加する方法もあります。 どの方法であっても、結果としてスマートコントラクトウォレットを介してイーサリアムにアクセスします。これは、既存のプロトコルの一部を利用しても、アドオンのトランザクションネットワークを介しても、ネイティブにサポートされます。 スマートコントラクトウォレットは、ユーザーにさまざまな利点をもたらします。 @@ -21,22 +21,22 @@ summaryPoints: - 信頼しているデバイスや個人間でアカウントのセキュリティを共有できる - 他のアカウントのガスを支払う、または他のアカウントに自分のガス代を支払ってもらうことができる - トランザクションをまとめて処理できる (例: 一括でスワップを承認して実行する) -- dApp とウォレットのデベロッパーがユーザーエクスペリエンスでイノベーションを起こす機会が増える +- dAppとウォレットのデベロッパーがユーザーエクスペリエンスでイノベーションを起こす機会が増える -現在、外部所有アカウント ([EOA](/glossary/#eoa)) のみがトランザクションを開始できるため、これらの利点はネイティブにサポートされていません。 EOA は、シンプルに公開鍵と秘密鍵のペアで構成されており、 仕組みは以下のとおりです。 +現在、外部所有アカウント ([EOA](/glossary/#eoa)) のみがトランザクションを開始できるため、これらの利点はネイティブにサポートされていません。 EOAは、シンプルに公開鍵と秘密鍵のペアで構成されており、 仕組みは以下のとおりです。 -- 秘密鍵を持っていれば、イーサリアム仮想マシン(EVM)のルールの範囲内で*何でも*できます。 -- 秘密鍵を持っていなければ、*何も*できません。 +- 秘密鍵を持っていれば、イーサリアム仮想マシン(EVM)のルールの範囲内で_何でも_できます。 +- 秘密鍵を持っていなければ、_何も_できません。 鍵を紛失すると、復元できません。また、鍵が盗まれると、アカウント内のすべての資金に即座にアクセスされてしまいます。 -スマートコントラクトウォレットは、これらの問題の解決策ですが、実装するロジックはイーサリアムで処理する前に一連の EOA トランザクションに変換する必要があるため、現在ではプログラムすることが難しくなっています。 アカウント抽象化により、スマートコントラクト自体がトランザクションを開始できるようになり、ユーザーが実装したいロジックをスマートコントラクトウォレット自体にコード化し、イーサリアム上で実行できるようになります。 +スマートコントラクトウォレットは、これらの問題の解決策ですが、実装するロジックはイーサリアムで処理する前に一連のEOAトランザクションに変換する必要があるため、現在ではプログラムすることが難しくなっています。 アカウント抽象化により、スマートコントラクト自体がトランザクションを開始できるようになり、ユーザーが実装したいロジックをスマートコントラクトウォレット自体にコード化し、イーサリアム上で実行できるようになります。 最終的に、アカウント抽象化によってスマートコントラクトウォレットのサポートが向上するため、構築が簡素化し、安全に使用できるようになり、 イーサリアムの基盤となる技術を知らずとも、イーサリアムのすべてのメリットを享受できるようになります。 ## シードフレーズを超えて {#beyond-seed-phrases} -現在のアカウントは、シードフレーズから計算された秘密鍵を使用して保護されています。 シードフレーズにアクセスできる人は、アカウントを保護する秘密鍵を簡単に発見し、保護されているすべての資産にアクセスできます。 秘密鍵とシードフレーズを紛失してしまうと、復元することはできず、ウォレットが管理する資産は永久に凍結されます。 シードフレーズの保護は、熟練ユーザーであっても簡単ではありません。また、ユーザーが詐欺に遭う最も一般的な手法の 1 つとしてシードフレーズフィッシングがあります。 +現在のアカウントは、シードフレーズから計算された秘密鍵を使用して保護されています。 シードフレーズにアクセスできる人は、アカウントを保護する秘密鍵を簡単に発見し、保護されているすべての資産にアクセスできます。 秘密鍵とシードフレーズを紛失してしまうと、復元することはできず、ウォレットが管理する資産は永久に凍結されます。 シードフレーズの保護は、熟練ユーザーであっても簡単ではありません。また、ユーザーが詐欺に遭う最も一般的な手法の1つとしてシードフレーズフィッシングがあります。 アカウント抽象化では、スマートコントラクトを使用して資産を保持し、トランザクションを承認することで、この問題を解決します。 これらのスマートコントラクトにカスタムロジックを施すことができ、可能な限り安全に、そしてユーザーごとにカスタマイズすることができます。 最終的には、アカウントへのアクセスを制御するために秘密鍵を使用しますが、より簡単で安全に秘密鍵を管理するための安全策が施してあります。 @@ -44,23 +44,23 @@ summaryPoints: ### スマートコントラクトウォレットに組み込めるセキュリティロジックの例: -- **マルチシグ認証**: 複数の信頼できるユーザーまたはデバイス間で認証資格情報を共有できます。 これにより、事前設定された金額を超えるトランザクションには、信頼できる当事者の特定の割合 (例: 5 人中の 3 人) からの承認が必要となるようにコントラクトを設定できます。 例えば、高額のトランザクションでは、モバイルデバイスとハードウェアウォレットの両方からの承認、または信頼できる家族に配布されたアカウントからの署名を必須にすることができます。 +- **マルチシグ認証**: 複数の信頼できるユーザーまたはデバイス間で認証資格情報を共有できます。 これにより、事前設定された金額を超えるトランザクションには、信頼できる当事者の特定の割合 (例: 5人中の3人) からの承認が必要となるようにコントラクトを設定できます。 例えば、高額のトランザクションでは、モバイルデバイスとハードウェアウォレットの両方からの承認、または信頼できる家族に配布されたアカウントからの署名を必須にすることができます。 - **アカウントの凍結**: デバイスが紛失したり侵害された場合、認証された別のデバイスからアカウントをロックすることができ、ユーザーの資産を保護します。 - **アカウントの復元**: デバイスを紛失したり、パスワードを忘れたりすることがあります。 現在の仕組みでは、あなたの資産が永久に凍結される可能性があります。 そこで、スマートコントラクトウォレットを使用することで、新しいデバイスを承認してアクセスをリセットできる事前承認済みアカウントを設定します。 -- **トランザクションリミットの設定**: 1 日、1 週間、1 か月などの期間でアカウントから転送できる金額の 1 日当たりのしきい値を指定できます。 つまり、攻撃者がアカウントにアクセスできたとしても、一度にすべての金額を流出させることはできなくなり、攻撃者からのアクセスを凍結してリセットすることができます。 -- **ホワイトリストの作成**: 安全であるとわかっている特定のアドレスへのトランザクションのみを許可します。 つまり、秘密鍵が*盗まれたとしても*、攻撃者はホワイトリストに登録されていない宛先アカウントに資金を送金することはできません。 これらのホワイトリストを変更するには複数の署名が必要になるため、攻撃者は、あなたの複数のバックアップキーにアクセスできない限り、リストに自分のアドレスを追加できません。 +- **トランザクションリミットの設定**: 1日、1週間、1か月などの期間でアカウントから転送できる金額の1日当たりのしきい値を指定できます。 つまり、攻撃者がアカウントにアクセスできたとしても、一度にすべての金額を流出させることはできなくなり、攻撃者からのアクセスを凍結してリセットすることができます。 +- **ホワイトリストの作成**: 安全であるとわかっている特定のアドレスへのトランザクションのみを許可します。 つまり、秘密鍵が_盗まれたとしても_、攻撃者はホワイトリストに登録されていない宛先アカウントに資金を送金することはできません。 これらのホワイトリストを変更するには複数の署名が必要になるため、攻撃者は、あなたの複数のバックアップキーにアクセスできない限り、リストに自分のアドレスを追加できません。 ## ユーザーエクスペリエンスの向上 {#better-user-experience} アカウント抽象化によって、スマートコントラクトウォレットがプロトコルレベルでサポートされるようになります。これにより、**ユーザーエクスペリエンスが全体的に改善**され、**セキュリティも向上**します。 アカウント抽象化を行う最も重要な理由は、スマートコントラクト、ウォレット、アプリケーションのデベロッパーが、これまでにない方法でユーザーエクスペリエンスをより自由に革新できるようになるからです。 アカウント抽象化によって明らかに改善する点として、トランザクションのバンドル化による速度と効率の向上が挙げられます 例えば、シンプルなスワップは、ワンクリックで完了できるはずです。しかし、現在は、スワップを実行する前に、個々のトークンの支出を承認するために、複数のトランザクションに署名する必要があります。 アカウント抽象化は、トランザクションをバンドル化することで、こうした摩擦を取り除きます。 さらに、バンドル化されたトランザクションは、各トランザクションに必要なトークンの正確な値を承認し、トランザクションが完了した後に承認を取り消すことができます。そのため、より安全性が高まります。 -ガス代の管理もアカウント抽象化によって大幅に改善されます。 アプリケーションは、ユーザーのガス代を支払うことができるだけでなく、ガス代を ETH 以外のトークンで支払うこともできます。このため、ユーザーは資金のトランザクションで ETH 残高を維持する必要がなくなります。 その仕組みを説明すると、コントラクト内でユーザーのトークンを ETH に交換し、その ETH をガス代の支払いに使用しています。 +ガス代の管理もアカウント抽象化によって大幅に改善されます。 アプリケーションは、ユーザーのガス代を支払うことができるだけでなく、ガス代をETH以外のトークンで支払うこともできます。このため、ユーザーは資金のトランザクションでETH残高を維持する必要がなくなります。 その仕組みを説明すると、コントラクト内でユーザーのトークンをETHに交換し、そのETHをガス代の支払いに使用しています。 -イーサリアムユーザーにとって、ガス代の管理は最も不便な点の 1 つです。イーサリアムでは、トランザクションの支払いに ETH しか使用できないためです。 例えば、ウォレットに USDC 残高はあるものの、ETH がないとします。 ガス代を払うことができないため、残高の USDC トークンを移動、交換することもできず、 その結果、USDC を ETH に交換することもできません。それ自体にガス代がかかるからです。 問題を解決するには、取引所または別のアドレスからアカウントに ETH を送信する必要があります。 しかし、スマートコントラクトウォレットがあれば、ガス料金を USDC で簡単に支払うことができ、アカウントが解放されます。 これにより、すべてのアカウントで ETH 残高を維持する必要がなくなります。 +イーサリアムユーザーにとって、ガス代の管理は最も不便な点の1つです。イーサリアムでは、トランザクションの支払いにETHしか使用できないためです。 例えば、ウォレットにUSDC残高はあるものの、ETHがないとします。 ガス代を払うことができないため、残高のUSDCトークンを移動、交換することもできず、 その結果、USDCをETHに交換することもできません。それ自体にガス代がかかるからです。 問題を解決するには、取引所または別のアドレスからアカウントにETHを送信する必要があります。 しかし、スマートコントラクトウォレットがあれば、ガス料金をUSDCで簡単に支払うことができ、アカウントが解放されます。 これにより、すべてのアカウントでETH残高を維持する必要がなくなります。 -また、アカウント抽象化により、dApp デベロッパーはガス代を自由に管理することができます。 例えば、お気に入りの DEX に対して、毎月固定の料金を支払うことで無制限のトランザクションができるかもしれません。 dApps は、プラットフォームの使用に対する報酬として、またはオンボーディングオファーとして、利用者に代わってすべてのガス代の払ってくれるかもしれません。 スマートコントラクトウォレットがプロトコルレベルでサポートされると、デベロッパーはガス代の改革をより簡単に行うことができます +また、アカウント抽象化により、dAppデベロッパーはガス代を自由に管理することができます。 例えば、お気に入りのDEXに対して、毎月固定の料金を支払うことで無制限のトランザクションができるかもしれません。 dAppsは、プラットフォームの使用に対する報酬として、またはオンボーディングオファーとして、利用者に代わってすべてのガス代の払ってくれるかもしれません。 スマートコントラクトウォレットがプロトコルレベルでサポートされると、デベロッパーはガス代の改革をより簡単に行うことができます @@ -68,59 +68,59 @@ summaryPoints: アカウント抽象化によって、購買がどのように変化するのか考えてみるのも面白いでしょう。 現在、各トランザクションは、正確かつ十分な量のトークンを事前に資金提供されたウォレットから承認、実行される必要があります。 アカウント抽象化では、オンライン ショッピングに近いエクスペリエンスが得られます。例えば、ユーザーは「バスケット」にアイテムを追加し、一度クリックするだけですべてを一括購入でき、必要なロジックはすべて、ユーザーではなくコントラクトで処理できます。 -アカウント抽象化は、ユーザーエクスペリエンスを向上させるための強力なツールです。これらの例は、その可能性のほんの一端に過ぎませんが、まだまだ想像もできないようなことを実現できるはずです。 アカウント抽象化によって、デベロッパーは現在の EOA の制約に縛られることなく、Web2 の優れた側面を Web3 に取り入れることで、セルフカストディを維持しながら、創造的に新しいユーザーエクスペリエンスをハックできるようになります。 +アカウント抽象化は、ユーザーエクスペリエンスを向上させるための強力なツールです。これらの例は、その可能性のほんの一端に過ぎませんが、まだまだ想像もできないようなことを実現できるはずです。 アカウント抽象化によって、デベロッパーは現在のEOAの制約に縛られることなく、Web2の優れた側面をWeb3に取り入れることで、セルフカストディを維持しながら、創造的に新しいユーザーエクスペリエンスをハックできるようになります。 ## アカウント抽象化の実装方法 {#how-will-aa-be-implemented} -スマートコントラクトウォレットはすでに存在していますが、EVM 自体がサポートしていないため、実装が難しい状況です。 代わりに、標準的なイーサリアムトランザクション周りを比較的複雑なコードでラップすることに依存しています。 イーサリアムでは、スマートコントラクトがトランザクションを開始できるようにし、オフチェーンではなくイーサリアムスマートコントラクトで必要なロジックを処理することで、スマートコントラクトウォレットに変えることができます。 スマートコントラクトにロジックを組み込むことで、ユーザーが署名したメッセージを通常のイーサリアムトランザクションに変換するためにウォレットデベロッパーが実行する「リレイヤー」が不要となるため、イーサリアムの分散化を高めることができます。 +スマートコントラクトウォレットはすでに存在していますが、EVM自体がサポートしていないため、実装が難しい状況です。 代わりに、標準的なイーサリアムトランザクション周りを比較的複雑なコードでラップすることに依存しています。 イーサリアムでは、スマートコントラクトがトランザクションを開始できるようにし、オフチェーンではなくイーサリアムスマートコントラクトで必要なロジックを処理することで、スマートコントラクトウォレットに変えることができます。 スマートコントラクトにロジックを組み込むことで、ユーザーが署名したメッセージを通常のイーサリアムトランザクションに変換するためにウォレットデベロッパーが実行する「リレイヤー」が不要となるため、イーサリアムの分散化を高めることができます。 -EIP-2771 では、イーサリアムのプロトコルに変更を加えることなく、第三者がユーザーの代わりにガス代を支払うことができるメタトランザクションの概念が導入されました このアイデアは、ユーザーが署名したトランザクションが「Forwarder」コントラクトに送信されるというものです。 Forwarder は、トランザクションをガスリレーに送信する前に、トランザクションが有効であることを検証する信頼できるエンティティです。 これはオフチェーンで行われ、ガス代を支払う必要はありません。 ガスリレーは、トランザクションを「Recipient」コントラクトに渡し、イーサリアムでトランザクションを実行できるようにするために必要なガスを支払います。 トランザクションは、「Forwarder」が「Recipient」によって認識、信頼されている場合に実行されます。 このモデルにより、デベロッパーはユーザー向けのガスレストランザクションを簡単に実装できます。 +EIP-2771では、イーサリアムのプロトコルに変更を加えることなく、第三者がユーザーの代わりにガス代を支払うことができるメタトランザクションの概念が導入されました このアイデアは、ユーザーが署名したトランザクションが「Forwarder」コントラクトに送信されるというものです。 Forwarderは、トランザクションをガスリレーに送信する前に、トランザクションが有効であることを検証する信頼できるエンティティです。 これはオフチェーンで行われ、ガス代を支払う必要はありません。 ガスリレーは、トランザクションを「Recipient」コントラクトに渡し、イーサリアムでトランザクションを実行できるようにするために必要なガスを支払います。 トランザクションは、「Forwarder」が「Recipient」によって認識、信頼されている場合に実行されます。 このモデルにより、デベロッパーはユーザー向けのガスレストランザクションを簡単に実装できます。 -EIP-4337 は、イーサリアムのプロトコルを変更せずに、分散型による方法でネイティブのスマートコントラクトウォレットをサポートする最初のステップです。 スマートコントラクトウォレットをサポートするコンセンサスレイヤーを変更する代わりに、通常のトランザクションのゴシッププロトコルに新しいシステムが個別に追加されます。 この上位レベルのシステムは、 UserOperationと呼ばれる新しいオブジェクトを中心に構築されており、ユーザーからのアクションと関連する署名をパッケージ化します。 これらのUserOperationオブジェクトは、専用のメンプールにブロードキャストされます。メンプールでは、バリデータがオブジェクトを収集して「バンドルトランザクション」にまとめます。 バンドルトランザクションは、複数のUserOperationsのシーケンスを表し、通常のトランザクションと同じようにイーサリアムブロックに含めることができます。バンドルトランザクションは、バリデータによって、通常のトランザクションと同じように、手数料最大化選択モデルを使用して選択されます。 +EIP-4337は、イーサリアムのプロトコルを変更せずに、分散型による方法でネイティブのスマートコントラクトウォレットをサポートする最初のステップです。 スマートコントラクトウォレットをサポートするコンセンサスレイヤーを変更する代わりに、通常のトランザクションのゴシッププロトコルに新しいシステムが個別に追加されます。 この上位レベルのシステムは、 UserOperationと呼ばれる新しいオブジェクトを中心に構築されており、ユーザーからのアクションと関連する署名をパッケージ化します。 これらのUserOperationオブジェクトは、専用のメンプールにブロードキャストされます。メンプールでは、バリデータがオブジェクトを収集して「バンドルトランザクション」にまとめます。 バンドルトランザクションは、複数のUserOperationsのシーケンスを表し、通常のトランザクションと同じようにイーサリアムブロックに含めることができます。バンドルトランザクションは、バリデータによって、通常のトランザクションと同じように、手数料最大化選択モデルを使用して選択されます。 -EIP-4337 では、ウォレットの動作方法も変わります。 各ウォレットで共通の複雑な安全ロジックを、ウォレットごとに再実装するのではなく、グローバルウォレットコントラクトと呼ばれる"エントリポイント"にアウトソースします。 これにより、フィーの支払いや EVM コードの実行などの操作が処理されるため、ウォレットデベロッパーは、優れたユーザーエクスペリエンスを提供することに集中できます。 +EIP-4337では、ウォレットの動作方法も変わります。 各ウォレットで共通の複雑な安全ロジックを、ウォレットごとに再実装するのではなく、グローバルウォレットコントラクトと呼ばれる"エントリポイント"にアウトソースします。 これにより、フィーの支払いやEVMコードの実行などの操作が処理されるため、ウォレットデベロッパーは、優れたユーザーエクスペリエンスを提供することに集中できます。 -注記: EIP4337 エントリポイントコントラクトは、2023 年 3 月 1 日にイーサリアムのメインネットにデプロイされました。 Etherscanでコントラクトを確認できます。 +注記: EIP4337エントリポイントコントラクトは、2023年3月1日にイーサリアムのメインネットにデプロイされました。 Etherscanでコントラクトを確認できます。 -EIP-2938は、新しいトランザクションタイプAA_TX_TYPEを導入することで、イーサリアムプロトコルを更新することを目的としています。AA_TX_TYPEには、noncetargetdataの 3 つのフィールドがあり、nonceはトランザクションカウンタ、targetはエントリポイントのコントラクトアドレス、dataは EVM バイトコードです。 これらのトランザクションを実行するには、NONCEPAYGASという 2 つの新しい命令(オペコード)を EVM に追加する必要があります。 このNONCEオペコードは、トランザクションのシーケンスを追跡します。一方PAYGASは、トランザクションの実行に必要なガスを計算してコントラクトの残高から引き出します。 これらの新機能により、イーサリアムに必要なインフラストラクチャがイーサリアムのプロトコルに組み込まれるため、スマートコントラクトウォレットをネイティブにサポートできます。 +EIP-2938は、新しいトランザクションタイプAA_TX_TYPEを導入することで、イーサリアムプロトコルを更新することを目的としています。AA_TX_TYPEには、noncetargetdataの3つのフィールドがあり、nonceはトランザクションカウンタ、targetはエントリポイントのコントラクトアドレス、dataはEVMバイトコードです。 これらのトランザクションを実行するには、NONCEPAYGASという2つの新しい命令(オペコード)をEVMに追加する必要があります。 このNONCEオペコードは、トランザクションのシーケンスを追跡します。一方PAYGASは、トランザクションの実行に必要なガスを計算してコントラクトの残高から引き出します。 これらの新機能により、イーサリアムに必要なインフラストラクチャがイーサリアムのプロトコルに組み込まれるため、スマートコントラクトウォレットをネイティブにサポートできます。 -現在、EIP-2938 はアクティブではありません。 プロトコルの変更が必要ない EIP-4337 が、コミュニティの支持を得ています。 +現在、EIP-2938はアクティブではありません。 プロトコルの変更が必要ないEIP-4337が、コミュニティの支持を得ています。 -EIP-3074では、イーサリアムの外部所有アカウントを更新し、スマートコントラクトにコントロールを委任できるようにすることを目的としています。 つまり、スマートコントラクトのロジックが EOA から発生するトランザクションを承認できるということです。 また、ガススポンサーやバッチトランザクションなどの機能が使えるようになります。 この機能を使用するには、AUTHAUTHCALLという新しい 2 つのオペコードを追加する必要があります。 EIP-3074 では、スマートコントラクトウォレットの利点を、コントラクトなしでも利用できるようになります。代わりに、「インボーカー」と呼ばれるアップグレード不可能、ステートレス、トラストレスである特定のタイプのコントラクトがトランザクションを処理します。 +EIP-3074では、イーサリアムの外部所有アカウントを更新し、スマートコントラクトにコントロールを委任できるようにすることを目的としています。 つまり、スマートコントラクトのロジックがEOAから発生するトランザクションを承認できるということです。 また、ガススポンサーやバッチトランザクションなどの機能が使えるようになります。 この機能を使用するには、AUTHAUTHCALLという新しい2つのオペコードを追加する必要があります。 EIP-3074では、スマートコントラクトウォレットの利点を、コントラクトなしでも利用できるようになります。代わりに、「インボーカー」と呼ばれるアップグレード不可能、ステートレス、トラストレスである特定のタイプのコントラクトがトランザクションを処理します。 -現在、EIP-3074 はアクティブではありません。 プロトコルの変更が必要ない EIP-4337 が、コミュニティの支持を得ています。 +現在、EIP-3074はアクティブではありません。 プロトコルの変更が必要ないEIP-4337が、コミュニティの支持を得ています。 ## 現在の進行状況 {#current-progress} -スマートコントラクトウォレットはすでに利用可能ですが、それらをできるだけ分散化してパーミッションレスにするには、さらなるアップグレードが必要です。 EIP-4337 は、イーサリアムのプロトコルに変更を加えずに実装できる成熟した提案です。そのため、すぐに実装される可能性があります。 ただし、イーサリアムのプロトコルを変更するアップグレードは、現在積極的に開発されておらず、プロトコルの変更を伴うリリースは、さらに時間がかかると予想されます。 EIP-4337 によってアカウント抽象化が十分に達成される可能性もあるため、プロトコルの変更がまったく必要なくなるかもしれません。 +スマートコントラクトウォレットはすでに利用可能ですが、それらをできるだけ分散化してパーミッションレスにするには、さらなるアップグレードが必要です。 EIP-4337は、イーサリアムのプロトコルに変更を加えずに実装できる成熟した提案です。そのため、すぐに実装される可能性があります。 ただし、イーサリアムのプロトコルを変更するアップグレードは、現在積極的に開発されておらず、プロトコルの変更を伴うリリースは、さらに時間がかかると予想されます。 EIP-4337によってアカウント抽象化が十分に達成される可能性もあるため、プロトコルの変更がまったく必要なくなるかもしれません。 ## 参考文献 {#further-reading} - [erc4337.io](https://www.erc4337.io/) -- [Devcon Bogota でのアカウント抽象化のパネルディスカッション](https://www.youtube.com/watch?app=desktop&v=WsZBymiyT-8) -- [Devcon Bogota「アカウント抽象化が dApp のゲームチェンジャーになる理由」](https://www.youtube.com/watch?v=OwppworJGzs) -- [Devcon Bogota「アカウント抽象化 ELI5」](https://www.youtube.com/watch?v=QuYZWJj65AY) +- [Devcon Bogotaでのアカウント抽象化のパネルディスカッション](https://www.youtube.com/watch?app=desktop&v=WsZBymiyT-8) +- [Devcon Bogota「アカウント抽象化がdAppのゲームチェンジャーになる理由」](https://www.youtube.com/watch?v=OwppworJGzs) +- [Devcon Bogota「アカウント抽象化ELI5」](https://www.youtube.com/watch?v=QuYZWJj65AY) - [ヴィタリックの「アカウント抽象化への道」メモ](https://notes.ethereum.org/@vbuterin/account_abstraction_roadmap#Transaction-inclusion-lists) -- [ヴィタリックのソーシャルリカバリウォレットに関するブログ投稿](https://vitalik.eth.limo/general/2021/01/11/recovery.html) -- [EIP-2938 のメモ](https://hackmd.io/@SamWilsn/ryhxoGp4D#What-is-EIP-2938) -- [EIP-2938 のドキュメント](https://eips.ethereum.org/EIPS/eip-2938) -- [EIP-4337 のメモ](https://medium.com/infinitism/erc-4337-account-abstraction-without-ethereum-protocol-changes-d75c9d94dc4a) -- [EIP-4337 のドキュメント](https://eips.ethereum.org/EIPS/eip-4337) -- [EIP-2771 のドキュメント](https://eips.ethereum.org/EIPS/eip-2771) -- [「アカウント抽象化の基礎」 -- アカウント抽象化とは パート 1](https://www.alchemy.com/blog/account-abstraction) +- [ヴィタリックのソーシャルリカバリウォレットに関するブログ投稿](https://vitalik.ca/general/2021/01/11/recovery.html) +- [EIP-2938のメモ](https://hackmd.io/@SamWilsn/ryhxoGp4D#What-is-EIP-2938) +- [EIP-2938のドキュメント](https://eips.ethereum.org/EIPS/eip-2938) +- [EIP-4337のメモ](https://medium.com/infinitism/erc-4337-account-abstraction-without-ethereum-protocol-changes-d75c9d94dc4a) +- [EIP-4337のドキュメント](https://eips.ethereum.org/EIPS/eip-4337) +- [EIP-2771のドキュメント](https://eips.ethereum.org/EIPS/eip-2771) +- [「アカウント抽象化の基礎」 -- アカウント抽象化とは パート1](https://www.alchemy.com/blog/account-abstraction) diff --git a/public/content/translations/ja/roadmap/beacon-chain/index.md b/public/content/translations/ja/roadmap/beacon-chain/index.md index 8bb8abd5e29..67d78a51a4d 100644 --- a/public/content/translations/ja/roadmap/beacon-chain/index.md +++ b/public/content/translations/ja/roadmap/beacon-chain/index.md @@ -4,19 +4,18 @@ description: ビーコンチェーン - プルーフ・オブ・ステークの lang: ja template: upgrade image: /upgrades/core.png -alt: summaryPoint1: イーサリアムエコシステムにプルーフ・オブ・ステークの導入を可能にしたのが、ビーコンチェーンです。 summaryPoint2: 2022年9月にプルーフ・オブ・ワーク・チェーンのイーサリアムとマージ(統合)されました。 summaryPoint3: ビーコンチェーンは、コンセンサスロジックとブロックゴシッププロトコルを導入し、現在はイーサリアムの安全性を保護しています。 --- - + ビーコンチェーンは、2020年12月にリリースされ、2022年9月15日のマージアップグレードでイーサリアムの合意メカニズムに、プルーフ・オブ・ステークとして正式に導入されました。 ## ビーコンチェーンとは {#what-is-the-beacon-chain} -ビーコンチェーンは、2020 年に開始されたオリジナルのプルーフ・オブ・ステーク型ブロックチェーンの名称です。 当初は、イーサリアムメインネットに適用する前に、プルーフ・オブ・ステークのコンセンサスロジックが健全で持続可能であることを確認するために作成されました。 そのため、元来のプルーフ・オブ・ワークのイーサリアムと並行して稼働していました。 ビーコンチェーンは「空の」ブロックのチェーンだったので、イーサリアムでプルーフ・オブ・ワークを停止し、プルーフ・オブ・ステークへと切り替えるには、ビーコンチェーンで実行クライアントのトランザクションデータを受け入れ、ブロックにバンドルし、プルーフ・オブ・ステークに基づく合意メカニズムを使ってブロックチェーンに構成する必要がありました。 同時に、オリジナルのイーサリアムのクライアントは、マイニング、ブロック伝播、コンセンサスロジックを停止し、ビーコンチェーンへと継承させました。 これが[マージ](/roadmap/merge/)として知られるイベントです。 マージによって、2 つのブロックチェーンは プルーフ・オブ・ステークに統合され、現在は、ノードごとに 2 つの異なるクライアントが必要になりました。 ビーコンチェーンは現在、コンセンサスレイヤーであり、ブロックのゴシップとコンセンサスロジックを処理するコンセンサスクライアントのピアツーピアネットワークです。一方、元々のクライアントは実行レイヤーを形成し、トランザクションのゴシップと実行、そしてイーサリアムの状態を管理しています。 2 つのレイヤーは、エンジン API を使ってお互いに通信することができます。 +ビーコンチェーンは、2020年に開始されたオリジナルのプルーフ・オブ・ステーク型ブロックチェーンの名称です。 当初は、イーサリアムメインネットに適用する前に、プルーフ・オブ・ステークのコンセンサスロジックが健全で持続可能であることを確認するために作成されました。 そのため、元来のプルーフ・オブ・ワークのイーサリアムと並行して稼働していました。 ビーコンチェーンは「空の」ブロックのチェーンだったので、イーサリアムでプルーフ・オブ・ワークを停止し、プルーフ・オブ・ステークへと切り替えるには、ビーコンチェーンで実行クライアントのトランザクションデータを受け入れ、ブロックにバンドルし、プルーフ・オブ・ステークに基づく合意メカニズムを使ってブロックチェーンに構成する必要がありました。 同時に、オリジナルのイーサリアムのクライアントは、マイニング、ブロック伝播、コンセンサスロジックを停止し、ビーコンチェーンへと継承させました。 これが[マージ](/roadmap/merge/)として知られるイベントです。 マージによって、2つのブロックチェーンは プルーフ・オブ・ステークに統合され、現在は、ノードごとに2つの異なるクライアントが必要になりました。 ビーコンチェーンは現在、コンセンサスレイヤーであり、ブロックのゴシップとコンセンサスロジックを処理するコンセンサスクライアントのピアツーピアネットワークです。一方、元々のクライアントは実行レイヤーを形成し、トランザクションのゴシップと実行、そしてイーサリアムの状態を管理しています。 2つのレイヤーは、エンジンAPIを使ってお互いに通信することができます。 ## ビーコンチェーンとは {#what-does-the-beacon-chain-do} @@ -26,7 +25,7 @@ summaryPoint3: ビーコンチェーンは、コンセンサスロジックと ### ステーキングの紹介 {#introducing-staking} -ビーコンチェーンの稼働の伴い、 [プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos/)がイーサリアムに導入されました。 イーサリアムの安全性が保たれ、バリデータはより多くの ETH を獲得することができるようになりました。 実際にバリデータソフトウェアを起動するには、ETH をステーキングすることになります。 ステーカーは、チェーンに新しいブロックを作成し、検証するバリデータソフトウェアを実行します。 +ビーコンチェーンの稼働の伴い、 [プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos/)がイーサリアムに導入されました。 イーサリアムの安全性が保たれ、バリデータはより多くのETHを獲得することができるようになりました。 実際にバリデータソフトウェアを起動するには、ETHをステーキングすることになります。 ステーカーは、チェーンに新しいブロックを作成し、検証するバリデータソフトウェアを実行します。 ステーキングは、かつての[マイニング](/developers/docs/mining/)と同じ目的を果たしますが、その手法は多くの点で異なります。 マイニングには、強力なハードウェアや大量のエネルギーが必要であり、そのため、多額の先行投資が必要になります。その結果、規模の経済が生まれ、集中化が進みました マイニングにおいても、資産を担保としてロックする必要がなかったため、攻撃後に悪意のある行為者を罰するプロトコルの能力にも限界がありました。 @@ -42,7 +41,7 @@ summaryPoint3: ビーコンチェーンは、コンセンサスロジックと ビーコンチェーンが元来のイーサリアムメインネットに統合されてから、イーサリアムコミュニティはネットワークのスケーリングを模索し始めました。 -プルーフ・オブ・ステークには、承認されたすべてのブロック作成者のレジストリを常に登録し、ETH をステーキングしているという利点があります。 このレジストリにより、特定のネットワークの責任を信頼おける方法で分割や制御することができます。 +プルーフ・オブ・ステークには、承認されたすべてのブロック作成者のレジストリを常に登録し、ETHをステーキングしているという利点があります。 このレジストリにより、特定のネットワークの責任を信頼おける方法で分割や制御することができます。 この責任において、プルーフ・オブ・ワークとは対照的です。プルーフ・オブ・ワークでは、マイナーはネットワークに対する義務を負わないため、ペナルティは一切なく、瞬時にマイニングを停止し、ノードソフトウエアを終了することができます。 ブロック提案者のレジストリもなく、ネットワークに関する責任を安全に分担する信頼できる方法もありません。 @@ -54,7 +53,7 @@ summaryPoint3: ビーコンチェーンは、コンセンサスロジックと ### ビーコンチェーンとマージ {#merge-and-beacon-chain} -当初、ビーコンチェーンはイーサリアムメインネットと別々に存在していましたが 2022 年に統合されました。 +当初、ビーコンチェーンはイーサリアムメインネットと別々に存在していましたが2022年に統合されました。 マージ diff --git a/public/content/translations/ja/roadmap/danksharding/index.md b/public/content/translations/ja/roadmap/danksharding/index.md index 998d693bf9d..f73842ad0fa 100644 --- a/public/content/translations/ja/roadmap/danksharding/index.md +++ b/public/content/translations/ja/roadmap/danksharding/index.md @@ -11,21 +11,21 @@ summaryPoints: # ダークシャーディング {#danksharding} -**ダンクシャーディング**は、イーサリアムが真にスケーラブルなブロックチェーンになるうえで重要な役割を果たしています。しかし、そこに到達するには、複数のプロトコルをアップグレードする必要があります。 **プロトダンクシャーディング**は、ダンクシャーディングへの中間ステップです。 どちらもユーザーにとってレイヤー 2 でのトランザクションを可能な限り安価にすることを目的としています。また、イーサリアムを 1 秒間のトランザクション件数を 10 万件以上に拡大することを目指しています。 +**ダンクシャーディング**は、イーサリアムが真にスケーラブルなブロックチェーンになるうえで重要な役割を果たしています。しかし、そこに到達するには、複数のプロトコルをアップグレードする必要があります。 **プロトダンクシャーディング**は、ダンクシャーディングへの中間ステップです。 どちらもユーザーにとってレイヤー2でのトランザクションを可能な限り安価にすることを目的としています。また、イーサリアムを1秒間のトランザクション件数を10万件以上に拡大することを目指しています。 ## プロトダンクシャーディングとは {#what-is-protodanksharding} -[EIP-4844](https://eips.ethereum.org/EIPS/eip-4844)として知られるプロトダンクシャーディングは、[ロールアップ](/layer2/#rollups)がより安価なデータをブロックに追加する方法です。 この名称は、アイデアを提案した 2 名の研究者 (プロトラムダ氏とダンクラッド・フィースト氏)に由来しています。 現在のシステムでは、ロールアップは`CALLDATA`にトランザクションを投稿するため、ユーザートランザクションのコストを安くするには限界があります。 たとえロールアップがデータを必要とするのが短期間であっても、すべてのイーサリアムノードによって処理され、チェーン上にデータが永久に存在するため高価になってしまいます。 プロトダンクシャーディングでは、ブロックに送信、添付できるデータブロブを導入します。 これらのブロブ内のデータは、EVM にアクセスできず、一定期間 (1 ~ 3 か月) が経過すると自動的に削除されます。 データブロブにより、ロールアップはデータをより安価に送信できるため、節約した費用をトランザクションのコストとして削減することができます。これにより、エンドユーザーはより安価にトランザクションを行うことができます。 +[EIP-4844](https://eips.ethereum.org/EIPS/eip-4844)として知られるプロトダンクシャーディングは、[ロールアップ](/layer2/#rollups)がより安価なデータをブロックに追加する方法です。 この名称は、アイデアを提案した2名の研究者 (プロトラムダ氏とダンクラッド・フィースト氏)に由来しています。 現在のシステムでは、ロールアップは`CALLDATA`にトランザクションを投稿するため、ユーザートランザクションのコストを安くするには限界があります。 たとえロールアップがデータを必要とするのが短期間であっても、すべてのイーサリアムノードによって処理され、チェーン上にデータが永久に存在するため高価になってしまいます。 プロトダンクシャーディングでは、ブロックに送信、添付できるデータブロブを導入します。 これらのブロブ内のデータは、EVMにアクセスできず、一定期間 (1~3か月) が経過すると自動的に削除されます。 データブロブにより、ロールアップはデータをより安価に送信できるため、節約した費用をトランザクションのコストとして削減することができます。これにより、エンドユーザーはより安価にトランザクションを行うことができます。 -ロールアップは、トランザクションをオフチェーンでバッチ処理し、その結果をイーサリアムに投稿することで、イーサリアムをスケーラビリティを改善する方法です。 ロールアップは、基本的にデータと実行確認の 2 つの要素で構成されています。 データは、イーサリアムに投稿される状態変更を生成するためにロールアップによって処理されている、トランザクションの完全なシーケンスです。 実行確認では、正直なアクターである証明者が、提案された状態変更が正しいことを確認するために、トランザクションを再度実行します。 実行確認を行うには、誰でもダウンロードして確認できるように、トランザクションデータの公開期間を十分に設けておく必要があります。 実行確認により、証明者は、ロールアップシーケンサーが行った不正行為を特定でき、異議申立をすることができます。 ただし、このトランザクションデータを永久的に保存する必要はありません。 +ロールアップは、トランザクションをオフチェーンでバッチ処理し、その結果をイーサリアムに投稿することで、イーサリアムをスケーラビリティを改善する方法です。 ロールアップは、基本的にデータと実行確認の2つの要素で構成されています。 データは、イーサリアムに投稿される状態変更を生成するためにロールアップによって処理されている、トランザクションの完全なシーケンスです。 実行確認では、正直なアクターである証明者が、提案された状態変更が正しいことを確認するために、トランザクションを再度実行します。 実行確認を行うには、誰でもダウンロードして確認できるように、トランザクションデータの公開期間を十分に設けておく必要があります。 実行確認により、証明者は、ロールアップシーケンサーが行った不正行為を特定でき、異議申立をすることができます。 ただし、このトランザクションデータを永久的に保存する必要はありません。 -ロールアップは、トランザクションデータへのコミットメントをオンチェーンに投稿し、実際のデータをデータブロブで入手できるようにするため、 証明者はコミットメントが有効であることを確認したり、間違っていると思われるデータに異議を唱えることができます。 ノードレベルでは、データブロブはコンセンサスクライアントに保持されます。 コンセンサスクライアントは、データを確認し、それがネットワーク全体に伝播したことを証明します。 データが永久的に保持される場合、これらのクライアントの容量が大きくなり、ノードの実行に大量のハードウェアが必要になる可能性があります そのため、データは 1 ~ 3 か月ごとにノードから自動的に削除されます。 コンセンサスクライアントのアテステーションは、証明者がデータを十分に検証する機会があったことを示しています。 実際のデータは、ロールアップオペレータやユーザーなどがオフチェーンに保存できます。 +ロールアップは、トランザクションデータへのコミットメントをオンチェーンに投稿し、実際のデータをデータブロブで入手できるようにするため、 証明者はコミットメントが有効であることを確認したり、間違っていると思われるデータに異議を唱えることができます。 ノードレベルでは、データブロブはコンセンサスクライアントに保持されます。 コンセンサスクライアントは、データを確認し、それがネットワーク全体に伝播したことを証明します。 データが永久的に保持される場合、これらのクライアントの容量が大きくなり、ノードの実行に大量のハードウェアが必要になる可能性があります そのため、データは1~3か月ごとにノードから自動的に削除されます。 コンセンサスクライアントのアテステーションは、証明者がデータを十分に検証する機会があったことを示しています。 実際のデータは、ロールアップオペレータやユーザーなどがオフチェーンに保存できます。 @@ -33,17 +33,17 @@ summaryPoints: ロールアップは、データブロブ内で実行されるトランザクションと、 データを示す「コミットメント」をイーサリアムに投稿します。 これは、多項式関数をデータに当てはめることによって行われます。 この関数は様々な点で値を求めることができます。 例えば、非常に単純な関数`f(x) = 2x-1`を定義したとして、この関数の点である`x = 1`、`x = 2`、`x = 3`で値を求めると、結果は、`1、3、5`になります。 証明者は、同じ関数をデータに適用し、同じ点で値を求めます。 元のデータが変更された場合は、関数は同一ではなくなり、そのため各点で算出される値も同一ではなくなります。 実際には、コミットメントと証明は暗号関数でラップされているため、より複雑になっています。 -### KZG とは {#what-is-kzg} +### KZGとは {#what-is-kzg} -KZG は、Kate-Zaverucha-Goldberg の頭文字で、これは 3 人の[原作者](https://link.springer.com/chapter/10.1007/978-3-642-17373-8_11)の名前を表しています。 データのブロブを小さな[暗号「コミットメント」](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html) まで縮小するスキームのことです。 ロールアップによって送信されたデータブロブは、ロールアップが不正な動作を行っていないか確認するために検証する必要があります。 そのためには、証明者がブロブ内のトランザクションを再実行して、コミットメントが正しいことを確認します。 これは、実行クライアントがマークルプルーフを使用してレイヤー 1 上のイーサリアムトランザクションの正当性をチェックする方法と、概念的には同じです。 KZG は、多項式をデータに当てはめる代替証明です。 コミットメントは、秘密になっている複数のデータ点で多項式を評価します。 証明者は、データに対して同じ多項式と同じ値で評価し、結果が同じであることを確認します。 これは、ゼロ知識技術と互換性のあるデータ検証方式であり、一部のロールアップやイーサリアムプロトコルの他の箇所で使用されています。 +KZGは、Kate-Zaverucha-Goldbergの頭文字で、これは3人の[原作者](https://link.springer.com/chapter/10.1007/978-3-642-17373-8_11)の名前を表しています。 データのブロブを小さな[暗号「コミットメント」](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html) まで縮小するスキームのことです。 ロールアップによって送信されたデータブロブは、ロールアップが不正な動作を行っていないか確認するために検証する必要があります。 そのためには、証明者がブロブ内のトランザクションを再実行して、コミットメントが正しいことを確認します。 これは、実行クライアントがマークルプルーフを使用してレイヤー1上のイーサリアムトランザクションの正当性をチェックする方法と、概念的には同じです。 KZGは、多項式をデータに当てはめる代替証明です。 コミットメントは、秘密になっている複数のデータ点で多項式を評価します。 証明者は、データに対して同じ多項式と同じ値で評価し、結果が同じであることを確認します。 これは、ゼロ知識技術と互換性のあるデータ検証方式であり、一部のロールアップやイーサリアムプロトコルの他の箇所で使用されています。 -### KZG セレモニーとは {#what-is-a-kzg-ceremony} +### KZGセレモニーとは {#what-is-a-kzg-ceremony} -KZG セレモニーは、イーサリアムコミュニティ全体から多くの人々が協力して生成する、データの検証に使用できる秘密のランダムな数字列を生成する方法です。 この数字列は、誰にも知られず、誰にも再現できないことが、非常に重要であり、 そのために、セレモニーに参加する各人は、前の参加者から文字列を受け取ります。 次に、ブラウザにマウスの動きを測定させるなどして、いくつかの新しいランダム値を作成します。それを以前の値と混ぜて、 次の参加者に送信し、送信後にローカルマシンからその値を破棄します。 セレモニーに参加する 1 人がこれを正直に行う限り、最終的な値が攻撃者に判明することはありません。 EIP-4844 の KZG セレモニーは一般公開され、何万人もの人々がエントロピーを追加するために参加しました。 セレモニーを妨害するためには、参加者の 100%が積極的に不正行為を行わなければなりません。 参加者の観点では、自分自身が正直であるとわかっていれば、その人自身がセレモニーの安全を確保したことがわかるので、他の人を信頼する必要はありません(参加者が個々に、N 人中 1 人の正直な参加者の要件を満たしています) 。 +KZGセレモニーは、イーサリアムコミュニティ全体から多くの人々が協力して生成する、データの検証に使用できる秘密のランダムな数字列を生成する方法です。 この数字列は、誰にも知られず、誰にも再現できないことが、非常に重要であり、 そのために、セレモニーに参加する各人は、前の参加者から文字列を受け取ります。 次に、ブラウザにマウスの動きを測定させるなどして、いくつかの新しいランダム値を作成します。それを以前の値と混ぜて、 次の参加者に送信し、送信後にローカルマシンからその値を破棄します。 セレモニーに参加する1人がこれを正直に行う限り、最終的な値が攻撃者に判明することはありません。 EIP-4844のKZGセレモニーは一般公開され、何万人もの人々がエントロピーを追加するために参加しました。 セレモニーを妨害するためには、参加者の100%が積極的に不正行為を行わなければなりません。 参加者の観点では、自分自身が正直であるとわかっていれば、その人自身がセレモニーの安全を確保したことがわかるので、他の人を信頼する必要はありません(参加者が個々に、N人中1人の正直な参加者の要件を満たしています) 。 -ロールアップがデータをブロブに投稿すると、チェーン上に投稿するという「コミットメント」を提供します。 このコミットメントは、特定の点でデータに適合する多項式を評価した結果です。 この点は、KZG セレモニーで生成された乱数によって定義され、 証明者はデータを検証するために同じ点で多項式を評価できます。同じ値になった場合、データは正しいということになります。 +ロールアップがデータをブロブに投稿すると、チェーン上に投稿するという「コミットメント」を提供します。 このコミットメントは、特定の点でデータに適合する多項式を評価した結果です。 この点は、KZGセレモニーで生成された乱数によって定義され、 証明者はデータを検証するために同じ点で多項式を評価できます。同じ値になった場合、データは正しいということになります。 @@ -61,11 +61,11 @@ KZG セレモニーは、イーサリアムコミュニティ全体から多く ダンクシャーディングは、プロトダンクシャーディングで始まったロールアップスケーリングの完成版です。 ダンクシャーディングは、イーサリアムに大容量のスペースをもたらし、ロールアップのトランザクションデータを圧縮して保存できるようにします。 これにより、イーサリアムは数百ものロールアップを簡単にサポートでき、毎秒数百万のトランザクションを処理できるようになります。 -この仕組みを説明すると、ブロックに添付されるブロブをプロトダンクシャーディングの 1 個から完全なダンクシャーディングである 64 個まで拡張する方法を導入することで機能します。 必要な残りの変更は、新しい大きなブロブを処理できるようにするためにコンセンサスクライアントの動作方法をすべて更新することです。 これらの変更の中には、ダンクシャーディングとは関係なく、別の目的のためにすでに計画されているものもあります。 例えば、ダンクシャーディングでは、提案者と作成者の分離が実装されている必要があります。 これは、さまざまなバリデータ間でブロックの作成とブロックの提案のタスクを分離するアップグレードです。 同様に、ダンクシャーディングにはデータ可用性のサンプリングが必要ですが、多くの履歴データを保存しない超軽量クライアント「ステートレスクライアント」の開発にも必要です。 +この仕組みを説明すると、ブロックに添付されるブロブをプロトダンクシャーディングの1個から完全なダンクシャーディングである64個まで拡張する方法を導入することで機能します。 必要な残りの変更は、新しい大きなブロブを処理できるようにするためにコンセンサスクライアントの動作方法をすべて更新することです。 これらの変更の中には、ダンクシャーディングとは関係なく、別の目的のためにすでに計画されているものもあります。 例えば、ダンクシャーディングでは、提案者と作成者の分離が実装されている必要があります。 これは、さまざまなバリデータ間でブロックの作成とブロックの提案のタスクを分離するアップグレードです。 同様に、ダンクシャーディングにはデータ可用性のサンプリングが必要ですが、多くの履歴データを保存しない超軽量クライアント「ステートレスクライアント」の開発にも必要です。 -提案者と作成者を分離することで、個々の検証者が 32MB のブロブデータに対して、コストのかかるコミットメントや証明を生成するのを防ぐことができます。 提案者と作成者の分離をしないと、自宅でステーキングをしている端末に過度の負担がかかり、より強力なハードウェアへの投資が必要となります。その結果、分散化に悪影響を及ぼします。 代わりに、専門のブロック作成者が、このコストのかかる計算作業を担当します。 そして、ブロック作成者は、ブロック提案者にブロックを提供してブロードキャストします。 ブロック提案者は、最も収益性の高いブロックを選択するだけです。 誰でも、安価かつ迅速にブロブを検証できます。つまり、通常のバリデータであれば、ブロック作成者が誠実な行動をしているかどうかをチェックできます。 この仕組みにより、分散化を犠牲にすることなく、大きなブロブを処理することができます。 不正なブロック作成者を簡単にネットワークから排除してスラッシュすることができます。ブロック作成自体が収益性の高い活動であるため、不正なブロック作成者の代わりに、他の候補者が参加することになります。 +提案者と作成者を分離することで、個々の検証者が32MBのブロブデータに対して、コストのかかるコミットメントや証明を生成するのを防ぐことができます。 提案者と作成者の分離をしないと、自宅でステーキングをしている端末に過度の負担がかかり、より強力なハードウェアへの投資が必要となります。その結果、分散化に悪影響を及ぼします。 代わりに、専門のブロック作成者が、このコストのかかる計算作業を担当します。 そして、ブロック作成者は、ブロック提案者にブロックを提供してブロードキャストします。 ブロック提案者は、最も収益性の高いブロックを選択するだけです。 誰でも、安価かつ迅速にブロブを検証できます。つまり、通常のバリデータであれば、ブロック作成者が誠実な行動をしているかどうかをチェックできます。 この仕組みにより、分散化を犠牲にすることなく、大きなブロブを処理することができます。 不正なブロック作成者を簡単にネットワークから排除してスラッシュすることができます。ブロック作成自体が収益性の高い活動であるため、不正なブロック作成者の代わりに、他の候補者が参加することになります。 @@ -77,15 +77,15 @@ KZG セレモニーは、イーサリアムコミュニティ全体から多く ### 現在の進行状況 {#current-progress} -完全なダンクシャーディングは、数年先を予定していますが、 プロトダンクシャーディングは、近日にリリースされます。 この記事の執筆時点(2023 年 2 月)において、KZG セレモニーはまだ開催中であり、これまでに 5 万人以上の参加者を集めています。 プロトダンクシャーディングの[EIP](https://eips.ethereum.org/EIPS/eip-4844)は完成に近づいており、仕様も合意に至っています。現在、クライアントのテストが行われており、本番環境に導入するためのプロトタイプが実装されています。 次のステップは、公開テストネット上で変更を実装することです。 [EIP 4844 準備チェックリスト](https://github.com/ethereum/pm/blob/master/Breakout-Room/4844-readiness-checklist.md#client-implementation-status)を参照しながら準備しましょう。 +完全なダンクシャーディングは、数年先を予定していますが、 プロトダンクシャーディングは、近日にリリースされます。 この記事の執筆時点(2023年2月)において、KZGセレモニーはまだ開催中であり、これまでに5万人以上の参加者を集めています。 プロトダンクシャーディングの[EIP](https://eips.ethereum.org/EIPS/eip-4844)は完成に近づいており、仕様も合意に至っています。現在、クライアントのテストが行われており、本番環境に導入するためのプロトタイプが実装されています。 次のステップは、公開テストネット上で変更を実装することです。 [EIP 4844準備チェックリスト](https://github.com/ethereum/pm/blob/master/Breakout-Room/4844-readiness-checklist.md#client-implementation-status)を参照しながら準備しましょう。 ### 参考文献 {#further-reading} - [プロトダンクシャーディングのメモ](https://notes.ethereum.org/@vbuterin/proto_danksharding_faq) - _ヴィタリック・ブテリン_ - [ダンクシャーディングに関するダンクラッドのメモ](https://notes.ethereum.org/@dankrad/new_sharding) - [ダンクラッド、プロト、ヴィタリックによるダンクシャーディングの議論](https://www.youtube.com/watch?v=N5p0TB77flM) -- [KZG セレモニー](https://ceremony.ethereum.org/) -- [信頼されたセットアップに関するカール・ベークハウゼン(Carl Beekhuizen)の Devcon でのトーク](https://archive.devcon.org/archive/watch/6/the-kzg-ceremony-or-how-i-learnt-to-stop-worrying-and-love-trusted-setups/?tab=YouTube) +- [KZGセレモニー](https://ceremony.ethereum.org/) +- [信頼されたセットアップに関するカール・ベークハウゼン(Carl Beekhuizen)のDevconでのトーク](https://archive.devcon.org/archive/watch/6/the-kzg-ceremony-or-how-i-learnt-to-stop-worrying-and-love-trusted-setups/?tab=YouTube) - [ブロブ向けのデータ可用性サンプリングの詳細](https://hackmd.io/@vbuterin/sharding_proposal#ELI5-data-availability-sampling) -- [ダンクラッド・フィーストによる KZG コミットメントと証明](https://youtu.be/8L2C6RDMV9Q) -- [KZG 多項式コミットメント](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html) +- [ダンクラッド・フィーストによるKZGコミットメントと証明](https://youtu.be/8L2C6RDMV9Q) +- [KZG多項式コミットメント](https://dankradfeist.de/ethereum/2020/06/16/kate-polynomial-commitments.html) diff --git a/public/content/translations/ja/roadmap/future-proofing/index.md b/public/content/translations/ja/roadmap/future-proofing/index.md index bb2a3795ac0..f3111b899b0 100644 --- a/public/content/translations/ja/roadmap/future-proofing/index.md +++ b/public/content/translations/ja/roadmap/future-proofing/index.md @@ -13,23 +13,23 @@ template: roadmap 現在のイーサリアムを保護するの一部の暗号技術は、量子コンピューティングが実現した際に脆弱性が露呈する可能性があります。 量子コンピューターが現代の暗号技術にとって脅威となるには数十年かかると言われていますが、イーサリアムは今後何世紀にもわたって安全に運用することを目標にしています。 そのため、[イーサリアムの量子耐性](https://consensys.net/blog/developers/how-will-quantum-supremacy-affect-blockchain/)をできるだけ早く実現する必要があります。 -イーサリアムのデベロッパーが直面している課題として、現在のプルーフ・オブ・ステークのプロトコルが、有効なブロックの投票を集約するために、非常に効率的な署名スキームである BLS に依存していることです。 この署名スキームは、量子コンピューターによって破られてしまう可能性があります。一方、量子耐性のある代替手段は、計算効率がそれほど良くありません。 +イーサリアムのデベロッパーが直面している課題として、現在のプルーフ・オブ・ステークのプロトコルが、有効なブロックの投票を集約するために、非常に効率的な署名スキームであるBLSに依存していることです。 この署名スキームは、量子コンピューターによって破られてしまう可能性があります。一方、量子耐性のある代替手段は、計算効率がそれほど良くありません。 -イーサリアムでは、暗号秘密を生成するために[「KZG」コミットメントスキーム](/roadmap/danksharding/#what-is-kzg)が広く使われています。しかし、このスキームは量子コンピュータによって破られる可能性があります。 現在は、多くのユーザーが生成したランダム性を使用して「信頼できるセットアップ」として回避されており、量子コンピューターによるリバースエンジニアリングができないようになっています。 しかし、理想的には、量子安全暗号を組み込むことで、脆弱性を根本的に解決することが望まれます。 BLS スキームの効率的な代替となる可能性のある 2 つの主要なアプローチとして、[STARK ベース](https://hackmd.io/@vbuterin/stark_aggregation)と[ラティスベース](https://medium.com/asecuritysite-when-bob-met-alice/so-what-is-lattice-encryption-326ac66e3175)の署名スキームがあります。 これらについては現在、研究および試作中です。 +イーサリアムでは、暗号秘密を生成するために[「KZG」コミットメントスキーム](/roadmap/danksharding/#what-is-kzg)が広く使われています。しかし、このスキームは量子コンピュータによって破られる可能性があります。 現在は、多くのユーザーが生成したランダム性を使用して「信頼できるセットアップ」として回避されており、量子コンピューターによるリバースエンジニアリングができないようになっています。 しかし、理想的には、量子安全暗号を組み込むことで、脆弱性を根本的に解決することが望まれます。 BLSスキームの効率的な代替となる可能性のある2つの主要なアプローチとして、[STARKベース](https://hackmd.io/@vbuterin/stark_aggregation)と[ラティスベース](https://medium.com/asecuritysite-when-bob-met-alice/so-what-is-lattice-encryption-326ac66e3175)の署名スキームがあります。 これらについては現在、研究および試作中です。 - KZG と信頼できるセットアップについての詳細 + KZGと信頼できるセットアップについての詳細 ## よりシンプルで効率的なイーサリアム {#simpler-more-efficient-ethereum} 複雑なシステムでは、攻撃者が悪用できるバグや脆弱性が発生しやすくなります。 そのため、イーサリアムは、ロードマップの中で、不要なコードを削除したり、改善したりして、システムを簡素化することを目指しています。 無駄のないシンプルなコードベースにすることで、デベロッパーは保守、理解しやすくなります。 -[イーサリアム仮想マシン(EVM)](/developers/docs/evm)をよりシンプルで効率的なものにするアップデートが予定されています。 その一環として、[SELFDESTRUCT オペコードが削除](https://hackmd.io/@vbuterin/selfdestruct)されます。このコマンドはめったに使用されなくなりましたが、状況によっては使用すると危険を伴う場合があります。例えば、特にイーサリアムのストレージモデルに対する将来のアップグレードと組み合わせた場合です。 イーサリアムクライアントは、現在でも完全に削除可能な古いトランザクションタイプをサポートしています。 また、ガスの計算方法も改善される予定です。暗号操作を支える算術演算に対して、より効率的な方法が導入されます。 +[イーサリアム仮想マシン(EVM)](/developers/docs/evm)をよりシンプルで効率的なものにするアップデートが予定されています。 その一環として、[SELFDESTRUCTオペコードが削除](https://hackmd.io/@vbuterin/selfdestruct)されます。このコマンドはめったに使用されなくなりましたが、状況によっては使用すると危険を伴う場合があります。例えば、特にイーサリアムのストレージモデルに対する将来のアップグレードと組み合わせた場合です。 イーサリアムクライアントは、現在でも完全に削除可能な古いトランザクションタイプをサポートしています。 また、ガスの計算方法も改善される予定です。暗号操作を支える算術演算に対して、より効率的な方法が導入されます。 同様に、現在のイーサリアムクライアントの他の部分もアップデートされる可能性があります。 一例として現在は、実行クライアントとコンセンサスクライアントが異なるデータ圧縮方式を使用しています。 この圧縮方式をネットワーク全体で統一すれば、クライアント間でのデータ共有がより簡単で直感的になります。 ## 現在の進行状況 {#current-progress} -イーサリアムの将来的な安全性を確保するために必要なアップグレードの多くは、まだ研究段階です。実装には数年かかると考えられており、 SELF-DESTRUCT の削除や、実行クライアントとコンセンサスクライアントで使用される圧縮方式の統一などのアップグレードは、量子耐性のある暗号よりも早く実現される可能性があります。 +イーサリアムの将来的な安全性を確保するために必要なアップグレードの多くは、まだ研究段階です。実装には数年かかると考えられており、 SELF-DESTRUCTの削除や、実行クライアントとコンセンサスクライアントで使用される圧縮方式の統一などのアップグレードは、量子耐性のある暗号よりも早く実現される可能性があります。 **参考文献** diff --git a/public/content/translations/ja/roadmap/index.md b/public/content/translations/ja/roadmap/index.md index 739ec407d13..1f8ac57c5bd 100644 --- a/public/content/translations/ja/roadmap/index.md +++ b/public/content/translations/ja/roadmap/index.md @@ -3,7 +3,7 @@ title: イーサリアムロードマップ description: イーサリアムのスケーラビリティ、セキュリティ、サステナビリティを改善する工程 lang: ja template: roadmap -image: /roadmap/roadmap-main.png +image: /heroes/roadmap-hub-hero.jpg alt: "イーサリアムロードマップ" summaryPoints: buttons: @@ -55,11 +55,11 @@ buttons: ## イーサリアムにロードマップが必要な理由は何ですか? {#why-does-ethereum-need-a-roadmap} -イーサリアムは定期的にアップグレードされており、その結果、スケーラビリティ、セキュリティ、サステナビリティが向上しています。 イーサリアムの中核的な強みの 1 つとして、研究開発から生まれた新しいアイデアに適応できることです。 この適応性によって、イーサリアムは新たな課題に取り組んでおり、最先端の技術的ブレークスルーにも対応できる柔軟性を備えています。 +イーサリアムは定期的にアップグレードされており、その結果、スケーラビリティ、セキュリティ、サステナビリティが向上しています。 イーサリアムの中核的な強みの1つとして、研究開発から生まれた新しいアイデアに適応できることです。 この適応性によって、イーサリアムは新たな課題に取り組んでおり、最先端の技術的ブレークスルーにも対応できる柔軟性を備えています。 -イーサリアムのロードマップは、研究者と開発者たちが長年かけて築き上げてきたものです。このプロトコルは非常に技術的な内容ではあるものの、やる気があれば誰でも参加することができます。 新しいアイデアは、通常、[ethresear.ch](https://ethresear.ch/)、[イーサリアム・マジシャンズ](https://www.figma.com/exit?url=https%3A%2F%2Fethereum-magicians.org%2F) 、イーサリアム研究開発の Discord サーバーなどのフォーラムで議論されます。 議論の内容は、新たに見つかった脆弱性への対応、アプリケーションレイヤーで活動する組織(dApp や取引所など)からの提案、エンドユーザーにとっての既知の摩擦(コストやトランザクション速度など)への対応だったりします。 新しいアイデアが成熟すると、[イーサリアム改善提案](https://eips.ethereum.org/)として提案できます。 このアイデアの創出は、誰でも参加できるオープンなプロセスです。コミュニティのメンバーであれば、いつでも議論に参加できます。 +イーサリアムのロードマップは、研究者と開発者たちが長年かけて築き上げてきたものです。このプロトコルは非常に技術的な内容ではあるものの、やる気があれば誰でも参加することができます。 新しいアイデアは、通常、[ethresear.ch](https://ethresear.ch/)、[イーサリアム・マジシャンズ](https://ethereum-magicians.org) 、イーサリアム研究開発のDiscordサーバーなどのフォーラムで議論されます。 議論の内容は、新たに見つかった脆弱性への対応、アプリケーションレイヤーで活動する組織(dAppや取引所など)からの提案、エンドユーザーにとっての既知の摩擦(コストやトランザクション速度など)への対応だったりします。 新しいアイデアが成熟すると、[イーサリアム改善提案](https://eips.ethereum.org/)として提案できます。 このアイデアの創出は、誰でも参加できるオープンなプロセスです。コミュニティのメンバーであれば、いつでも議論に参加できます。 [イーサリアムにおけるガバナンスの詳細](/governance/) @@ -80,9 +80,9 @@ buttons: ## ロードマップに終わりはありますか? {#when-will-the-roadmap-be-finished} -イーサリアムでは、今後 6 か月の間に、ステーキングの引き出しなどのアップグレードを実装します 。一方、耐量子暗号などのアップグレードは優先度が低く、今後 5〜10 年間は実装されないかもしれません。 イーサリアムは、多数のロードマップアイテムを同時に進めており、それぞれ異なる速度で開発されています。そのため、各アップグレードの正確なタイミングを予測するのは難しくなっています。 アップグレードの緊急性は、時間の経過とともに外部要因によって変化する可能性があります。例えば、量子コンピューターの性能と普及が急速に進むにつれて、耐量子暗号の緊急性がますます高まっていくかもしれません。 +イーサリアムでは、今後6か月の間に、ステーキングの引き出しなどのアップグレードを実装します 。一方、耐量子暗号などのアップグレードは優先度が低く、今後5〜10年間は実装されないかもしれません。 イーサリアムは、多数のロードマップアイテムを同時に進めており、それぞれ異なる速度で開発されています。そのため、各アップグレードの正確なタイミングを予測するのは難しくなっています。 アップグレードの緊急性は、時間の経過とともに外部要因によって変化する可能性があります。例えば、量子コンピューターの性能と普及が急速に進むにつれて、耐量子暗号の緊急性がますます高まっていくかもしれません。 -イーサリアムの発展を考えるには、生物学的進化を参考にするのも 1 つの方法です。 新しい課題に適応し、適応度を維持できるネットワークは、より成功する可能性が高くなります。そのため、ネットワークのパフォーマンスが上がるにつれて、スケーラブルで安全なプロトコルが必要になります。またプロトコルの変更を最小限に抑え、変化に対して耐性を持つことも重要です。 +イーサリアムの発展を考えるには、生物学的進化を参考にするのも1つの方法です。 新しい課題に適応し、適応度を維持できるネットワークは、より成功する可能性が高くなります。そのため、ネットワークのパフォーマンスが上がるにつれて、スケーラブルで安全なプロトコルが必要になります。またプロトコルの変更を最小限に抑え、変化に対して耐性を持つことも重要です。 ## アップグレードをするには、何が必要ですか? {#do-i-have-to-do-anything-when-there-is-an-upgrade} @@ -94,7 +94,7 @@ buttons: - マージ: プルーフ・オブ・ワークからプルーフ・オブ・ステークへの移行に関連するアップグレード - サージ: ロールアップとデータシャーディングによるスケーラビリティ向上に関連するアップグレード -- スカージ: MEV からの検閲耐性、分散化、プロトコルのリスクに関連するアップグレード +- スカージ: MEVからの検閲耐性、分散化、プロトコルのリスクに関連するアップグレード - バージ: ブロックの検証をより簡単にするアップグレード - パージ: ノード実行における計算コストの削減とプロトコルの簡素化に関連するアップグレード - スプラージ: これまでのカテゴリに分類できないその他のアップグレード @@ -103,13 +103,13 @@ buttons: ## シャーディングとは何ですか? {#what-about-sharding} -シャーディングでは、イーサリアムのブロックチェーンを分割する技術です。バリデータのサブセットは、それぞれのチェーンでデータを検証する役割を担います。 これは、もともとイーサリアムをスケーリングする方法として開発されました。 しかし、レイヤー 2 ロールアップの開発が予想以上に進み、すでにさまざまなスケーリング機能を提供できるようになりました。また、プロトダンクシャーディングの実装後には、さらに多くの機能を提供する予定となっているため、 「シャードチェーン」は不要になり、ロードマップから削除されました。 +シャーディングでは、イーサリアムのブロックチェーンを分割する技術です。バリデータのサブセットは、それぞれのチェーンでデータを検証する役割を担います。 これは、もともとイーサリアムをスケーリングする方法として開発されました。 しかし、レイヤー2ロールアップの開発が予想以上に進み、すでにさまざまなスケーリング機能を提供できるようになりました。また、プロトダンクシャーディングの実装後には、さらに多くの機能を提供する予定となっているため、 「シャードチェーン」は不要になり、ロードマップから削除されました。 ## 特定の技術アップグレードについての情報 {#looking-for-specific-technical-upgrades} -- [ダンクシャーディング](/roadmap/danksharding) - ダンクシャーディングは、イーサリアムのブロックに「ブロブ」と呼ばれるデータを追加することで、ユーザーのレイヤー 2 ロールアップ使用料を大幅に削減します。 -- [ステーキングの引き出し](/saking/withdrawals) - 上海/カペラのアップグレードにより、イーサリアム上のステーキングした ETH を引き出せるようになりました。また、ステーキングした ETH のロックを解除できるようになりました。 -- [シングルスロット・ファイナリティ](/roadmap/single-slot-finality) - 15 分待たずに、同一のスロット内でブロックが提案され、ファイナライズが可能になります。 これにより、アプリにとっては利便性が向上し、攻撃がはるかに困難になります。 +- [ダンクシャーディング](/roadmap/danksharding) - ダンクシャーディングは、イーサリアムのブロックに「ブロブ」と呼ばれるデータを追加することで、ユーザーのレイヤー2ロールアップ使用料を大幅に削減します。 +- [ステーキングの引き出し](/saking/withdrawals) - 上海/カペラのアップグレードにより、イーサリアム上のステーキングしたETHを引き出せるようになりました。また、ステーキングしたETHのロックを解除できるようになりました。 +- [シングルスロット・ファイナリティ](/roadmap/single-slot-finality) - 15分待たずに、同一のスロット内でブロックが提案され、ファイナライズが可能になります。 これにより、アプリにとっては利便性が向上し、攻撃がはるかに困難になります。 - [プロポーザー/ビルダーセパレーション](/roadmap/pbs) - ブロックを構築するタスクとブロックを提案するタスクを別々のバリデータに分割することで、イーサリアムにおけるコンセンサス合意プロセスを、より効率的で公平にし、検閲耐性のあるものにします。 - [シークレットリーダー選出](/roadmap/secret-leader-election) - 高度な暗号化を使い、現在のブロック提案者のアイデンティティが公開されないようにします。これにより、特定の攻撃タイプから保護できます。 - [アカウント抽象化](/roadmap/account-abstraction) - アカウント抽象化はイーサリアムのアップグレードの一種です。複雑なミドルウェアを使用することなく、イーサリアム上でスマートコントラクトウォレットをネイティブにサポートします。 diff --git a/public/content/translations/ja/roadmap/merge/index.md b/public/content/translations/ja/roadmap/merge/index.md index 5cc17b30956..a8f5212ff28 100644 --- a/public/content/translations/ja/roadmap/merge/index.md +++ b/public/content/translations/ja/roadmap/merge/index.md @@ -4,32 +4,31 @@ description: マージについて - イーサリアムメインネットへの lang: ja template: upgrade image: /upgrades/merge.png -alt: summaryPoint1: イーサリアムメインネットは現在プルーフ・オブ・ステークを使用していますが、これまではそうではありませんでした。 summaryPoint2: 旧プルーフ・オブ・ワークのメカニズムからプルーフ・オブ・ステークへのアップグレードはマージと呼ばれます。 summaryPoint3: マージとは、元のイーサリアムメインネットが、ビーコンチェーンとよばれる別のプルーフ・オブ・ステークのブロックチェーンと統合(マージ)し、1つのチェーンになったことを意味します。 summaryPoint4: マージによりイーサリアムのエネルギー消費が最大99.95%削減されました。 --- - + マージは、2022年9月15日に行われました。 これにより、イーサリアムはプルーフ・オブ・ステーク・コンセンサスへの移行を完了し、公式にプルーフ・オブ・ワークは廃止されました。この移行により、エネルギー消費量が最大99.95%削減されました。 ## マージとは {#what-is-the-merge} -マージとは、イーサリアムの元の実行レイヤー ([誕生](/history/#frontier)から存在するメインネット) と、新規のプルーフ・オブ・ステークのコンセンサスレイヤーであるビーコンチェーンをマージ(統合)することでした。 これにより、エネルギー集約的なマイニングが不要になり、代わりにステーキングされた ETH を利用して、ネットワークのセキュリティが確保されるようになりました。 イーサリアムのビジョンである、より高性能なスケーラビリティ、より安心なセキュリティ、より高いレベルの持続可能性を実現するための、本当にエキサイティングなステップとなりました。 +マージとは、イーサリアムの元の実行レイヤー ([誕生](/history/#frontier)から存在するメインネット) と、新規のプルーフ・オブ・ステークのコンセンサスレイヤーであるビーコンチェーンをマージ(統合)することでした。 これにより、エネルギー集約的なマイニングが不要になり、代わりにステーキングされたETHを利用して、ネットワークのセキュリティが確保されるようになりました。 イーサリアムのビジョンである、より高性能なスケーラビリティ、より安心なセキュリティ、より高いレベルの持続可能性を実現するための、本当にエキサイティングなステップとなりました。 -当初、[メインネット](/glossary/#mainnet)とは別に[ビーコンチェーン](/roadmap/beacon-chain/)がリリースされました。 メインネットでは[プルーフ・オブ・ワーク](/developers/docs/consensus-mechanisms/pow/)によりすべてのアカウント、残高、スマートコントラクトおよびブロックチェーンの状態の安全性が保たれ、それと同時に[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos/)を活用したビーコンチェーンが並行して稼働していました。 マージでは、これらの 2 つのシステムが最終的に統合され、プルーフ・オブ・ワークが永久にプルーフ・オブ・ステークに置き換わりました。 +当初、[メインネット](/glossary/#mainnet)とは別に[ビーコンチェーン](/roadmap/beacon-chain/)がリリースされました。 メインネットでは[プルーフ・オブ・ワーク](/developers/docs/consensus-mechanisms/pow/)によりすべてのアカウント、残高、スマートコントラクトおよびブロックチェーンの状態の安全性が保たれ、それと同時に[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos/)を活用したビーコンチェーンが並行して稼働していました。 マージでは、これらの2つのシステムが最終的に統合され、プルーフ・オブ・ワークが永久にプルーフ・オブ・ステークに置き換わりました。 イーサリアムが、恒星間航行への準備が不十分で打ち上げられた宇宙船だと想像してみてください。 ビーコンチェーンによって、新型のエンジンと強化された船体が構築されました。 大規模なテストが行われた後、旧式のエンジンと新型のエンジンを飛行中に入れ替える時期となりました。 より効率的な新型のエンジンを既存の宇宙船にマージしたことにより、何光年もの長い宇宙への旅ができるようになったのです。 ## メインネットとのマージ {#merging-with-mainnet} -イーサリアムメインネットは、その誕生からマージまで、プルーフ・オブ・ワークにより保護されてきました。 プルーフ・オブ・ワークのもと、トランザクション、スマートコントラクト、アカウントなど、馴染みのあるすべての機能を備えた、イーサリアムのブロックチェーンが 2015 年 7 月に実現しました。 +イーサリアムメインネットは、その誕生からマージまで、プルーフ・オブ・ワークにより保護されてきました。 プルーフ・オブ・ワークのもと、トランザクション、スマートコントラクト、アカウントなど、馴染みのあるすべての機能を備えた、イーサリアムのブロックチェーンが2015年7月に実現しました。 -イーサリアムの歴史を通して、デベロッパーはプルーフ・オブ・ワークからプルーフ・オブ・ステークへの最終的な移行の準備を行ってきました。 2020 年 12 月 1 日、メインネットとは別のブロックチェーンとして、ビーコンチェーンが誕生し、メインネットと並行して稼働しました。 +イーサリアムの歴史を通して、デベロッパーはプルーフ・オブ・ワークからプルーフ・オブ・ステークへの最終的な移行の準備を行ってきました。 2020年12月1日、メインネットとは別のブロックチェーンとして、ビーコンチェーンが誕生し、メインネットと並行して稼働しました。 ビーコンチェーンは、もともとはメインネットのトランザクションの処理はせず、 代わりに、アクティブなバリデータとそのアカウント残高に合意することで、独自の状態でコンセンサスに達していました。 膨大なテストを経て、ビーコンチェーンは実世界のデータでのコンセンサスに用いる時が来ました。 マージ後は、ビーコンチェーンが実行レイヤーのトランザクションやアカウント残高を含む全てのネットワークデータのコンセンサスエンジンになりまりました。 @@ -45,7 +44,7 @@ summaryPoint4: マージによりイーサリアムのエネルギー消費が **保有者やユーザーにとっては、マージにより何かが変わったということはありません。** -_繰り返しになりますが_、ETH やイーサリアム上の他のデジタル資産のユーザーや保有者、またノードを運用していないステイカーは、 **マージに伴い、資金やウォレットに何かをする必要はありません**。ETH は ETH のままです。 マージ後も、「古い ETH」/「新しい ETH」や「ETH1」/「ETH2」のようなものはなく、ウォレットは以前とまったく同じように動作します。そうでないと言う人は詐欺師の可能性があります。 +_繰り返しになりますが_、ETHやイーサリアム上の他のデジタル資産のユーザーや保有者、またノードを運用していないステイカーは、 **マージに伴い、資金やウォレットに何かをする必要はありません**。ETHはETHのままです。 マージ後も、「古いETH」/「新しいETH」や「ETH1」/「ETH2」のようなものはなく、ウォレットは以前とまったく同じように動作します。そうでないと言う人は詐欺師の可能性があります。 プルーフ・オブ・ワークを停止し、プルーフ・オブ・ステークに移行した後も、イーサリアムの誕生以降の全トランザクション履歴はそのままで、変更されていません。 マージ以前にウォレットに保有されていた資金は、マージ後も引き続きご利用いただけます。 **ユーザーや保有者は、何かをアップグレードする必要はありません。** @@ -61,12 +60,12 @@ id="staking-node-operators"> 主なアクション項目は次のとおりです。 1. コンセンサスクライアントと実行クライアントの両方を実行します。実行データを取得するためのサードパーティーエンドポイントは、マージ以降は利用できなくなっています。 -2. 実行クライアントとコンセンサスクライアントが安全に通信できるように、共有の JWT シークレットで認証します。 -3. 獲得したトランザクションフィーのチップまたは MEV を受け取るための「フィーの受取人」のアドレスを設定します。 +2. 実行クライアントとコンセンサスクライアントが安全に通信できるように、共有のJWTシークレットで認証します。 +3. 獲得したトランザクションフィーのチップまたはMEVを受け取るための「フィーの受取人」のアドレスを設定します。 -上記の最初の 2 つの項目が完了していないと、両方のレイヤーが同期および認証されるまで、ノードが「オフライン」として表示されてしまいます。 +上記の最初の2つの項目が完了していないと、両方のレイヤーが同期および認証されるまで、ノードが「オフライン」として表示されてしまいます。 -「フィーの受取人」を設定しなくても、バリデータは通常どおり動作しますが、バリデータが提案したブロックの未焼却のフィーのチップや獲得できたはずの MEV を逃すことになります。 +「フィーの受取人」を設定しなくても、バリデータは通常どおり動作しますが、バリデータが提案したブロックの未焼却のフィーのチップや獲得できたはずのMEVを逃すことになります。
-マージまでは、ネットワークから送信されるブロックを受信し、適切に検証し、伝搬するには、実行クライアント(Geth、Erigon、Besu、Nethermind など)だけで十分でした。 マージ後は、実行ペイロードに含まれるトランザクションの有効性は、それ自体の「コンセンサスブロック」の有効性にも依存します。 +マージまでは、ネットワークから送信されるブロックを受信し、適切に検証し、伝搬するには、実行クライアント(Geth、Erigon、Besu、Nethermindなど)だけで十分でした。 マージ後は、実行ペイロードに含まれるトランザクションの有効性は、それ自体の「コンセンサスブロック」の有効性にも依存します。 -そのため、マージ後のイーサリアム・フルノードでは、今は実行レイヤクライアントとコンセンサスレイヤクライアントの両方が必要になります。 これらの 2 つのクライアントは、新しいエンジン API を使用して連携します。 エンジン API では、JWT シークレットを使用した認証が必要で、JWT シークレットは両方のクライアントに提供され、安全な通信が行われます。 +そのため、マージ後のイーサリアム・フルノードでは、今は実行レイヤクライアントとコンセンサスレイヤクライアントの両方が必要になります。 これらの2つのクライアントは、新しいエンジンAPIを使用して連携します。 エンジンAPIでは、JWTシークレットを使用した認証が必要で、JWTシークレットは両方のクライアントに提供され、安全な通信が行われます。 主なアクションアイテムは以下の通りです。 - 実行クライアントに加え、コンセンサスクライアントをインストールする -- 実行クライアントとコンセンサスクライアントが安全に通信できるように、共有 JWT シークレットで認証する +- 実行クライアントとコンセンサスクライアントが安全に通信できるように、共有JWTシークレットで認証する 上記の項目が完了していないと、両方のレイヤーの同期と認証が完了するまで、ノードが「オフライン」のように表示されます。 @@ -102,13 +101,13 @@ id="developers">
  • セーフヘッド確定したブロックのコンセプト
  • -詳細については、Tim Beiko によるブログ投稿マージがイーサリアムのアプリケーションレイヤーに与える影響をご覧ください。 +詳細については、Tim Beikoによるブログ投稿マージがイーサリアムのアプリケーションレイヤーに与える影響をご覧ください。
    ## マージとエネルギー消費 {#merge-and-energy} -マージは、イーサリアムでのプルーフ・オブ・ワークの終わりを意味し、より持続可能で環境に優しいイーサリアムの時代をスタートさせました。 イーサリアムのエネルギー消費量は推定で 99.95%減少し、環境に優しいブロックチェーンとなりました。 [イーサリアムのエネルギー消費の詳細](/energy-consumption/) +マージは、イーサリアムでのプルーフ・オブ・ワークの終わりを意味し、より持続可能で環境に優しいイーサリアムの時代をスタートさせました。 イーサリアムのエネルギー消費量は推定で99.95%減少し、環境に優しいブロックチェーンとなりました。 [イーサリアムのエネルギー消費の詳細](/energy-consumption/) ## マージとスケーリング {#merge-and-scaling} @@ -122,9 +121,9 @@ contentPreview="False. Anyone is free to sync their own self-verified copy of Et イーサリアムのノードには、ブロックを提案できるノードとできないノードがあります。 -ブロックを提案するノードは、イーサリアムの全ノードのうち、ごくわずかに過ぎません。 このカテゴリには、プルーフ・オブ・ワーク(PoW) のマイニングノードとプルーフ・オブ・ステーク(PoS) のバリデータノードがあります。 このカテゴリでは、時折次のブロックを提案し、プロトコル報酬を得る能力と引き換えに、経済的リソース(プルーフ・オブ・ワークでは GPU ハッシュパワー、プルーフ・オブ・ステークでは ETH のステーキング)を必要とします。 +ブロックを提案するノードは、イーサリアムの全ノードのうち、ごくわずかに過ぎません。 このカテゴリには、プルーフ・オブ・ワーク(PoW) のマイニングノードとプルーフ・オブ・ステーク(PoS) のバリデータノードがあります。 このカテゴリでは、時折次のブロックを提案し、プロトコル報酬を得る能力と引き換えに、経済的リソース(プルーフ・オブ・ワークではGPUハッシュパワー、プルーフ・オブ・ステークではETHのステーキング)を必要とします。 -ネットワーク上の他のノード (例: 大多数)は、利用可能なストレージとインターネット接続の 1〜2TB の消費者グレードのコンピュータを超えて経済的なリソースを何もコミットする必要はありません。 これらのノードはブロックを提案しませんが、新しいブロックをリスニングし、ブロックの出現時にネットワークのコンセンサスルールに従って有効性を検証し、すべてのブロック提案者に責任を持たせます。このようにネットワークを保護する重要な役割を担っています。 ブロックが有効と判断されれば、ノードはそのブロックをネットワークを通じて伝搬し続けます。 何らかの理由でブロックが無効と判断された場合、ノードソフトウェアはそのブロックを無効とみなし、伝搬を停止させます。 +ネットワーク上の他のノード (例: 大多数)は、利用可能なストレージとインターネット接続の1〜2TBの消費者グレードのコンピュータを超えて経済的なリソースを何もコミットする必要はありません。 これらのノードはブロックを提案しませんが、新しいブロックをリスニングし、ブロックの出現時にネットワークのコンセンサスルールに従って有効性を検証し、すべてのブロック提案者に責任を持たせます。このようにネットワークを保護する重要な役割を担っています。 ブロックが有効と判断されれば、ノードはそのブロックをネットワークを通じて伝搬し続けます。 何らかの理由でブロックが無効と判断された場合、ノードソフトウェアはそのブロックを無効とみなし、伝搬を停止させます。 両方の合意メカニズム(プルーフ・オブ・ワークまたはプルーフ・オブ・ステーク)のもとで、誰でもブロックを生成しないノードを実行できます。可能な限り多くのユーザーにノードの実行を推奨します。 ノードの運用はイーサリアムに非常に大きな貢献となり、セキュリティやプライバシー、検閲耐性を向上させるなど、ノードを運用するすべての人もその恩恵を受けることになります。 @@ -140,7 +139,7 @@ contentPreview="False. The Merge was a change of consensus mechanism, not an exp ガス代は、ネットワーク容量に対するネットワーク需要の産物です。 マージにより、コンセンサスにプルーフ・オブ・ワークからプルーフ・オブ・ステークに移行しましたが、ネットワーク容量やスループットに直接影響するパラメーターは大幅に変更されませんでした。 -ロールアップを中心としたロードマップでは、レイヤー 2でのユーザーアクティビティのスケーリングに集中して取り組み、レイヤー 1 メインネットをロールアップのデータ保存に最適化された安全な分散型決済レイヤーとして稼働させ、ロールアップトランザクションの大幅な低コスト化を目指しています。 プルーフ・オブ・ステークへの移行は、これを実現するための重要な布石となります。 ガスとフィーについての詳細 +ロールアップを中心としたロードマップでは、レイヤー2でのユーザーアクティビティのスケーリングに集中して取り組み、レイヤー1メインネットをロールアップのデータ保存に最適化された安全な分散型決済レイヤーとして稼働させ、ロールアップトランザクションの大幅な低コスト化を目指しています。 プルーフ・オブ・ステークへの移行は、これを実現するための重要な布石となります。 ガスとフィーについての詳細
    @@ -149,9 +148,9 @@ title="誤解: "マージにより、トランザクションが大幅に contentPreview="False. Though some slight changes exist, transaction speed is mostly the same on layer 1 now as it was before The Merge."> トランザクションの「速度」は、ブロックに含まれるまでの時間や確定までの時間など、いくつかの方法で測定することができます。 いずれも若干の違いはありますが、ユーザーが気づくようなものではありません。 -従来、プルーフ・オブ・ワークでの目標は約 13.3 秒ごとに新しいブロックを生成することでした。 プルーフ・オブ・ステークの下では、スロットが 12 秒ごとに正確に発生し、そのたびにバリデータがブロックを公開する機会があります。 ほとんどのスロットにはブロックがありますが、必ずしもすべてのスロットにブロックがあるわけではありません (例: バリデータがオフラインの場合など) 。 プルーフ・オブ・ステークでは、プルーフ・オブ・ワークに比べてブロックの生成頻度が 10%程度高くなっています。 これはかなり些細な変更のため、ユーザーが気付くほどではありません。 +従来、プルーフ・オブ・ワークでの目標は約13.3秒ごとに新しいブロックを生成することでした。 プルーフ・オブ・ステークの下では、スロットが12秒ごとに正確に発生し、そのたびにバリデータがブロックを公開する機会があります。 ほとんどのスロットにはブロックがありますが、必ずしもすべてのスロットにブロックがあるわけではありません (例: バリデータがオフラインの場合など) 。 プルーフ・オブ・ステークでは、プルーフ・オブ・ワークに比べてブロックの生成頻度が10%程度高くなっています。 これはかなり些細な変更のため、ユーザーが気付くほどではありません。 -プルーフ・オブ・ステークにより、以前は存在しなかったトランザクションのファイナリティのコンセプトが導入されました。 プルーフ・オブ・ワークでは、トランザクションが含まれるブロックの改ざんは、新たなブロックがマイニングされるたびに、指数関数的に難しくなっていきますが、可能性が完全にゼロになることはありません。 プルーフ・オブ・ステークでは、ブロックはエポック(6.4 分間、この間に 32 ブロックが生成可能)に束ねられ、バリデータが投票します。 1 つのエポックの終了時に、バリデータはそのエポックを「正当」とみなすかどうか投票します。 バリデータがエポックの正当性に同意した場合、次のエポックで確定されます。 確定したトランザクションを取り消すには、ステーキングされた全 ETH の 3 分の 1 以上を取得し、焼却する必要があるため、経済的に不可能となります。 +プルーフ・オブ・ステークにより、以前は存在しなかったトランザクションのファイナリティのコンセプトが導入されました。 プルーフ・オブ・ワークでは、トランザクションが含まれるブロックの改ざんは、新たなブロックがマイニングされるたびに、指数関数的に難しくなっていきますが、可能性が完全にゼロになることはありません。 プルーフ・オブ・ステークでは、ブロックはエポック(6.4分間、この間に32ブロックが生成可能)に束ねられ、バリデータが投票します。 1つのエポックの終了時に、バリデータはそのエポックを「正当」とみなすかどうか投票します。 バリデータがエポックの正当性に同意した場合、次のエポックで確定されます。 確定したトランザクションを取り消すには、ステーキングされた全ETHの3分の1以上を取得し、焼却する必要があるため、経済的に不可能となります。 @@ -159,9 +158,9 @@ contentPreview="False. Though some slight changes exist, transaction speed is mo title="誤解: "マージにより、ステーキングの引き出しができるようになった"" contentPreview="False, but staking withdrawals have since been enabled via the Shanghai/Capella upgrade."> -マージ後の初期段階では、ステーカーはブロック提案の結果として獲得したフィーチップと MEV のみにアクセスできました。 これらの報酬は、バリデータが管理する非ステーキングアカウント (フィーの受取人と呼ばれる) に入金され、すぐに利用できます。 これらの報酬は、バリデータの職務を遂行するためのプロトコル報酬と別です。 +マージ後の初期段階では、ステーカーはブロック提案の結果として獲得したフィーチップとMEVのみにアクセスできました。 これらの報酬は、バリデータが管理する非ステーキングアカウント (フィーの受取人と呼ばれる) に入金され、すぐに利用できます。 これらの報酬は、バリデータの職務を遂行するためのプロトコル報酬と別です。 -上海/カペラネットワークのアップグレード以降、 ステーカーは引き出しアドレスを指定して、超過しているステーキング残高(32ETH を越えた分のプロトコル報酬)の自動支払を受け取れるようになりました。 このアップグレードにより、バリデータがネットワークから抜け出すときに、ロックを解除して残高全体を回収できるようになりました。 +上海/カペラネットワークのアップグレード以降、 ステーカーは引き出しアドレスを指定して、超過しているステーキング残高(32ETHを越えた分のプロトコル報酬)の自動支払を受け取れるようになりました。 このアップグレードにより、バリデータがネットワークから抜け出すときに、ロックを解除して残高全体を回収できるようになりました。 ステーキングの引き出しについての詳細 @@ -170,18 +169,18 @@ contentPreview="False, but staking withdrawals have since been enabled via the S -上海/カペラアップグレードにより出金が可能になってから、バリデータは 32ETH を超えるステーキング残高を出金するよう奨励されています。これらの資金は利回りに追加されず、ロックされているためです。 年換算利回り(ステークした ETH の合計により決定)によっては、バリデータをやめて残高を引き出すか、報酬を使ってさらにステーキングして、より多くの利回りを得ることもできます。 +上海/カペラアップグレードにより出金が可能になってから、バリデータは32ETHを超えるステーキング残高を出金するよう奨励されています。これらの資金は利回りに追加されず、ロックされているためです。 年換算利回り(ステークしたETHの合計により決定)によっては、バリデータをやめて残高を引き出すか、報酬を使ってさらにステーキングして、より多くの利回りを得ることもできます。 -ステーキングの重要な注意点として、全バリデータの退出はプロトコルによってレート制限が設定されており、エポックごとに(6.4 分ごとに)退出できるバリデータの数は限られています。 この制限はアクティブなバリデータの数に応じて変動しますが、1 日の間にネットワークから退出できるのは、ステークされた ETH の合計の約 0.33%になります。 +ステーキングの重要な注意点として、全バリデータの退出はプロトコルによってレート制限が設定されており、エポックごとに(6.4分ごとに)退出できるバリデータの数は限られています。 この制限はアクティブなバリデータの数に応じて変動しますが、1日の間にネットワークから退出できるのは、ステークされたETHの合計の約0.33%になります。 -これにより、ステークされた資金の大量流出を防ぎます。 さらに、プロトコルがスラッシングペナルティを執行する前に、ステークされた全ての ETH の大部分にアクセスできる攻撃者がスラッシング対象の違反をして、同じエポック内で違反しているバリデータの残高をすべて終了または引き出してしまうことを防ぎます。 +これにより、ステークされた資金の大量流出を防ぎます。 さらに、プロトコルがスラッシングペナルティを執行する前に、ステークされた全てのETHの大部分にアクセスできる攻撃者がスラッシング対象の違反をして、同じエポック内で違反しているバリデータの残高をすべて終了または引き出してしまうことを防ぎます。 また、年換算利回りは意図的にダイナミックに設定されており、ステーカー市場がバリデータの報酬額をバランスよく調整できるようになっています。 レートが低すぎる場合は、ステーカーはプロトコルが制限するレート範囲内で退出していきます。 その結果、残っているステーカーの年換算利回りが徐々に上昇し、新しいステーカーを引き寄せたり、ステーカーが再度戻ってくることになります。 -## Eth2 の名称廃止 {#eth2} +## Eth2の名称廃止 {#eth2} -「Eth2」という用語は廃止されました。 「Eth1」と「Eth2」が単一チェーンに統合された今では、2 つのイーサリアムネットワークを区別する必要はなくなり「イーサリアム」のみとなりました。 +「Eth2」という用語は廃止されました。 「Eth1」と「Eth2」が単一チェーンに統合された今では、2つのイーサリアムネットワークを区別する必要はなくなり「イーサリアム」のみとなりました。 混乱をなくすため、次の名称が変更になりました。 @@ -200,7 +199,7 @@ contentPreview="False. Validator exits are rate limited for security reasons."> マージにより、元のメインネットの実行レイヤーへ、新しくコンセンサスレイヤーとしてビーコンチェーンが正式に採用されました。 マージ以降、バリデータがイーサリアムメインネットの保護にあたり、[プルーフ・オブ・ワーク](/developers/docs/consensus-mechanisms/pow/)によるマイニングはブロック生成の有効な手段ではなくなっています。 -ブロックは、コンセンサスに参加する権利を得るために、ETH をステーキングしたノードを検証することで提案されます。 これらのアップグレードは、シャーディングを含む将来のスケーラビリティのアップグレードの準備段階となります。 +ブロックは、コンセンサスに参加する権利を得るために、ETHをステーキングしたノードを検証することで提案されます。 これらのアップグレードは、シャーディングを含む将来のスケーラビリティのアップグレードの準備段階となります。 ビーコンチェーン @@ -208,15 +207,15 @@ contentPreview="False. Validator exits are rate limited for security reasons."> ### マージと上海アップグレード {#merge-and-shanghai} -プルーフ・オブ・ステークへの移行を簡略化し、移行作業に最大限の注力を注ぐため、マージでは、ステーキングした ETH の引き出し機能など、いくつかの予定されたいた機能が対象外となりました。 この機能は別途、上海/カペラアップグレードのアップグレードで有効化されました。 +プルーフ・オブ・ステークへの移行を簡略化し、移行作業に最大限の注力を注ぐため、マージでは、ステーキングしたETHの引き出し機能など、いくつかの予定されたいた機能が対象外となりました。 この機能は別途、上海/カペラアップグレードのアップグレードで有効化されました。 -さらにご興味のある方は、ヴィタリックが 2021 年 4 月の ETHGlobal イベントで発表した[マージ後の予定](https://youtu.be/7ggwLccuN5s?t=101)をご覧ください。 +さらにご興味のある方は、ヴィタリックが2021年4月のETHGlobalイベントで発表した[マージ後の予定](https://youtu.be/7ggwLccuN5s?t=101)をご覧ください。 ### マージとシャーディング {#merge-and-data-sharding} -もともとの計画では、マージ前にシャーディングに取り組み、スケーラビリティに対応する予定でした。 しかし、[レイヤー 2 スケーリングソリューション](/layer-2/)の高まりにより、まずはプルーフ・オブ・ワークからプルーフ・オブ・ステークへの移行が優先されました。 +もともとの計画では、マージ前にシャーディングに取り組み、スケーラビリティに対応する予定でした。 しかし、[レイヤー2スケーリングソリューション](/layer-2/)の高まりにより、まずはプルーフ・オブ・ワークからプルーフ・オブ・ステークへの移行が優先されました。 -シャーディング計画は急速に進展していますが、トランザクションの実行をスケールリングするレイヤー 2 技術の台頭と成功により、ロールアップコントラクトからの圧縮コールデータ(calldata)の保存を負荷分散する最適な方法を見つけることにシフトしています。これにより、ネットワーク容量を指数関数的に増やすことができるようになります。 プルーフ・オブ・ステークへの移行がなければ、これは実現不可能なことでした。 +シャーディング計画は急速に進展していますが、トランザクションの実行をスケールリングするレイヤー2技術の台頭と成功により、ロールアップコントラクトからの圧縮コールデータ(calldata)の保存を負荷分散する最適な方法を見つけることにシフトしています。これにより、ネットワーク容量を指数関数的に増やすことができるようになります。 プルーフ・オブ・ステークへの移行がなければ、これは実現不可能なことでした。 シャーディング画像 diff --git a/public/content/translations/ja/roadmap/merge/issuance/index.md b/public/content/translations/ja/roadmap/merge/issuance/index.md index 0af063497d9..fb07218b074 100644 --- a/public/content/translations/ja/roadmap/merge/issuance/index.md +++ b/public/content/translations/ja/roadmap/merge/issuance/index.md @@ -4,25 +4,25 @@ description: マージがETHの供給に与えた影響についての概要 lang: ja --- -# マージが ETH の供給に与えた影響について {#how-the-merge-impacts-ETH-supply} +# マージがETHの供給に与えた影響について {#how-the-merge-impacts-ETH-supply} -マージとは、2022 年 9 月にイーサリアムネットワークがプルーフ・オブ・ワークからプルーフ・オブ・ステークへ移行したアップデートのことです。 この移行により、ETH の発行方法が変更されました。 以前は、実行レイヤー( メインネット)とコンセンサスレイヤー( ビーコンチェーン)の 2 つのレイヤーから発行されていましたが、 マージ以降は、実行レイヤーで発行されなくなりました。 それでは、詳しく見ていきましょう。 +マージとは、2022年9月にイーサリアムネットワークがプルーフ・オブ・ワークからプルーフ・オブ・ステークへ移行したアップデートのことです。 この移行により、ETHの発行方法が変更されました。 以前は、実行レイヤー( メインネット)とコンセンサスレイヤー( ビーコンチェーン)の2つのレイヤーから発行されていましたが、 マージ以降は、実行レイヤーで発行されなくなりました。 それでは、詳しく見ていきましょう。 -## ETH を発行するコンポーネント {#components-of-eth-issuance} +## ETHを発行するコンポーネント {#components-of-eth-issuance} -ETH の供給は、「発行」と「バーン」という 2 つの主要な要因に分けられます。 +ETHの供給は、「発行」と「バーン」という2つの主要な要因に分けられます。 -ETH の**発行**は、ETH を作成するプロセスで以前は存在しなかった仕組みです。 ETH を破壊して流通から排除することを**バーン**といいます。 発行とバーンの割合は、いくつかのパラメータに基づいて計算されます。発行とバーンのバランスによって、イーサのインフレ/デフレ率が決まります。 +ETHの**発行**は、ETHを作成するプロセスで以前は存在しなかった仕組みです。 ETHを破壊して流通から排除することを**バーン**といいます。 発行とバーンの割合は、いくつかのパラメータに基づいて計算されます。発行とバーンのバランスによって、イーサのインフレ/デフレ率が決まります。 -- プルーフ・オブ・ステークに移行する前、マイナー全体で、1 日あたり約 13,000ETH を発行していました。 -- ステーキングされている計約 1,400 万 ETH に基づいて、1 日あたり約 1,700ETH がステーカーに発行されます。 -- ステーキングによる正確な発行量は、ステーキングされた ETH の総量に応じて変動します。 -- **マージ以降、1 日あたり最大 1,700ETH しか発行されなくなり、新たな ETH の発行総量は、最大で約 88%減少しています** -- バーンは、ネットワークの需要に応じて変動します。 とある日に、平均のガス価格が 16Gwei 以上になると、バリデータによって発行される約 1,700ETH が実質的に相殺されるので、その日の純 ETH インフレ率はゼロ以下になります。 +- プルーフ・オブ・ステークに移行する前、マイナー全体で、1日あたり約13,000ETHを発行していました。 +- ステーキングされている計約1,400万ETHに基づいて、1日あたり約 1,700ETHがステーカーに発行されます。 +- ステーキングによる正確な発行量は、ステーキングされたETHの総量に応じて変動します。 +- **マージ以降、1日あたり最大 1,700ETHしか発行されなくなり、新たなETHの発行総量は、最大で約88%減少しています** +- バーンは、ネットワークの需要に応じて変動します。 とある日に、平均のガス価格が16Gwei以上になると、バリデータによって発行される約1,700ETHが実質的に相殺されるので、その日の純ETHインフレ率はゼロ以下になります。 @@ -30,29 +30,29 @@ title="ETHの発行についての概要"> ### 実行レイヤーでの発行 {#el-issuance-pre-merge} -プルーフ・オブ・ワークでは、マイナーは実行レイヤーのみとやり取りを行い、最初に次のブロックを解決したマイナーがブロック報酬を受け取っていました。 2019 年の[コンスタンティノープルアップグレード](/history/#constantinople)以降、ブロックごとの報酬は 2ETH になりました。 マイナーは、[オマー](/glossary/#ommer)ブロック(最長または正規チェーンに含まれない有効なブロック)を発行しても報酬を受けました。 オマーブロックあたりの報酬は最大 1.75 ETH で、正規ブロックから発行された報酬とは*別*でした。 マイニングのプロセスは経済的に集中化された活動であり、これを維持するには、ETH の発行量を歴史的に高い水準に維持する必要があったのです。 +プルーフ・オブ・ワークでは、マイナーは実行レイヤーのみとやり取りを行い、最初に次のブロックを解決したマイナーがブロック報酬を受け取っていました。 2019年の[コンスタンティノープルアップグレード](/history/#constantinople)以降、ブロックごとの報酬は2ETHになりました。 マイナーは、[オマー](/glossary/#ommer)ブロック(最長または正規チェーンに含まれない有効なブロック)を発行しても報酬を受けました。 オマーブロックあたりの報酬は最大1.75 ETHで、正規ブロックから発行された報酬とは_別_でした。 マイニングのプロセスは経済的に集中化された活動であり、これを維持するには、ETHの発行量を歴史的に高い水準に維持する必要があったのです。 ### コンセンサスレイヤーでの発行 {#cl-issuance-pre-merge} -2020 年に稼働を開始した[ビーコンチェーン](/history/#beacon-chain-genesis)では、 マイナーに代わって、バリデータがプルーフ・オブ・ステークでネットワークを保護します。 ビーコンチェーンは、イーサリアムユーザーがメインネット(実行レイヤー)上のスマートコントラクトに ETH を一方向に入金することによってブートされます。ビーコンチェーンは、この入金をリッスンしており、ユーザーに対して新しいチェーンに同額の ETH をクレジットします。 マージが起こるまで、ビーコンチェーンのバリデータは、トランザクションの処理を行わず、基本的にはバリデータプールの状態についてのコンセンサスを形成していました。 +2020年に稼働を開始した[ビーコンチェーン](/history/#beacon-chain-genesis)では、 マイナーに代わって、バリデータがプルーフ・オブ・ステークでネットワークを保護します。 ビーコンチェーンは、イーサリアムユーザーがメインネット(実行レイヤー)上のスマートコントラクトにETHを一方向に入金することによってブートされます。ビーコンチェーンは、この入金をリッスンしており、ユーザーに対して新しいチェーンに同額のETHをクレジットします。 マージが起こるまで、ビーコンチェーンのバリデータは、トランザクションの処理を行わず、基本的にはバリデータプールの状態についてのコンセンサスを形成していました。 -ビーコンチェーンのバリデータは、チェーンの状態を証明し、ブロックを提案することで、報酬として ETH を受け取ります。 報酬(またはペナルティ)は、バリデータのパフォーマンスに応じて、各エポック(6.4 分ごと)に計算、分配されます。 バリデータの報酬は、プルーフ・オブ・ワーク時代のマイニング報酬(約 13.5 秒ごとに 2ETH)と比べて**大幅**に少なくなっています。これは、バリデータノードの運用にそれほどコストがかからないため、高い報酬は必要ないからです。 +ビーコンチェーンのバリデータは、チェーンの状態を証明し、ブロックを提案することで、報酬としてETHを受け取ります。 報酬(またはペナルティ)は、バリデータのパフォーマンスに応じて、各エポック(6.4分ごと)に計算、分配されます。 バリデータの報酬は、プルーフ・オブ・ワーク時代のマイニング報酬(約13.5秒ごとに2ETH)と比べて**大幅**に少なくなっています。これは、バリデータノードの運用にそれほどコストがかからないため、高い報酬は必要ないからです。 ### マージ以前の発行についての概要 {#pre-merge-issuance-breakdown} -総 ETH 供給量: **約 120,520,000ETH**(2022 年 9 月のマージ時点) +総ETH供給量: **約120,520,000ETH**(2022年9月のマージ時点) **実行レイヤーでの発行** -- 13.3 秒あたり 2.08ETH と推定されています。\*: 年間で**約 4,930,000**ETH が発行される計算になります。 -- 結果、**約 4.09%**のインフレ率(年間 493 万/合計 1 億 2050 万)。 -- \*この計算には、正規ブロックごとに発行される 2ETH と、その期間におけるオマーブロックの平均 0.08ETH が含まれています。 また、[ディフィカルティボム](/glossary/#difficulty-bomb)の影響を受けないベースラインブロック時間ターゲットである 13.3 秒を使用しています。 ([参照元をご覧ください](https://bitinfocharts.com/ethereum/)) +- 13.3秒あたり2.08ETHと推定されています。\*: 年間で**約4,930,000**ETHが発行される計算になります。 +- 結果、**約4.09%**のインフレ率(年間493万/合計1億2050万)。 +- \*この計算には、正規ブロックごとに発行される2ETHと、その期間におけるオマーブロックの平均0.08ETHが含まれています。 また、[ディフィカルティボム](/glossary/#difficulty-bomb)の影響を受けないベースラインブロック時間ターゲットである13.3秒を使用しています。 ([参照元をご覧ください](https://bitinfocharts.com/ethereum/)) **コンセンサスレイヤーでの発行** -- ステーキングされた合計が 14,000,000ETH だと、ETH 発行レートは、1 日あたり約 1700ETH になります。([参照元をご覧ください](https://ultrasound.money/)) -- 年間で**約 620,500**ETH が発行される計算になります。 -- 結果、**約 0.52%**のインフレ率(年間 62 万 500/合計 1 憶 1930 万)。 +- ステーキングされた合計が14,000,000ETHだと、ETH発行レートは、1日あたり約1700ETHになります。([参照元をご覧ください](https://ultrasound.money/)) +- 年間で**約620,500**ETHが発行される計算になります。 +- 結果、**約0.52%**のインフレ率(年間62万500/合計1憶1930万)。 合計年発行率(マージ前): 約4.61% (4.09% + 0.52%)

    @@ -60,7 +60,7 @@ title="ETHの発行についての概要"> 約11.3%がコンセンサスレイヤーのステーカーへ発行されました (0.52 / 4.61 * 100) 。
    -## マージ以降(現在) {#post-merge} +## マージ以降(現在) {#post-merge} ### 実行レイヤーでの発行 {#el-issuance-post-merge} @@ -68,67 +68,67 @@ title="ETHの発行についての概要"> ### コンセンサスレイヤーでの発行 {#cl-issuance-post-merge} -コンセンサスレイヤーでの発行は、マージ以前から同様に現在も続いており、ブロックを証明して提案したバリデータには少額の報酬が支払われます。 報酬は、コンセンサスレイヤー内で管理される*バリデータ残高*に積み立てられ、 メインネット上でトランザクションが可能な現行のアカウント (「実行」アカウント)とは別のイーサリアムアカウントに蓄積されます。そのため、他のイーサリアムアカウントとの自由なトランザクションはできません。 また、これらのアカウントの資金は、指定された 1 つの実行アドレス以外には引き出すことができません。 +コンセンサスレイヤーでの発行は、マージ以前から同様に現在も続いており、ブロックを証明して提案したバリデータには少額の報酬が支払われます。 報酬は、コンセンサスレイヤー内で管理される_バリデータ残高_に積み立てられ、 メインネット上でトランザクションが可能な現行のアカウント (「実行」アカウント)とは別のイーサリアムアカウントに蓄積されます。そのため、他のイーサリアムアカウントとの自由なトランザクションはできません。 また、これらのアカウントの資金は、指定された1つの実行アドレス以外には引き出すことができません。 -2023 年 4 月に実施された上海/カペラのアップグレードにより、ステーカーは引き出しが可能になりました。 ただし、*収益/報酬(32ETH を越える残高)*は、ステークウェイト(最大 32)として貢献しないため、引き出さない方がよいとされています。 +2023年4月に実施された上海/カペラのアップグレードにより、ステーカーは引き出しが可能になりました。 ただし、_収益/報酬(32ETHを越える残高)_は、ステークウェイト(最大32)として貢献しないため、引き出さない方がよいとされています。 ステーカーは、バリデータの残高すべてを引き出して、アクティビティを終了することもできます。 ただし、イーサリアムの安定性を確保するために、同時に終了するバリデータの数には上限が設けられています。 -1 日あたち、すべてのバリデータのうち約 0.33%が終了できます。 デフォルトでは、エポックごとに 4 台のバリデータが終了できます(6.4 分ごと 4 台、1 日では 900 台) 。 バリデータ数が 262,144(218)台を超えると、65,536(216)台のバリデータが増設されるたびに、追加で 1 台のバリデータが終了できます。 例えば、バリデータが 327,680 台を超えると、エポックごとに 5 台が終了すします(1 日あたり 1,125 台) 。 アクティブなバリデータ数が 393,216 台を超えると、6 台の終了が許可されます(以降も同様です)。 +1日あたち、すべてのバリデータのうち約0.33%が終了できます。 デフォルトでは、エポックごとに4台のバリデータが終了できます(6.4分ごと4台、1日では900台) 。 バリデータ数が262,144(218)台を超えると、65,536(216)台のバリデータが増設されるたびに、追加で1台のバリデータが終了できます。 例えば、バリデータが327,680台を超えると、エポックごとに5台が終了すします(1日あたり1,125台) 。 アクティブなバリデータ数が393,216台を超えると、6台の終了が許可されます(以降も同様です)。 -多数のバリデータが引き出すと、ネットワークが不安定になる可能性があるため、終了するバリデータの最大数を 4 台に縮小し、「ステーキングされた ETH が一度に大量に引き出されること」を防ぎます。 +多数のバリデータが引き出すと、ネットワークが不安定になる可能性があるため、終了するバリデータの最大数を4台に縮小し、「ステーキングされたETHが一度に大量に引き出されること」を防ぎます。 ### マージ以降のインフレについての概要 {#post-merge-inflation-breakdown} -- 総 ETH 供給量: **約 120,520,000ETH**(2022 年 9 月のマージ時点) +- 総ETH供給量: **約120,520,000ETH**(2022年9月のマージ時点) - 実行レイヤーでの発行: **0**(なし) -- コンセンサスレイヤーでの発行: 上記(マージ以前)と同じで、年間発行率**約 0.52%**(合計 1,400 万 ETH がステーキングされている場合) +- コンセンサスレイヤーでの発行: 上記(マージ以前)と同じで、年間発行率**約0.52%**(合計1,400万ETH がステーキングされている場合) 合計年間発行率: 約0.52%

    年間ETH発行の純削減率: 約88.7% ((4.61% - 0.52%) / 4.61% * 100)
    -## バーン(焼却) {#the-burn} +## バーン(焼却) {#the-burn} -ETH の発行とは逆に、イーサリアムでは ETH がバーンされるレートがあります。 イーサリアムでトランザクションを実行するには、最低手数料(「ベースフィー」)を支払う必要があります。ベースフィーは、ネットワークの混雑状況によって(ブロックごとに)常に変動し、 ETH で支払われます。ベースフィーは、トランザクションが有効に成立するために*必要*となり、 トランザクション処理中に*バーン*され、流通から消滅します。 +ETHの発行とは逆に、イーサリアムではETHがバーンされるレートがあります。 イーサリアムでトランザクションを実行するには、最低手数料(「ベースフィー」)を支払う必要があります。ベースフィーは、ネットワークの混雑状況によって(ブロックごとに)常に変動し、 ETHで支払われます。ベースフィーは、トランザクションが有効に成立するために_必要_となり、 トランザクション処理中に_バーン_され、流通から消滅します。 フィーのバーンは、2021年8月のロンドンアップグレードから始まり、マージ以降も継続されます。 -ロンドンのアップグレードで実装されたフィーのバーンに加えて、バリデータがオフラインになるとペナルティを課されます。さらに深刻なことに、ネットワークのセキュリティを脅かす特定のルールに違反した場合にはスラッシュされることがあります。 これらのペナルティにより、バリデータの残高から ETH が減少し、他のどのアカウントにも直接報酬として支払われず、事実上は流通から消滅することになります。 +ロンドンのアップグレードで実装されたフィーのバーンに加えて、バリデータがオフラインになるとペナルティを課されます。さらに深刻なことに、ネットワークのセキュリティを脅かす特定のルールに違反した場合にはスラッシュされることがあります。 これらのペナルティにより、バリデータの残高からETHが減少し、他のどのアカウントにも直接報酬として支払われず、事実上は流通から消滅することになります。 ### デフレ時における平均ガス価格の計算 {#calculating-average-gas-price-for-deflation} -上述したように、特定の日に発行される ETH の量はステーキングされた ETH の合計額によって決まります。 この記事の執筆時点では、1 日あたり約 1700ETH が発行されています。 +上述したように、特定の日に発行されるETHの量はステーキングされたETHの合計額によって決まります。 この記事の執筆時点では、1日あたり約1700ETHが発行されています。 -指定された 24 時間内で、ETH の発行を完全に相殺するのに必要な平均ガス価格を決定するには、ブロック時間を 12 秒として、1 日の総ブロック数を計算することから始めます。 +指定された24時間内で、ETHの発行を完全に相殺するのに必要な平均ガス価格を決定するには、ブロック時間を12秒として、1日の総ブロック数を計算することから始めます。 - `(1ブロック/12秒) * (60秒/分) = 5ブロック/分` - `(5ブロック/分) * (60分/時間) = 300ブロック/時間` - `(300ブロック/時間) * (24時間/日) = 7200ブロック/日` -各ブロックは、`15x10^6 gas/block`をターゲットとしています([ガスの詳細](/developers/docs/gas/))。 1 日あたりの合計 ETH 発行量が 1700ETH であるとすると、発行を相殺するために必要な平均ガス価格(ガスあたりの gwei)は、次の計算式で求めることができます。 +各ブロックは、`15x10^6 gas/block`をターゲットとしています([ガスの詳細](/developers/docs/gas/))。 1日あたりの合計ETH発行量が1700ETHであるとすると、発行を相殺するために必要な平均ガス価格(ガスあたりのgwei)は、次の計算式で求めることができます。 - `7200 blocks/day * 15x10^6 gas/block *`**`Y gwei/gas`**`* 1 ETH/ 10^9 gwei = 1700 ETH/day` `Y`を次のように求めます。 -- `Y = (1700(10^9))/(7200 * 15(10^6)) = (17x10^3)/(72 * 15) = 16 gwei`(有効数字 2 桁に丸める) +- `Y = (1700(10^9))/(7200 * 15(10^6)) = (17x10^3)/(72 * 15) = 16 gwei`(有効数字2桁に丸める) -上記の最終ステップを再構成するもう 1 つの方法は、`1700`を 1 日あたりの ETH 発行量を意味する変数`X`に置き換え、残りは次のように単純化します。 +上記の最終ステップを再構成するもう1つの方法は、`1700`を1日あたりのETH発行量を意味する変数`X`に置き換え、残りは次のように単純化します。 - `Y = (X(10^3)/(7200 * 15)) = X/108` これは、`X`の関数として単純化することができます。 -- `f(X) = X/108`: ここで`X`は、ETH の一日の発行量、そして`f(X)`は、新しく発行されたすべての ETH を相殺するために必要なガス価格あたりの gwei を表しています。 +- `f(X) = X/108`: ここで`X`は、ETHの一日の発行量、そして`f(X)`は、新しく発行されたすべてのETHを相殺するために必要なガス価格あたりのgweiを表しています。 -したがって、例えば`X`(一日の ETH 発行量)がステークされた合計 ETH 量をもととして 1800ETH になったとすると、`f(X)`(すべての発行量を相殺するために必要な gwei) は、`17gwei`となります(有効数字 2 桁の場合) 。 +したがって、例えば`X`(一日のETH発行量)がステークされた合計ETH量をもととして1800ETHになったとすると、`f(X)`(すべての発行量を相殺するために必要なgwei) は、`17gwei`となります(有効数字2桁の場合) 。 ## さらに学びたい方へ {#further-reading} - [マージ](/roadmap/merge/) -- [Ultrasound.money](https://ultrasound.money/) - _ETH の発行とバーンをリアルタイムで可視化したダッシュボードが利用可能_ +- [Ultrasound.money](https://ultrasound.money/) - _ETHの発行とバーンをリアルタイムで可視化したダッシュボードが利用可能_ - [Charting Ethereum Issuance](https://www.attestant.io/posts/charting-ethereum-issuance/) - _Jim McDonald 2020_ diff --git a/public/content/translations/ja/roadmap/pbs/index.md b/public/content/translations/ja/roadmap/pbs/index.md index f19fffa01d4..6266e5ef6b5 100644 --- a/public/content/translations/ja/roadmap/pbs/index.md +++ b/public/content/translations/ja/roadmap/pbs/index.md @@ -6,13 +6,13 @@ lang: ja # プロポーザー/ビルダーセパレーション(PBS) {#proposer-builder-separation} -現在、イーサリアムのバリデータは、*ブロックを作成、ブロードキャスト*します。 バリデータは、ゴシップネットワークを通じて伝達されたトランザクションを 1 つのブロックにまとめて、イーサリアムネットワーク上のピアに送信します。 **プロポーザー/ビルダーセパレーション(PBS)**は、ブロック提案とブロック生成のタスクを複数のバリデータに分割します。 ブロックビルダーは、各スロットのブロック提案者にブロックを提供する責任を負います。 ブロックプロポーザーは、ブロックの内容を事前に知ることができません。ブロックビルダーに料金を支払い、最も報酬の高いものを選び、その後、ブロックをピアに送信します。 +現在、イーサリアムのバリデータは、_ブロックを作成、ブロードキャスト_します。 バリデータは、ゴシップネットワークを通じて伝達されたトランザクションを1つのブロックにまとめて、イーサリアムネットワーク上のピアに送信します。 **プロポーザー/ビルダーセパレーション(PBS)**は、ブロック提案とブロック生成のタスクを複数のバリデータに分割します。 ブロックビルダーは、各スロットのブロック提案者にブロックを提供する責任を負います。 ブロックプロポーザーは、ブロックの内容を事前に知ることができません。ブロックビルダーに料金を支払い、最も報酬の高いものを選び、その後、ブロックをピアに送信します。 このアップグレードが重要な理由はいくつかあります。 まず、このアップグレードでプロトコルレベルでトランザクションの検閲を防ぐことができます。 次に、ブロック構築の収益性をより最適化できる機関投資家に個人のバリデータが出し抜かれることを防ぐことができます。 最後に、ダンクシャーディングのアップグレードが有効になると、イーサリアムのスケーリングを補助します。 -## PBS と検閲耐性 {#pbs-and-censorship-resistance} +## PBSと検閲耐性 {#pbs-and-censorship-resistance} -ブロックビルダーとブロック提案者を分離すると、ブロックビルダーがトランザクションを検閲することがかなり困難になります。 これは、PBS により、ブロックが提案される前に、検閲が行われていないことを保証する比較的複雑な基準を追加できるためです。 ブロック提案者は、ブロックビルダーとは別のエンティティであるため、ブロックビルダーによる検閲を防ぐ役割を担うことができます。 +ブロックビルダーとブロック提案者を分離すると、ブロックビルダーがトランザクションを検閲することがかなり困難になります。 これは、PBSにより、ブロックが提案される前に、検閲が行われていないことを保証する比較的複雑な基準を追加できるためです。 ブロック提案者は、ブロックビルダーとは別のエンティティであるため、ブロックビルダーによる検閲を防ぐ役割を担うことができます。 例えば、包含リストを導入すると、バリデータがトランザクションについて把握した時に、それがブロックに含まれていないことがわかった場合、次のブロックでそのトランザクションを必ず含めるように強制できるようになります。 包含リストは、ブロック提案者のローカルのメンプール(認識しているトランザクションのリスト)から生成され、ブロックが提案される直前にピアに送信されます。 包含リストのトランザクションのいずれかが失われている場合、提案者はブロックを拒否するか、提案する前に失われているトランザクションを追加するか、ブロックを提案して他のバリデータからブロックを受信した場合に拒否することができます。 また、より効率的なバージョンもあります。ビルダーは利用可能なブロック領域をすべて活用する必要があることを主張し、そうしなかった場合、提案者の包含リストからトランザクションを追加するというアイデアです。 まだ研究中の分野なので、包含リストの最適な構成はまだ決定されていません。 @@ -20,32 +20,32 @@ lang: ja -経済力のある組織は、特定のアドレスのトランザクションをブロックするようにバリデータに圧力をかけてくるかもしれません。 バリデータは、ブラックリストに登録されたアドレスのトランザクションを検出し、その組織が提案したブロックを除外することで、この圧力に対抗します。 PBS を導入すると、ブロック提案者は、自身のブロックでどのトランザクションをブロードキャストしているのか分からなくなるので、この対抗策は使えなくなります。 住んでいる地域で検閲が法律になっている場合、個人やアプリが検閲ルールに準拠しなければならないことがあります。 これらのケースでは、コンプライアンスはアプリケーションレベルで行われ、プロトコルはパーミッションレスで検閲が行われない状態のままです。 +経済力のある組織は、特定のアドレスのトランザクションをブロックするようにバリデータに圧力をかけてくるかもしれません。 バリデータは、ブラックリストに登録されたアドレスのトランザクションを検出し、その組織が提案したブロックを除外することで、この圧力に対抗します。 PBSを導入すると、ブロック提案者は、自身のブロックでどのトランザクションをブロードキャストしているのか分からなくなるので、この対抗策は使えなくなります。 住んでいる地域で検閲が法律になっている場合、個人やアプリが検閲ルールに準拠しなければならないことがあります。 これらのケースでは、コンプライアンスはアプリケーションレベルで行われ、プロトコルはパーミッションレスで検閲が行われない状態のままです。 -## PBS と MEV {#pbs-and-mev} +## PBSとMEV {#pbs-and-mev} -**最大抽出可能価値(MEV)**とは、トランザクションを好ましい順序に並べ替えることによって収益を最大化するバリデータのことです。 具体的には、分散型取引所での裁定取引(大規模な売買を行うフロントランニング)や、DeFi ポジションの清算などが挙げられます。 MEV を最大化するには、高度な技術ノウハウと、通常のバリデータに追加するカスタムソフトウェアが必要です。そのため MEV 抽出において、組織的なオペレータの方が個人や趣味でバリデータ立てている人物よりも優れたパフォーマンスを発揮する可能性が非常に高くなります。 つまり、集中化されたオペレータは、個人でステーキングするよりも高いリターンを得られる可能性があるため、ホームステークを阻害する力が働いてしまうということです。 +**最大抽出可能価値(MEV)**とは、トランザクションを好ましい順序に並べ替えることによって収益を最大化するバリデータのことです。 具体的には、分散型取引所での裁定取引(大規模な売買を行うフロントランニング)や、DeFiポジションの清算などが挙げられます。 MEVを最大化するには、高度な技術ノウハウと、通常のバリデータに追加するカスタムソフトウェアが必要です。そのためMEV抽出において、組織的なオペレータの方が個人や趣味でバリデータ立てている人物よりも優れたパフォーマンスを発揮する可能性が非常に高くなります。 つまり、集中化されたオペレータは、個人でステーキングするよりも高いリターンを得られる可能性があるため、ホームステークを阻害する力が働いてしまうということです。 -PBS では、MEV の経済を再設定することによって、この問題を解決します。 ブロック提案者は、MEV を自分で探す代わりに、ブロックビルダーが提案したブロックの中から、適当なブロックを選択します。 ブロックビルダーは、MEV を巧みに抽出しているかもしれませんが、その報酬はブロック提案者に支払われます。 つまり、専門のブロックビルダーが小さなプールを持っていても、MEV の抽出を独占していても、その報酬は、個人のホームステーカーを含む、ネットワーク上のすべてのバリデータに分配される可能性があるということです。 +PBSでは、MEVの経済を再設定することによって、この問題を解決します。 ブロック提案者は、MEVを自分で探す代わりに、ブロックビルダーが提案したブロックの中から、適当なブロックを選択します。 ブロックビルダーは、MEVを巧みに抽出しているかもしれませんが、その報酬はブロック提案者に支払われます。 つまり、専門のブロックビルダーが小さなプールを持っていても、MEVの抽出を独占していても、その報酬は、個人のホームステーカーを含む、ネットワーク上のすべてのバリデータに分配される可能性があるということです。 -個人でステークするよりも、プールでステークする方が有利になるかもしれません。これは、複雑な MEV 戦略によって得られる報酬が増えるからです。 ブロックの構築とブロックの提案を分離することで、抽出された MEV は、最も使われている MEV サーチャーに集中するのではなく、より多くのバリデータに分散されます。 同時に、専門のブロックビルダーの存在を許可することで、ブロック構築の負担が軽減され、MEV の盗難も防止されます。また、独立したバリデータの数も最大化され、ブロックの正しさをチェックできるようになります。 これは、「証明者と検証者の非対称性」という重要なコンセプトであり、ブロックが誠実であることを証明できる堅牢かつ最大限に分散化された検証者のネットワークが存在する限り、集中的なブロック生成は問題ないという考えを参考にしています。 分散化はあくまでも手段であって、目的ではありません。私たちが本当に望んでいるのは、正しいブロックです。 +個人でステークするよりも、プールでステークする方が有利になるかもしれません。これは、複雑なMEV戦略によって得られる報酬が増えるからです。 ブロックの構築とブロックの提案を分離することで、抽出されたMEVは、最も使われているMEVサーチャーに集中するのではなく、より多くのバリデータに分散されます。 同時に、専門のブロックビルダーの存在を許可することで、ブロック構築の負担が軽減され、MEVの盗難も防止されます。また、独立したバリデータの数も最大化され、ブロックの正しさをチェックできるようになります。 これは、「証明者と検証者の非対称性」という重要なコンセプトであり、ブロックが誠実であることを証明できる堅牢かつ最大限に分散化された検証者のネットワークが存在する限り、集中的なブロック生成は問題ないという考えを参考にしています。 分散化はあくまでも手段であって、目的ではありません。私たちが本当に望んでいるのは、正しいブロックです。 -## PBS とダンクシャーディング {#pbs-and-danksharding} +## PBSとダンクシャーディング {#pbs-and-danksharding} -ダンクシャーディングは、イーサリアムの処理能力を 1 秒あたり 10 万トランザクション以上までスケーリングします。これにより、ロールアップユーザーの手数料を最小限に抑えることができます。 ダンクシャーディングでは、ブロックビルダーの作業負荷が増加します。ブロックビルダーは、最大 64MB のロールアップデータの証明を 1 秒未満で計算する必要があるため、PBS に依存しています。 このタスクは、かなりのハードウェアリソースを必要とするものです。そのため、専門のビルダーが専属で取り組む必要がありますが、 現在の状況では、いずれにせよ MEV 抽出によって、ブロック構築は、より洗練化した強力なオペレーターを中心にますます集中化する可能性があります。 プロポーザー/ビルダーセパレーションは、ブロックの検証やステーキング報酬の分配といった重要な役割を、複数のバリデーターに分散することで、集中化を防ぐための仕組みです。 また、この仕組みには、副次的な利点もあります。それは、専門のブロックビルダーが、ダンクシャーディングに必要なデータ証明を、より意欲的に計算できるようになるということです。 +ダンクシャーディングは、イーサリアムの処理能力を1秒あたり10万トランザクション以上までスケーリングします。これにより、ロールアップユーザーの手数料を最小限に抑えることができます。 ダンクシャーディングでは、ブロックビルダーの作業負荷が増加します。ブロックビルダーは、最大64MBのロールアップデータの証明を1秒未満で計算する必要があるため、PBSに依存しています。 このタスクは、かなりのハードウェアリソースを必要とするものです。そのため、専門のビルダーが専属で取り組む必要がありますが、 現在の状況では、いずれにせよMEV抽出によって、ブロック構築は、より洗練化した強力なオペレーターを中心にますます集中化する可能性があります。 プロポーザー/ビルダーセパレーションは、ブロックの検証やステーキング報酬の分配といった重要な役割を、複数のバリデーターに分散することで、集中化を防ぐための仕組みです。 また、この仕組みには、副次的な利点もあります。それは、専門のブロックビルダーが、ダンクシャーディングに必要なデータ証明を、より意欲的に計算できるようになるということです。 ## 現在の進行状況 {#current-progress} -PBS の研究は、順調に進んでいます。しかし、イーサリアムクライアントでプロトタイプを作成するには、まだいくつかの設計上の重大な問題を解決する必要があります。 そのため、仕様の確定に至っていません。 つまり、PBS の実装は 1 年以上先になる可能性があります。 最新の研究状況は、[こちら](https://notes.ethereum.org/@vbuterin/pbs_censorship_resistance)でご確認ください。 +PBSの研究は、順調に進んでいます。しかし、イーサリアムクライアントでプロトタイプを作成するには、まだいくつかの設計上の重大な問題を解決する必要があります。 そのため、仕様の確定に至っていません。 つまり、PBSの実装は1年以上先になる可能性があります。 最新の研究状況は、[こちら](https://notes.ethereum.org/@vbuterin/pbs_censorship_resistance)でご確認ください。 ## 参考文献 {#further-reading} -- [研究状況: PBS の下での検閲耐性](https://notes.ethereum.org/@vbuterin/pbs_censorship_resistance) -- [PBS にふさわしい手数料市場のデザイン](https://ethresear.ch/t/proposer-block-builder-separation-friendly-fee-market-designs/9725) -- [PBS と検閲耐性](https://notes.ethereum.org/@fradamt/H1TsYRfJc#Secondary-auctions) +- [研究状況: PBSの下での検閲耐性](https://notes.ethereum.org/@vbuterin/pbs_censorship_resistance) +- [PBSにふさわしい手数料市場のデザイン](https://ethresear.ch/t/proposer-block-builder-separation-friendly-fee-market-designs/9725) +- [PBSと検閲耐性](https://notes.ethereum.org/@fradamt/H1TsYRfJc#Secondary-auctions) - [包括リスト](https://notes.ethereum.org/@fradamt/H1ZqdtrBF) diff --git a/public/content/translations/ja/roadmap/scaling/index.md b/public/content/translations/ja/roadmap/scaling/index.md index 5e5ea41acc7..2fd5847e575 100644 --- a/public/content/translations/ja/roadmap/scaling/index.md +++ b/public/content/translations/ja/roadmap/scaling/index.md @@ -7,7 +7,7 @@ alt: "イーサリアムロードマップ" template: roadmap --- -イーサリアムは、[レイヤー 2](/layer-2/#rollups)(ロールアップとも呼ばれます)と呼ばれるスケーリング技術で、トランザクションをまとめて処理し、出力をイーサリアムに送信します。 ロールアップでは、イーサリアムメインネットよりも最大 8 倍安価に取引を行うことができますが、ロールアップのさらなる最適化によって、さらにコストを削減できる可能性があります。 ただし、ロールアップには一部の集中化されたコンポーネントも含まれており、これはロールアップが成熟するにつれてデベロッパーによって取り除かれる予定です。 +イーサリアムは、[レイヤー2](/layer-2/#rollups)(ロールアップとも呼ばれます)と呼ばれるスケーリング技術で、トランザクションをまとめて処理し、出力をイーサリアムに送信します。 ロールアップでは、イーサリアムメインネットよりも最大8倍安価に取引を行うことができますが、ロールアップのさらなる最適化によって、さらにコストを削減できる可能性があります。 ただし、ロールアップには一部の集中化されたコンポーネントも含まれており、これはロールアップが成熟するにつれてデベロッパーによって取り除かれる予定です。
      @@ -24,15 +24,15 @@ template: roadmap ### プロトダンクシャーディング {#proto-danksharding} -ロールアップのデータは、イーサリアム上に永続的に保存されるため、コストがかかります。 ユーザーは、ロールアップで支払うトランザクションコストの 90%以上を、データストレージに費やしています。 トランザクションコストを削減するため、新たに「ブロブ」と呼ばれる一時ストレージ領域にデータを移動できるようになりました。 ブロブは、永続的でないため、比較的コストが安くなっており、不要になるとイーサリアムから削除されます。 ロールアップデータの長期保存は、ロールアップオペレータ、取引所、インデックスサービスなど、それを必要とする人々の役割となります。 イーサリアムへのブロブトランザクションの追加は、「プロトダンクシャーディング」と呼ばれるアップグレードの一部であり、 2023 年後半の比較的早い時期にリリースされる予定です。 +ロールアップのデータは、イーサリアム上に永続的に保存されるため、コストがかかります。 ユーザーは、ロールアップで支払うトランザクションコストの90%以上を、データストレージに費やしています。 トランザクションコストを削減するため、新たに「ブロブ」と呼ばれる一時ストレージ領域にデータを移動できるようになりました。 ブロブは、永続的でないため、比較的コストが安くなっており、不要になるとイーサリアムから削除されます。 ロールアップデータの長期保存は、ロールアップオペレータ、取引所、インデックスサービスなど、それを必要とする人々の役割となります。 イーサリアムへのブロブトランザクションの追加は、「プロトダンクシャーディング」と呼ばれるアップグレードの一部であり、 2023年後半の比較的早い時期にリリースされる予定です。 -プロトダンクシャーディングによって、イーサリアムプロトコルにブロブトランザクションが組み込まれると、イーサリアムのブロックにたくさんのブロブを追加できるようになります。 これにより、イーサリアムのスループットが大幅に向上し(100 倍以上)、トランザクションのコストも下げることができます。 +プロトダンクシャーディングによって、イーサリアムプロトコルにブロブトランザクションが組み込まれると、イーサリアムのブロックにたくさんのブロブを追加できるようになります。 これにより、イーサリアムのスループットが大幅に向上し(100倍以上)、トランザクションのコストも下げることができます。 ### ダークシャーディング {#danksharding} -ブロブデータ拡張の第 2 段階は、大変複雑です。理由は、ロールアップデータがネットワーク上で利用可能であることを確認する新しい方法が必要だからです。また、バリデータの役割を分離して、ブロック構築とブロック提案に分けることも必要です。 さらに、バリデータがブロブデータの小さなサブセットを検証したことを暗号的に証明する方法も必要になります。 +ブロブデータ拡張の第2段階は、大変複雑です。理由は、ロールアップデータがネットワーク上で利用可能であることを確認する新しい方法が必要だからです。また、バリデータの役割を分離して、ブロック構築とブロック提案に分けることも必要です。 さらに、バリデータがブロブデータの小さなサブセットを検証したことを暗号的に証明する方法も必要になります。 -この 2 番目のステップは、[「ダンクシャーディング」](/roadmap/danksharding/)と呼ばれます。 完全に実装されるまでには、数年かかると予想されています。 ダンクシャーディングは、[ブロック構築とブロック提案を分離する](/roadmap/pbs)などの他の開発に依存しています。また、データが利用可能であることを効率的に確認するために、[データ可用性サンプリング(DAS)](/developers/docs/data-availability)と呼ばれる、数キロバイトのデータをランダムにサンプリングする新しいネットワーク設計も採用しています。 +この2番目のステップは、[「ダンクシャーディング」](/roadmap/danksharding/)と呼ばれます。 完全に実装されるまでには、数年かかると予想されています。 ダンクシャーディングは、[ブロック構築とブロック提案を分離する](/roadmap/pbs)などの他の開発に依存しています。また、データが利用可能であることを効率的に確認するために、[データ可用性サンプリング(DAS)](/developers/docs/data-availability)と呼ばれる、数キロバイトのデータをランダムにサンプリングする新しいネットワーク設計も採用しています。 ダンクシャーディングの詳細 diff --git a/public/content/translations/ja/roadmap/secret-leader-election/index.md b/public/content/translations/ja/roadmap/secret-leader-election/index.md index 76c494e099f..85e4c933f25 100644 --- a/public/content/translations/ja/roadmap/secret-leader-election/index.md +++ b/public/content/translations/ja/roadmap/secret-leader-election/index.md @@ -10,34 +10,34 @@ summaryPoints: # シークレットリーダー選出 {#single-secret-leader-election} -現在の[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos)ベースのコンセンサスメカニズムでは、今後のブロック提案者のリストが公開され、彼らの IP アドレスをマッピングすることが可能です。 そのため、攻撃者は、ブロックを提案する予定のバリデータを特定し、そのバリデータに対してサービス拒否(DOS)攻撃を仕掛けることで、時間通りにブロックの提案を行わせないように妨害することができます。 +現在の[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos)ベースのコンセンサスメカニズムでは、今後のブロック提案者のリストが公開され、彼らのIPアドレスをマッピングすることが可能です。 そのため、攻撃者は、ブロックを提案する予定のバリデータを特定し、そのバリデータに対してサービス拒否(DOS)攻撃を仕掛けることで、時間通りにブロックの提案を行わせないように妨害することができます。 -この状況は、攻撃者にとって利益を得る機会になる可能性があります。 例えば、スロット`n+1`に選ばれたブロック提案者が、スロット`n`の提案者に対して DoS 攻撃を行うことで、ブロックを提案する機会を奪うことができます。 これにより、攻撃側のブロック提案者は、両方のスロットの MEV を抽出したり、2 つのブロックに分かれるはずだったすべてのトランザクションを 1 つのブロックにまとめたりすることで、関連するすべての手数料を独占できます。 この攻撃は、高度な方法を使って DOS 攻撃から防御することができる技術力の高い機関のバリデータよりも、一般的な家庭のバリデータに対して悪影響を与える可能性が高く、結果的にバリデータの集中化につながる可能性があります。 +この状況は、攻撃者にとって利益を得る機会になる可能性があります。 例えば、スロット`n+1`に選ばれたブロック提案者が、スロット`n`の提案者に対してDoS攻撃を行うことで、ブロックを提案する機会を奪うことができます。 これにより、攻撃側のブロック提案者は、両方のスロットのMEVを抽出したり、2つのブロックに分かれるはずだったすべてのトランザクションを1つのブロックにまとめたりすることで、関連するすべての手数料を独占できます。 この攻撃は、高度な方法を使ってDOS攻撃から防御することができる技術力の高い機関のバリデータよりも、一般的な家庭のバリデータに対して悪影響を与える可能性が高く、結果的にバリデータの集中化につながる可能性があります。 -この問題には、いくつかの解決策があります。 1 つは、[分散バリデータ技術](https://github.com/ethereum/distributed-validator-specs)です。これは、バリデータの実行に必要なさまざまなタスクを、冗長性のある複数のマシンに分散する技術です。これにより、攻撃者が特定のスロットでブロックの提案を妨害するのが難しくなります。 しかし、最も有効な解決策は、**シークレット・シングル・リーダー選出(SSLE)** です。 +この問題には、いくつかの解決策があります。 1つは、[分散バリデータ技術](https://github.com/ethereum/distributed-validator-specs)です。これは、バリデータの実行に必要なさまざまなタスクを、冗長性のある複数のマシンに分散する技術です。これにより、攻撃者が特定のスロットでブロックの提案を妨害するのが難しくなります。 しかし、最も有効な解決策は、**シークレット・シングル・リーダー選出(SSLE)** です。 ## シークレット・シングル・リーダー選出 {#secret-leader-election} -SSLE(シークレット・シングル・リーダー選出)では、選出されたバリデータのみが自分が選ばれたことを知ることができるように、高度な暗号化が使用されます。 これは、各バリデータが秘密に対するコミットメントを送信することで機能します。このコミットメントは、バリデータ全員で共有します。 コミットメントは、シャッフル、再構成され、誰もコミットメントをバリデータにマッピングすることはできませんが、各バリデータは自分に属するコミットメントを把握しています。 その後、ランダムに 1 つのコミットメントが選ばれます。 バリデータが自身のコミットメントが選ばれたことを確認すると、そのバリデータがブロックを提案する番になります。 +SSLE(シークレット・シングル・リーダー選出)では、選出されたバリデータのみが自分が選ばれたことを知ることができるように、高度な暗号化が使用されます。 これは、各バリデータが秘密に対するコミットメントを送信することで機能します。このコミットメントは、バリデータ全員で共有します。 コミットメントは、シャッフル、再構成され、誰もコミットメントをバリデータにマッピングすることはできませんが、各バリデータは自分に属するコミットメントを把握しています。 その後、ランダムに1つのコミットメントが選ばれます。 バリデータが自身のコミットメントが選ばれたことを確認すると、そのバリデータがブロックを提案する番になります。 このアイデアを実装した主要なものとして、[ウィスク](https://ethresear.ch/t/whisk-a-practical-shuffle-based-ssle-protocol-for-ethereum/11763)と呼ばれるものがあります。 ウィスクは、次のように機能します。 1. バリデータは共有シークレットにコミットします。 このコミットメントスキームでは、バリデータのアイデンティティにバインドできるように設計されています。また、第三者がこのバインドをリバースエンジニアリングして、特定のコミットメントを特定のバリデータに関連づけることができないようにランダム化することもできます。 -2. エポックの開始時に、RANDAO を用いて 16,384 のバリデータからランダムなバリデータセットが選択され、コミットメントがサンプリングされます。 -3. 次の 8182 スロット(1 日分)の間に、ブロック提案者は独自のプライベートエントロピーを使用して、コミットメントのサブセットをシャッフルし、ランダム化します。 -4. シャッフルが終了したら、RANDAO を使用して、コミットメントを順番に並べたリストを作成します。 このリストは、イーサリアムスロットにマッピングされます。 +2. エポックの開始時に、RANDAOを用いて16,384のバリデータからランダムなバリデータセットが選択され、コミットメントがサンプリングされます。 +3. 次の8182スロット(1日分)の間に、ブロック提案者は独自のプライベートエントロピーを使用して、コミットメントのサブセットをシャッフルし、ランダム化します。 +4. シャッフルが終了したら、RANDAOを使用して、コミットメントを順番に並べたリストを作成します。 このリストは、イーサリアムスロットにマッピングされます。 5. バリデータは、自身のコミットメントが特定のスロットに紐づいていることを確認し、そのスロットになったらブロックを提案します。 6. この手順を繰り返し行うことで、スロットに対するコミットメントの割り当ては、常に現在のスロットよりもはるかに先に進んでいきます。 -これにより、攻撃者は、次のブロックを提案する特定のバリデータが事前にわからないので、DOS 攻撃ができなくなります。 +これにより、攻撃者は、次のブロックを提案する特定のバリデータが事前にわからないので、DOS攻撃ができなくなります。 ## シークレット・非シングル・リーダー選出(SnSLE) {#secret-non-single-leader-election} -プルーフ・オブ・ワークにおいてブロックの提案を決定する方法と同様に、バリデータが各スロットでブロックを提案する機会をランダムに与える仕組みもあり、シークレット・非シングル・リーダー選出(SnSLE)と呼ばれています。 例えば、現在のプロトコルでバリデータをランダムに選択するために使われている RANDAO 関数を活用すれば、簡単に実現できます。 RANDAO を使うアイデアとは、多くの独立しているバリデータから送信されたハッシュを混合することで、十分な乱数が生成するというものです。 SnSLE において、これらのハッシュを使って、次のブロック提案者を選ぶことができます。例えば、最小値のハッシュの選択です。 有効なハッシュ値の範囲を設定することで、各スロットでバリデータが選ばれる可能性を調整することができます。 ハッシュ値が`2^256 * 5 / N` (`N` = アクティブなバリデータ数)未満でなければならないとアサートすると、各スロットで個々のバリデータが選択される可能性は、`5/N`になります。 この例では、少なくとも 1 人の提案者が各スロットで有効なハッシュを生成する確率は 99.3%になります。 +プルーフ・オブ・ワークにおいてブロックの提案を決定する方法と同様に、バリデータが各スロットでブロックを提案する機会をランダムに与える仕組みもあり、**シークレット・非シングル・リーダー選出(SnSLE)**と呼ばれています。 例えば、現在のプロトコルでバリデータをランダムに選択するために使われているRANDAO関数を活用すれば、簡単に実現できます。 RANDAOを使うアイデアとは、多くの独立しているバリデータから送信されたハッシュを混合することで、十分な乱数が生成するというものです。 SnSLEにおいて、これらのハッシュを使って、次のブロック提案者を選ぶことができます。例えば、最小値のハッシュの選択です。 有効なハッシュ値の範囲を設定することで、各スロットでバリデータが選ばれる可能性を調整することができます。 ハッシュ値が`2^256 * 5 / N` (`N` = アクティブなバリデータ数)未満でなければならないとアサートすると、各スロットで個々のバリデータが選択される可能性は、`5/N`になります。 この例では、少なくとも1人の提案者が各スロットで有効なハッシュを生成する確率は99.3%になります。 ## 現在の進行状況 {#current-progress} -SSLE と SnSLE はまだ研究段階にあるため、 仕様が決まっていません。 また、SSLE と SnSLE は競合しているので、両方が実装されるということはありません。 この提案をリリースするには、さらに研究開発を行い、プロトタイピングを作成した上で、公開テストネットで実装する必要があります。 +SSLEとSnSLEはまだ研究段階にあるため、 仕様が決まっていません。 また、SSLEとSnSLEは競合しているので、両方が実装されるということはありません。 この提案をリリースするには、さらに研究開発を行い、プロトタイピングを作成した上で、公開テストネットで実装する必要があります。 ## 参考文献 {#further-reading} diff --git a/public/content/translations/ja/roadmap/security/index.md b/public/content/translations/ja/roadmap/security/index.md index 3c525979778..981c6e3c9a0 100644 --- a/public/content/translations/ja/roadmap/security/index.md +++ b/public/content/translations/ja/roadmap/security/index.md @@ -13,25 +13,25 @@ template: roadmap ## ステーキングの引き出し {#staking-withdrawals} -イーサリアムのプルーフ・オブ・ワークからプルーフ・オブ・ステークへのアップグレードは、イーサリアムの先駆者たちが自分のイーサ(ETH)をデポジットコントラクトに「ステーキング」することで始まりました。 このステーキングに使われる ETH は、ネットワークの保護に使われます。 ただし、この ETH は、現時点ではロックされており、ユーザーに返すことはできません。 プルーフ・オブ・ステークのアップグレードでは、ステーキングした ETH の引き出しが可能になります。 これは、プルーフ・オブ・ステークのプロトコルが完全に機能するために重要な要素であり、ステーカーが ETH 報酬を自由に使えるようになることで、イーサリアムのセキュリティにも有益です。 なぜなら、ステーキングに流動性を求めるユーザーが、リキッドステーキングデリバティブ(LSD)に頼る必要がなくなるからです。LSD は、イーサリアムを集中化させる力になる可能性があります。 このアップグレードは、2023 年 4 月 12 日に完了する予定です。 +イーサリアムのプルーフ・オブ・ワークからプルーフ・オブ・ステークへのアップグレードは、イーサリアムの先駆者たちが自分のイーサ(ETH)をデポジットコントラクトに「ステーキング」することで始まりました。 このステーキングに使われるETHは、ネットワークの保護に使われます。 ただし、このETHは、現時点ではロックされており、ユーザーに返すことはできません。 プルーフ・オブ・ステークのアップグレードでは、ステーキングしたETHの引き出しが可能になります。 これは、プルーフ・オブ・ステークのプロトコルが完全に機能するために重要な要素であり、ステーカーがETH報酬を自由に使えるようになることで、イーサリアムのセキュリティにも有益です。 なぜなら、ステーキングに流動性を求めるユーザーが、リキッドステーキングデリバティブ(LSD)に頼る必要がなくなるからです。LSDは、イーサリアムを集中化させる力になる可能性があります。 このアップグレードは、2023年4月12日に完了する予定です。 引き出しについての詳細 ## 攻撃からの防御 {#defending-against-attacks} -引き出しが可能になった後にも、イーサリアムの[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos/)のプロトコルにはいくつかの改善点があります。 1 つは、[ビューマージ](https://ethresear.ch/t/view-merge-as-a-replacement-for-proposer-boost/13739)と呼ばれる、より安全なフォーク選択アルゴリズムです。 これにより、高度なタイプの攻撃をさらに防ぐことができます。 +引き出しが可能になった後にも、イーサリアムの[プルーフ・オブ・ステーク](/developers/docs/consensus-mechanisms/pos/)のプロトコルにはいくつかの改善点があります。 1つは、[ビューマージ](https://ethresear.ch/t/view-merge-as-a-replacement-for-proposer-boost/13739)と呼ばれる、より安全なフォーク選択アルゴリズムです。 これにより、高度なタイプの攻撃をさらに防ぐことができます。 -イーサリアムがブロックを確定させるまでの時間を短縮することで、ユーザーがより快適に利用できるようになります。また、攻撃者が、高度な「再編成」攻撃を行って直近のブロックの再シャッフルを試みることで、利益を得たり、特定のトランザクションを検閲しようとするのを防ぐことができます。 [**シングルスロット・ファイナリティ(SSF)**](/roadmap/single-slot-finality/)は、トランザクションが確定に至るまでの遅延時間を短縮する方法です。 現行のシステムでは、15 分以内に生成されたブロックは、理論上攻撃者が他のバリデータにブロックの再構成を誘導できます。 SSF では、この脆弱性が解消されます。 個人からアプリや取引所まで、全てのユーザーは、トランザクションが取り消されないという保証を迅速に受けられます。ネットワークでは、SSF によりあらゆる種類の攻撃を遮断することができます。 +イーサリアムがブロックを確定させるまでの時間を短縮することで、ユーザーがより快適に利用できるようになります。また、攻撃者が、高度な「再編成」攻撃を行って直近のブロックの再シャッフルを試みることで、利益を得たり、特定のトランザクションを検閲しようとするのを防ぐことができます。 [**シングルスロット・ファイナリティ(SSF)**](/roadmap/single-slot-finality/)は、トランザクションが確定に至るまでの遅延時間を短縮する方法です。 現行のシステムでは、15分以内に生成されたブロックは、理論上攻撃者が他のバリデータにブロックの再構成を誘導できます。 SSFでは、この脆弱性が解消されます。 個人からアプリや取引所まで、全てのユーザーは、トランザクションが取り消されないという保証を迅速に受けられます。ネットワークでは、SSFによりあらゆる種類の攻撃を遮断することができます。 シングルスロット・ファイナリティの詳細 ## 検閲からの防御 {#defending-against-censorship} -分散化は、個人や少数のグループのバリデータが、過剰な影響力を持ってしまうことを防ぐ効果があります。 新たなステーキングの技術は、イーサリアムのバリデータを可能な限り分散化した状態に保ち、ハードウェア、ソフトウェア、ネットワークの障害から保護します。 この新たなステーキングの技術では、複数のノード間でバリデータの責任を共有するソフトウェアも対象になっています。 これを、**分散バリデータ技術(DVT)**と呼びます。 DVT により、複数のコンピュータが共同で検証を行うことで、冗長性とフォールトトレランスが向上します。そのため、ステーキングプールでは、DVT の使用が推奨されています。 DVT では、バリデータ鍵を複数のシステムに分割します。これにより、1 つのオペレータが複数のバリデータを実行できなくなり、 不正なオペレータによるイーサリアムへ攻撃が困難になります。 つまり、バリデータを個人ではなく、*コミュニティ*全体で実行することで、セキュリティを高めるというアイデアです。 +分散化は、個人や少数のグループのバリデータが、過剰な影響力を持ってしまうことを防ぐ効果があります。 新たなステーキングの技術は、イーサリアムのバリデータを可能な限り分散化した状態に保ち、ハードウェア、ソフトウェア、ネットワークの障害から保護します。 この新たなステーキングの技術では、複数のノード間でバリデータの責任を共有するソフトウェアも対象になっています。 これを、**分散バリデータ技術(DVT)**と呼びます。 DVTにより、複数のコンピュータが共同で検証を行うことで、冗長性とフォールトトレランスが向上します。そのため、ステーキングプールでは、DVTの使用が推奨されています。 DVTでは、バリデータ鍵を複数のシステムに分割します。これにより、1つのオペレータが複数のバリデータを実行できなくなり、 不正なオペレータによるイーサリアムへ攻撃が困難になります。 つまり、バリデータを個人ではなく、_コミュニティ_全体で実行することで、セキュリティを高めるというアイデアです。 分散バリデータ技術の詳細 -**プロポーザー/ビルダーセパレーション(PBS)**の実装により、イーサリアムの検閲耐性が大幅に向上します。 PBS では、ブロックの作成とイーサリアムネットワーク全体へのブロードキャストを別々のバリデータが担います。 これにより、利益を最大化している専門家のブロック構築アルゴリズムによる利益の偏りを防ぎ、ネットワーク全体でより公平な利益分配を実現します。また、時間の経過とともに、最もパフォーマンスの高い機関投資家に**ステークが集中化することを防ぐ**ことができます。 ブロック提案者は、ブロックビルダーの市場から提供されたブロックの中から、最も収益性の高いものを選択できます。 しかし、検閲を行うためには、収益性の低いブロックを選択なければならない状況が頻繁に発生します。これは、**ネットワーク上の残りのバリデータにとっても利益が低く、経済的に不合理**な行為です。 +**プロポーザー/ビルダーセパレーション(PBS)**の実装により、イーサリアムの検閲耐性が大幅に向上します。 PBSでは、ブロックの作成とイーサリアムネットワーク全体へのブロードキャストを別々のバリデータが担います。 これにより、利益を最大化している専門家のブロック構築アルゴリズムによる利益の偏りを防ぎ、ネットワーク全体でより公平な利益分配を実現します。また、時間の経過とともに、最もパフォーマンスの高い機関投資家に**ステークが集中化することを防ぐ**ことができます。 ブロック提案者は、ブロックビルダーの市場から提供されたブロックの中から、最も収益性の高いものを選択できます。 しかし、検閲を行うためには、収益性の低いブロックを選択なければならない状況が頻繁に発生します。これは、**ネットワーク上の残りのバリデータにとっても利益が低く、経済的に不合理**な行為です。 イーサリアムの検閲耐性をさらに向上させるために、暗号化されたトランザクションや包含リストなどのアドオンが検討されています。 これらのアドオンを使うと、ブロックの構築者や提案者は、ブロックに含まれる実際のトランザクションを把握できなくなります。 @@ -39,10 +39,10 @@ template: roadmap ## バリデータの保護 {#protecting-validators} -高度な攻撃者は、次に担当するバリデータを特定して、ブロックの提案を阻止するためにスパムを送信してくる可能性があります。これは**サービス拒否(DoS)攻撃**と呼ばれるものです。 [**シークレットリーダー選出(SLE)**](/roadmap/secret-leader-election)が実装されれば、ブロック提案者を事前に知ることができなくなるため、このタイプの攻撃から保護することができます。 SLE は、候補のブロック提案者を表す暗号コミットメントのセットを、継続的にシャッフルして順番を決め、その順番でバリデータを選択します。この方法により、バリデータは自分の順番を事前に知ることができます。 +高度な攻撃者は、次に担当するバリデータを特定して、ブロックの提案を阻止するためにスパムを送信してくる可能性があります。これは**サービス拒否(DoS)攻撃**と呼ばれるものです。 [**シークレットリーダー選出(SLE)**](/roadmap/secret-leader-election)が実装されれば、ブロック提案者を事前に知ることができなくなるため、このタイプの攻撃から保護することができます。 SLEは、候補のブロック提案者を表す暗号コミットメントのセットを、継続的にシャッフルして順番を決め、その順番でバリデータを選択します。この方法により、バリデータは自分の順番を事前に知ることができます。 シークレットリーダー選出の詳細 ## 現在の進行状況 {#current-progress} -ロードマップ上のセキュリティアップグレードの研究は進んでいますが、実装にはまだ時間がかかりそうです。 ビューマージ、PBS、SSF、SLE における次のステップは、仕様を決定し、プロトタイプの構築を開始することです。 +ロードマップ上のセキュリティアップグレードの研究は進んでいますが、実装にはまだ時間がかかりそうです。 ビューマージ、PBS、SSF、SLEにおける次のステップは、仕様を決定し、プロトタイプの構築を開始することです。 diff --git a/public/content/translations/ja/roadmap/single-slot-finality/index.md b/public/content/translations/ja/roadmap/single-slot-finality/index.md index ba528957ef4..add46d2a795 100644 --- a/public/content/translations/ja/roadmap/single-slot-finality/index.md +++ b/public/content/translations/ja/roadmap/single-slot-finality/index.md @@ -6,61 +6,61 @@ lang: ja # シングルスロット・ファイナリティ {#single-slot-finality} -イーサリアムのブロックが確定するまで、約 15 分かかります。 しかし、イーサリアムのコンセンサスメカニズムでブロックをより効率的に検証することで、ファイナリティまでの時間を大幅に短縮することができます。 15 分間待つ必要はなく、同じスロット内でブロックが提案され、確定することができます。 このコンセプトは、**シングルスロット・ファイナリティ(SSF)**と呼ばれます。 +イーサリアムのブロックが確定するまで、約15分かかります。 しかし、イーサリアムのコンセンサスメカニズムでブロックをより効率的に検証することで、ファイナリティまでの時間を大幅に短縮することができます。 15分間待つ必要はなく、同じスロット内でブロックが提案され、確定することができます。 このコンセプトは、**シングルスロット・ファイナリティ(SSF)**と呼ばれます。 ## ファイナリティとは {#what-is-finality} -ファイナリティとは、イーサリアムの新しいコンセンサスメカニズムであるプルーフ・オブ・ステークにおいて、ステークされた ETH 全体の少なくとも 33%をバーンしない限り、ブロックを変更したり、ブロックチェーンから削除したりできないことを保証する仕組みです。 これは、「暗号経済」を利用したセキュリティです。チェーンの順序や内容を変更する際に非常に高いコストがかかるため、合理的な経済主体がチェーンを変更しようとする試みを防ぐことができます。 +ファイナリティとは、イーサリアムの新しいコンセンサスメカニズムであるプルーフ・オブ・ステークにおいて、ステークされたETH全体の少なくとも33%をバーンしない限り、ブロックを変更したり、ブロックチェーンから削除したりできないことを保証する仕組みです。 これは、「暗号経済」を利用したセキュリティです。チェーンの順序や内容を変更する際に非常に高いコストがかかるため、合理的な経済主体がチェーンを変更しようとする試みを防ぐことができます。 ## ファイナリティを短縮する理由 {#why-aim-for-quicker-finality} -現在のファイナリティに至るまでの時間は、長すぎることが判明しています。 ほとんどのユーザーは、ファイナリティに至るまで 15 分待つことも嫌がります。高いトランザクションスループットを必要とするアプリや取引所でも、トランザクションが永続的になったことを確認するために、長い間待たなければならなりません。 ブロックの提案とファイナリティの間に遅延があると、攻撃者が特定のブロックを検閲したり、MEV を抽出したりするなど、ショートレンジの再編成の機会が生じてしまいます。 ブロックを段階的にアップグレードするメカニズムも非常に複雑で、セキュリティの脆弱性を解消するために何度もパッチが当てられており、イーサリアムのコードベースの中でちょっとしたバグが入りやすい部分の 1 つです。 これらの問題は、ファイナリティに至るまでの時間を単一のスロットに短縮することで、すべて解決できます。 +現在のファイナリティに至るまでの時間は、長すぎることが判明しています。 ほとんどのユーザーは、ファイナリティに至るまで15分待つことも嫌がります。高いトランザクションスループットを必要とするアプリや取引所でも、トランザクションが永続的になったことを確認するために、長い間待たなければならなりません。 ブロックの提案とファイナリティの間に遅延があると、攻撃者が特定のブロックを検閲したり、MEVを抽出したりするなど、ショートレンジの再編成の機会が生じてしまいます。 ブロックを段階的にアップグレードするメカニズムも非常に複雑で、セキュリティの脆弱性を解消するために何度もパッチが当てられており、イーサリアムのコードベースの中でちょっとしたバグが入りやすい部分の1つです。 これらの問題は、ファイナリティに至るまでの時間を単一のスロットに短縮することで、すべて解決できます。 ## 分散化・時間・オーバーヘッドのトレードオフ {#the-decentralization-time-overhead-tradeoff} -ファイナリティ保証は、新しいブロックの即時のプロパティではありません。 新しいブロックがファイナライズされるまでには時間がかかります。 時間がかかる理由は、ネットワーク上でステーキングされた ETH の合計の 3 分の 2 以上に相当するバリデータが、ブロックをファイナライズするために投票(「証明」)する必要があるからです。 ネットワーク上の各バリデータノードは、他のノードから送られるアテステーションを処理して、ブロックが 3 分の 2 のしきい値に達したかどうかを確認する必要があります。 +ファイナリティ保証は、新しいブロックの即時のプロパティではありません。 新しいブロックがファイナライズされるまでには時間がかかります。 時間がかかる理由は、ネットワーク上でステーキングされたETHの合計の3分の2以上に相当するバリデータが、ブロックをファイナライズするために投票(「証明」)する必要があるからです。 ネットワーク上の各バリデータノードは、他のノードから送られるアテステーションを処理して、ブロックが3分の2のしきい値に達したかどうかを確認する必要があります。 ファイナライズに達するまでの時間が短くなるほど、アテステーションの処理を速く実行する必要があるため、各ノードでより高いコンピューティングパワーが必要になります。 また、ネットワーク上のバリデータノードの数が増えるほど、各ブロックごとに処理するアテステーションが増えるため、必要な処理能力も増加します。 より高い処理能力が必要になると、バリデータノードを実行するために必要なハードウェアの費用が高くなるため、参加できる人が減ってしまいます。 一方、ブロックの間隔を長くすると、各ノードで必要なコンピューティングパワーは減りますが、アテステーションの処理が遅くなるため、ファイナリティに至るまでの時間が長くなります。 -したがって、オーバーヘッド(コンピューティングパワー)、分散化(チェーンの検証に参加できるノードの数)、ファイナリティまでの時間の間にトレードオフがあります。 理想的なシステムでは、最小のコンピューティングパワー、最大の分散化、ファイナリティに達する最短の時間というように、3 つのパラメータを最適なバランスで実現することが重要です。 +したがって、オーバーヘッド(コンピューティングパワー)、分散化(チェーンの検証に参加できるノードの数)、ファイナリティまでの時間の間にトレードオフがあります。 理想的なシステムでは、最小のコンピューティングパワー、最大の分散化、ファイナリティに達する最短の時間というように、3つのパラメータを最適なバランスで実現することが重要です。 -イーサリアムの現在のコンセンサスメカニズムでは、次のように、これら 3 つのパラメータのバランスを取っています。 +イーサリアムの現在のコンセンサスメカニズムでは、次のように、これら3つのパラメータのバランスを取っています。 -- **最小ステークを 32ETH に設定。** これにより、個々のノードが処理する必要があるバリデータのアテステーションの上限数が設定されます。よって、各ノードの計算要件の上限も設定されます。 -- **ファイナリティまでの時間を約 15 分に設定。** これにより、一般的な家庭用コンピュータで実行されるバリデータが各ブロックのアテステーションを安全に処理するのに十分な時間が与えられます。 +- **最小ステークを32ETHに設定。** これにより、個々のノードが処理する必要があるバリデータのアテステーションの上限数が設定されます。よって、各ノードの計算要件の上限も設定されます。 +- **ファイナリティまでの時間を約15分に設定。** これにより、一般的な家庭用コンピュータで実行されるバリデータが各ブロックのアテステーションを安全に処理するのに十分な時間が与えられます。 -現在の仕組みでは、ファイナリティまでの時間を短くするには、ネットワーク上のバリデータの数を減らすか、各ノードのハードウェア要件を増やす必要があります。 ただし、各ノードのオーバーヘッドを増加させることなく、より多くのアテステーションをカウントできるように処理方法を改善することができます。 これにより、2 つのエポックにまたがることなく、単一スロット内でファイナリティを決定できるようになります。 +現在の仕組みでは、ファイナリティまでの時間を短くするには、ネットワーク上のバリデータの数を減らすか、各ノードのハードウェア要件を増やす必要があります。 ただし、各ノードのオーバーヘッドを増加させることなく、より多くのアテステーションをカウントできるように処理方法を改善することができます。 これにより、2つのエポックにまたがることなく、単一スロット内でファイナリティを決定できるようになります。 -## SSF への道筋 {#routes-to-ssf} +## SSFへの道筋 {#routes-to-ssf} -現在のコンセンサスメカニズムでは、委員会と呼ばれているものが複数のバリデータからのアテステーションをまとめて、ブロックを検証するために各バリデータが処理しなければならないメッセージの数を減らしています。 各バリデータは、各エポック(32 スロット)で証明する機会がありますが、各スロットでは、バリデータのサブセットのみが証明を行います。このサブセットを「委員会」と呼びます。 委員会は、複数のバリデータが「アグリゲータ」として選択され、サブネットに分割されることによって選ばれます。 これらのアグリゲータはそれぞれ、サブネット内の他のバリデータから受け取ったすべての署名を、1 つの集約された署名にまとめます。 個々のコントリビューションを最も多いアグリゲータが、その集約された署名をブロック提案者に渡します。ブロック提案者は、その署名を、他の委員会から受け取った集約された署名とともに、ブロックにまとめます。 +現在のコンセンサスメカニズムでは、委員会と呼ばれているものが複数のバリデータからのアテステーションをまとめて、ブロックを検証するために各バリデータが処理しなければならないメッセージの数を減らしています。 各バリデータは、各エポック(32スロット)で証明する機会がありますが、各スロットでは、バリデータのサブセットのみが証明を行います。このサブセットを「委員会」と呼びます。 委員会は、複数のバリデータが「アグリゲータ」として選択され、サブネットに分割されることによって選ばれます。 これらのアグリゲータはそれぞれ、サブネット内の他のバリデータから受け取ったすべての署名を、1つの集約された署名にまとめます。 個々のコントリビューションを最も多いアグリゲータが、その集約された署名をブロック提案者に渡します。ブロック提案者は、その署名を、他の委員会から受け取った集約された署名とともに、ブロックにまとめます。 -このプロセスでは、「32 スロット × 64 の委員会 × 委員会あたり 256 のバリデータ = エポックあたり 524,288 のバリデータ」となり、各バリデータが各エポックで投票する十分な容量を提供します。 執筆時点(2023 年 2 月)では、約 513,000 ものバリデータが存在しています。 +このプロセスでは、「32スロット × 64の委員会 × 委員会あたり256のバリデータ = エポックあたり524,288のバリデータ」となり、各バリデータが各エポックで投票する十分な容量を提供します。 執筆時点(2023年2月)では、約513,000ものバリデータが存在しています。 このスキームにおいて、ブロックに投票するには、すべてのバリデータがエポック全体でアテステーションを分配する必要があります。 しかしながら、各バリデータが各スロットで証明できるように、このメカニズムを改善する実現可能な方法があります。 -イーサリアムのコンセンサスメカニズムが設計された当初、署名集約スキーム(BLS)のスケーラビリティは懸念されていましたが、その後の研究により、BLS は当初考えられていたよりもはるかにスケーラブルであることがわかりました。また、クライアントにおける署名の処理および検証の処理能力も向上したことで、 バリデータから送られる膨大な数のアテステーションの処理が、現実的に 1 つのスロット内で可能になりました。 例えば、100 万のバリデータが各スロットで 2 回投票し、スロットの時間を 16 秒に調節している場合、スロットあたり 100 万のアテステーションを処理するためには、ノードは 1 秒に最低 125,000 もの集約に対して署名を検証する必要があります。 実際には、一般的なコンピュータが 1 つの署名を検証するのに約 500 ナノ秒かかるので、125,000 の署名の検証は約 62.5 ミリ秒で完了します。これは、1 秒のしきい値をはるかに下回っています。 +イーサリアムのコンセンサスメカニズムが設計された当初、署名集約スキーム(BLS)のスケーラビリティは懸念されていましたが、その後の研究により、BLSは当初考えられていたよりもはるかにスケーラブルであることがわかりました。また、クライアントにおける署名の処理および検証の処理能力も向上したことで、 バリデータから送られる膨大な数のアテステーションの処理が、現実的に1つのスロット内で可能になりました。 例えば、100万のバリデータが各スロットで2回投票し、スロットの時間を16秒に調節している場合、スロットあたり100万のアテステーションを処理するためには、ノードは1秒に最低125,000もの集約に対して署名を検証する必要があります。 実際には、一般的なコンピュータが1つの署名を検証するのに約500ナノ秒かかるので、125,000の署名の検証は約62.5ミリ秒で完了します。これは、1秒のしきい値をはるかに下回っています。 -スーパー委員会を設けることで、効率性がさらに向上する可能性があります。具体的には、125,000 ものバリデータをスロットごとにランダムに選択するなどです。 このバリデータのサブセットのみがブロックに対して投票できるため、ブロックがファイナライズされるかどうかを決定できるのです。 このアイデアが受け入れられるかどうかは、イーサリアムへの攻撃の成功に必要なコストを、コミュニティがどの程度高く設定するかにかかっています。 現在の仕様では、ステーキングされた総イーサの 3 分の 2 が必要ですが、このアイデアでは、*スーパー委員会*内でステーキングされたイーサの 3 分の 2 を使って不正なブロックをファイナライズさせる可能性があるためです。 これはまだ研究中の分野ですが、そもそもスーパー委員会を必要とするほどの大きなバリデータセットの場合、そのサブ委員会のいずれかを攻撃するコストが非常に高くなると考えられます(例: ETH 建ての攻撃コストは、`2/3 * 125,000 * 32 = ~2.6 million ETH`になります)。 攻撃のコストは、バリデータセットのサイズを増やすことで調整可能です(例: 攻撃のコストを 100 万 ETH、400 万 ETH、1000 万 ETH などにするために、バリデータのサイズを調整する等) 。 コミュニティの[事前調査](https://youtu.be/ojBgyFl6-v4?t=755)によると、100 万から 200 万イーサが許容可能な攻撃コストです。この場合、スーパー委員会ごとのバリデータ数は、約 65,536 ~ 97,152 になります。 +スーパー委員会を設けることで、効率性がさらに向上する可能性があります。具体的には、125,000ものバリデータをスロットごとにランダムに選択するなどです。 このバリデータのサブセットのみがブロックに対して投票できるため、ブロックがファイナライズされるかどうかを決定できるのです。 このアイデアが受け入れられるかどうかは、イーサリアムへの攻撃の成功に必要なコストを、コミュニティがどの程度高く設定するかにかかっています。 現在の仕様では、ステーキングされた総イーサの3分の2が必要ですが、このアイデアでは、_スーパー委員会_内でステーキングされたイーサの3分の2を使って不正なブロックをファイナライズさせる可能性があるためです。 これはまだ研究中の分野ですが、そもそもスーパー委員会を必要とするほどの大きなバリデータセットの場合、そのサブ委員会のいずれかを攻撃するコストが非常に高くなると考えられます(例: ETH建ての攻撃コストは、`2/3 * 125,000 * 32 = ~2.6 million ETH`になります)。 攻撃のコストは、バリデータセットのサイズを増やすことで調整可能です(例: 攻撃のコストを100万ETH、400万ETH、1000万ETHなどにするために、バリデータのサイズを調整する等) 。 コミュニティの[事前調査](https://youtu.be/ojBgyFl6-v4?t=755)によると、100万から200万イーサが許容可能な攻撃コストです。この場合、スーパー委員会ごとのバリデータ数は、約65,536~97,152になります。 -しかし、検証自体はボトルネックではありません。バリデータノードにとって実際に問題となるのは、署名の集約です。 署名の集約をスケールするには、各サブネットのバリデータの数を増やす、サブネットの数を増やす、集約レイヤーを追加する(つまり、委員会の委員会を実装する)などの方法が考えられます。 解決策の 1 つとして、専門のアグリゲーターを許可する方法があります。これは、プロポーザー/ビルダーセパレーション(PBS)とダンクシャーディングの環境下で、ブロック構築とロールアップデータのコミットメント生成を専門のブロックビルダーにアウトソーシングするのと似た方法です。 +しかし、検証自体はボトルネックではありません。バリデータノードにとって実際に問題となるのは、署名の集約です。 署名の集約をスケールするには、各サブネットのバリデータの数を増やす、サブネットの数を増やす、集約レイヤーを追加する(つまり、委員会の委員会を実装する)などの方法が考えられます。 解決策の1つとして、専門のアグリゲーターを許可する方法があります。これは、プロポーザー/ビルダーセパレーション(PBS)とダンクシャーディングの環境下で、ブロック構築とロールアップデータのコミットメント生成を専門のブロックビルダーにアウトソーシングするのと似た方法です。 -## SSF におけるフォーク選択ルールの役割 {#role-of-the-fork-choice-rule} +## SSFにおけるフォーク選択ルールの役割 {#role-of-the-fork-choice-rule} -現在のコンセンサスメカニズムでは、ファイナリティガジェット(バリデータの 3 分の 2 がチェーンを証明したかどうかを判断するアルゴリズム)とフォーク選択ルール(複数のチェーンが存在する場合に、どのチェーンが正しいかを判断するアルゴリズム)が密接に連携して動作しています。 フォーク選択アルゴリズムでは、 最後にファイナライズしたブロック*以降*のブロックのみが対象と見なされます。 SSF では、ブロックが提案されると同時に、そのスロットのファイナリティが発生します。そのため、フォーク選択ルールが適用されるブロックがありません。 つまり、SSF では、フォーク選択アルゴリズム*または*ファイナリティガジェットの*いずれか*が常に有効です。 ファイナリティガジェットは、3 分の 2 のバリデータがオンラインで、ブロックが正しいことが証明された場合に、そのブロックを確定します。 ブロックが 3 分の 2 のしきい値を超えることができない場合は、フォーク選択ルールが作動して、どのチェーンに従うかを決定します。 多少のニュアンスが追加されるものの、バリデータの 3 分の 1 以上がオフラインになった場合でも、チェーンを回復する非アクティブリークメカニズムを維持する機会も生まれます。 +現在のコンセンサスメカニズムでは、ファイナリティガジェット(バリデータの3分の2がチェーンを証明したかどうかを判断するアルゴリズム)とフォーク選択ルール(複数のチェーンが存在する場合に、どのチェーンが正しいかを判断するアルゴリズム)が密接に連携して動作しています。 フォーク選択アルゴリズムでは、 最後にファイナライズしたブロック_以降_のブロックのみが対象と見なされます。 SSFでは、ブロックが提案されると同時に、そのスロットのファイナリティが発生します。そのため、フォーク選択ルールが適用されるブロックがありません。 つまり、SSFでは、フォーク選択アルゴリズム_または_ファイナリティガジェットの_いずれか_が常に有効です。 ファイナリティガジェットは、3分の2のバリデータがオンラインで、ブロックが正しいことが証明された場合に、そのブロックを確定します。 ブロックが3分の2のしきい値を超えることができない場合は、フォーク選択ルールが作動して、どのチェーンに従うかを決定します。 多少のニュアンスが追加されるものの、バリデータの3分の1以上がオフラインになった場合でも、チェーンを回復する非アクティブリークメカニズムを維持する機会も生まれます。 ## 未解決の問題 {#outstanding-issues} -サブネットごとのバリデータ数を増やすことで集約をスケーリングする際の問題は、ピアツーピアネットワークの負荷が増大することです。 また、集約レイヤーを追加すると、エンジニアリングが非常に複雑になり、レイテンシーが増加します(つまり、ブロック提案者が全てのサブネットアグリゲーターからのメッセージを受信するまでに時間がかかる可能性があります)。 BLS 署名集約を使用しても、ネットワーク上にアクティブなバリデータが多数存在する場合、各スロット内で処理できる数を超えてしまう可能性があります。その場合の対応方法は明らかになっていません。 1 つの解決策として考えられるのは、全バリデータが各スロットで証明を行い、SSF において委員会を廃止し、有効残高の 32ETH 上限を撤廃することです。つまり、複数のバリデータを管理するオペレータは、ステークを統合して実行回数を減らし、バリデータノードはバリデータセット全体を構成することで処理するメッセージの数を減らすことができます。 大規模なステーカーがバリデータを統合することに同意することで、この問題は解決します。 また、バリデータの数やステーキングされた ETH の量に一定の上限を設けることも可能ですが、 その場合は、参加を許可するバリデータを選ぶ何らかのメカニズムが必要になるため、望ましくない二次的な影響が生じる可能性があります。 +サブネットごとのバリデータ数を増やすことで集約をスケーリングする際の問題は、ピアツーピアネットワークの負荷が増大することです。 また、集約レイヤーを追加すると、エンジニアリングが非常に複雑になり、レイテンシーが増加します(つまり、ブロック提案者が全てのサブネットアグリゲーターからのメッセージを受信するまでに時間がかかる可能性があります)。 BLS署名集約を使用しても、ネットワーク上にアクティブなバリデータが多数存在する場合、各スロット内で処理できる数を超えてしまう可能性があります。その場合の対応方法は明らかになっていません。 1つの解決策として考えられるのは、全バリデータが各スロットで証明を行い、SSFにおいて委員会を廃止し、有効残高の32ETH上限を撤廃することです。つまり、複数のバリデータを管理するオペレータは、ステークを統合して実行回数を減らし、バリデータノードはバリデータセット全体を構成することで処理するメッセージの数を減らすことができます。 大規模なステーカーがバリデータを統合することに同意することで、この問題は解決します。 また、バリデータの数やステーキングされたETHの量に一定の上限を設けることも可能ですが、 その場合は、参加を許可するバリデータを選ぶ何らかのメカニズムが必要になるため、望ましくない二次的な影響が生じる可能性があります。 ## 現在の進行状況 {#current-progress} -SSF はまだ研究段階です。 [バークルツリー](/roadmap/verkle-trees/)や[ダンクシャーディング](/roadmap/danksharding])などの他の大きなアップグレードが完了してから、数年後になるかもしれません。 +SSFはまだ研究段階です。 [バークルツリー](/roadmap/verkle-trees/)や[ダンクシャーディング](/roadmap/danksharding])などの他の大きなアップグレードが完了してから、数年後になるかもしれません。 ## 参考文献 {#further-reading} -- [ヴィタリックによる EDCON 2022 での SSF の説明](https://www.youtube.com/watch?v=nPgUKNPWXNI) +- [ヴィタリックによるEDCON 2022でのSSFの説明](https://www.youtube.com/watch?v=nPgUKNPWXNI) - [ヴィタリックのノート: シングルスロット・ファイナリティへの道](https://notes.ethereum.org/@vbuterin/single_slot_finality) diff --git a/public/content/translations/ja/roadmap/statelessness/index.md b/public/content/translations/ja/roadmap/statelessness/index.md index 182b724204a..d95b07803fc 100644 --- a/public/content/translations/ja/roadmap/statelessness/index.md +++ b/public/content/translations/ja/roadmap/statelessness/index.md @@ -8,7 +8,7 @@ lang: ja 真に分散化するためには、一般的なハードウェアでイーサリアムノードを実行できることが重要です。 なぜなら、ユーザーがノードを実行することで、サードパーティにデータを供給してもらうのではなく、自身で暗号チェックを行って情報を検証できるからです。 また、ノードを実行することで、仲介者を介することなく、イーサリアムのピアツーピアネットワークに直接トランザクションを送信できます。 これらの利点を享受できるのが高価なハードウェアを使用するユーザーだけだと、分散化は実現できません。 そのため、ノードは、携帯電話やマイクロコンピュータ、家庭用コンピュータでも問題なく動作できるように、処理要件やメモリ要件を極力抑えて実行する必要があります。 -現在のイーサリアムでは、ノードへのユニバーサルアクセスを妨げている主な障壁は、高いディスク容量要件です。 これは主に、イーサリアムの状態データの大部分を保存する必要があることに起因しています。 状態データには、新しいブロックとトランザクションを正しく処理するために必要となる重要な情報が含まれています。 この記事の執筆時点では、イーサリアムのフルノードを実行するには、2TB の高速 SSD が推奨されています。 古いデータをプルーニングしないノードの場合、ストレージ容量は週に約 14GB ずつ増加していきます。誕生以降のすべてのデータを保存するアーカイブノードでは、現在 12TB 近くの容量が必要です(この記事は 2023 年 2 月に執筆されました)。 +現在のイーサリアムでは、ノードへのユニバーサルアクセスを妨げている主な障壁は、高いディスク容量要件です。 これは主に、イーサリアムの状態データの大部分を保存する必要があることに起因しています。 状態データには、新しいブロックとトランザクションを正しく処理するために必要となる重要な情報が含まれています。 この記事の執筆時点では、イーサリアムのフルノードを実行するには、2TBの高速SSDが推奨されています。 古いデータをプルーニングしないノードの場合、ストレージ容量は週に約14GBずつ増加していきます。誕生以降のすべてのデータを保存するアーカイブノードでは、現在12TB近くの容量が必要です(この記事は2023年2月に執筆されました)。 古いデータは安価なハードドライブで保存できますが、新しいこれから受信するブロックを処理するには遅すぎます。 イーサリアムの状態は「無限」に増えるため、現在のクライアントのストレージ設計を維持したまま、データをより安価で保存できるようにしても、問題の根本的な解決にはなりません。つまり、ストレージ要件は今後も増加する可能性があり、技術的な改善は常に求められます。また、状態の肥大化に追いつくためにも、継続的な努力が必要です。 そのため、クライアントは、ローカルデータベースによるデータの検索に依存しない、ブロックとトランザクションを検証する新しい方法を見つける必要があります。 @@ -16,7 +16,7 @@ lang: ja 各ノードが保存する必要があるデータ量を削減するには、以下の方法があります。それぞれ異なる範囲でイーサリアムのコアプロトコルを更新する必要があります。 -- **履歴の有効期限**: イーサリアムクライアントの状態データを処理する方法自体は変更しませんが、ノードが X ブロックよりも古い状態データを破棄できるようにします。 +- **履歴の有効期限**: イーサリアムクライアントの状態データを処理する方法自体は変更しませんが、ノードがXブロックよりも古い状態データを破棄できるようにします。 - **状態の有効期限**: 頻繁に使用されない状態データを非アクティブにすることができます。 非アクティブなデータは、復元されない限りクライアントによって無視されます。 - **弱いステートレス**: ブロック作成者のみが、すべての状態データにアクセスする必要があり、他のノードはローカル状態データベースがなくても、ブロックを検証できます。 - **強いステートレス**: すべての状態データにアクセスするノードが不要になります。 @@ -25,13 +25,13 @@ lang: ja ### 履歴の有効期限 {#history-expiry} -履歴の有効期限とは、クライアントが必要性の低い古いデータを削除することです。少量の履歴データは少量しか保存しないため、新しいデータが到着すると古いデータを削除します。 クライアントが履歴データを必要とする理由は、2 つあります。1 つはデータの同期、もう 1 つはデータのリクエストの処理です。 もともとクライアントでは、始まりのブロックから同期することで、連続する各ブロックがチェーンの先頭に至るまで正しく追加されていることを検証する必要がありました。 しかし、現在のクライアントでは、「弱い主観性チェックポイント」と呼ばれる方法を使って、チェーンの先頭にたどり着くまでの時間を短縮しています。 これらのチェックポイントは、イーサリアムの始まりではなく、現在に近い始まりのブロックを基準にしているため、信頼できる開始点となります。 つまり、最新の弱い主観性チェックポイントより前のすべての情報は、 クライアントがチェーンの先頭へ同期する機能に影響を与えることなく削除できるということです。 現在のクライアントは、ローカルデータベースから履歴データを取得することで、(JSON-RPC 経由で届く)履歴データのリクエストを処理しています。 ただし、履歴の有効期限が切れると、リクエストされたデータが削除されている場合は、履歴データを取得できません。 この履歴データを提供するには、いくつかの革新的なソリューションが必要です。 +履歴の有効期限とは、クライアントが必要性の低い古いデータを削除することです。少量の履歴データは少量しか保存しないため、新しいデータが到着すると古いデータを削除します。 クライアントが履歴データを必要とする理由は、2つあります。1つはデータの同期、もう1つはデータのリクエストの処理です。 もともとクライアントでは、始まりのブロックから同期することで、連続する各ブロックがチェーンの先頭に至るまで正しく追加されていることを検証する必要がありました。 しかし、現在のクライアントでは、「弱い主観性チェックポイント」と呼ばれる方法を使って、チェーンの先頭にたどり着くまでの時間を短縮しています。 これらのチェックポイントは、イーサリアムの始まりではなく、現在に近い始まりのブロックを基準にしているため、信頼できる開始点となります。 つまり、最新の弱い主観性チェックポイントより前のすべての情報は、 クライアントがチェーンの先頭へ同期する機能に影響を与えることなく削除できるということです。 現在のクライアントは、ローカルデータベースから履歴データを取得することで、(JSON-RPC経由で届く)履歴データのリクエストを処理しています。 ただし、履歴の有効期限が切れると、リクエストされたデータが削除されている場合は、履歴データを取得できません。 この履歴データを提供するには、いくつかの革新的なソリューションが必要です。 -履歴データを取得する方法の 1 つは、クライアントがポータルネットワークなどのソリューションを介して、ピアから履歴データをリクエストすることです。 ポータルネットワークは、まだ開発中ではありますが、履歴データを提供するピアツーピアネットワークです。各ノードは、イーサリアムの履歴の一部を保存し、履歴全体がネットワーク全体に分散されるようにします。 履歴データのリクエストは、関連するデータを保存しているピアを探し出し、そのピアからデータを取得することで処理されます。 また、履歴データへのアクセスを必要とするのは、通常アプリであるため、アプリがデータを保存する役割を担うかもしれません。 イーサリアム空間には、履歴のアーカイブを維持したいという利他的なアクターが十分に存在する可能性があります。 履歴データストレージを管理するための DAO が立ち上がる可能性もあります。あるいは、これらすべての選択肢を組み合わせた理想的な方法があるかもしれません。 これらのプロバイダは、トレント、FTP、Filecoin、IPFS など、様々な方法でデータを提供することが考えられます。 +履歴データを取得する方法の1つは、クライアントがポータルネットワークなどのソリューションを介して、ピアから履歴データをリクエストすることです。 ポータルネットワークは、まだ開発中ではありますが、履歴データを提供するピアツーピアネットワークです。各ノードは、イーサリアムの履歴の一部を保存し、履歴全体がネットワーク全体に分散されるようにします。 履歴データのリクエストは、関連するデータを保存しているピアを探し出し、そのピアからデータを取得することで処理されます。 また、履歴データへのアクセスを必要とするのは、通常アプリであるため、アプリがデータを保存する役割を担うかもしれません。 イーサリアム空間には、履歴のアーカイブを維持したいという利他的なアクターが十分に存在する可能性があります。 履歴データストレージを管理するためのDAOが立ち上がる可能性もあります。あるいは、これらすべての選択肢を組み合わせた理想的な方法があるかもしれません。 これらのプロバイダは、トレント、FTP、Filecoin、IPFSなど、様々な方法でデータを提供することが考えられます。 履歴の有効期限を実装することについては、多少の議論があります。イーサリアムはこれまで、履歴データが常に利用可能であることを暗黙的に保証してきました。 そのため、誕生からのフル同期は、過去のデータの再構築にスナップショットを利用する場合でも、標準として常に可能になっています。 履歴の有効期限があることで、イーサリアムコアプロトコルは履歴データの保証責任を放棄します。 こうして、過去データを提供するのが中央集権的な組織になってしまうと、新たな検閲リスクが生じる可能性があります。 -EIP-4444 は、現在も活発な議論が行われており、まだリリースする準備はできていません。 EIP-4444 の課題は、技術的なものではなく、そのほとんどがコミュニティ管理に関するものであることが興味深い点です。 この機能をリリースするには、単なる合意だけでなく、信頼できるエンティティによる履歴データの保存および提供の約束を含めたコミュニティの賛同が必要になります。 +EIP-4444は、現在も活発な議論が行われており、まだリリースする準備はできていません。 EIP-4444の課題は、技術的なものではなく、そのほとんどがコミュニティ管理に関するものであることが興味深い点です。 この機能をリリースするには、単なる合意だけでなく、信頼できるエンティティによる履歴データの保存および提供の約束を含めたコミュニティの賛同が必要になります。 このアップグレードは、イーサリアムノードにおける状態データの扱いを大きく変えるものではありません。あくまでも、履歴データへのアクセス方法を変更するだけです。 @@ -44,7 +44,7 @@ EIP-4444 は、現在も活発な議論が行われており、まだリリー レンタル料による有効期限の場合、データベースをアクティブ状態に維持するためには、アカウントに直接貸し出すことが考えられます。 時間による有効期限の場合、最後のアカウント操作から有効期限をカウントダウンによるものか、すべてのアカウントの定期的な有効期限切れによるものか、いずれの可能性も考えられます また、時間ベースのモデルとレンタル料ベースのモデルの両方の要素を組み合わせたメカニズムも考えられます。例えば、各アカウントは、時間ベースの有効期限が切れる前に少額の料金を支払いをすることで、アクティブな状態を維持できる等です。 状態の有効期限が切れても、非アクティブな状態は**削除されない**ことに注意してください。アクティブな状態とは別に保存されます。 また、非アクティブな状態をアクティブに戻すこともできます。 -この機能を実現するには、約 1 年間の状態ツリーが必要です。 新たな期間が開始するたびに、新たな状態ツリーが作成されます。 現在の状態ツリーのみ変更でき、以前のものは変更できません。 イーサリアムノードでは、現在の状態ツリーと次の最新の状態ツリーのみを保持する予定です。 そのためには、アドレスにその存在期間をタイムスタンプする方法が必要になります。 [いくつかの方法](https://ethereum-magicians.org/t/types-of-resurrection-metadata-in-state-expiry/6607)が考えられますが、有力な方法としては、追加情報を格納できるように[アドレスを長くするよう](https://ethereum-magicians.org/t/increasing-address-size-from-20-to-32-bytes/5485)要求することです。これにより、アドレスが長くなるほど安全性が高まるという利点も追加されます。 このロードマップアイテムは、[アドレス空間拡張](https://ethereum-magicians.org/t/increasing-address-size-from-20-to-32-bytes/5485)と呼ばれます。 +この機能を実現するには、約1年間の状態ツリーが必要です。 新たな期間が開始するたびに、新たな状態ツリーが作成されます。 現在の状態ツリーのみ変更でき、以前のものは変更できません。 イーサリアムノードでは、現在の状態ツリーと次の最新の状態ツリーのみを保持する予定です。 そのためには、アドレスにその存在期間をタイムスタンプする方法が必要になります。 [いくつかの方法](https://ethereum-magicians.org/t/types-of-resurrection-metadata-in-state-expiry/6607)が考えられますが、有力な方法としては、追加情報を格納できるように[アドレスを長くするよう](https://ethereum-magicians.org/t/increasing-address-size-from-20-to-32-bytes/5485)要求することです。これにより、アドレスが長くなるほど安全性が高まるという利点も追加されます。 このロードマップアイテムは、[アドレス空間拡張](https://ethereum-magicians.org/t/increasing-address-size-from-20-to-32-bytes/5485)と呼ばれます。 履歴の有効期限と同様に、状態の有効期限では、ユーザーは古い状態データを自分で保存する必要がなくなります。代わりに、中央集権型のプロバイダー、利他的なコミュニティのメンバー、またはポータルネットワークなどのより革新的な分散型ソリューションなど、他のエンティティが保存の責任を担います。 @@ -52,7 +52,7 @@ EIP-4444 は、現在も活発な議論が行われており、まだリリー ## ステートレス {#statelessness} -「状態」の概念がなくなるわけではなく、イーサリアムノードが状態データを処理する方法が変更されるものであるため、ステートレスという名称は少し不適切かもしれません。 ステートレスには、弱いステートレスと強いステートレスの 2 種類があります。 弱いステートレスでは、状態ストレージの役割を少数のノードに負わせることで、ほとんどのノードをステートレスにすることができます。 強いステートレスでは、すべてのノードが完全な状態データを保存する必要がなくなります。 弱いステートレスと強いステートレスのどちらも、通常のバリデータに次の利点をもたらします。 +「状態」の概念がなくなるわけではなく、イーサリアムノードが状態データを処理する方法が変更されるものであるため、ステートレスという名称は少し不適切かもしれません。 ステートレスには、弱いステートレスと強いステートレスの2種類があります。 弱いステートレスでは、状態ストレージの役割を少数のノードに負わせることで、ほとんどのノードをステートレスにすることができます。 強いステートレスでは、すべてのノードが完全な状態データを保存する必要がなくなります。 弱いステートレスと強いステートレスのどちらも、通常のバリデータに次の利点をもたらします。 - ほぼ瞬時に同期できる - ブロックを順不同で検証できる @@ -66,7 +66,7 @@ EIP-4444 は、現在も活発な議論が行われており、まだリリー **弱いステートレスでは、ブロックの提案には、完全な状態データへのアクセスが必要になりますが、ブロックの検証では状態データは不要です。** -これを実現するには、イーサリアムクライアントに[バークルツリー](/roadmap/verkle-trees)が実装されている必要があります。 バークルツリーは、イーサリアムの状態データを保存するための次世代のデータ構造です。ローカルデータベースでブロックを検証する代わりに、データに対して小さな固定サイズの「ウィットネス」をピア間で受け渡し、ブロックを検証します。 [プロポーザー/ビルダーセパレーション](/roadmap/pbs/)も必要です。これにより、ブロックビルダーは、完全な状態データへのアクセスが必要なため、より強力なハードウェアを備えた専門のノードになります。 +これを実現するには、イーサリアムクライアントに[バークルツリー](/roadmap/verkle-trees/)が実装されている必要があります。 バークルツリーは、イーサリアムの状態データを保存するための次世代のデータ構造です。ローカルデータベースでブロックを検証する代わりに、データに対して小さな固定サイズの「ウィットネス」をピア間で受け渡し、ブロックを検証します。 [プロポーザー/ビルダーセパレーション](/roadmap/pbs/)も必要です。これにより、ブロックビルダーは、完全な状態データへのアクセスが必要なため、より強力なハードウェアを備えた専門のノードになります。 @@ -81,7 +81,7 @@ EIP-4444 は、現在も活発な議論が行われており、まだリリー ### 強いステートレス {#strong-statelessness} -強いステートレスでは、ブロックに状態データを保存する必要がなくなります。 代わりに、集約されたウィットネスとともにトランザクションが送信されます。 ブロック生成者は、関連するアカウントのウィットネスを生成するために必要な状態のみを保存します。 状態に対する責任はほとんどユーザーが負い、ユーザーはどのアカウントとストレージ鍵とやり取りしているかを宣言するために、ウィットネスと「アクセスリスト」を送信します。 +強いステートレスでは、ブロックに状態データを保存する必要がなくなります。 代わりに、集約されたウィットネスとともにトランザクションが送信されます。 ブロック生成者は、関連するアカウントのウィットネスを生成するために必要な状態のみを保存します。 状態に対する責任はほとんどユーザーが負い、ユーザーはどのアカウントとストレージ鍵とやり取りしているかを宣言するために、ウィットネスと「アクセスリスト」を送信します。 これにより、ノードが非常に軽量になりますが、スマートコントラクトとのトランザクションがより困難になるなどのトレードオフがあります。 強いステートレスは、研究者によって調査されていますが、現時点では、イーサリアムのロードマップには含まれていません。イーサリアムのスケーリングには、弱いステートレスが十分に機能すると考えられているためです。 @@ -91,12 +91,12 @@ EIP-4444 は、現在も活発な議論が行われており、まだリリー ## 参考文献 {#further-reading} -- [ヴィタリックによるステートレスに関する AMA](https://www.reddit.com/r/ethereum/comments/o9s15i/impromptu_technical_ama_on_statelessness_and/) +- [ヴィタリックによるステートレスに関するAMA](https://www.reddit.com/r/ethereum/comments/o9s15i/impromptu_technical_ama_on_statelessness_and/) - [状態サイズの管理理論](https://hackmd.io/@vbuterin/state_size_management) - [Resurrection-conflict-minimized 状態境界](https://ethresear.ch/t/resurrection-conflict-minimized-state-bounding-take-2/8739) - [ステートレスと状態の有効期限への工程](https://hackmd.io/@vbuterin/state_expiry_paths) -- [EIP-4444 の仕様](https://eips.ethereum.org/EIPS/eip-4444) -- [アレックス・ストークス(Alex Stokes)EIP-4444 の概要を説明するビデオ](https://youtu.be/SfDC_qUZaos) +- [EIP-4444の仕様](https://eips.ethereum.org/EIPS/eip-4444) +- [アレックス・ストークス(Alex Stokes)EIP-4444の概要を説明するビデオ](https://youtu.be/SfDC_qUZaos) - [ステートレスにすることが重要な理由](https://dankradfeist.de/ethereum/2021/02/14/why-stateless.html) - [ステートレスクライアントのオリジナルコンセプトに関するノート](https://ethresear.ch/t/the-stateless-client-concept/172) - [状態の有効期限の詳細](https://hackmd.io/@vbuterin/state_size_management#A-more-moderate-solution-state-expiry) diff --git a/public/content/translations/ja/roadmap/user-experience/index.md b/public/content/translations/ja/roadmap/user-experience/index.md index de914192e35..e9cf4e03df0 100644 --- a/public/content/translations/ja/roadmap/user-experience/index.md +++ b/public/content/translations/ja/roadmap/user-experience/index.md @@ -7,11 +7,11 @@ alt: "イーサリアムロードマップ" template: roadmap --- -イーサリアムを簡単に使用するためには、鍵やウォレットの管理からトランザクションの開始まで、さまざまな手順が必要です。 一般への普及を促進するには、これらの手順を簡略化して、イーサリアムを大幅に使いやすくする必要があります。また、Web2 アプリのようなスムーズなユーザーエクスペリエンスを提供することで、パーミッションレスで検閲耐性のあるアクセスを体験できるようにしなければなりません。 +イーサリアムを簡単に使用するためには、鍵やウォレットの管理からトランザクションの開始まで、さまざまな手順が必要です。 一般への普及を促進するには、これらの手順を簡略化して、イーサリアムを大幅に使いやすくする必要があります。また、Web2アプリのようなスムーズなユーザーエクスペリエンスを提供することで、パーミッションレスで検閲耐性のあるアクセスを体験できるようにしなければなりません。 ## シードフレーズを超えて {#no-more-seed-phrases} -イーサリアムのアカウントは、 「公開鍵」でアカウントを特定し、「秘密鍵」でメッセージに署名します。この鍵のペアを利用して、イーサリアムのアカウントは保護されています。 秘密鍵は、マスターパスワードのようなものです。この鍵があれば、イーサリアムアカウントに完全にアクセスすることができます。 イーサリアムのアカウントの操作は、銀行や Web2 アプリのように、ユーザーに代わって口座を管理する仕組みとは異なるため、戸惑う人もいるでしょう。 集中化されているサードパーティに依存することなくイーサリアムを一般に普及させるには、ユーザーが公開鍵と秘密鍵による暗号化や鍵管理を理解しなくても、自分の資産を保管し、自分のデータを管理できる簡単でスムーズな方法が必要です。 +イーサリアムのアカウントは、 「公開鍵」でアカウントを特定し、「秘密鍵」でメッセージに署名します。この鍵のペアを利用して、イーサリアムのアカウントは保護されています。 秘密鍵は、マスターパスワードのようなものです。この鍵があれば、イーサリアムアカウントに完全にアクセスすることができます。 イーサリアムのアカウントの操作は、銀行やWeb2アプリのように、ユーザーに代わって口座を管理する仕組みとは異なるため、戸惑う人もいるでしょう。 集中化されているサードパーティに依存することなくイーサリアムを一般に普及させるには、ユーザーが公開鍵と秘密鍵による暗号化や鍵管理を理解しなくても、自分の資産を保管し、自分のデータを管理できる簡単でスムーズな方法が必要です。 これに対する解決策は、スマートコントラクトウォレットを使用してイーサリアムとやり取りすることです。 スマートコントラクトウォレットは、鍵の紛失や盗難に備えたアカウント保護、より優れた不正行為の検出や防御、新しい機能の追加など、さまざまなメリットをもたらします。 スマートコントラクトウォレットはすでに存在していますが、まだ使いにくいため、イーサリアムプロトコルがそれらをより便利に使えるようにサポートする必要があります。 この追加サポートは、アカウント抽象化と呼ばれています。 @@ -25,11 +25,11 @@ template: roadmap バークルツリーについての詳細 -これらのアップグレードにより、ノードの実行に対する障壁が事実上無くなります。 ユーザーは、コンピューターや携帯電話のディスク容量や CPU を気にせずに、イーサリアムに安全かつパーミッションレスにアクセスできるようになります。また、アプリを使用するときに、データやネットワークへのアクセスでサードパーティに依存する必要がなくなります。 +これらのアップグレードにより、ノードの実行に対する障壁が事実上無くなります。 ユーザーは、コンピューターや携帯電話のディスク容量やCPUを気にせずに、イーサリアムに安全かつパーミッションレスにアクセスできるようになります。また、アプリを使用するときに、データやネットワークへのアクセスでサードパーティに依存する必要がなくなります。 ## 現在の進行状況 {#current-progress} -スマートコントラクトウォレットはすでに利用可能ですが、それらをできるだけ分散化してパーミッションレスにするには、さらなるアップグレードが必要です。 EIP-4337 は、イーサリアムのプロトコルへを変更せずに導入できる成熟した提案です。 EIP-4337 で必要となる主要なスマートコントラクトは、2023 年 3 月にデプロイされました。 +スマートコントラクトウォレットはすでに利用可能ですが、それらをできるだけ分散化してパーミッションレスにするには、さらなるアップグレードが必要です。 EIP-4337は、イーサリアムのプロトコルへを変更せずに導入できる成熟した提案です。 EIP-4337で必要となる主要なスマートコントラクトは、2023年3月にデプロイされました。 完全なステートレスはまだ研究段階にあり、実装されるのは数年先になると考えられます。 データ有効期限を含む完全にステートレスになる工程には、いくつかのマイルストーンがあり、そのうちのいくつかは、近い将来に実装される可能性がありますが、 [バークルツリー](/roadmap/verkle-trees/)や[プロポーザー/ビルダーセパレーション](/roadmap/pbs/)などの他の工程が先に完了している必要があります。 diff --git a/public/content/translations/ja/roadmap/verkle-trees/index.md b/public/content/translations/ja/roadmap/verkle-trees/index.md index 906ba2033af..997a7471f16 100644 --- a/public/content/translations/ja/roadmap/verkle-trees/index.md +++ b/public/content/translations/ja/roadmap/verkle-trees/index.md @@ -13,33 +13,33 @@ summaryPoints: ## ステートレス {#statelessness} -バークルツリーは、ステートレスなイーサリアムクライアントの実現に欠かせない重要なステップです。 ステートレスクライアントは、受信したブロックを検証するために、状態データベース全体を格納する必要がありません。 クライアントがローカルに保存しているイーサリアムの状態のコピーを使用してブロックを検証する代わりに、ブロックに含まれる状態データの「ウィットネス」を使用します。 この「ウィットネス」は、特定の一連のトランザクションを実行するために必要な状態データの個々の部分を集めたもので、データ全体の一部であることを示す暗号学的証明になります。 このウィットネスを、状態データベースの*代わりに*使用します。 ネットワーク全体に安全にブロードキャストするには、バリデータが 12 秒のスロット内に処理できる必要があります。そのためには、ウィットネスが非常に小さくなければなりません。 しかし、現在の状態データの構造では、ウィットネスが大きすぎるため、適していません。 バークルツリーは、小さなウィットネスを可能にすることで、この問題を解決します。これにより、ステートレスクライアントを実現するための、1 つの大きな障害を克服することができます。 +バークルツリーは、ステートレスなイーサリアムクライアントの実現に欠かせない重要なステップです。 ステートレスクライアントは、受信したブロックを検証するために、状態データベース全体を格納する必要がありません。 クライアントがローカルに保存しているイーサリアムの状態のコピーを使用してブロックを検証する代わりに、ブロックに含まれる状態データの「ウィットネス」を使用します。 この「ウィットネス」は、特定の一連のトランザクションを実行するために必要な状態データの個々の部分を集めたもので、データ全体の一部であることを示す暗号学的証明になります。 このウィットネスを、状態データベースの_代わりに_使用します。 ネットワーク全体に安全にブロードキャストするには、バリデータが12秒のスロット内に処理できる必要があります。そのためには、ウィットネスが非常に小さくなければなりません。 しかし、現在の状態データの構造では、ウィットネスが大きすぎるため、適していません。 バークルツリーは、小さなウィットネスを可能にすることで、この問題を解決します。これにより、ステートレスクライアントを実現するための、1つの大きな障害を克服することができます。 -イーサリアムクライアントは現在、状態データを保存するためにパトリシア・マークル・ツリーと呼ばれるデータ構造を使用しています。 個々のアカウントに関する情報はツリー上のリーフとして保存され、そのリーフのペアが 1 つのハッシュになるまで繰り返しハッシュ化されます。 この最後のハッシュは、「ルート」と呼ばれます。 イーサリアムクライアントは、ブロック内のすべてのトランザクションを実行し、ローカルにある状態ツリーを更新することで、ブロックを検証します。 ローカルにあるツリーのルートが、ブロック提案者によって提供されたルートと同じであれば、ブロックは有効であると判断されます。なぜなら、ブロック提案者と検証ノードが異なる計算を実行した場合、ルートハッシュが完全に違うものになるためです。 問題は、ブロックチェーンを検証するために、各クライアントがブロックの先頭までの状態ツリー全体と複数の履歴ブロックを保持する必要があることです(Geth のデフォルト設定では、ヘッドから遡って 128 ブロックの状態データを保持します)。 現在の状態では、クライアントは大容量のディスク領域が必要になり、安価で低電力のハードウェアでフルノードを実行する際の障壁となります。 これに対する解決策は、より効率的な構造(バークルツリー)を持った状態ツリーを更新することです。バークルツリーでは、完全な状態データの代わりに、共有可能なデータである小さな「ウィットネス」を使うことで集約することができます。 状態データをバークルツリーに再フォーマットすることは、ステートレスクライアントへ移行するための足掛かりとなります。 +イーサリアムクライアントは現在、状態データを保存するためにパトリシア・マークル・ツリーと呼ばれるデータ構造を使用しています。 個々のアカウントに関する情報はツリー上のリーフとして保存され、そのリーフのペアが1つのハッシュになるまで繰り返しハッシュ化されます。 この最後のハッシュは、「ルート」と呼ばれます。 イーサリアムクライアントは、ブロック内のすべてのトランザクションを実行し、ローカルにある状態ツリーを更新することで、ブロックを検証します。 ローカルにあるツリーのルートが、ブロック提案者によって提供されたルートと同じであれば、ブロックは有効であると判断されます。なぜなら、ブロック提案者と検証ノードが異なる計算を実行した場合、ルートハッシュが完全に違うものになるためです。 問題は、ブロックチェーンを検証するために、各クライアントがブロックの先頭までの状態ツリー全体と複数の履歴ブロックを保持する必要があることです(Gethのデフォルト設定では、ヘッドから遡って128ブロックの状態データを保持します)。 現在の状態では、クライアントは大容量のディスク領域が必要になり、安価で低電力のハードウェアでフルノードを実行する際の障壁となります。 これに対する解決策は、より効率的な構造(バークルツリー)を持った状態ツリーを更新することです。バークルツリーでは、完全な状態データの代わりに、共有可能なデータである小さな「ウィットネス」を使うことで集約することができます。 状態データをバークルツリーに再フォーマットすることは、ステートレスクライアントへ移行するための足掛かりとなります。 ## ウィットネスの説明とその必要性 {#what-is-a-witness} -ブロックの検証では、ブロックに含まれるトランザクションを再実行し、その変更をイーサリアムの状態ツリーに適用することで、新しいルートハッシュを計算します。 検証されたブロックでは、その計算された状態ルートのハッシュがブロックで提供されたものと一致します。つまり、ブロックの提案者が本当にルートハッシュの計算を行ったことが確認できます。 現状のイーサリアムクライアントで状態を更新するには、状態ツリー全体にアクセスする必要があり、この巨大なデータ構造がローカルに保存されていなければなりません。 ウィットネスは、ブロック内のトランザクションを実行するために必要な状態データのフラグメントのみを含みます。 バリデータは、このフラグメントを使用して、ブロック提案者がブロックトランザクションを正しく実行し、状態が正常に更新されたかどうかを検証できます。 ただし、ウィットネスが各ノードにおいて 12 秒間のスロット内で安全に受信、処理されるためには、イーサリアムネットワーク上のピア間で十分な速度で転送する必要があります。 ウィットネスが大きすぎると、一部のノードにおいて、それをダウンロードしてチェーンを最新の状態を維持するのに時間がかかりすぎる可能性があります。 これでは、高速インターネット接続を持つノードのみがブロックの検証に参加できることになり、中央集権的な影響力を高めてしまいます。 バークルツリーを使用することで、状態をハードウェアドライブに保存する必要がなくなります。 つまり、ブロックを検証するために必要な*すべて*がブロック内に含まれます。 残念ながら、マークルツリーから生成されるウィットネスは大きすぎるため、ステートレスクライアントをサポートできません。 +ブロックの検証では、ブロックに含まれるトランザクションを再実行し、その変更をイーサリアムの状態ツリーに適用することで、新しいルートハッシュを計算します。 検証されたブロックでは、その計算された状態ルートのハッシュがブロックで提供されたものと一致します。つまり、ブロックの提案者が本当にルートハッシュの計算を行ったことが確認できます。 現状のイーサリアムクライアントで状態を更新するには、状態ツリー全体にアクセスする必要があり、この巨大なデータ構造がローカルに保存されていなければなりません。 ウィットネスは、ブロック内のトランザクションを実行するために必要な状態データのフラグメントのみを含みます。 バリデータは、このフラグメントを使用して、ブロック提案者がブロックトランザクションを正しく実行し、状態が正常に更新されたかどうかを検証できます。 ただし、ウィットネスが各ノードにおいて12秒間のスロット内で安全に受信、処理されるためには、イーサリアムネットワーク上のピア間で十分な速度で転送する必要があります。 ウィットネスが大きすぎると、一部のノードにおいて、それをダウンロードしてチェーンを最新の状態を維持するのに時間がかかりすぎる可能性があります。 これでは、高速インターネット接続を持つノードのみがブロックの検証に参加できることになり、中央集権的な影響力を高めてしまいます。 バークルツリーを使用することで、状態をハードウェアドライブに保存する必要がなくなります。 つまり、ブロックを検証するために必要な_すべて_がブロック内に含まれます。 残念ながら、マークルツリーから生成されるウィットネスは大きすぎるため、ステートレスクライアントをサポートできません。 ## バークルツリーが小さなウィットネスを可能にする仕組み {#why-do-verkle-trees-enable-smaller-witnesses} -マークルツリーの構造では、ウィットネスのサイズが非常に大きくなるため、12 秒間のスロット内では、ピア間で安全にブロードキャストすることができません。 これは、ウィットネスがリーフが持つデータからルートハッシュへ接続するパスであるためです。 データを確認するには、各リーフからルートに接続するための全ての中間ハッシュだけでなく、全ての「兄弟」ノードのハッシュを持っている必要があります。 証明内にある各ノードには、ツリーの一段階上へのハッシュを作成するためにハッシュされる兄弟ノードがあります。 これは非常に大きなデータになります。 バークルツリーは、ツリーのリーフとルートの距離を短縮し、ルートハッシュを検証するために兄弟ノードを提供する必要性をなくすことで、ウィットネスのサイズを削減します。 また、ハッシュ形式のベクトルコミットメントの代わりに強力な多項式コミットメント機構を利用することで、スペース効率がさらに向上します。 多項式コミットメントにより、ウィットネスが証明するリーフの数に関係なく、サイズを固定にすることができます。 +マークルツリーの構造では、ウィットネスのサイズが非常に大きくなるため、12秒間のスロット内では、ピア間で安全にブロードキャストすることができません。 これは、ウィットネスがリーフが持つデータからルートハッシュへ接続するパスであるためです。 データを確認するには、各リーフからルートに接続するための全ての中間ハッシュだけでなく、全ての「兄弟」ノードのハッシュを持っている必要があります。 証明内にある各ノードには、ツリーの一段階上へのハッシュを作成するためにハッシュされる兄弟ノードがあります。 これは非常に大きなデータになります。 バークルツリーは、ツリーのリーフとルートの距離を短縮し、ルートハッシュを検証するために兄弟ノードを提供する必要性をなくすことで、ウィットネスのサイズを削減します。 また、ハッシュ形式のベクトルコミットメントの代わりに強力な多項式コミットメント機構を利用することで、スペース効率がさらに向上します。 多項式コミットメントにより、ウィットネスが証明するリーフの数に関係なく、サイズを固定にすることができます。 多項式コミットメントスキームでは、ウィットネスが管理しやすいサイズになり、ピアツーピアネットワーク上で簡単に転送できます。 この仕組みにより、クライアントは、各ブロックの状態変化を最小限のデータで検証することができます。 -ウィットネスのサイズは、含まれるリーフの数によって変わります。 例えば、1000 枚のリーフを扱うウィットネスは、マークルツリーで約 3.5MB(ツリーが 7 レベルと仮定しています)、 バークルツリーでは約 150KB(ツリーが 4 レベルあると仮定します)となり、**約 23 分の 1**に縮小できます。 このウィットネスのサイズ縮小により、ステートレスクライアントでも許容できる大きさになります。 多項式ウィットネスは、使用される個別の多項式コミットメントによって、0.128 ~ 1KB の範囲に収まります。 +ウィットネスのサイズは、含まれるリーフの数によって変わります。 例えば、1000枚のリーフを扱うウィットネスは、マークルツリーで約3.5MB(ツリーが7レベルと仮定しています)、 バークルツリーでは約150KB(ツリーが4レベルあると仮定します)となり、**約23分の1**に縮小できます。 このウィットネスのサイズ縮小により、ステートレスクライアントでも許容できる大きさになります。 多項式ウィットネスは、使用される個別の多項式コミットメントによって、0.128~1KBの範囲に収まります。 ## バークルツリーの構造 {#what-is-the-structure-of-a-verkle-tree} -バークルツリーは、`(key,value)`のペアで構成されたデータ構造です。キーは、31 バイトの*ステム*と 1 バイトの*サフィックス*で構成されています。 これらのキーは、*拡張*ノードと*内部*ノードに編成されます。 拡張ノードは、1 つのステムを表すノードです。256 個の子ノードがあり、それぞれ異なるサフィックスを持っています。 内部ノードも 256 個の子ノードを持っていますが、他の拡張ノードになることもあります。 バークルツリーとマークルツリー構造の主な違いは、バークルツリーの方がはるかにフラットなことです。 つまり、リーフとルートを結ぶ中間ノードが少ないため、証明を生成するために必要なデータが小さくなります。 +バークルツリーは、`(key,value)`のペアで構成されたデータ構造です。キーは、31バイトの_ステム_と1バイトの_サフィックス_で構成されています。 これらのキーは、_拡張_ノードと_内部_ノードに編成されます。 拡張ノードは、1つのステムを表すノードです。256個の子ノードがあり、それぞれ異なるサフィックスを持っています。 内部ノードも256個の子ノードを持っていますが、他の拡張ノードになることもあります。 バークルツリーとマークルツリー構造の主な違いは、バークルツリーの方がはるかにフラットなことです。 つまり、リーフとルートを結ぶ中間ノードが少ないため、証明を生成するために必要なデータが小さくなります。 ![](./verkle.png) @@ -51,15 +51,15 @@ summaryPoints: [ビバリーヒルズ・バークルテストネットの探索](https://beverlyhills.ethpandaops.io) -[Guillaume Ballet による Condrieu バークルテストネットの説明をご覧ください](https://www.youtube.com/watch?v=cPLHFBeC0Vg) (Condrieu テストネットはプルーフ・オブ・ワークでしたが、現在は[Kaustinen テストネット](https://kaustinen.ethdevops.io)に置き換えらていることにご注意ください)。 +[Guillaume BalletによるCondrieuバークルテストネットの説明をご覧ください](https://www.youtube.com/watch?v=cPLHFBeC0Vg) (Condrieuテストネットはプルーフ・オブ・ワークでしたが、現在は[Kaustinenテストネット](https://kaustinen.ethdevops.io)に置き換えらていることにご注意ください)。 ## 参考文献 {#further-reading} -- [ダンクラッド・フィーストによる PEEPanEIP でのバークルツリーの説明](https://www.youtube.com/watch?v=RGJOQHzg3UQ) -- [Guillaume Ballet による ETHGlobal でのバークルツリーの説明](https://www.youtube.com/watch?v=f7bEtX3Z57o) -- [Devcon6 での Guillaume Ballet による「バークルツリーがイーサリアムを効率的にする仕組み」](https://www.youtube.com/watch?v=Q7rStTKwuYs) -- [ETHDenver 2020 での Piper Merriam によるステートレスクライアントに関する説明](https://www.youtube.com/watch?v=0yiZJNciIJ4) +- [ダンクラッド・フィーストによるPEEPanEIPでのバークルツリーの説明](https://www.youtube.com/watch?v=RGJOQHzg3UQ) +- [Guillaume BalletによるETHGlobalでのバークルツリーの説明](https://www.youtube.com/watch?v=f7bEtX3Z57o) +- [Devcon6でのGuillaume Balletによる「バークルツリーがイーサリアムを効率的にする仕組み」](https://www.youtube.com/watch?v=Q7rStTKwuYs) +- [ETHDenver 2020でのPiper Merriamによるステートレスクライアントに関する説明](https://www.youtube.com/watch?v=0yiZJNciIJ4) - [ゼロ知識ポッドキャストでのダンクラッド・フィーストによるバークルツリーとステートレスに関する説明](https://zeroknowledge.fm/episode-202-stateless-ethereum-verkle-tries-with-dankrad-feist/) - [ヴィタリック・ブテリンによるバークルツリーの説明](https://vitalik.eth.limo/general/2021/06/18/verkle.html) - [ダンクラッド・フィーストによるバークルツリーの説明](https://dankradfeist.de/ethereum/2021/06/18/verkle-trie-for-eth1.html) -- [バークルツリーの EIP ドキュメント](https://notes.ethereum.org/@vbuterin/verkle_tree_eip#Illustration) +- [バークルツリーのEIPドキュメント](https://notes.ethereum.org/@vbuterin/verkle_tree_eip#Illustration) diff --git a/public/content/translations/pl/community/get-involved/index.md b/public/content/translations/pl/community/get-involved/index.md index 2fc324eff24..3769f42dad1 100644 --- a/public/content/translations/pl/community/get-involved/index.md +++ b/public/content/translations/pl/community/get-involved/index.md @@ -28,7 +28,7 @@ Czy masz doświadczenie w matematyce, kryptografii lub ekonomii? Może zainteres - Napisz lub zrecenzuj Propozycję Ulepszenia Ethereum - Napisz EIP 1. Przedstaw swój pomysł na [Ethereum Magicians](https://ethereum-magicians.org) - 2. Przeczytaj [EIP-1](https://eip.ethereum.org/EIPS/eip-1) — **Tak, jest to _cały_ dokument.** + 2. Przeczytaj [EIP-1](https://eips.ethereum.org/EIPS/eip-1) — **Tak, jest to _cały_ dokument.** 3. Postępuj zgodnie z instrukcjami w EIP-1. Odwołaj się do niego podczas pisania wersji wstępnej. - Dowiedz się jak zostać [edytorem EIP](https://eips.ethereum.org/EIPS/eip-5069) - Możesz już teraz recenzować EIP! Zobacz [otwarte pull requesty (PR) z tagiem `e-review`](https://github.com/ethereum/EIPs/pulls?q=is%3Apr+is%3Aopen+label%3Ae-review). Przekaż techniczną opinię na temat linku `discussion-to`. diff --git a/public/content/translations/pl/community/grants/index.md b/public/content/translations/pl/community/grants/index.md index bc38982af0d..b21a24d80ce 100644 --- a/public/content/translations/pl/community/grants/index.md +++ b/public/content/translations/pl/community/grants/index.md @@ -15,31 +15,27 @@ Ta lista jest tworzona przez naszą społeczność. Jeśli czegoś brakuje lub j Te programy wspierają rozległy ekosystem Ethereum, oferując granty dla wielu projektów. Obejmują one rozwiązania skalowalności, budowania społeczności, bezpieczeństwa, prywatności i nie tylko. Granty te nie są specyficzne dla żadnej platformy Ethereum i są dobrym miejscem do rozpoczęcia, jeśli nie masz pewności. - [Program wsparcia ekosystemu prowadzony przez EF](https://esp.ethereum.foundation) — _Finansowanie projektów open source, które przynoszą korzyści Ethereum, ze szczególnym naciskiem na uniwersalne narzędzia, infrastrukturę, badania i dobra publiczne_ -- [Ethereum RFP](https://github.com/ethereum/requests-for-proposals) — _Zapytania o propozycje Fundacji Ethereum prac i projektów w ekosystemie Ethereum_ -- [MetaCartel](https://www.metacartel.org/grants/) — _Rozwój zdecentralizowanych aplikacji, tworzenie DAO_ -- [Moloch DAO](https://www.molochdao.com/) — _Prywatność, skalowanie warstwy 2, bezpieczeństwo klienta i nie tylko_ -- [Open Grants](https://opengrants.com/explore) -- [Granty DAO](https://docs.google.com/spreadsheets/d/1XHc-p_MHNRdjacc8uOEjtPoWL86olP4GyxAJOFO0zxY/edit#gid=0) — _Arkusz kalkulacyjny Google organizacji oferujących granty_ -- [Crunchbase dla grantów Web3](https://www.cryptoneur.xyz/web3-grants) — _Filtruj i wyszukuj granty według kategorii, przypadku użycia, kwoty i nie tylko. Przyczyń się, aby pomóc innym w znalezieniu odpowiedniego grantu._ -- [Granty Akademickie](https://esp.ethereum.foundation/academic-grants) — _Granty na wsparcie prac akademickich związanych z Ethereum_ +- [MetaCartel](https://www.metacartel.org/grants/) — _rozwój zdecentralizowanych aplikacji, tworzenie DAO_ +- [Moloch DAO](https://www.molochdao.com/) — _prywatność, skalowanie warstwy 2, bezpieczeństwo klienta i nie tylko_ +- [Granty DAO](https://docs.google.com/spreadsheets/d/1XHc-p_MHNRdjacc8uOEjtPoWL86olP4GyxAJOFO0zxY/edit#gid=0) — _arkusz kalkulacyjny Google organizacji oferujących granty_ +- [Crunchbase dla grantów Web3](https://www.cryptoneur.xyz/web3-grants) — _filtruj i wyszukuj granty według kategorii, przypadku użycia, kwoty i nie tylko. Przyczyń się, aby pomóc innym w znalezieniu odpowiedniego grantu._ +- [Granty Akademickie](https://esp.ethereum.foundation/academic-grants) — _granty na wsparcie prac akademickich związanych z Ethereum_ +- [Blockworks Grantfarm](https://blockworks.co/grants/programs) - _Firma Blockworks opracowała kompleksowy katalog wszystkich dotacji, zapytań ofertowych i nagród za błędy._ ## Granty specyficzne dla projektu {#project-specific} Projekty te stworzyły własne granty dla projektów mających na celu rozwój i eksperymentowanie z własną technologią. - [Program grantów Aave](https://aavegrants.org/) — _DAO grantów [Aave](https://aave.com/)_ -- [Balancer](https://balancergrants.notion.site/Balancer-Community-Grants-23e562c5bc4347cd8304637bff0058e6) — _Fundusz ekosystemu [Balancer](https://balancer.fi/)_ +- [Balancer](https://quark-ceres-740.notion.site/Balancer-Grants-938f1b979810427f8d903a904315da41) — _fundusz ekosystemu [Balancer](https://balancer.fi/)_ - [Program grantów Chainlink](https://chain.link/community/grants) — _Granty społeczności [Chainlink](https://chain.link/)_ -- [Program grantów Compound](https://compoundgrants.org/) — _Ekosystem finansowy [Compound](https://compound.finance/)_ - [Program grantów Decetraland](https://governance.decentraland.org/grants/) — _Metaverse DAO [Decentraland](https://decentraland.org/)_ -- [Organizacja grantów ekosystemu Lido (LEGO)](https://lego.lido.fi/) — _Ekosystem finansowy [Lido](https://lido.fi/)_ +- [Organizacja grantów ekosystemu Lido (LEGO)](https://lido.fi/lego) — _ekosystem finansowy [Lido](https://lido.fi/)_ - [Program MetaMask](https://metamaskgrants.org/) — _DAO prowadzonych przez pracowników grantów [MetaMask](https://metamask.io/)_ -- [Program grantów mStable](https://docs.mstable.org/advanced/grants-program) — _Społeczność [mStable](https://mstable.org/)_ -- [Program grantów sieci SKALE](https://skale.space/developers#grants) — _Ekosystem [sieci SKALE](https://skale.space/)_ -- [The Graph](https://airtable.com/shrdfvnFvVch3IOVm) — _Ekosystem [The Graph](https://thegraph.com/)_ -- [Program grantów UMA](https://grants.umaproject.org/) — _Wsparcie dla deweloperów [UMA](https://umaproject.org/)_ -- [Program grantów Uniswap](https://www.unigrants.org/) — _Społeczność [Uniswap](https://uniswap.org/)_ -- [Granty Web3](https://web3grants.net) — _Obszerna lista programów grantowych związanych z web3/krypto_ +- [Program grantów sieci SKALE](https://skale.space/developers#grants) — _ekosystem [sieci SKALE](https://skale.space/)_ +- [The Graph](https://airtable.com/shrdfvnFvVch3IOVm) — _ekosystem [The Graph](https://thegraph.com/)_ +- [Program grantów Uniswap](https://www.uniswapfoundation.org/apply-for-a-grant) — _społeczność [Uniswap](https://uniswap.org/)_ +- [Granty Web3](https://web3grants.net) — _obszerna lista programów grantowych związanych z web3/krypto_ ## Quadratic funding {#quadratic-funding} diff --git a/public/content/translations/pl/community/language-resources/index.md b/public/content/translations/pl/community/language-resources/index.md index a4ca3261834..dfd08947fb1 100644 --- a/public/content/translations/pl/community/language-resources/index.md +++ b/public/content/translations/pl/community/language-resources/index.md @@ -72,7 +72,7 @@ Jeśli jesteś dwujęzyczny i chcesz pomóc nam dotrzeć do większej liczby os - [Gwei.cz](https://gwei.cz) — lokalna społeczność skupiona wokół Web3, tworzy treści edukacyjne, organizuje wydarzenia online i stacjonarne - [Gwei.cz Příručka](https://prirucka.gwei.cz/) — przewodnik Ethereum dla początkujących - [DAO Příručka](https://dao.gwei.cz/) — przewodnik dla początkujących o DAO -- [Mastering Ethereum](https://ipfs.infura-ipfs.io/ipfs/bafybeidvuxhnsgfx3tncpfxheqglkjwmdxclknlgd7s7qggd2a6bzgb27m) — doskonalenie Ethereum po czesku +- [Mastering Ethereum](https://ipfs.io/ipfs/bafybeidvuxhnsgfx3tncpfxheqglkjwmdxclknlgd7s7qggd2a6bzgb27m) — doskonalenie Ethereum po czesku ### Francuski {#fr} diff --git a/public/content/translations/pl/community/online/index.md b/public/content/translations/pl/community/online/index.md index 54dfa383fca..6fb5e38d8db 100644 --- a/public/content/translations/pl/community/online/index.md +++ b/public/content/translations/pl/community/online/index.md @@ -24,13 +24,13 @@ Setki tysięcy entuzjastów Ethereum gromadzi się na tych forach internetowych, Ethereum Cat Herders — społeczność skoncentrowana na oferowaniu wsparcia w zarządzaniu projektami rozwoju Ethereum Ethereum Hackers — czat Discord prowadzony przez ETHGlobal: społeczność internetowa dla hakerów Ethereum na całym świecie CryptoDevs — społeczność Discord skupiająca się na rozwoju Ethereum -EthStaker Discord — prowadzone przez społeczność wskazówki, edukacja, wsparcie i zasoby dla obecnych i potencjalnych stakerów +EthStaker Discord — prowadzone przez społeczność wskazówki, edukacja, wsparcie i zasoby dla obecnych i potencjalnych stakerów Zespół strony internetowej ethereum.org — wpadnij i porozmawiaj o tworzeniu i projektowaniu strony internetowej ethereum.org z zespołem i ludźmi ze społeczności Matos Discord — społeczność twórców web3, w której spotykają się budujący, przedstawiciele przemysłu i entuzjaści Ethereum. Jesteśmy pasjonatami rozwoju, projektowania i kultury web3. Przyjdź tworzyć z nami. -Solidity Gitter — czat dla deweloperów Solidity (Gitter) +Solidity Gitter — czat dla deweloperów Solidity (Gitter) Solidity Matrix — czat dla rozwoju Solidity (Matrix) -Ethereum Stack Exchange _— forum pytań i odpowiedzi_ -Peeranha _— zdecentralizowane forum pytań i odpowiedzi_ +Ethereum Stack Exchange *— forum pytań i odpowiedzi* +Peeranha *— zdecentralizowane forum pytań i odpowiedzi* ## YouTube i Twitter {#youtube-and-twitter} diff --git a/public/content/translations/pl/community/research/index.md b/public/content/translations/pl/community/research/index.md index 67909b2f103..c05488d3534 100644 --- a/public/content/translations/pl/community/research/index.md +++ b/public/content/translations/pl/community/research/index.md @@ -35,7 +35,7 @@ Badania nad konsensusem są związane z [mechanizmem proof-of-stake Ethereum](/d - zwiększanie bezpieczeństwa lub wydajności implementacji klienta; - oraz rozwijanie lekkich klientów. -Oprócz badań wybiegających w przyszłość, badane są niektóre fundamentalne przeprojektowania protokołu, takie jak nieodwołalność pojedynczego slotu, aby umożliwić znaczące ulepszenia Ethereum. Co więcej, wydajność, bezpieczeństwo i monitorowanie sieci peer-to-peer między klientami konsensusu są również ważnymi tematami badawczymi. +Oprócz badań wybiegających w przyszłość, badane są niektóre fundamentalne przeprojektowania protokołu, takie jak finalizacja pojedynczego slotu, aby umożliwić znaczące ulepszenia Ethereum. Co więcej, wydajność, bezpieczeństwo i monitorowanie sieci peer-to-peer między klientami konsensusu są również ważnymi tematami badawczymi. #### Podstawowe informacje {#background-reading} @@ -48,7 +48,7 @@ Oprócz badań wybiegających w przyszłość, badane są niektóre fundamentaln - [Konsensus ethresear.ch](https://ethresear.ch/c/consensus/29) - [Dylemat dostępności/nieodwołalności](https://arxiv.org/abs/2009.04987) -- [Single slot finality](https://ethresear.ch/t/a-model-for-cumulative-committee-based-finality/10259) +- [Finalizacja pojedynczego slotu](https://ethresear.ch/t/a-model-for-cumulative-committee-based-finality/10259) - [Separacja proponujący-budujący](https://notes.ethereum.org/@vbuterin/pbs_censorship_resistance) ### Wykonanie {#execution} @@ -124,7 +124,7 @@ Jednym ze szczególnych obszarów warstwy 2, który wymaga dalszych badań i roz - [Wprowadzenie do mostów blockchain](/bridges/) - [Vitalik o mostach](https://old.reddit.com/r/ethereum/comments/rwojtk/ama_we_are_the_efs_research_team_pt_7_07_january/hrngyk8/) - [Artykuł o mostach blockchain](https://medium.com/1kxnetwork/blockchain-bridges-5db6afac44f8) -- [Wartość zablokowana w mostach]() +- [Wartość zablokowana w mostach](https://dune.com/eliasimos/Bridge-Away-(from-Ethereum)) #### Ostatnie badania {#recent-research-3} @@ -216,7 +216,7 @@ Aby wprowadzić więcej osób do Ethereum, ekosystem musi poprawić UX/UI. Będz ### Ekonomia {#economics} -Badania ekonomiczne w Ethereum zasadniczo opierają się na dwóch podejściach: walidacji bezpieczeństwa mechanizmów opartych na zachętach ekonomicznych („mikroekonomia”) i analizie przepływów wartości między protokołami, aplikacjami i użytkownikami („makroekonomia”). Istnieją złożone czynniki krypto-ekonomiczne związane z natywnym aktywem Ethereum (Ethereum) i tokenami zbudowanymi na nim (na przykład NFT i tokeny ERC20). +Badania ekonomiczne w Ethereum zasadniczo opierają się na dwóch podejściach: walidacji bezpieczeństwa mechanizmów opartych na zachętach ekonomicznych („mikroekonomia”) i analizie przepływów wartości między protokołami, aplikacjami i użytkownikami („makroekonomia”). Istnieją złożone czynniki krypto-ekonomiczne związane z natywnym aktywem Ethereum (eter) i tokenami zbudowanymi na nim (na przykład NFT i tokeny ERC20). #### Podstawowe informacje {#background-reading-9} @@ -346,7 +346,6 @@ Narzędzia dla deweloperów Ethereum szybko się poprawiają. W tym obszarze wym - [Frameworki dla deweloperów](/developers/docs/frameworks/) - [Lista narzędzi deweloperskich konsensusu](https://github.com/ConsenSys/ethereum-developer-tools-list) - [Standardy tokenów](/developers/docs/standards/tokens/) -- [Biastek: narzędzia Ethereum](https://biastek.com/ethereum-tools/) - [CryptoDevHub: Narzędzia EVM](https://cryptodevhub.io/wiki/ethereum-virtual-machine-tools) #### Ostatnie badania {#recent-research-17} diff --git a/public/content/translations/pl/community/support/index.md b/public/content/translations/pl/community/support/index.md index 66a749ef960..0ba37c42e93 100644 --- a/public/content/translations/pl/community/support/index.md +++ b/public/content/translations/pl/community/support/index.md @@ -39,7 +39,7 @@ Szukasz portfela Ethereum? [ Zapoznaj się z naszą pełną listą portfeli Ethe Budowanie może być trudne. Oto kilka miejsc skoncentrowanych na rozwoju z doświadczonymi deweloperami Ethereum, którzy chętnie pomogą. - [Alchemy University](https://university.alchemy.com/#starter_code) -- [Discord CryptoDevs](https://discord.gg/Z9TA39m8Yu) +- [Discord CryptoDevs](https://discord.com/invite/5W5tVb3) - [Ethereum StackExchange](https://ethereum.stackexchange.com/) - [StackOverflow](https://stackoverflow.com/questions/tagged/web3) - [Web3 University](https://www.web3.university/) @@ -53,7 +53,7 @@ Czy twoje pytanie dotyczy konkretnego narzędzia, projektu lub biblioteki? Więk Oto kilka popularnych przykładów: -- [Solidity](https://gitter.im/ethereum/solidity) +- [Solidity](https://gitter.im/ethereum/solidity/) - [ethers.js](https://discord.gg/6jyGVDK6Jx) - [web3.js](https://discord.gg/GsABYQu4sC) - [Hardhat](https://discord.gg/xtrMGhmbfZ) @@ -65,7 +65,7 @@ Oto kilka popularnych przykładów: Jeśli uruchamiasz węzeł lub walidator, oto kilka społeczności, które pomogą Ci zacząć. -- [Discord EthStaker](https://discord.io/ethstaker) +- [Discord EthStaker](https://discord.gg/ethstaker) - [Reddit EthStaker](https://www.reddit.com/r/ethstaker) Większość zespołów tworzących klienty Ethereum ma również dedykowane, publiczne przestrzenie, w których można uzyskać wsparcie i zadawać pytania. diff --git a/public/content/translations/pl/decentralized-identity/index.md b/public/content/translations/pl/decentralized-identity/index.md index ed2e85ad6a4..3cb7ce04529 100644 --- a/public/content/translations/pl/decentralized-identity/index.md +++ b/public/content/translations/pl/decentralized-identity/index.md @@ -6,16 +6,16 @@ template: use-cases emoji: ":id:" sidebarDepth: 2 image: /eth-gif-cat.png -summaryPoint1: W tradycyjnych systemach tożsamościwydawanie, utrzymywanie i kontrola identyfikatorów są scentralizowane. +summaryPoint1: W tradycyjnych systemach tożsamości wydawanie, utrzymywanie i kontrola Twoich identyfikatorów są scentralizowane. summaryPoint2: Tożsamość zdecentralizowana usuwa zależność od scentralizowanych podmiotów trzecich. -summaryPoint3: Dzięki crypto użytkownicy, po raz kolejny, mają teraz narzędzia do wydawania i kontrolowania własnych identyfikatorów i zaświadczeń. +summaryPoint3: Dzięki technologii kryptograficznej użytkownicy mają ponownie narzędzia do wydawania, przechowywania i kontrolowania własnych identyfikatorów i poświadczeń. --- Tożsamość stanowi dzisiaj podstawę praktycznie każdego aspektu życia. Korzystając z usług internetowych, otwierając konto bankowe, głosując w wyborach, kupując nieruchomości, zatrudniając się — zawsze musisz udowodnić swoją tożsamość. Jednak tradycyjne systemy zarządzania tożsamością od dawna polegają na scentralizowanych pośrednikach, którzy wydają, przechowują i kontrolują Twoje identyfikatory oraz [poświadczenia](#what-are-attestations). Oznacza to, że nie możesz kontrolować informacji związanych z tożsamością ani decydować, kto ma dostęp do informacji umożliwiających identyfikację osoby (PII) i jak duży jest ten dostęp. -Te problemy rozwiązują zdecentralizowane systemy tożsamości oparte na publicznych łańcuchach bloków, takie jak Ethereum. Tożsamość zdecentralizowana umożliwia jednostkom zarządzanie informacjami związanymi z ich tożsamością. Dzięki zdecentralizowanym rozwiązaniom w zakresie tożsamości możesz _samodzielnie_ tworzyć identyfikatory oraz żądać swoich poświadczeń i przechowywać je bez polegania na organach centralnych, takich jak dostawcy usług lub rządy. +Te problemy rozwiązują zdecentralizowane systemy tożsamości oparte na publicznych blockchainach takich jak Ethereum. Tożsamość zdecentralizowana umożliwia jednostkom zarządzanie informacjami związanymi z ich tożsamością. Dzięki zdecentralizowanym rozwiązaniom w zakresie tożsamości możesz _samodzielnie_ tworzyć identyfikatory oraz żądać swoich poświadczeń i przechowywać je bez polegania na organach centralnych, takich jak dostawcy usług lub rządy. ## Co to jest tożsamość? {#what-is-identity} @@ -33,7 +33,7 @@ Identyfikator jest informacją, która wskazuje określoną lub określone tożs Te tradycyjne przykłady identyfikatorów są wydawane, przechowywane i kontrolowane przez jednostki centralne. Potrzebujesz pozwolenia od swojego rządu, aby zmienić swoje imię i nazwisko, a od platformy mediów społecznościowych, aby zmienić swój identyfikator. -## Co to są atesty? {#what-are-attestations} +## Co to są poświadczenia? {#what-are-attestations} Poświadczenie jest oświadczeniem złożonym przez jeden podmiot na temat innego podmiotu. Jeśli mieszkasz w Stanach Zjednoczonych, prawo jazdy wydane przez departament pojazdów mechanicznych (jeden podmiot) potwierdza, że inny podmiot (Ty) jest uprawniony do prowadzenia samochodu. @@ -161,6 +161,7 @@ Istnieje wiele ambitnych projektów wykorzystujących Ethereum jako podstawę zd - **[Proof of Humanity (lub PoH)](https://www.proofofhumanity.id)** — _ system weryfikacji tożsamości społecznościowej oparty na Ethereum._ - **[BrightID](https://www.brightid.org/)** — _sieć zdecentralizowanych tożsamości społecznościowych typu open source. Jej celem jest zreformowanie weryfikacji tożsamości poprzez tworzenie i analizę wykresu społecznego._ - **[Proof-of-personhood Passport](https://proofofpersonhood.com/)** — _zdecentralizowany agregator tożsamości cyfrowych._ +- **[walt.id](https://walt.id)** — _zdecentralizowana infrastruktura tożsamości i portfela o otwartym kodzie źródłowym, która umożliwia deweloperom i organizacjom wykorzystanie niezależnej tożsamości i NFT/SBT._ ## Dalsza lektura {#further-reading} @@ -170,6 +171,7 @@ Istnieje wiele ambitnych projektów wykorzystujących Ethereum jako podstawę zd - [Co to jest Ethereum ERC725? Samodzielne zarządzanie tożsamością w łańcuchu bloków](https://cryptoslate.com/what-is-erc725-self-sovereign-identity-management-on-the-blockchain/) — _Sam Town_ - [Jak łańcuch bloków może rozwiązać problem cyfrowej tożsamości](https://time.com/6142810/proof-of-humanity/) — _Andrew R. Chow_ - [Co to jest zdecentralizowana tożsamość i dlaczego warto się nią zajmować?](https://web3.hashnode.com/what-is-decentralized-identity) — _Emmanuel Awosika_ +- [Wprowadzenie do zdecentralizowanej tożsamości](https://walt.id/white-paper/digital-identity) — _Dominik Beron_ ### Materiały wideo {#videos} @@ -177,9 +179,11 @@ Istnieje wiele ambitnych projektów wykorzystujących Ethereum jako podstawę zd - [Logowanie za pomocą Ethereum i zdecentralizowanej tożsamości za pomocą Ceramic, IDX, React i 3ID Connect](https://www.youtube.com/watch?v=t9gWZYJxk7c) — _samouczek YouTube pokazujący, jak zbudować system zarządzania tożsamością do tworzenia, odczytywania i aktualizowania profilu użytkownika przy użyciu portfela Ethereum autorstwa Nadera Dabita._ - [BrightID — zdecentralizowana tożsamość w Ethereum](https://www.youtube.com/watch?v=D3DbMFYGRoM) — _odcinek podcastu Bankless omawiający BrightID, zdecentralizowane rozwiązanie tożsamości dla Ethereum._ - [Internet poza łańcuchem: zdecentralizowana tożsamość i weryfikowalne dane uwierzytelniające](https://www.youtube.com/watch?v=EZ_Bb6j87mg) — prezentacja EthDenver 2022 autorstwa Evina McMullena. +- [Wyjaśnienie weryfikowalnych danych uwierzytelniających](https://www.youtube.com/watch?v=ce1IdSr-Kig) — film wyjaśniający na YouTube z demonstracją autorstwa Tamino Baumanna ### Społeczności {#communities} - [Sojusz ERC-725 na GitHub](https://github.com/erc725alliance) — _zwolennicy standardu ERC725 do zarządzania tożsamością w łańcuchu bloków Ethereum._ - [Serwer Discord SpruceID](https://discord.com/invite/Sf9tSFzrnt) — _społeczność dla entuzjastów i programistów pracujących nad logowaniem za pomocą Ethereum._ - [Veramo Labs](https://discord.gg/sYBUXpACh4) — _społeczność programistów uczestniczących w budowaniu struktury weryfikowalnych danych dla aplikacji._ +- [walt.id](https://discord.com/invite/AW8AgqJthZ) — _społeczność deweloperów i twórców pracujących nad przypadkami użycia zdecentralizowanej tożsamości w różnych branżach_ diff --git a/public/content/translations/pl/defi/index.md b/public/content/translations/pl/defi/index.md index 3ed5cad1322..b1fe04fde62 100644 --- a/public/content/translations/pl/defi/index.md +++ b/public/content/translations/pl/defi/index.md @@ -277,7 +277,7 @@ Zdecentralizowane ubezpieczenia mają na celu obniżenie kosztów ubezpieczenia, Produkty Ethereum, podobnie jak każde oprogramowanie, mogą zawierać błędy i są narażone na oprogramowanie wykorzystujące luki. Dlatego obecnie wiele dostępnych produktów ubezpieczeniowych koncentruje się na ochronie użytkowników przed utratą środków. Jednak pojawiają się projekty, które zaczynają obejmować swoim zasięgiem wszystko, czym może nas zaskoczyć życie. Dobrym tego przykładem jest program Crop firmy Etherisc, którego celem jest [ochrona drobnych rolników w Kenii przed suszami i powodziami](https://blog.etherisc.com/etherisc-teams-up-with-chainlink-to-deliver-crop-insurance-in-kenya-137e433c29dc). Zdecentralizowane ubezpieczenie może zapewnić tańszą ochronę ubezpieczeniową dla rolników, którzy często nie są uwzględniani przez tradycyjnych ubezpieczycieli. - Zobacz d-aplikacje ubezpieczeniowe + Zobacz zdecentralizowane aplikacje ubezpieczeniowe diff --git a/public/content/translations/pl/desci/index.md b/public/content/translations/pl/desci/index.md index 59439376328..d6aac3be9fa 100644 --- a/public/content/translations/pl/desci/index.md +++ b/public/content/translations/pl/desci/index.md @@ -18,7 +18,7 @@ Zdecentralizowana nauka (DeSci) jest ruchem, który ma na celu zbudowanie public DeSci ma na celu stworzenie ekosystemu, w którym naukowcy są zachęcani do otwartego dzielenia się swoimi badaniami i otrzymują uznanie za swoją pracę, jednocześnie umożliwiając każdemu łatwy dostęp do badań i uczestniczenie w nich. DeSci działa w oparciu o ideę, że wiedza naukowa powinna być dostępna dla każdego, a proces badań naukowych powinien być przejrzysty. DeSci tworzy bardziej zdecentralizowany i rozproszony model badań naukowych, dzięki czemu są one bardziej odporne na cenzurę i kontrolę ze strony władz centralnych. DeSci to środowisko, w którym nowe i niekonwencjonalne pomysły mogą się rozwijać poprzez decentralizację dostępu do finansowania, narzędzi naukowych i kanałów komunikacji. -Zdecentralizowana nauka umożliwia bardziej zróżnicowane źródła finansowania (od [DAO](/dao/), [kwadratowych darowizn](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2003531) do finansowania społecznościowego i innych form), łatwiejszy dostęp do danych i metod, a także poprzez zapewnienie zachęt do odtwarzalności. +Zdecentralizowana nauka pozwala na bardziej zróżnicowane źródła finansowania (od [DAO](/dao/), [kwadratowych darowizn](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2003531) do finansowania społecznościowego i nie tylko), bardziej dostępne dane i metody oraz poprzez zapewnienie zachęt do odtwarzalności. ### Juan Benet — ruch DeSci @@ -103,7 +103,7 @@ Przeglądaj projekty i dołącz do społeczności DeSci. - [OceanDAO: DAO finansuje naukę związaną z danymi](https://oceanprotocol.com/dao) - [Opscientia: otwarty, zdecentralizowany przepływ prac naukowych](https://opsci.io/research/) - [LabDAO: projektuj białka in-silico (za pomocą komputera)](https://alphafodl.vercel.app/) -- [Bio.xyz: zdobądź fundusze na swój biotechnologiczny projekt DAO lub desci](https://www.molecule.to/) +- [Bio.xyz: zdobądź fundusze na swój biotechnologiczny projekt DAO lub desci](https://www.bio.xyz/) - [Research Hub: wysyłaj wyniki naukowe i angażuj się w rozmowy z partnerami](https://www.researchhub.com/) - [VitaDAO: uzyskuj środki finansowe w ramach sponsorowanych umów badawczych na długotrwałe badania](https://www.vitadao.com/) - [Protokół Fleminga: gospodarka danymi typu open-source, która wspiera wspólne odkrycia biomedyczne](https://medium.com/@FlemingProtocol/a-data-economy-for-patient-driven-biomedical-innovation-9d56bf63d3dd) diff --git a/public/content/translations/pl/guides/how-to-swap-tokens/index.md b/public/content/translations/pl/guides/how-to-swap-tokens/index.md index e0c477e148d..ddc39bbab67 100644 --- a/public/content/translations/pl/guides/how-to-swap-tokens/index.md +++ b/public/content/translations/pl/guides/how-to-swap-tokens/index.md @@ -12,7 +12,7 @@ Wymiana tokenów obejmuje wymianę dwóch różnych aktywów istniejących w sie **Wymaganie wstępne:** -- posiadanie portfela kryptowalutowego, możesz postępować zgodnie z tym samouczkiem: [Jak „zarejestrować” konto Ethereum](/guides/how-to-register-an-ethereum-account/) +- posiadanie portfela kryptowalutowego, możesz postępować zgodnie z tym samouczkiem: [Jak „zarejestrować” konto Ethereum](/guides/how-to-create-an-ethereum-account/) - dodanie środków do portfela ## 1. Podłącz swój portfel do wybranej przez siebie zdecentralizowanej giełdy (DEX) diff --git a/public/content/translations/pl/guides/how-to-use-a-bridge/index.md b/public/content/translations/pl/guides/how-to-use-a-bridge/index.md index 65b310b8af0..3d7375616c4 100644 --- a/public/content/translations/pl/guides/how-to-use-a-bridge/index.md +++ b/public/content/translations/pl/guides/how-to-use-a-bridge/index.md @@ -10,7 +10,7 @@ Jeśli ruch na Ethereum jest duży, może stać się drogi. Jednym z rozwiązań **Wymaganie wstępne:** -- posiadanie portfela kryptowalutowego, możesz postępować zgodnie z tym samouczkiem: [Jak „zarejestrować” konto Ethereum](/guides/how-to-register-an-ethereum-account/) +- posiadanie portfela kryptowalutowego, możesz postępować zgodnie z tym samouczkiem: [Jak „zarejestrować” konto Ethereum](/guides/how-to-create-an-ethereum-account/) - dodanie środków do portfela ## 1. Określ jaką sieć warstwy 2 chcesz używać diff --git a/public/content/translations/pl/guides/how-to-use-a-wallet/index.md b/public/content/translations/pl/guides/how-to-use-a-wallet/index.md index 290d868ace8..408269211fb 100644 --- a/public/content/translations/pl/guides/how-to-use-a-wallet/index.md +++ b/public/content/translations/pl/guides/how-to-use-a-wallet/index.md @@ -51,7 +51,7 @@ Twój adres będzie taki sam we wszystkich projektach Ethereum. Nie musisz rejes 1. Odwiedź stronę internetową dowolnego projektu. 2. Jeśli strona docelowa projektu jest tylko statycznym opisem projektu, powinieneś mieć możliwość kliknięcia przycisku „Otwórz aplikację” w menu, który przeniesie Cię do rzeczywistej aplikacji internetowej. -3. Gdy będziesz w aplikacji kliknij „Połącz”. +3. Gdy będziesz w aplikacji, kliknij „Połącz”. ![Przycisk pozwalający użytkownikowi połączyć się ze stroną internetową za pomocą portfela](./connect1.png) diff --git a/public/content/translations/pl/nft/index.md b/public/content/translations/pl/nft/index.md index 2258f8e89e1..bff48785784 100644 --- a/public/content/translations/pl/nft/index.md +++ b/public/content/translations/pl/nft/index.md @@ -14,15 +14,15 @@ summaryPoint3: Wspierane przez inteligentne kontrakty na blockchainie Ethereum. ## Czym są NFT? {#what-are-nfts} -NFT to tokeny, które są unikalne. Każdy NFT ma inne właściwości (niezamienne) i można udowodnić, że jest rzadki. Różni się to od tokenów takich jak ERC-20, gdzie każdy token w zestawie jest identyczny i ma te same właściwości („zamienne”). Nie obchodzi cię, który konkretnie banknot masz w portfelu, ponieważ wszystkie są identyczne i warte tyle samo. Jednakże _ma_ znaczenie, który konkretnie NFT posiadasz, ponieważ wszystkie mają indywidualne właściwości, które odróżniają je od innych („niezamienne”). +NFT to tokeny, które są unikalne. Każdy NFT ma inne właściwości (niezamienne) i można udowodnić, że jest rzadki. Różni się to od tokenów takich jak ETH lub innych tokenów opartych na Ethereum, takich jak USDC, gdzie każdy token jest identyczny i ma te same właściwości („zamienne”). Nie ma znaczenia, który konkretnie banknot (lub ETH) masz w portfelu, ponieważ wszystkie są identyczne i warte tyle samo. Jednakże _ma_ znaczenie, który konkretnie NFT posiadasz, ponieważ wszystkie mają indywidualne właściwości, które odróżniają je od innych („niezamienne”). -Unikalność każdego NFT umożliwia tokenizację rzeczy takich jak dzieła artystyczne, przedmioty kolekcjonerskie, a nawet nieruchomości, gdzie jeden konkretny unikalny NFT reprezentuje konkretny unikalny prawdziwy lub cyfrowy przedmiot. Własność aktywa zabezpieczona jest przez blockchain Ethereum — nikt nie może zmodyfikować rejestrów własności ani skopiować/wkleić nowego NFT. +Unikalność każdego NFT umożliwia tokenizację rzeczy takich jak dzieła artystyczne, przedmioty kolekcjonerskie, a nawet nieruchomości, gdzie jeden konkretny unikalny NFT reprezentuje konkretny unikalny prawdziwy lub cyfrowy przedmiot. Własność aktywa jest publicznie weryfikowalna na blockchainie Ethereum. ## Internet rzeczy {#internet-of-assets} -NFT i Ethereum rozwiązują niektóre z problemów występujących w dzisiejszym internecie. Ponieważ wszystko staje się coraz bardziej cyfrowe, istnieje potrzeba odtworzenia właściwości przedmiotów fizycznych, takich jak rzadkość, unikalność i dowód własności w sposób, który nie jest kontrolowany przez centralną organizację. Na przykład, dzięki NFT możesz posiadać muzykę mp3, która nie jest specyficzna dla konkretnej aplikacji muzycznej jednej firmy, lub możesz mieć nazwę konta w mediach społecznościowych, którą możesz sprzedać lub wymienić, ale nie może ona zostać samowolnie odebrana przez dostawcę platformy. +NFT i Ethereum rozwiązują niektóre z problemów występujących w dzisiejszym Internecie. Ponieważ wszystko staje się coraz bardziej cyfrowe, istnieje potrzeba odtworzenia właściwości przedmiotów fizycznych, takich jak rzadkość, unikalność i dowód własności w sposób, który nie jest kontrolowany przez centralną organizację. Dzięki NFT możesz na przykład posiadać plik muzyczny mp3 we wszystkich aplikacjach opartych na Ethereum i nie być przywiązanym do konkretnej aplikacji muzycznej danej firmy, takiej jak Spotify lub Apple Music. Możesz posiadać nazwę w mediach społecznościowych, którą możesz sprzedać lub wymienić, ale nie może ona zostać samowolnie odebrana przez dostawcę platformy. Oto jak wygląda porównanie Internetu NFT z Internetem, z którego korzysta większość z nas... @@ -30,19 +30,13 @@ Oto jak wygląda porównanie Internetu NFT z Internetem, z którego korzysta wi | Internet NFT | Internet dzisiaj | | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Ty jesteś właścicielem swoich aktywów! Tylko Ty możesz je sprzedać lub wymienić. | Wynajmujesz aktywa od jakiejś organizacji. | +| Ty jesteś właścicielem swoich aktywów! Tylko Ty możesz je sprzedać lub wymienić. | Wynajmujesz aktywa od jakiejś organizacji i mogą one zostać Ci odebrane. | | NFT są cyfrowo unikalne, nie istnieją dwa takie same NFT. | Kopia jakiejś jednostki często nie może być odróżniona od oryginału. | | Własność NFT jest przechowywana w blockchainie tak, aby każdy mógł ją zweryfikować. | Rejestry własności przedmiotów cyfrowych są przechowywane na serwerach kontrolowanych przez instytucje — musisz im wierzyć na słowo. | | NFT to inteligentne kontrakty na Ethereum. Oznacza to, że można je łatwo wykorzystać w innych inteligentnych kontraktach i aplikacjach na Ethereum! | Firmy posiadające elementy cyfrowe zazwyczaj wymagają własnej infrastruktury typu „ogrodzony ogród” („walled garden”). | | Twórcy mogą sprzedawać swoje prace w dowolnym miejscu i mają dostęp do globalnego rynku. | Twórcy opierają się na infrastrukturze i systemie dystrybucji platform, z których korzystają. Są one często objęte określonymi warunkami użytkowania i ograniczeniami geograficznymi. | | Twórcy NFT mogą zachować prawa własności do własnej pracy i zaprogramować tantiemy bezpośrednio w kontrakcie NFT. | Platformy, takie jak serwisy streamingu muzyki, zachowują większość zysków ze sprzedaży. | -## Jak działają NFT? {#how-nfts-work} - -Podobnie jak każdy token wydany na Ethereum, NFT są wydawane przez inteligentny kontrakt. Inteligentny kontrakt jest zgodny z jednym z kilku standardów NFT (najczęściej ERC-721 lub ERC-1155), które określają funkcje, jakie posiada kontrakt. Kontrakt może tworzyć („wybijać”) NFT i przypisywać je do określonego właściciela. Własność jest określona w kontrakcie poprzez mapowanie określonych NFT na określone adresy. NFT ma ID i zazwyczaj powiązane z nim metadane, które sprawiają, że konkretny token jest unikalny. - -Kiedy ktoś tworzy lub wybija NFT, tak naprawdę wykonuje funkcję w inteligentnym kontrakcie, która przypisuje określony NFT do jego adresu. Informacja ta jest przechowywana w pamięci kontraktu, która jest częścią blochainu. Twórca kontraktu może zapisać w niej dodatkową logikę, na przykład ograniczając całkowitą ilość lub określając tantiemę, która ma być wypłacana twórcy za każdym razem, gdy token zostanie przeniesiony. - ## W jakim celu używa się NFT? {#nft-use-cases} NFT są używane do wielu rzeczy, w tym: @@ -58,23 +52,37 @@ NFT są używane do wielu rzeczy, w tym: - zdecentralizowane nazwy domen internetowych - jako zabezpieczenie w DeFi -Być może jesteś artystą, który chce udostępniać swoje prace za pomocą NFT, bez utraty kontroli i poświęcania zysków na rzecz pośredników. Możesz utworzyć nowy kontrakt i określić liczbę NFT, ich właściwości oraz link do określonego dzieła sztuki. Jako artysta możesz zaprogramować w inteligentnym kontrakcie tantiemy, które powinny zostać Ci zapłacone (np. przekazać 5% ceny sprzedaży właścicielowi kontraktu za każdym razem, gdy NFT zostanie przeniesione). Zawsze możesz również udowodnić, że NFT został stworzony przez Ciebie, ponieważ jesteś właścicielem portfela, który wdrożył kontrakt. Kupujący mogą łatwo udowodnić, że posiadają autentyczny NFT z Twojej kolekcji, ponieważ ich adres portfela jest powiązany z tokenem w Twoim inteligentnym kontrakcie. Mogą go używać w całym ekosystemie Ethereum, mając pewność co do jego autentyczności. +Być może jesteś artystą, który chce udostępniać swoje prace za pomocą NFT, bez utraty kontroli i poświęcania zysków na rzecz pośredników. Możesz utworzyć nowy kontrakt i określić liczbę NFT, ich właściwości oraz link do określonego dzieła sztuki. Jako artysta możesz zaprogramować w inteligentnym kontrakcie tantiemy, które powinny zostać Ci zapłacone (np. przekazywać 5% ceny sprzedaży właścicielowi kontraktu za każdym razem, gdy NFT zostanie przeniesione). Zawsze możesz również udowodnić, że NFT został stworzony przez Ciebie, ponieważ jesteś właścicielem portfela, który wdrożył kontrakt. Kupujący mogą łatwo udowodnić, że posiadają autentyczny NFT z Twojej kolekcji, ponieważ ich adres portfela jest powiązany z tokenem w Twoim inteligentnym kontrakcie. Mogą go używać w całym ekosystemie Ethereum, mając pewność co do jego autentyczności. -To tak jak bilet na wydarzenie sportowe. Podobnie jak organizator wydarzenia może wybrać, ile biletów chce sprzedać, twórca NFT może zdecydować, ile istnieje replik. Czasami są to dokładne repliki, takie jak 5000 takich samych biletów wstępu. Czasami wybijanych jest kilka bardzo podobnych, ale każdy z nich nieco się różni, np. bilet z przypisanym miejscem. Można je kupować i sprzedawać peer-to-peer bez płacenia osobie obsługującej bilety, a kupujący zawsze ma pewność co do autentyczności biletu, sprawdzając adres kontraktu. +Pomyśl o tym tak jak o bilecie na wydarzenie sportowe. Podobnie jak organizator wydarzenia może wybrać, ile biletów chce sprzedać, twórca NFT może zdecydować, ile istnieje replik. Czasami są to dokładne repliki, takie jak 5000 takich samych biletów wstępu. Czasami wybijanych jest kilka bardzo podobnych, ale każdy z nich nieco się różni, np. bilet z przypisanym miejscem. Można je kupować i sprzedawać peer-to-peer bez płacenia osobie obsługującej bilety, a kupujący zawsze ma pewność co do autentyczności biletu, sprawdzając adres kontraktu. -Na ethereum.org NFT są używane do pokazania, że ludzie wnieśli swój wkład do naszego repozytorium GitHub lub uczestniczyli w rozmowach, a nawet mamy własną nazwę domeny NFT. Jeśli przyczynisz się do rozwoju ethereum.org, możesz otrzymać NFT w formie POAPu. Niektóre spotkania kryptowalutowe wykorzystywały tokeny POAP jako bilety. [Więcej na temat przyczyniania się do rozwoju Ethereum](/contributing/#poap). +Na ethereum.org, NFT są używane do pokazania, że ludzie wnieśli znaczący wkład w nasze repozytorium na GitHubie (zaprogramowali stronę, napisali lub zmodyfikowali artykuł...), przetłumaczyli nasze treści lub uczestniczyli w naszych rozmowach ze społecznością, mamy nawet własną nazwę domeny NFT. Jeśli przyczynisz się do rozwoju ethereum.org, możesz otrzymać NFT w formie POAPu. Niektóre spotkania kryptowalutowe wykorzystywały POAPy jako bilety. [Więcej na temat przyczyniania się do rozwoju](/contributing/#poap). ![ethereum.org POAP](./poap.png) -Ta strona ma alternatywną domenę obsługiwaną przez NFT, **ethereum.eth**. Nasz adres `.org` jest zarządzany centralnie przez DNS, podczas gdy ethereum`.eth` jest zarejestrowany na Ethereum za pośrednictwem Ethereum Name Service (ENS). Jest ona naszą własnością i jest zarządzana przez nas. [Sprawdź nasz wpis do ENS](https://app.ens.domains/name/ethereum.eth) +Ta strona ma również alternatywną domenę obsługiwaną przez NFT, **ethereum.eth**. Nasz adres `.org` jest zarządzany centralnie przez dostawcę DNS, podczas gdy ethereum`.eth` jest zarejestrowany na Ethereum za pośrednictwem Ethereum Name Service (ENS). Jest ona naszą własnością oraz jest zarządzana przez nas. [Sprawdź nasz rekord ENS](https://app.ens.domains/name/ethereum.eth) [Więcej o ENS](https://app.ens.domains) +## Jak działają NFT? {#how-nfts-work} + +NFT, podobnie jak inne cyfrowe elementy w blockchainie Ethereum, są tworzone za pomocą specjalnego programu komputerowego opartego na Ethereum, zwanego „inteligentnym kontraktem”. Kontrakty te są zgodne z pewnymi zasadami, takimi jak standardy ERC-721 lub ERC-1155, które określają, co kontrakt może robić. + +Inteligentny kontrakt NFT może robić kilka kluczowych czynności: + +- **Tworzyć NFT:** może tworzyć nowe NFT. +- **Przypisywać własność:** utrzymuje kontrolę nad tym, kto jest właścicielem, którego NFT, łącząc je z określonymi adresami Ethereum. +- **Nadawać każdemu NFT własne ID:** każdy NFT ma numer, który sprawia, że jest unikalny. Ponadto dołączone są do niego zazwyczaj pewne informacje (metadane) opisujące, co reprezentuje NFT. + +Kiedy ktoś „tworzy” lub „wybija” NFT, w zasadzie mówi inteligentnemu kontraktowi, aby dał mu prawo własności do konkretnego NFT. Ta informacja jest bezpiecznie i publicznie przechowywana w blockchainie. + +Co więcej, twórca kontraktu może dodać dodatkowe zasady. Może ograniczyć liczbę NFT, które mogą zostać utworzone lub zdecydować, że powinien otrzymywać niewielką tantiemę za każdym razem, gdy NFT zmieni właściciela. + ### Bezpieczeństwo NFT {#nft-security} -Bezpieczeństwo Ethereum wynika z algorytmu proof-of-stake. System został zaprojektowany w celu ekonomicznego zniechęcenia do złośliwych działań, dzięki czemu Ethereum jest odporne na manipulacje. To właśnie umożliwia działanie NFT. Gdy blok zawierający Twoją transakcję NFT zostanie sfinalizowany, zmiana go kosztowałaby atakującego miliony ETH. Każdy, kto korzysta z oprogramowania Ethereum, byłby w stanie natychmiast wykryć nieuczciwe manipulacje w NFT, a przestępca zostałby ekonomicznie ukarany i wyrzucony. +Bezpieczeństwo Ethereum wynika z algorytmu proof-of-stake. System ten został zaprojektowany w celu ekonomicznego zniechęcenia do złośliwych działań, dzięki czemu Ethereum jest odporne na manipulacje. To właśnie umożliwia działanie NFT. Gdy blok zawierający Twoją transakcję NFT zostanie sfinalizowany, zmiana go kosztowałaby atakującego miliony ETH. Każdy, kto korzysta z oprogramowania Ethereum, byłby w stanie natychmiast wykryć nieuczciwą manipulację w NFT, a przestępca zostałby ekonomicznie ukarany i wyrzucony. Kwestie bezpieczeństwa związane z NFT są najczęściej związane z oszustwami typu phishing, lukami w inteligentnych kontraktach lub błędami użytkownika (takimi jak nieumyślne ujawnienie kluczy prywatnych), co sprawia, że dbanie o bezpieczeństwo portfela ma kluczowe znaczenie dla właścicieli NFT. diff --git a/public/content/translations/pl/refi/index.md b/public/content/translations/pl/refi/index.md index 384f88abaed..39856041f20 100644 --- a/public/content/translations/pl/refi/index.md +++ b/public/content/translations/pl/refi/index.md @@ -18,7 +18,7 @@ summaryPoint3: Narzędzie do drastycznego skalowania aktywów przynoszących kor Zamiast tego ReFi ma na celu rozwiązywanie problemów środowiskowych, komunalnych lub społecznych poprzez tworzenie cykli regeneracyjnych. Systemy te tworzą wartość dla uczestników, jednocześnie przynosząc korzyści ekosystemom i społecznościom. -Jednym z fundamentów ReFi jest koncepcja ekonomii regeneracyjnej, której pionierem jest John Fullerton z [Capital Institute](https://capitalinstitute.org). Zaproponował osiem powiązanych ze sobą zasad, które leżą u podstaw zdrowia systemowego: +Jednym z fundamentów ReFi jest koncepcja ekonomii regeneracyjnej, której pionierem jest John Fullerton z Capital Institute. Zaproponował [osiem powiązanych ze sobą zasad](https://capitalinstitute.org/8-principles-regenerative-economy/), które leżą u podstaw zdrowia systemowego: ![Osiem połączonych ze sobą zasad](refi-regenerative-economy-diagram.png) diff --git a/public/content/translations/pl/smart-contracts/index.md b/public/content/translations/pl/smart-contracts/index.md index be2e32b4919..cd636764c7e 100644 --- a/public/content/translations/pl/smart-contracts/index.md +++ b/public/content/translations/pl/smart-contracts/index.md @@ -22,10 +22,6 @@ Alicja i Bob urządzają sobie wyścig rowerowy. Załóżmy, że Alice założy Ten jaskrawy przykład ilustruje problem z dowolną umową nieinteligentną. Nawet jeśli warunki umowy zostaną spełnione (np. Ty jesteś zwycięzcą wyścigu), nadal musisz ufać innej osobie, że wywiąże się z umowy (np. wypłaci zakład). -## Inteligentne kontrakty {#smart-contracts} - -Inteligentne kontrakty digitalizują umowy, przekształcając warunki umowy w kod komputerowy, który automatycznie wykonuje się, gdy warunki kontraktu są spełnione. - ## Cyfrowy automat do sprzedaży {#vending-machine} Prostą metaforą inteligentnego kontraktu jest automat sprzedający, który działa nieco podobnie do inteligentnego kontraktu — określone wejścia gwarantują z góry określone wyjścia. diff --git a/public/content/translations/pl/staking/pools/index.md b/public/content/translations/pl/staking/pools/index.md index 4234aaba88c..58933d27d26 100644 --- a/public/content/translations/pl/staking/pools/index.md +++ b/public/content/translations/pl/staking/pools/index.md @@ -53,14 +53,14 @@ Dostępnych jest wiele opcji ułatwiających konfigurację. Skorzystaj z powyżs -Należy pamiętać, że ważne jest, aby wybrać usługę, która poważnie traktuje [różnorodność klientów](/developers/docs/nodes-and-clients/client-diversity/), ponieważ zwiększa to bezpieczeństwo sieci i ogranicza ryzyko. Usługi, które mają dowody na ograniczanie korzystania z większości klientów, są oznaczone „różnorodność klientów wykonawczych” i „różnorodność klientów konsensusu.” +Należy pamiętać, że ważne jest, aby wybrać usługę, która poważnie traktuje [różnorodność klientów](/developers/docs/nodes-and-clients/client-diversity/), ponieważ zwiększa to bezpieczeństwo sieci i ogranicza ryzyko. Usługi, które mają dowody na ograniczanie korzystania z większości klientów, są oznaczone jako „różnorodność klientów wykonawczych” i „różnorodność klientów konsensusu”. Masz sugestię dotyczącą narzędzia do stakingu, które pominęliśmy? Zapoznaj się z naszymi [zasadami umieszczania produktów na liście](/contributing/adding-staking-products/), aby sprawdzić, czy są one odpowiednie i przesłać je do recenzji. ## Często zadawane pytania {#faq} -Zazwyczaj tokeny stakingu ERC-20 są wydawane stakerom, które reprezentują wartość zestakowanego przez nich ETH plus nagrody. Należy pamiętać, że różne pule będą dystrybuować nagrody ze stakowania do swoich użytkowników za pomocą nieco innych metod, ale jest to częste. +Zazwyczaj tokeny stakingu ERC-20 są wydawane stakerom i reprezentują wartość zestakowanego przez nich ETH plus nagrody. Należy pamiętać, że różne pule będą dystrybuować nagrody ze stakowania do swoich użytkowników za pomocą nieco innych metod, ale jest to częste. @@ -81,5 +81,6 @@ Niektóre opcje puli są bardziej zdecentralizowane niż inne, jeśli chodzi o w ## Dodatkowo przeczytaj {#further-reading} +- [Katalog stakingu Ethereum](https://www.staking.directory/) — _Eridian i Spacesider_ - [Staking z Rocket Pool - Przegląd stakingu](https://docs.rocketpool.net/guides/staking/overview.html) — _Dokumenty RocketPool_ - [Staking Ethereum z Lido](https://help.lido.fi/en/collections/2947324-staking-ethereum-with-lido) — _dokumenty pomocy Lido_ diff --git a/public/content/translations/pl/staking/saas/index.md b/public/content/translations/pl/staking/saas/index.md index 8203a0bb034..9ebd84679ee 100644 --- a/public/content/translations/pl/staking/saas/index.md +++ b/public/content/translations/pl/staking/saas/index.md @@ -47,7 +47,7 @@ Poniżej znajduje się paru dostępnych dostawców SaaS. Skorzystaj z powyższyc -Należy pamiętać o znaczeniu wspierania [różnorodności klientów](/developers/docs/nodes-and-clients/client-diversity/), ponieważ poprawia to bezpieczeństwo sieci i ogranicza ryzyko. Usługi, które mają dowody na ograniczanie korzystania z większości klientów, są oznaczone „różnorodność klientów wykonawczych” i „różnorodność klientów konsensusu.” +Należy pamiętać o znaczeniu wspierania [różnorodności klientów](/developers/docs/nodes-and-clients/client-diversity/), ponieważ poprawia to bezpieczeństwo sieci i ogranicza ryzyko. Usługi, które mają dowody na ograniczanie korzystania z większości klientów, są oznaczone jako „różnorodność klientów wykonawczych” i „różnorodność klientów konsensusu”. ### Generatory kluczy @@ -91,4 +91,5 @@ Skontaktuj się z indywidualnym dostawcą SaaS, aby uzyskać więcej informacji ## Dodatkowo przeczytaj {#further-reading} +- [Katalog stakingu Ethereum](https://www.staking.directory/) — _Eridian i Spacesider_ - [Ocena usług stakingu](https://www.attestant.io/posts/evaluating-staking-services/) — _Jim McDonald 2020 r._ diff --git a/public/content/translations/pl/staking/solo/index.md b/public/content/translations/pl/staking/solo/index.md index 811d8a2116f..e05f7e76dc2 100644 --- a/public/content/translations/pl/staking/solo/index.md +++ b/public/content/translations/pl/staking/solo/index.md @@ -109,7 +109,7 @@ Dostępnych jest wiele opcji ułatwiających konfigurację. Skorzystaj z powyżs -Należy pamiętać o znaczeniu wybrania [klienta mniejszościowego](/developers/docs/nodes-and-clients/client-diversity/), ponieważ poprawia to bezpieczeństwo sieci i ogranicza ryzyko. Narzędzia, które pozwalają na konfigurację klienta mniejszościowego są oznaczone jako „multi-klient”. +Należy pamiętać o znaczeniu wybrania [klienta mniejszościowego](/developers/docs/nodes-and-clients/client-diversity/), ponieważ poprawia to bezpieczeństwo sieci i ogranicza ryzyko. Narzędzia, które pozwalają na konfigurację klienta mniejszościowego, są oznaczone jako „multi-klient”. ### Generatory kluczy @@ -195,6 +195,7 @@ Aby odblokować i otrzymać całe saldo z powrotem, należy również zakończy ## Dalsza lektura {#further-reading} +- [Katalog stakingu Ethereum](https://www.staking.directory/) — _Eridian i Spacesider_ - [Problem różnorodności klientów Ethereum](https://hackernoon.com/ethereums-client-diversity-problem) — _@emmanuelawosika 2022 r._ - [Wspieranie różnorodności klientów](https://www.attestant.io/posts/helping-client-diversity/) — _Jim McDonald 2022 r._ - [Różnorodność klientów w warstwie konsensusu Ethereum](https://mirror.xyz/jmcook.eth/S7ONEka_0RgtKTZ3-dakPmAHQNPvuj15nh0YGKPFriA) — _jmcook.eth 2022 r._ diff --git a/public/content/translations/pl/staking/withdrawals/index.md b/public/content/translations/pl/staking/withdrawals/index.md index e9f76d356ca..626d86b30e4 100644 --- a/public/content/translations/pl/staking/withdrawals/index.md +++ b/public/content/translations/pl/staking/withdrawals/index.md @@ -114,12 +114,12 @@ Rozszerzając te obliczenia, możemy oszacować czas potrzebny na przetworzenie | Liczba wypłat | Czas realizacji | -| :-----------: | :-------------: | -| 400,000 | 3,5 dnia | -| 500,000 | 4,3 dnia | -| 600,000 | 5,2 dnia | -| 700,000 | 6,1 dnia | -| 800,000 | 7,0 dni | +| :-------------------: | :--------------: | +| 400,000 | 3,5 dnia | +| 500,000 | 4,3 dnia | +| 600,000 | 5,2 dnia | +| 700,000 | 6,1 dnia | +| 800,000 | 7,0 dni | @@ -194,7 +194,7 @@ eventCategory="FAQ" eventAction="I operate a validator. Where can I find more information on enabling withdrawals?" eventName="read more"> -Operatorom walidatorów zaleca się odwiedzenie strony wypłaty Staking Launchpad, gdzie można znaleźć więcej szczegółów na temat przygotowania walidatora do wypłat. przygotowane, czas zdarzeń i więcej szczegółów na temat funkcjonowania wypłat. +Operatorom walidatorów zaleca się odwiedzenie strony wypłaty Staking Launchpad, gdzie można znaleźć więcej szczegółów na temat przygotowania walidatora do wypłat, czasu wydarzeń i więcej szczegółów na temat działania wypłat. Aby najpierw wypróbować swoją konfigurację w sieci testowej, odwiedź Goerli Testnet Staking Launchpad, aby rozpocząć. @@ -214,5 +214,5 @@ Nie. Po wyjściu walidatora i wypłaceniu jego pełnego salda wszelkie dodatkowe - [EIP-4895: Wypłaty z łańcucha śledzącego jako operacje](https://eips.ethereum.org/EIPS/eip-4895) - [Ethereum Cat Herders — Szanghaj](https://www.ethereumcatherders.com/shanghai_upgrade/index.html) - [PEEPanEIP #94: Wypłata zestakowanego ETH (testowanie) z Potuz & Hsiao-Wei Wang](https://www.youtube.com/watch?v=G8UstwmGtyE) -- [PEEPanEIP#68: EIP-4895: Łańcuch śledzący wywiera wypłaty jako operacje z Alexem Stokesem](https://www.youtube.com/watch?v=CcL9RJBljUs) +- [PEEPanEIP#68: EIP-4895: Wypłaty push łańcucha śledzącego jako operacje z Alexem Stokesem](https://www.youtube.com/watch?v=CcL9RJBljUs) - [Zrozumienie efektywnego bilansu walidatora](https://www.attestant.io/posts/understanding-validator-effective-balance/) diff --git a/public/content/translations/pt-br/about/index.md b/public/content/translations/pt-br/about/index.md index 7b62188d139..bd53d2f5084 100644 --- a/public/content/translations/pt-br/about/index.md +++ b/public/content/translations/pt-br/about/index.md @@ -104,7 +104,7 @@ Nós usamos um conjunto de [princípios de design](/contributing/design-principl Construímos e lançamos um [sistema de design](https://www.figma.com/file/NrNxGjBL0Yl1PrNrOT8G2B/ethereum.org-Design-System?node-id=0%3A1&t=QBt9RkhpPqzE3Aa6-1) para enviar funcionalidades mais rapidamente e permitir que os membros da comunidade participem do design aberto do ethereum.org. -Quer se envolver?[Acompanhe no Figma](https://www.figma.com/file/NrNxGjBL0Yl1PrNrOT8G2B/ethereum.org-Design-System), [assuntos no GitHub](https://github.com/ethereum/ethereum-org-website/issues/6284) e junte-se à conversa em nosso [canal #design no Discord](https://discord.gg/ethereum-org). +Quer se envolver?[Acompanhe no Figma](https://www.figma.com/file/NrNxGjBL0Yl1PrNrOT8G2B/ethereum.org-Design-System), [assuntos no GitHub](https://github.com/ethereum/ethereum-org-website/issues/6284) e junte-se à conversa em nosso [canal #design no Discord](https://discord.gg/bKycYhVUwV). ## Guia de estilo {#style-guide} diff --git a/public/content/translations/pt-br/community/code-of-conduct/index.md b/public/content/translations/pt-br/community/code-of-conduct/index.md index 86f60aaa7f5..97f86892aa1 100644 --- a/public/content/translations/pt-br/community/code-of-conduct/index.md +++ b/public/content/translations/pt-br/community/code-of-conduct/index.md @@ -52,7 +52,7 @@ Exemplos de comportamento inaceitável por parte dos participantes incluem: - Violência física, ameaça de violência física ou incentivo à violência física de qualquer tipo - Usar linguagem ou imagens sexualizadas ou impor atenção sexual indesejada -- Fazer-se passar por outra pessoa ou reivindicar, de forma desonesta, afiliação a alguma pessoa ou organização. +- Fazer-se passar por outra pessoa ou reivindicar, de forma desonesta, afiliação a alguma pessoa ou organização - Brincadeiras de mau gosto, comentários ofensivos/pejorativos e ataques pessoais ou políticos - Assediar outros membros da comunidade em canais públicos ou privados - Publicar informações privadas de outras pessoas, como endereço físico ou eletrônico, sem permissão explícita diff --git a/public/content/translations/pt-br/community/get-involved/index.md b/public/content/translations/pt-br/community/get-involved/index.md index ae0f42d6c1b..800711d9be5 100644 --- a/public/content/translations/pt-br/community/get-involved/index.md +++ b/public/content/translations/pt-br/community/get-involved/index.md @@ -28,7 +28,7 @@ Você tem formação em matemática, criptografia ou economia? Talvez tenha inte - Escreva ou avalie uma proposta de melhoria do Ethereum (EIP) - Escreva uma EIP 1. Envie a sua ideia em [Ethereum Magicians](https://ethereum-magicians.org) - 2. Leia a [EIP-1](https://eip.ethereum.org/EIPS/eip-1) - **Sim, esse é o documento _na íntegra_.** + 2. Leia a [EIP-1](https://eips.ethereum.org/EIPS/eip-1) - **Sim, esse é o documento _na íntegra_.** 3. Siga as orientações estabelecidas na EIP-1. Consulte-a ao redigir a sua versão preliminar. - Saiba como se tornar um [editor de EIP](https://eips.ethereum.org/EIPS/eip-5069) - Você pode fazer a revisão por pares de EIPs agora mesmo! Consulte os [PRs abertos com a tag `e-review`](https://github.com/ethereum/EIPs/pulls?q=is%3Apr+is%3Aopen+label%3Ae-review). Envie feedback técnico por meio do link `discussion-to`. diff --git a/public/content/translations/pt-br/community/grants/index.md b/public/content/translations/pt-br/community/grants/index.md index e854cc23703..9c95ed0a19c 100644 --- a/public/content/translations/pt-br/community/grants/index.md +++ b/public/content/translations/pt-br/community/grants/index.md @@ -15,31 +15,27 @@ Esta página é administrada por nossa comunidade. Se houver algo faltando ou er Esses programas abrangem um amplo ecossistema Ethereum ao oferecer recompensas a um grande escopo de projetos. Eles incluem soluções de dimensionamento, formação de comunidades, segurança, privacidade e muito mais. Essas recompensas não são específicas de nenhuma plataforma Ethereum e são um bom lugar para começar se você não tiver certeza. - [ Programa de suporte ao ecossistema EF](https://esp.ethereum.foundation)-_ Financiar projetos de código aberto que beneficiam o Ethereum, com foco particular em ferramentas universais, infraestrutura, pesquisa e bens públicos _ -- [ Ethereum RFP](https://github.com/ethereum/requests-for-proposals)-_ Solicitações de propostas da Fundação Ethereum para trabalho e projetos no seu ecossistema_ - [MetaCartel](https://www.metacartel.org/grants/) – _Desenvolvimento de Dapp, criação de DAO_ - [Moloch DAO](https://www.molochdao.com/) – _Privacidade, dimensionamento da camada 2, segurança do cliente e mais_ -- [Recompensas abertas](https://opengrants.com/explore) - [Concessões DAO](https://docs.google.com/spreadsheets/d/1XHc-p_MHNRdjacc8uOEjtPoWL86olP4GyxAJOFO0zxY/edit#gid=0) – _Planilha Google de organizações que oferecem concessões_ -- [Crunchbase para subvenções Web3](https://www.cryptoneur.xyz/web3-grants) – _Filtre e pesquise subvenções por categoria, caso de uso, valor e muito mais. Contribua para ajudar outros a encontrar a subvenção certa._ +- [Crunchbase para concessões Web3](https://www.cryptoneur.xyz/web3-grants) – _Filtre e pesquise subvenções por categoria, caso de uso, valor e muito mais. Contribua para ajudar outros a encontrar a concessão certa._ - [Bolsas acadêmicas](https://esp.ethereum.foundation/academic-grants) – _Bolsas para apoiar o trabalho acadêmico relacionado com o Ethereum_ +- [Blockworks Grantfarm](https://blockworks.co/grants/programs) - _A Blockworks compilou um diretório abrangente de todas as recompensas, RFPs e programas de caça a bugs._ ## Especificidades do projeto {#project-specific} Estes projetos criaram seus próprios programas de recompensas destinados a desenvolvimento e experimentação de suas tecnologias. - [Programa de concessões Aave](https://aavegrants.org/) – _[Aave](https://aave.com/) concede DAO_ -- [Balancer](https://balancergrants.notion.site/Balancer-Community-Grants-23e562c5bc4347cd8304637bff0058e6) – _Fundo do ecossistema [Balancer](https://balancer.fi/)_ +- [Balancer](https://quark-ceres-740.notion.site/Balancer-Grants-938f1b979810427f8d903a904315da41) – _Fundo do ecossistema [Balancer](https://balancer.fi/)_ - [Programa de concessões da Chainlink](https://chain.link/community/grants) – _Concessões da comunidade da [Chainlink](https://chain.link/)_ -- [Programa de concessões Compound](https://compoundgrants.org/) – _Ecossistema financeiro [Compound](https://compound.finance/)_ -- [Programa de Recompensas Decentraland](https://governance.decentraland.org/grants/) – _[Decentraland](https://decentraland.org/)Metaverso DAO_ -- [Organização de concessões do ecossistema Lido (LEGO)](https://lego.lido.fi/) – _Ecossistema financeiro [Lido](https://lido.fi/)_ +- [Programa de recompensas Decentraland](https://governance.decentraland.org/grants/) – _[Decentraland](https://decentraland.org/)Metaverso DAO_ +- [Lido Ecosystem Grants Organisation (LEGO)](https://lido.fi/lego) – _Ecossistema financeiro [Lido](https://lido.fi/)_ - [Programa MetaMask](https://metamaskgrants.org/) - _[MetaMask](https://metamask.io/) bolsas lideradas por funcionários DAO_ -- [Programa de bolsas mStable](https://docs.mstable.org/advanced/grants-program) – _Comunidade [mStable](https://mstable.org/)_ - [Programa de bolsas da SKALE Network](https://skale.space/developers#grants) - _[Ecossistema da SKALE Network](https://skale.space/)_ - [The Graph](https://airtable.com/shrdfvnFvVch3IOVm) – _Ecossistema [The Graph](https://thegraph.com/)_ -- [Programa de bolsas UMA](https://grants.umaproject.org/): _[suporte ao desenvolvedor](https://umaproject.org/)UMA_ -- [Programa de bolsas da Uniswap](https://www.unigrants.org/) – _Comunidade [Uniswap](https://uniswap.org/)_ -- [Bolsas Web3](https://web3grants.net) – _Uma extensa lista de programas de bolsas relacionados com web3/criptomoedas_ +- [Uniswap Grants Program](https://www.uniswapfoundation.org/apply-for-a-grant) - _[Comunidade da Uniswap](https://uniswap.org/)_ +- [Web3 Grants](https://web3grants.net) – _Uma extensa lista de programas de concessão web3/crypto relacionados_ ## Financiamento quadrático {#quadratic-funding} diff --git a/public/content/translations/pt-br/community/language-resources/index.md b/public/content/translations/pt-br/community/language-resources/index.md index e67a8b6cec5..dc97cadd3db 100644 --- a/public/content/translations/pt-br/community/language-resources/index.md +++ b/public/content/translations/pt-br/community/language-resources/index.md @@ -72,7 +72,7 @@ Se você for bilíngue e deseja nos ajudar a alcançar mais pessoas, também pod - [Gwei.cz](https://gwei.cz) – Comunidade local em torno da Web3, que cria conteúdo educacional, organiza eventos online e presenciais - [Gwei.cz Příručka](https://prirucka.gwei.cz/) – Guia Ethereum para iniciantes - [DAO Příručka](https://dao.gwei.cz/) – Guia do iniciante para DAOs -- [ Mastering Ethereum](https://ipfs.infura-ipfs.io/ipfs/bafybeidvuxhnsgfx3tncpfxheqglkjwmdxclknlgd7s7qggd2a6bzgb27m) – Dominando o Ethereum em Tcheco +- [ Mastering Ethereum](https://ipfs.io/ipfs/bafybeidvuxhnsgfx3tncpfxheqglkjwmdxclknlgd7s7qggd2a6bzgb27m) – Dominando o Ethereum em Tcheco ### Francês {#fr} diff --git a/public/content/translations/pt-br/community/online/index.md b/public/content/translations/pt-br/community/online/index.md index 86ecbb5c9d3..f033df02b2d 100644 --- a/public/content/translations/pt-br/community/online/index.md +++ b/public/content/translations/pt-br/community/online/index.md @@ -24,13 +24,13 @@ Centenas de milhares de entusiastas do Ethereum se reúnem nestes fóruns na Int Ethereum Cat Herders –Comunidade orientada em torno da oferta de apoio à gestão de projetos para o desenvolvimento do Ethereum Ethereum Hackers – Chat no Discord administrado pela ETHGlobal: uma comunidade online para hackers Ethereum em todo o mundo CryptoDevs – Comunidade Discord focada no desenvolvimento do Ethereum -EthStaker Discord - orientação, educação, apoio e recursos geridos pela comunidade para stakers existentes e potenciais +EthStaker Discord - orientação, educação, apoio e recursos geridos pela comunidade para stakers existentes e potenciais Equipe do site Ethereum.org – pare e converse sobre desenvolvimento e design do site ethereum.org com a equipe e pessoas da comunidade Matos Discord – comunidade de criadores da Web3 na qual construtores, líderes do setor e entusiastas do Ethereum se encontram. Somos apaixonados pelo desenvolvimento, design e cultura Web3. Venha criar conosco. -Solidity Gitter — chat para desenvolvimento do solidity (Gitter) +Solidity Gitter — chat para desenvolvimento do solidity (Gitter) Solidity Matrix — chat para desenvolvimento do solidity (Matrix) -Ethereum Stack Exchange _ — fórum de perguntas e respostas_ -Peeranha _ — fórum descentralizado de perguntas e respostas_ +Ethereum Stack Exchange — fórum de perguntas e respostas +Peeranha — fórum descentralizado de perguntas e respostas ## YouTube e Twitter {#youtube-and-twitter} diff --git a/public/content/translations/pt-br/community/research/index.md b/public/content/translations/pt-br/community/research/index.md index 88436fb1277..04a436a8941 100644 --- a/public/content/translations/pt-br/community/research/index.md +++ b/public/content/translations/pt-br/community/research/index.md @@ -124,7 +124,7 @@ Uma área específica da camada 2 que exige mais pesquisa e desenvolvimento são - [Introdução às pontes de blockchain](/bridges/) - [Vitalik sobre pontes](https://old.reddit.com/r/ethereum/comments/rwojtk/ama_we_are_the_efs_research_team_pt_7_07_january/hrngyk8/) - [Artigo de pontes de blockchain](https://medium.com/1kxnetwork/blockchain-bridges-5db6afac44f8) -- [Valor bloqueado em pontes]() +- [Valor bloqueado em pontes](https://dune.com/eliasimos/Bridge-Away-(from-Ethereum)) #### Pesquisa recente {#recent-research-3} @@ -152,11 +152,11 @@ A fragmentação do blockchain do Ethereum faz parte do roadmap de desenvolvimen #### Leitura de apoio {#background-reading-5} -- [Ethereum na ARM](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/) +- [Ethereum on ARM](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/) #### Pesquisa recente {#recent-research-5} -- [ecsda em FGPAs](https://ethresear.ch/t/does-ecdsa-on-fpga-solve-the-scaling-problem/6738) +- [ecdsa em FPGAs](https://ethresear.ch/t/does-ecdsa-on-fpga-solve-the-scaling-problem/6738) ## Segurança {#security} @@ -346,7 +346,6 @@ As ferramentas para desenvolvedores do Ethereum têm melhorado rapidamente. Há - [Frameworks do desenvolvedor](/developers/docs/frameworks/) - [Lista de ferramentas do desenvolvedor de consenso](https://github.com/ConsenSys/ethereum-developer-tools-list) - [Padrões de token](/developers/docs/standards/tokens/) -- [Biastek: ferramentas Ethereum](https://biastek.com/ethereum-tools/) - [CryptoDevHub: ferramentas EVM](https://cryptodevhub.io/wiki/ethereum-virtual-machine-tools) #### Pesquisa recente {#recent-research-17} diff --git a/public/content/translations/pt-br/community/support/index.md b/public/content/translations/pt-br/community/support/index.md index 32eb46c156d..2e94d7c8c43 100644 --- a/public/content/translations/pt-br/community/support/index.md +++ b/public/content/translations/pt-br/community/support/index.md @@ -39,7 +39,7 @@ Procurando uma carteira Ethereum? [Veja a nossa lista completa de carteiras Ethe Desevolver um dapp pode ser difícil. Aqui estão alguns espaços voltados ao desenvolvimento com desenvolvedores Ethereum experientes dispostos a ajudar. - [Universidade Alchemy](https://university.alchemy.com/#starter_code) -- [Discord CryptoDevs](https://discord.gg/Z9TA39m8Yu) +- [Discord CryptoDevs](https://discord.com/invite/5W5tVb3) - [Stackexchange do Ethereum](https://ethereum.stackexchange.com/) - [StackOverflow](https://stackoverflow.com/questions/tagged/web3) - [Universidade Web3](https://www.web3.university/) @@ -53,7 +53,7 @@ Sua pergunta está relacionada a uma ferramenta, projeto ou biblioteca em partic Aqui estão alguns exemplos populares: -- [Solidity](https://gitter.im/ethereum/solidity) +- [Solidity](https://gitter.im/ethereum/solidity/) - [ethers.js](https://discord.gg/6jyGVDK6Jx) - [web3.js](https://discord.gg/GsABYQu4sC) - [Hardhat](https://discord.gg/xtrMGhmbfZ) @@ -65,7 +65,7 @@ Aqui estão alguns exemplos populares: Se você estiver executando um nó ou validador, aqui estão algumas comunidades que se dedicam a ajudá-lo a começar. -- [Discord EthStaker](https://discord.io/ethstaker) +- [Discord EthStaker](https://discord.gg/ethstaker) - [Reddit EthStaker](https://www.reddit.com/r/ethstaker) A maioria das equipes que estão construindo clientes Ethereum também tem espaços dedicados ao público, onde você pode obter suporte e fazer perguntas. diff --git a/public/content/translations/pt-br/contributing/adding-desci-projects/index.md b/public/content/translations/pt-br/contributing/adding-desci-projects/index.md index fb6d6deea0b..07b5b7694f9 100644 --- a/public/content/translations/pt-br/contributing/adding-desci-projects/index.md +++ b/public/content/translations/pt-br/contributing/adding-desci-projects/index.md @@ -37,7 +37,7 @@ O Ethereum é fluido por natureza, por isso, suas equipes e produtos vêm e vão - garantir que todos os projetos listados ainda atendam aos nossos critérios - verificar se não há produtos sugeridos que atendam mais aos nossos critérios do que os atualmente listados -O ethereum.org é mantido pela comunidade de código aberto e dependemos da comunidade para ajudar a mantê-lo atualizado. Se você observar alguma informação sobre os projetos listados que precisam ser atualizados, abra um tíquete ou uma solicitação por pull em nosso repositório do GitHub. +O ethereum.org é mantido pela comunidade de código aberto e dependemos da comunidade para ajudar a mantê-lo atualizado. Se você notar alguma informação sobre projetos listados que precisam ser atualizados, abra um tíquete ou uma solicitação de pull em nosso repositório do GitHub. ## Termos de uso {#terms-of-use} diff --git a/public/content/translations/pt-br/contributing/adding-developer-tools/index.md b/public/content/translations/pt-br/contributing/adding-developer-tools/index.md index 9874eefdaef..11139288968 100644 --- a/public/content/translations/pt-br/contributing/adding-developer-tools/index.md +++ b/public/content/translations/pt-br/contributing/adding-developer-tools/index.md @@ -54,7 +54,7 @@ A menos que os produtos sejam ordenados especificamente de outra forma, como em ## Adicione sua ferramenta de desenvolvedor {#how-decisions-about-the-site-are-made} -Se você deseja adicionar uma ferramenta de desenvolvedor ao ethereum.org e ela atender aos critérios, crie um tíquete no GitHub. +Se você deseja adicionar uma ferramenta de desenvolvedor ao ethereum.org que atende aos critérios, crie um tíquete no GitHub. Criar tíquete diff --git a/public/content/translations/pt-br/contributing/adding-exchanges/index.md b/public/content/translations/pt-br/contributing/adding-exchanges/index.md index d04e1baff27..2ef923a0d70 100644 --- a/public/content/translations/pt-br/contributing/adding-exchanges/index.md +++ b/public/content/translations/pt-br/contributing/adding-exchanges/index.md @@ -20,7 +20,7 @@ Devido a esse contexto, precisaremos de algumas informações específicas quand ## Do que precisamos {#what-we-need} -- As restrições geográficas aplicáveis ao câmbio +- As restrições geográficas aplicáveis ao câmbio. As restrições geográficas associadas ao câmbio devem ser detalhadas em uma página ou seção dedicada do site da corretora de câmbio. - As moedas que os usuários podem usar para comprar ETH - Prova de que a agência de câmbio é uma empresa comercial legítima - Qualquer informação adicional que você tenha: podem ser informações sobre a empresa, como anos de operação, apoio financeiro, etc. diff --git a/public/content/translations/pt-br/contributing/adding-glossary-terms/index.md b/public/content/translations/pt-br/contributing/adding-glossary-terms/index.md index 64eb3ae3f9d..6f5a315b1a9 100644 --- a/public/content/translations/pt-br/contributing/adding-glossary-terms/index.md +++ b/public/content/translations/pt-br/contributing/adding-glossary-terms/index.md @@ -23,4 +23,4 @@ Novos termos inseridos no glossário serão avaliados pelos seguintes critérios ## Adicione seu termo {#how-decisions-about-the-site-are-made} -Se você quiser adicionar um termo ao glossário no ethereum.org e que atenda aos critérios, [ abra um tíquete no GitHub](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=feature+%3Asparkles%3A%2Ccontent+%3Afountain_pen%3A&template=suggest_glossary_term.yaml). +Se você quiser adicionar um termo ao glossário no ethereum.org que atenda aos critérios, [abra um tíquete no GitHub](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=feature+%3Asparkles%3A%2Ccontent+%3Afountain_pen%3A&template=suggest_glossary_term.yaml). diff --git a/public/content/translations/pt-br/contributing/adding-layer-2s/index.md b/public/content/translations/pt-br/contributing/adding-layer-2s/index.md index 2f75be526bb..8bd03a8ee16 100644 --- a/public/content/translations/pt-br/contributing/adding-layer-2s/index.md +++ b/public/content/translations/pt-br/contributing/adding-layer-2s/index.md @@ -90,7 +90,7 @@ _Não consideramos outras soluções de dimensionamento que não usam o Ethereum ## Adicione sua camada 2 {#add-exchange} -Se você deseja adicionar a camada 2 ao ethereum.org, crie um tíquete no GitHub. +Se você quiser adicionar uma camada 2 ao ethereum.org, abra um tíquete no Github. Crie um ticket diff --git a/public/content/translations/pt-br/contributing/adding-products/index.md b/public/content/translations/pt-br/contributing/adding-products/index.md index 61ebb3f3f62..21ecdd5bd30 100644 --- a/public/content/translations/pt-br/contributing/adding-products/index.md +++ b/public/content/translations/pt-br/contributing/adding-products/index.md @@ -85,7 +85,7 @@ O Ethereum é fluido por natureza, por isso, suas equipes e produtos vêm e vão - garantir que todos os dapps listados continuem atendendo a nossos critérios - verificar se não há produtos sugeridos que atendam mais aos nossos critérios do que os atualmente listados -Você pode nos ajudar com isso, verificando e nos informando. [Abra um tíquete](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=Type%3A+Feature&template=feature_request.yaml&title=) ou envie um email para[website@ethereum.org](mailto:website@ethereum.org) +Você pode nos ajudar com isso, verificando e nos informando. [Abra um tíquete](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=Type%3A+Feature&template=feature_request.yaml&title=) ou envie um e-mail para[website@ethereum.org](mailto:website@ethereum.org) _Estamos também investigando opções de votação para que a comunidade possa indicar suas preferências e destacar os melhores produtos disponíveis para recomendarmos._ @@ -93,7 +93,7 @@ _Estamos também investigando opções de votação para que a comunidade possa ## Adicione seu produto {#add-your-product} -Se você quiser adicionar um dapp ao ethereum.org e ele atender aos critérios, crie um tíquete no GitHub. +Se você quiser adicionar um dapp ao ethereum.org e ele atender aos critérios, abra um tíquete no GitHub. Criar um novo problema diff --git a/public/content/translations/pt-br/contributing/adding-staking-products/index.md b/public/content/translations/pt-br/contributing/adding-staking-products/index.md index 3fcf88e2410..393d0e7f9f7 100644 --- a/public/content/translations/pt-br/contributing/adding-staking-products/index.md +++ b/public/content/translations/pt-br/contributing/adding-staking-products/index.md @@ -8,7 +8,7 @@ lang: pt-br Queremos ter certeza de que listamos os melhores recursos possíveis, mantendo os usuários seguros e confiantes. -Qualquer pessoa é livre para sugerir a adição de participações em produtos ou serviços no ethereum.org. Se houver algum que esquecemos, **[sugira aqui](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=feature+%3Asparkles%3A%2Ccontent+%3Afountain_pen%3A&template=suggest_staking_product.yaml)!** +Qualquer pessoa é livre para sugerir a adição de participações em produtos ou serviços no ethereum.org. Se houver algum de que esquecemos, **[sugira aqui](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=feature+%3Asparkles%3A%2Ccontent+%3Afountain_pen%3A&template=suggest_staking_product.yaml)!** Atualmente, listamos participações em produtos e serviços nas seguintes páginas: @@ -20,7 +20,7 @@ A prova de participação na Beacon Chain está ativa desde 1 de dezembro de 202 ## O framework de decisão {#the-decision-framework} -A decisão de listar um produto no ethereum.org não depende de um único fator. Vários critérios são considerados em conjunto ao decidir listar um produto ou serviço. Quanto esses critérios ou mais forem atendidos, maior será a probabilidade de eles serem listados. +A decisão de listar um produto no ethereum.org não depende de um único fator. Vários critérios são considerados em conjunto ao decidir listar um produto ou serviço. Quanto mais desses critérios forem atendidos, maior será a probabilidade de eles serem listados. **Primeiro, de qual categoria de produto ou serviço isso se trata?** @@ -29,7 +29,7 @@ A decisão de listar um produto no ethereum.org não depende de um único fator. - Participação como Serviço (SaaS) - Pool de participação (staking) -Atualmente, estamos listando apenas produtos ou serviços nessas categorias. +Atualmente, estamos apenas listando produtos ou serviços nessas categorias. ### Critérios para inclusão {#criteria-for-inclusion} @@ -50,6 +50,11 @@ As submissões de produtos ou serviços de participação serão avaliadas pelos - Quais etapas na jornada dos usuários exigem que humanos de confiança tenham as chaves de seus fundos ou distribuam recompensas adequadamente? - Isso é usado para determinar a pontuação de produtos e serviços "sem confiança". +**O projeto fornece informação precisa e confiável?** + +- É crucial que o website do produto exiba informações atualizadas, precisas e que não induzam a erro, particularmente se ele pertence ao protocolo Ethereum ou outras tecnologias relacionadas. +- Envios contendo informações incorretas, detalhes desatualizados, afirmações potencialmente confusas sobre o Ethereum ou outros assuntos relevantes não serão listadas, ou serão removidas se já estiverem listadas. + **Quais plataformas são suportadas?** - ou seja, Linux, macOS, Windows, iOS, Android @@ -63,7 +68,7 @@ Para qualquer sistema personalizado ou contrato inteligente envolvido: - Projetos de código aberto devem ter um repositório de código-fonte disponível publicamente - Isso é usado para determinar a pontuação de "código aberto" dos produtos. -**O produto está fora do desenvolvimento _beta_?** +**O produto está fora do desenvolvimento de uma versão _beta_?** - Onde se encontra o produto em seu ciclo de desenvolvimento? - Os produtos na fase beta não são considerados para inclusão no ethereum.org @@ -82,14 +87,14 @@ Para qualquer sistema personalizado ou contrato inteligente envolvido: Para produtos de software relacionados à configuração de nó ou cliente, gerenciamento ou migração: -**Quais clientes da camada de consenso (por exemplo, Lighthouse, Teku, Nimbus, Prysm) são suportados?** +**Quais clientes da camada de consenso (como Lighthouse, Teku, Nimbus, Prysm) são suportados?** - Quais clientes são suportados? O usuário pode escolher? - Isso é usado para determinar a pontuação dos produtos "multicliente". #### Participação sobre Serviço {#staking-as-a-service} -Para [listagens de participação como serviço](/staking/saas/) (ou seja, operação de nó delegado): +Para [listagens de staking-as-a-service](/staking/saas/) (ou seja, operação de nó delegada): **Quais são as taxas associadas ao uso do serviço?** @@ -108,7 +113,7 @@ Para [listagens de participação como serviço](/staking/saas/) (ou seja, opera **Qual é a diversidade de clientes dos nós que estão sendo operados?** -- Qual é a porcentagem de chaves do validador sendo executadas por um cliente para constituir a camada de consenso (CL)? +- Que percentual de chaves validadoras estão sendo rodadas pela por uma maioria de clientes de camada de consenso (CL)? - Na última edição, o Prysm é o cliente da camada de consenso executado pela maioria dos nós operadores, o que é perigoso para a rede. Se um cliente atualmente estiver usando mais de 33% da rede, solicitamos os dados relacionados a esse uso. - Isso é usado para determinar a pontuação de “diversidade de clientes” dos produtos. @@ -123,7 +128,7 @@ Para [serviços de participação (stake) em pool](/staking/pools/): **Quais são as taxas ou requisitos de participação (stake) envolvidos?** - Qual é o percentual de recompensas removidas como taxas? -- Quaisquer requisitos adicionais de participação? +- Você tem requisitos adicionais de participação (staking)? **Há um token de liquidez?** @@ -139,14 +144,14 @@ Para [serviços de participação (stake) em pool](/staking/pools/): **Qual é a diversidade de clientes dos operadores de nós em pool?** - Qual é a porcentagem de operadores de nós que usam um cliente da camada de consenso? -- Na última edição, o Prysm é o cliente da camada de concenso executado pela maioria dos nós operadores, o que é perigoso para a rede. Se qualquer cliente CL está atualmente sendo usado acima de 33% da rede, ele pede os dados relacionados para o uso. -- Isso é usado para determinar a pontuação de "clientes distintos" dos produtos. +- Na última edição, o Prysm é o cliente da camada de consenso executado pela maioria dos nós operadores, o que é perigoso para a rede. Se um cliente atualmente estiver usando mais de 33% da rede, solicitamos os dados relacionados a esse uso. +- Isso é usado para determinar a pontuação de “diversidade de clientes” dos produtos. ### Outros critérios: os bons para ter {#other-criteria} **Quais interfaces de usuário são suportadas?** -- Por exemplo, Aplicativos de navegador, desktop, mobile ou CLI +- ou seja, Aplicativos de navegador, desktop, mobile ou CLI **Para ferramentas de nós, o software fornece uma maneira fácil de alternar entre clientes?** @@ -158,13 +163,13 @@ Para [serviços de participação (stake) em pool](/staking/pools/): ## Como exibimos os resultados {#product-ordering} -Os [critérios de inclusão](#criteria-for-inclusion) acima são usados para calcular a pontuação acumulada para cada produto ou serviço. Isso é usado como meio de classificação e apresentação de produtos que atendem a determinados critérios objetivos. Quanto mais critérios forem fornecidos para essa evidência, maior será a classificação de um produto, com ligações carregadas aleatoriamente. +Os [critérios de inclusão](#criteria-for-inclusion) acima são usados para calcular a pontuação acumulada para cada produto ou serviço. Isso é usado como meio de classificação e apresentação de produtos que atendem a determinados critérios objetivos. Quanto mais critérios forem fornecidos para essa evidência, maior será a classificação de um produto, com ligações exibidas aleatoriamente durante o carregamento. Atualmente, a lógica e os valores do código para esses critérios estão contidos [neste componente JavaScript](https://github.com/ethereum/ethereum-org-website/blob/dev/src/components/Staking/StakingProductsCardGrid.js#L350) em nosso repositório. ## Adicione seu produto ou serviço {#add-product} -Se você quiser adicionar uma participação (stake) de produto ou serviço ao ethereum.org, crie um tíquete no GitHub. +Se você quiser adicionar uma participação (stake) de produto ou serviço ao ethereum.org, crie um tíquete no Github. Crie um ticket diff --git a/public/content/translations/pt-br/contributing/content-resources/index.md b/public/content/translations/pt-br/contributing/content-resources/index.md index 1cdd883e273..8215db0dd93 100644 --- a/public/content/translations/pt-br/contributing/content-resources/index.md +++ b/public/content/translations/pt-br/contributing/content-resources/index.md @@ -25,7 +25,7 @@ Conteúdos de aprendizado serão avaliados pelos seguintes critérios: ## Adicione seu recurso de conteúdo {#add-your-content-resource} -Se você deseja adicionar uma fonte de conteúdo que atende aos critérios ao ethereum.org, crie um tíquete no GitHub. +Se você deseja adicionar uma fonte de conteúdo ao ethereum.org que atende aos critérios, abra um tíquete no GitHub. Criar um novo problema diff --git a/public/content/translations/pt-br/contributing/design/adding-design-resources/index.md b/public/content/translations/pt-br/contributing/design/adding-design-resources/index.md new file mode 100644 index 00000000000..29f23778127 --- /dev/null +++ b/public/content/translations/pt-br/contributing/design/adding-design-resources/index.md @@ -0,0 +1,67 @@ +--- +title: Adicionando recursos de design +description: Diretrizes e requisitos para garantir a qualidade dos materiais de design no ethereum.org +lang: pt-br +--- + +Qualquer pessoa pode sugerir novos materiais de design para a página de [Design e UX na web3](/developers/docs/design-and-ux/). + +Esteja ciente de que o foco desta página é fornecer valor ao usuário para candidatos a designers web3. A seção de design não está lá para anunciar seus serviços, produtos ou plataformas. + +Para garantir que possamos manter um alto padrão de informações e promover visões valiosas, estabelecemos uma política de listagem: + +## Estudos de Pesquisa e Painéis {#Research-studies} + +1. Metodologia do Som + +a. A metodologia deve definir claramente como os dados foram coletados. + +b. O número de participantes envolvidos na pesquisa deve ser informado. + +c. Os métodos de pesquisa empregados devem ser descritos. + +2. Relevância para designers Web3 e casos de uso comuns de design + +a. O tópico da pesquisa deve ser relevante para designers web3 e abordar casos de uso comuns de design. + +3. Foco no fornecimento de informações + +a. O objetivo principal do texto deve ser compartilhar informações em vez de promover um projeto ou empresa específica. + +## Artigos {#Articles} + +1. Relevância para Designers/Pesquisadores Web3 e Casos de Uso Comuns de Design Web3 + +a. O tópico do artigo deve ser pertinente para designers e pesquisadores web3, com foco em casos de uso comuns de design web3. + +2. Qualidade básica de redação + +a. O artigo deve estar livre de erros gramaticais e ortográficos. + +b. A ênfase deve ser colocada na entrega de informações e aprendizados fundamentais. + +c. A redação deve ser concisa e direta. + +3. Objetivo do texto + +a. O objetivo principal do artigo deve ser compartilhar informações em vez de promover um determinado projeto ou empresa. + +## Comunidades / DAOs {#Communities-and-DAOs} + +1. O site deve indicar claramente como participar da Comunidade/DAO + +2. Benefícios claros de ser um membro + +a. Os benefícios de se tornar um membro devem ser apresentados em destaque. + +**Exemplos**: receber comentários sobre o trabalho, acessar oportunidades de trabalho ou recompensas, compartilhar conhecimentos de design e pesquisa. + +3. Comunicação ativa e vibrante no Discord + +a. A comunidade do Discord deve exibir uma comunicação ativa e engajada. + +b. Os moderadores devem se envolver ativamente na manutenção da comunidade e na facilitação de discussões. + +c. A comunidade deve demonstrar um histórico de conversas valiosas e produtivas nas últimas duas semanas. + +Ao aderir a esses critérios, nosso objetivo é promover um ambiente próspero e de compartilhamento de conhecimento em nossa comunidade. Nós acreditamos que esta política de lista branca vai garantir que nossos usuários tenham acesso a recursos confiáveis, relevantes e perspicazes. Agradecemos sua compreensão e cooperação para manter a qualidade do conteúdo em nossa plataforma. diff --git a/public/content/translations/pt-br/contributing/design/index.md b/public/content/translations/pt-br/contributing/design/index.md new file mode 100644 index 00000000000..6699fa9d24c --- /dev/null +++ b/public/content/translations/pt-br/contributing/design/index.md @@ -0,0 +1,77 @@ +--- +title: Contribuição no design +description: Contribuição no design do ethereum.org +lang: pt-br +--- + +# Contribuição no design do ethereum.org {#design-contributions} + +O design é um componente crítico de qualquer projeto e, dedicando seu tempo e habilidades de design ao Ethereum.org, você pode ajudar a melhorar a experiência do usuário para nossos visitantes. Contribuir para um projeto de código aberto oferece uma oportunidade de ganhar experiência relevante e desenvolver suas habilidades em um ambiente colaborativo. Você terá a chance de trabalhar com outros designers, desenvolvedores e membros da comunidade, todos com suas próprias perspectivas e visões. + +Por fim, essa é uma ótima maneira de construir um portfólio diversificado e impressionante que mostre suas habilidades de design. + +## Como contribuir? + +### Forneça feedback sobre os primeiros protótipos de design {#design-critique} + +Às vezes, precisamos de ajuda para testar nossas ideias originais. Esta é uma ótima maneira de como contribuir sem nenhum conhecimento técnico. + +1. A equipe de design compartilhará um desenho de projeto no [Discord](https://discord.com/invite/CetY6Y4) e no [GitHub](https://github.com/ethereum/ethereum-org-website/labels/design%20required%20%F0%9F%8E%A8). +2. Você será guiado pelos projetos para fornecer feedback por meio da função de comentários. +3. O resultado será compartilhado em problemas do GitHub e depois fechado pela equipe. + +### Participe da pesquisa de levantamento {#answer-surveys} + +Forneça seus comentários em nosso site: + +1. Visitando ethereum.org e lendo as páginas. +2. Clicando no widget de feedback no canto inferior direito e respondendo a perguntas relacionadas ao design e conteúdo. +3. Foque nas perguntas de formato livre. + +### Encontre problemas relacionados ao design no site e reporte-os {#report-design-issues} + +O Ethereum.org é um site de rápido crescimento com muitos recursos e conteúdo. Algumas das interfaces de usuário podem facilmente se tornar obsoletas ou poderiam ser aprimoradas. Se você encontrar qualquer caso parecido, por favor reporte ele para que chame a nossa atenção. + +1. Acesse o site e preste atenção em seu design. +2. Faça capturas de tela e anotações se você notar algum problema visual ou de experiência do usuário. +3. Reporte os problemas encontrados usando um [formulário de bug](https://github.com/ethereum/ethereum-org-website/issues/new/choose). + +### Proponha mudanças de design {#propose-design-changes} + +Se você se sente à vontade para enfrentar desafios de design, visite nosso quadro de problemas do GitHub e filtre por [problemas relacionados ao design](https://github.com/ethereum/ethereum-org-website/labels/design%20required%20%F0%9F%8E%A8). + +1. Vá ao nosso site e preste atenção em seu design ou acesse nosso repositório GitHub e analise os problemas sinalizados com a [Etiqueta "Design necessário"](https://github.com/ethereum/ethereum-org-website/labels/design%20required%20%F0%9F%8E%A8). +2. Idealize a solução e desenhe-a. (idealmente usando nosso [sistema de design](https://www.figma.com/community/file/1134414495420383395)). +3. Proponha a solução no tíquete do GitHub correspondente ou [abra um novo.](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=feature+%3Asparkles%3A&template=feature_request.yaml&title=Feature+request) +4. Aguarde a revisão do time de design. + +### Construir o Sistema de Design juntos {#Contribute-to-design-system} + +Nosso sistema de design torna o projeto ethereum.org divertido e fácil. Se você é um designer experiente, você pode nos ajudar a preparar muitos componentes para o site. + +1. Selecione um problema para trabalhar no painel [sobre sistema de design](https://github.com/ethereum/ethereum-org-website/labels/design%20system) no GitHub ou crie um novo. +2. Peça que o problema selecionado seja atribuído a você. +3. Comece a projetar o componente solicitado na figma. +4. Compartilhe-o com a equipe de design no GitHub, assim que você precisar de revisão ou orientação. +5. A equipe de design revisará. +6. A equipe de design vai incorporar as mudanças no arquivo principal e publicará o arquivo para a comunidade. + +### Escreva o conteúdo relacionado ao design no site {#write-design-articles} + +A comunidade de desenvolvedores Ethereum é forte, mas a comunidade de design está ficando um pouco para trás. Se você é um designer com conhecimento em web3, por favor, considere compartilhar seus aprendizados com a comunidade maior, para que todos possamos crescer e melhorar juntos; temos [uma página sobre design para Ethereum](/developers/docs/design-and-ux/) para a qual você pode contribuir. Você também pode verificar nossas [políticas de listagem](/contributing/design/adding-design-resources). + +1. Idealize sobre tópicos de design que devem ser cobertos no ethereum.org e seriam benéficos para os designers no espaço. +2. Vá ao nosso repositório do GitHub e [levante um problema](https://github.com/ethereum/ethereum-org-website/issues/new) propondo um tópico (não escreva o conteúdo ainda). +3. Aguarde a aprovação do time de design. +4. Uma vez aprovado, escreva o conteúdo. +5. Envie-o no problema GH correspondente. + +### Desenhe novas ilustrações {#prepare-illustrations} + +As visualizações são uma das ferramentas mais poderosas para explicar tópicos abstratos. Há um enorme potencial ao adicionar diagramas e infográficos. Afinal, uma imagem pode dizer mil palavras. + +1. Vá ao nosso site e veja as páginas onde alguns novos infográficos poderiam ser adicionados. +2. Certifique-se de que o estilo da ilustração corresponda aos nossos [recursos](/assets/). +3. Vá ao nosso repositório GitHub e [levante um problema](https://github.com/ethereum/ethereum-org-website/issues/new) propondo a ilustração. +4. A equipe de design irá analisá-lo. +5. Nós criamos um novo problema para pedir a um desenvolvedor que implemente a nova imagem. diff --git a/public/content/translations/pt-br/contributing/index.md b/public/content/translations/pt-br/contributing/index.md index 2a9febc4d48..46cb5a86a9c 100644 --- a/public/content/translations/pt-br/contributing/index.md +++ b/public/content/translations/pt-br/contributing/index.md @@ -16,10 +16,10 @@ O site ethereum.org, como o Ethereum de forma mais ampla, é um projeto de códi ## Formas de contribuir {#ways-to-contribute} - [Trabalhe em um tíquete aberto](https://github.com/ethereum/ethereum-org-website/issues) _ — Trabalho pendente identificado_ -- [Participe do programa de tradução](/contributing/translation-program/) _ — Ajude-nos a traduzir o ethereum.org para novos idiomas_ -- [Ajude com o design do site](/contributing/design/) _ — Designers de todos os níveis podem contribuir para melhorar o site_ +- [Participar do programa de tradução](/contributing/translation-program/) _ — Ajude-nos a traduzir o ethereum.org para novos idiomas_ +- [Ajudar com o design do site](/contributing/design/) _ — Designers de todos os níveis podem contribuir para melhorar o site_ - [Adicionar recursos da comunidade](/contributing/content-resources/) _ — Adicione um artigo ou recurso útil a uma página relevante_ -- [Adicione um produto](/contributing/adding-products/) _ — Adicione um dapp ou carteira a uma página relevante_ +- [Adicionar um produto](/contributing/adding-products/) _ — Adicione um dapp ou carteira a uma página relevante_ - [Adicionar ferramentas de desenvolvedor](/contributing/adding-developer-tools/) _ — Adicione uma ferramenta de desenvolvedor a uma página relevante_ - [Adicionar uma troca](/contributing/adding-exchanges/) _ — Adicione um câmbio ao nosso [localizador de câmbios](/get-eth/#country-picker)_ - [Melhorar nossa pesquisa](https://www.notion.so/efdn/Ethereum-org-User-Persona-Memo-b44dc1e89152457a87ba872b0dfa366c) _ — Envie seus comentários sobre nossa pesquisa ou contribua com a sua própria_ @@ -30,6 +30,8 @@ O site ethereum.org, como o Ethereum de forma mais ampla, é um projeto de códi - [Adicionar um produto ou serviço de staking](/contributing/adding-staking-products/) _ — Adicione um projeto que ajude a facilitar o stake individual, stake combinado ou stake como serviço_ - [Adicionar uma carteira](/contributing/adding-wallets/) _ — Adicione uma carteira à [página de pesquisa de carteiras](/wallets/find-wallet/)_ - [Sugerir um projeto para nossa página DeSci](/contributing/adding-desci-projects/) _ — Adicione um projeto construído no Ethereum que contribua para a ciência descentralizada_ +- [Questionários](/contributing/quizzes/) _- Adicione, atualize e exclua bancos de perguntas do questionário para uma página relevante_ +- [Sugerir um recurso de design](/contributing/design/adding-design-resources/) _- Adicionar, atualizar e excluir recursos úteis de design_ _Alguma dúvida?_ 🤔 Entre em contato no nosso [servidor do Discord](https://discord.gg/ethereum-org) @@ -49,6 +51,7 @@ Antes de contribuir, certifique-se de está familiarizado com: - a [visão do ethereum.org](/about/) em evolução - nossos [princípios de design](/contributing/design-principles/) - nosso [guia de estilo](/contributing/style-guide/) +- nosso [código de conduta](/community/code-of-conduct) ## Como são tomadas as decisões sobre o site {#how-decisions-about-the-site-are-made} @@ -74,13 +77,24 @@ Se a sua contribuição for incluída no ethereum.org, cunharemos um POAP único ### Como solicitar seu POAP {#how-to-claim} -1. Entre em nosso [servidor do Discord](https://discord.gg/ethereum-org). +1. Entre em nosso [servidor do Discord](https://discord.gg/premid). 2. Cole o link com sua contribuição no `#🥇| ` [canal poaps](https://discord.com/channels/714888181740339261/804005643211898911). 3. Espere que um membro de nossa equipe envie um link para o seu POAP. 4. Solicite seu POAP! Você só deve usar carteiras autônomas para reivindicar POAPs. Não use contas de agências de câmbio ou outras contas das quais você não possui as chaves privadas, pois você não poderá acessar ou gerenciar seus POAPs. +## Resgate seu GitPOAP {#claim-gitpoap} + +O GITPOAP também reconhecerá automaticamente sua contribuição fusionada e permitirá que você cunhe um POAP de colaboradores exclusivo e separado na sua própria plataforma! + +### Como solicitar seu POAP {#how-to-claim} + +1. Visite [GitPOAP](https://www.gitpoap.io). +2. Conecte-se à sua carteira ou mesmo ao seu e-mail com a opção de entrada. +3. Procure seu nome de usuário no GitHub, endereço ETH, nomes ENS ou qualquer GitPOAP para verificar se você é elegível. +4. Se sua conta no GitHub for elegível, você poderá cunhar um GitPOAP! + ## Colaboradores {#contributors} diff --git a/public/content/translations/pt-br/contributing/quizzes/index.md b/public/content/translations/pt-br/contributing/quizzes/index.md new file mode 100644 index 00000000000..02f684c109e --- /dev/null +++ b/public/content/translations/pt-br/contributing/quizzes/index.md @@ -0,0 +1,62 @@ +--- +title: Adicionando um questionário +description: A política que nós usamos quando adicionando questionários na ethereum.org +lang: pt-br +--- + +# Questionários {#quizzes} + +Questionários são uma oportunidade para os usuários testarem se entenderam o conteúdo da página que acabaram de ler. As questões devem ser baseadas somente no conteúdo fornecido na página e não deve perguntar sobre informações que não estejam mencionadas na página. + +As questões são estruturadas como a seguir. A questão mostra 1 resposta correta com uma explicação do porquê ela é correta, 3 respostas incorretas com uma explicação do porquê elas são incorretas. + +Alguns exemplos de questionários atuais podem ser encontrados aqui: + +- [Camada 2](/layer-2) +- [NFT](/nft/) +- [O que é o Ethereum?](/what-is-ethereum/) +- [O que é ETH?](/eth/) + +## Adicionando um questionário de aprendizado + +Se há uma página que não tem um questionário de aprendizado criado para ela, por favor [abra um issue](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=&template=suggest_quiz.yaml) para ela. + +Por favor forneça as seguintes informações: + +- A página a qual você quer adicionar um questionário +- 5 questões com as seguintes informações: + - A seção da página em que a questão é baseada + - Enunciado da questão + - 1 resposta correta com uma explicação da razão pela qual ela é correta + - 3 respostas incorretas, cada uma com uma explicação porquê elas são incorretas + +## Adicionando uma pergunta ao questionário + +Se há uma questão que você quer adicionar para o banco de questões para um questionário, por favor [abra um issue](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=&template=suggest_quiz.yaml) e forneça as seguintes informações: + +- A página a qual você quer adicionar uma questão de questionário +- Para cada questão, forneça as seguintes informações: + - A seção da página em que a questão é baseada + - Enunciado da questão + - 1 resposta correta com uma explicação da razão pela qual ela é correta + - 3 respostas incorretas, cada uma com uma explicação porquê elas são incorretas + +## Atualizando uma questão de questionário + +Se há uma questão que você quer atualizar no banco de questões para um questionário, por favor [abra um issue](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=&template=suggest_quiz.yaml) e forneça as seguintes informações: + +- A página à qual você quer atualizar uma questão de questionário +- Para cada questão sendo atualizada, forneça as seguintes informações: + - A seção da página em que a questão é baseada + - Enunciado da questão que você quer atualizar + - Enunciado da questão atualizado + - 1 resposta correta com uma explicação da razão pela qual ela é correta + - 3 respostas incorretas, cada uma com uma explicação porquê elas são incorretas + +## Removendo uma questão de questionário + +Se o conteúdo não existe mais na página de uma questão e ela precisa ser removida, [abra um tíquete](https://github.com/ethereum/ethereum-org-website/issues/new?assignees=&labels=&template=suggest_quiz.yaml) para remover a questão e forneça as seguintes informações: + +- A página à qual você quer excluir uma questão de questionário +- A questão que você quer excluir +- Explicação, se necessário, da razão pela qual a questão deve ser removida diff --git a/public/content/translations/pt-br/contributing/translation-program/faq/index.md b/public/content/translations/pt-br/contributing/translation-program/faq/index.md index 23af6adcb01..de0624572e7 100644 --- a/public/content/translations/pt-br/contributing/translation-program/faq/index.md +++ b/public/content/translations/pt-br/contributing/translation-program/faq/index.md @@ -110,10 +110,10 @@ O processo de revisão é simples: uma vez que um determinado [lote de conteúdo Atualmente, todo o conteúdo que não está na língua inglesa é traduzido diretamente do conteúdo em inglês, e qualquer conteúdo que não esteja nesse idioma não pode ser adicionado a outros idiomas. -Para sugerir um novo conteúdo para o ethereum.org, é possível [registrar uma contribuição](https://github.com/ethereum/ethereum-org-website/issues) no GitHub. Se adicionado, o conteúdo será escrito em inglês e traduzido para outros idiomas usando o Crowdin. +Para sugerir um novo conteúdo para o ethereum.org, é possível [criar um tíquete](https://github.com/ethereum/ethereum-org-website/issues) no GitHub. Se adicionado, o conteúdo será escrito em inglês e traduzido para outros idiomas usando o Crowdin. Planejamos adicionar suporte para adições de conteúdos que não estejam em inglês em um futuro próximo. ## Entre em contato conosco {#contact} -Agradecemos por ter lido todas estas informações. Esperamos que elas tenham incentivado você a participar de nosso programa. Junte-se ao nosso [canal de tradução do Discord](https://discord.gg/ethereum-org) para fazer perguntas e colaborar com outros tradutores, ou entre em contato conosco em translations@ethereum.org! +Agradecemos por ter lido todas estas informações. Esperamos que elas tenham incentivado você a participar de nosso programa. Junte-se ao nosso [canal de tradução do Discord](https://discord.gg/XVepFu7sqR) para fazer perguntas e colaborar com outros tradutores, ou entre em contato conosco em translations@ethereum.org! diff --git a/public/content/translations/pt-br/contributing/translation-program/how-to-translate/index.md b/public/content/translations/pt-br/contributing/translation-program/how-to-translate/index.md index 19a63214c8c..5e4f9bdd65e 100644 --- a/public/content/translations/pt-br/contributing/translation-program/how-to-translate/index.md +++ b/public/content/translations/pt-br/contributing/translation-program/how-to-translate/index.md @@ -18,7 +18,7 @@ Para as pessoas que aprendem melhor de forma visual, assistam ao vídeo do Luka Você precisará fazer login na sua conta do Crowdin ou criar uma conta, caso ainda não tenha. Você só precisa de uma conta de e-mail e senha para se cadastrar. - + Junte-se ao projeto @@ -38,7 +38,7 @@ Não vê seu idioma na lista? [Abra um tíquete](https://github.com/ethereum/eth ![Arquivos traduzidos e não traduzidos no Crowdin](./crowdin-files.png) -Uma nota sobre recipientes de conteúdo: utilizamos “recipientes de conteúdos” dentro do Crowdin para ter o conteúdo de prioridade mais alta lançado primeiro. Ao verificar um idioma, por exemplo, [Filipino](https://crowdin.com/project/ethereum-org/fil#) você verá pastas por categoria de conteúdo (“1. Página inicial", "2. Use páginas do Ethereum” etc.). +Uma nota sobre recipientes de conteúdo: utilizamos “recipientes de conteúdos” dentro do Crowdin para ter o conteúdo de prioridade mais alta lançado primeiro. Ao verificar um idioma, por exemplo, [Filipino](https://crowdin.com/project/ethereum-org/fil#) você verá pastas por categoria de conteúdo (“1. Página inicial", "2. Essenciais", "3. Explorando”, etc.). Recomendamos que você traduza nesta ordem numérica (1 → 2 → 3 → ⋯) para assegurar que as páginas de maior impacto sejam traduzidas primeiro. diff --git a/public/content/translations/pt-br/contributing/translation-program/index.md b/public/content/translations/pt-br/contributing/translation-program/index.md index 849c4771ac5..37e0454af91 100644 --- a/public/content/translations/pt-br/contributing/translation-program/index.md +++ b/public/content/translations/pt-br/contributing/translation-program/index.md @@ -22,7 +22,7 @@ O Programa de Tradução do ethereum.org está aberto e qualquer um pode contrib _Junte-se ao [ethereum.org Discord](/discord/) para colaborar com traduções, fazer perguntas, compartilhar comentários e ideias ou juntar-se a um grupo de tradução._ - + Comece a traduzir @@ -36,7 +36,7 @@ Leia mais sobre a [missão e visão](/contributing/translation-program/mission-a ### Nosso progresso até agora {#our-progress} -- [**Mais de 5.000** tradutores](/contributing/translation-program/contributors/) +- [**5.100 +** tradutores](/contributing/translation-program/contributors/) - [**54** idiomas presentes no site](/languages/) - [**3 milhões** de palavras traduzidas em 2022](/contributing/translation-program/acknowledgements/) @@ -77,7 +77,7 @@ Para outras ferramentas úteis de tradução, comunidades de tradutores e postag ## Envolva-se {#get-in-touch} -Você tem alguma dúvida? Ou quer colaborar com nossa equipe e outros tradutores? Publique no canal #translations do nosso [servidor Discord do ethereum.org](https://discord.gg/ethereum-org) +Você tem alguma dúvida? Ou quer colaborar com nossa equipe e outros tradutores? Publique no canal #translations do nosso [servidor Discord do ethereum.org](https://discord.gg/6WX7E97) Você também pode entrar em contato conosco por meio do e-mail translations@ethereum.org diff --git a/public/content/translations/pt-br/contributing/translation-program/resources/index.md b/public/content/translations/pt-br/contributing/translation-program/resources/index.md index 3ba18e0f13d..ec1dbe736be 100644 --- a/public/content/translations/pt-br/contributing/translation-program/resources/index.md +++ b/public/content/translations/pt-br/contributing/translation-program/resources/index.md @@ -38,7 +38,7 @@ Para se manter atualizado sobre os avanços mais recentes do Programa de Traduç ## Horários de trabalho para tradutores {#office-hours} -Temos horários de plantão para tradutores na segunda quarta-feira de cada mês. Eles são mantidos no canal de voz #horários de plantão no [Discord do ethereum.org](https://discord.gg/geKhWjtF), no qual você também pode encontrar os horários exatos e detalhes adicionais. +Temos horários de plantão para tradutores na segunda quarta-feira de cada mês. Eles são mantidos no canal de voz #horários de plantão no [Discord do ethereum.org](/discord/), no qual você também pode encontrar os horários exatos e detalhes adicionais. O horário de plantão permite que nossos tradutores façam perguntas sobre o processo de tradução, forneçam comentários sobre o programa, compartilhem suas ideias ou simplesmente conversem com a equipe principal do ethereum.org. Por último, queremos usar essas chamadas para comunicar desenvolvimentos recentes no Programa de Tradução e compartilhar dicas importantes e instruções com nossos colaboradores. diff --git a/public/content/translations/pt-br/contributing/translation-program/translators-guide/index.md b/public/content/translations/pt-br/contributing/translation-program/translators-guide/index.md index 79cfe10415a..05ee871ab02 100644 --- a/public/content/translations/pt-br/contributing/translation-program/translators-guide/index.md +++ b/public/content/translations/pt-br/contributing/translation-program/translators-guide/index.md @@ -116,7 +116,7 @@ A melhor maneira de lidar com links é copiá-los diretamente da fonte, clicando ![Exemplo de link.png](./example-of-link.png) -Os links também aparecem no texto de origem na forma de tags (por exemplo, <0> ). Se você passar o mouse por cima da tag, o editor exibirá seu conteúdo completo. Às vezes, essas tags representarão links. +Links também aparecem no texto fonte na forma de tags (ou seja, <0> ). Se você passar o mouse por cima da tag, o editor exibirá seu conteúdo completo. Às vezes, essas tags representarão links. É muito importante copiar os links da origem e não mudar a sua ordem. diff --git a/public/content/translations/pt-br/developers/docs/blocks/index.md b/public/content/translations/pt-br/developers/docs/blocks/index.md index 0756285de93..b238868da7e 100644 --- a/public/content/translations/pt-br/developers/docs/blocks/index.md +++ b/public/content/translations/pt-br/developers/docs/blocks/index.md @@ -40,7 +40,7 @@ Prova de participação significa o seguinte: Há muitas informações contidas em um bloco. No nível mais alto, um bloco contém os seguintes campos: | Campo | Descrição | -| :--------------- | :--------------------------------------------------------- | +|:---------------- |:---------------------------------------------------------- | | `slot` | o slot ao qual o bloco pertence | | `proposer_index` | a ID do validador que propõe o bloco | | `parent_root` | o hash do bloco anterior | @@ -50,7 +50,7 @@ Há muitas informações contidas em um bloco. No nível mais alto, um bloco con O bloco `body` contém vários campos próprios: | Campo | Descrição | -| :------------------- | :------------------------------------------------------------ | +|:-------------------- |:------------------------------------------------------------- | | `randao_reveal` | um valor usado para selecionar o proponente do próximo bloco | | `eth1_data` | informações sobre o contrato de depósito | | `graffiti` | dados arbitrários usados para marcar blocos | @@ -65,7 +65,7 @@ O bloco `body` contém vários campos próprios: O campo `attestations` contém uma lista de todas as atestações no bloco. As atestações têm seu próprio tipo de dados que contém vários dados. Cada atestação contém: | Campo | Descrição | -| :----------------- | :---------------------------------------------------------- | +|:------------------ |:----------------------------------------------------------- | | `aggregation_bits` | uma lista de quais validadores participaram desta atestação | | `data` | um contêiner com vários subcampos | | `signature` | assinatura agregada com todos os validadores de atestação | @@ -73,7 +73,7 @@ O campo `attestations` contém uma lista de todas as atestações no bloco. As a O campo `data` no `attestation` contém o seguinte: | Campo | Descrição | -| :------------------ | :----------------------------------------------- | +|:------------------- |:------------------------------------------------ | | `slot` | o local ao qual a atestação se refere | | `index` | índices para as atestações dos validadores | | `beacon_block_root` | o hash raiz do bloco Beacon contendo este objeto | @@ -85,7 +85,7 @@ A execução das transações no `execution_payload` atualiza o estado global. T O `execution_payload_header` contém os seguintes campos: | Campo | Descrição | -| :------------------ | :----------------------------------------------------------------- | +|:------------------- |:------------------------------------------------------------------ | | `parent_hash` | hash do bloco pai | | `fee_recipient` | endereço da conta para pagar taxas de transação para | | `state_root` | hash raiz para o estado global após aplicar alterações neste bloco | @@ -105,7 +105,7 @@ O `execution_payload_header` contém os seguintes campos: O próprio `execution_payload` contém o seguinte (note que é idêntico ao cabeçalho, exceto que, em vez do hash raiz das transações, ele inclui a lista real de transações e informações de retirada): | Campo | Descrição | -| :----------------- | :----------------------------------------------------------------- | +|:------------------ |:------------------------------------------------------------------ | | `parent_hash` | hash do bloco pai | | `fee_recipient` | endereço da conta para pagar taxas de transação para | | `state_root` | hash raiz para o estado global após aplicar alterações neste bloco | @@ -125,7 +125,7 @@ O próprio `execution_payload` contém o seguinte (note que é idêntico ao cabe A lista `withdrawals` contém objetos `withdrawal` estruturados da seguinte forma: | Campo | Descrição | -| :--------------- | :---------------------------- | +|:---------------- |:----------------------------- | | `endereço` | endereço da conta que retirou | | `amount` | quantidade retirada | | `index` | valor do índice da retirada | diff --git a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pos/block-proposal/index.md b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pos/block-proposal/index.md index 00de9fab23b..52527a8e786 100644 --- a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pos/block-proposal/index.md +++ b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pos/block-proposal/index.md @@ -64,6 +64,6 @@ O proponente de blocos recebe pagamento pelo seu trabalho. Há uma `base_reward` - [Introdução aos blocos](/developers/docs/blocks/) - [Introdução à prova de participação](/developers/docs/consensus-mechanisms/pos/) -- [Especificações do consenso do Ethereum](https://www.github.com/ethereum/consensus-specs) +- [Especificações do consenso do Ethereum](https://github.com/ethereum/consensus-specs) - [Introdução ao Gasper](/developers/docs/consensus-mechanisms/pos/) - [Atualizando o Ethereum](https://eth2book.info/) diff --git a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pos/index.md b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pos/index.md index 876cfe76f66..aa164b42c6c 100644 --- a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pos/index.md +++ b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pos/index.md @@ -16,7 +16,7 @@ A prova de participação é um meio de provar que os validadores colocam algo d ## Validadores {#validators} -Para participar como validador, um usuário deve depositar 32 ETH no contrato de depósito e executar três softwares separados: um cliente de execução, um cliente de consenso e um validador. Ao depositar seu ETH, o usuário entra em uma fila de ativação que limita a taxa de novos validadores que entram na rede. Uma vez ativados, os validadores recebem novos blocos de pares na rede Ethereum. As transações entregues no bloco são reexecutadas para verificar se, as alterações propostas para o estado do Ethereum são válidas e a assinatura do bloco é verificada. O validador então envia um voto (chamado de atestação) a favor desse bloco para toda a rede. +To participate as a validator, a user must deposit 32 ETH into the deposit contract and run three separate pieces of software: an execution client, a consensus client, and a validator client. Ao depositar seu ETH, o usuário entra em uma fila de ativação que limita a taxa de novos validadores que entram na rede. Uma vez ativados, os validadores recebem novos blocos de pares na rede Ethereum. As transações entregues no bloco são reexecutadas para verificar se, as alterações propostas para o estado do Ethereum são válidas e a assinatura do bloco é verificada. O validador então envia um voto (chamado de atestação) a favor desse bloco para toda a rede. Enquanto na prova de trabalho, o tempo dos blocos é determinado pela dificuldade de mineração, na prova de participação o tempo é fixo. O tempo na prova de participação do Ethereum é dividido em espaços (12 segundos) e épocas (32 espaços). Um validador é selecionado aleatoriamente para ser um proponente de bloco em cada espaço. Esse validador é responsável por criar um novo bloco e enviá-lo para outros nós da rede. Também em cada slot, um comitê de validadores é escolhido aleatoriamente, cujos votos são utilizados para determinar a validade do bloco proposto. Dividir o validador configurado em comitês é importante para manter a carga de rede gerenciável. Os comitês dividem o conjunto de validadores, de modo que cada validador ativo ateste em cada época, mas não em cada espaço (slot). diff --git a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/index.md b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/index.md index 2f33ec4694f..97227170952 100644 --- a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/index.md +++ b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/index.md @@ -68,7 +68,7 @@ Para complicar ainda mais, as transações rejeitadas na bifurcação temporári ## Uso de energia na prova de trabalho {#energy} -Uma importante crítica à prova de trabalho é a quantidade de energia necessária para manter a rede segura. Para manter a segurança e a descentralização, o Ethereum na prova de trabalho consumia grandes quantidades de energia. Pouco antes de mudar para a prova de participação, os mineradores do Ethereum consumiam coletivamente cerca de 70 TWh/ano (aproximadamente o mesmo que a República Tcheca – de acordo com [digiconomist](https://digiconomist.net) em 18 de julho de 2022). +Uma importante crítica à prova de trabalho é a quantidade de energia necessária para manter a rede segura. Para manter a segurança e a descentralização, o Ethereum na prova de trabalho consumia grandes quantidades de energia. Pouco antes de mudar para a prova de participação, os mineradores do Ethereum consumiam coletivamente cerca de 70 TWh/ano (aproximadamente o mesmo que a República Tcheca – de acordo com [digiconomist](https://digiconomist.net/) em 18 de julho de 2022). ## Prós e contras {#pros-and-cons} diff --git a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/index.md b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/index.md index 5d32213258b..5eb4f08e938 100644 --- a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/index.md +++ b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/index.md @@ -43,7 +43,7 @@ Para conhecer ainda mais a rentabilidade da mineração, use uma calculadora de O seguinte fornece uma visão geral de como as transações foram mineradas na prova de trabalho Ethereum. Uma descrição análoga deste processo para a prova de participação Ethereum pode ser encontrada [aqui](/developers/docs/consensus-mechanisms/pos/#transaction-execution-ethereum-pos). -1. Um usuário escreve e assina uma solicitação de [transação](/developers/docs/transactions/) com a chave privada de alguma [conta](/developers/docs/accounts/). +1. Um usuário escreve e assina uma solicitação de [transação](/developers/docs/transactions/) com a chave privada de alguma [ conta ](/developers/docs/accounts/). 2. O usuário transmite a solicitação de transação para toda a rede Ethereum de algum [nó](/developers/docs/nodes-and-clients/). 3. Ao ouvir tomar conhecimento da nova solicitação de transação, cada nó na rede Ethereum adiciona a solicitação ao seu mempool local, uma lista de todas as solicitações de transação sobre as quais eles têm conhecimento que ainda não foram confirmadas na blockchain em um bloco. 4. Em algum ponto, um nó de mineração agrega várias dezenas ou centenas de solicitações de transação a um [bloco](/developers/docs/blocks/) potencial, de uma forma que maximiza as [taxas de transação](/developers/docs/gas/) que eles ganham enquanto ainda estão abaixo do limite de gás de bloco. Então, o nó de mineração: diff --git a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto/index.md b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto/index.md index 3f5b0428f79..c396ee0a381 100644 --- a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto/index.md +++ b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto/index.md @@ -294,7 +294,7 @@ Para certos valores de `P` e `w`, a função `pow(x, w, P)` pode ter muitas coli Dado que `P` é primo, então um `w` apropriado para uma função hash de exponenciação modular pode ser escolhida usando o seguinte resultado: > Observação 3. Considere `P` um primo; `w` e `P-1` são relativamente primos, se e somente se para todos `a` e `b` em `Z/PZ`: -> +> >
      > `aʷ mod P ≡ bʷ mod P` se e somente se `a mod P ≡ b mod P` >
      diff --git a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md index 8e8381dd4eb..547b3e3c738 100644 --- a/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md +++ b/public/content/translations/pt-br/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md @@ -135,7 +135,7 @@ def calc_dataset(full_size, cache): ## Loop principal {#main-loop} -Agora, especificamos o loop padrão "hashimoto" principal, onde agregamos dados do conjunto de dados completo para produzir nosso valor final para um cabeçalho em particular ou nonce. No código abaixo, `header` representa o _hash \_SHA3-256 da representação RLP de um cabeçalho de bloco \_truncado_, ou seja, de um cabeçalho excluindo os campos **mixHash** e **nonce**. `nonce` é os oito bytes de um inteiro sem sinal de 64 bits na ordem big-endian. Então `nonce[::-1]` é a representação little-endian de oito bytes desse valor: +Agora, especificamos o loop padrão "hashimoto" principal, onde agregamos dados do conjunto de dados completo para produzir nosso valor final para um cabeçalho em particular ou nonce. No código abaixo, `header` representa o _hash _SHA3-256 da representação RLP de um cabeçalho de bloco _truncado_, ou seja, de um cabeçalho excluindo os campos **mixHash** e **nonce**. `nonce` é os oito bytes de um inteiro sem sinal de 64 bits na ordem big-endian. Então `nonce[::-1]` é a representação little-endian de oito bytes desse valor: ```python def hashimoto(header, nonce, full_size, dataset_lookup): diff --git a/public/content/translations/pt-br/developers/docs/dapps/index.md b/public/content/translations/pt-br/developers/docs/dapps/index.md index fd44943e0d4..ffa529e600d 100644 --- a/public/content/translations/pt-br/developers/docs/dapps/index.md +++ b/public/content/translations/pt-br/developers/docs/dapps/index.md @@ -35,7 +35,7 @@ Um contrato inteligente é um código presente na blockchain Ethereum e funciona - **Completar a integridade dos dados**: os dados armazenados na blockchain são imutáveis e indiscutíveis, graças aos primitivos criptográficos. Atores mal-intencionados não podem forjar transações ou outros dados que já foram tornados públicos. - **Computação sem confiança/comportamento verificável** – Contratos inteligentes podem ser analisados e têm garantia de execução de maneiras previsíveis, sem a necessidade de confiar em uma autoridade central. Isso não é verdade nos modelos tradicionais; por exemplo, quando usamos sistemas bancários on-line, temos que confiar que as instituições financeiras não usarão indevidamente nossos dados financeiros, adulterarão registros ou serão hackeadas. -## Desvantagens do desenvolvimento de dapps {#drawbacks-of-dapp-development} +## Benefícios do desenvolvimento de dapps {#drawbacks-of-dapp-development} - **Manutenção**: os dapps podem ser mais difíceis de manter, porque o código e os dados publicados na blockchain são mais difíceis de modificar. É difícil para os desenvolvedores fazerem atualizações em seus dapps (ou nos dados armazenados sob um dapp) uma vez que eles foram implantados, mesmo se bugs ou riscos de segurança forem identificados em uma versão antiga. - **Impactos no desempenho**: há um grande impacto no desempenho, e o dimensionamento é realmente difícil. Para alcançar o nível de segurança, integridade, transparência e confiabilidade que o Ethereum aspira, cada nó executa e armazena cada transação. Além disso, o consenso de prova de participação também leva tempo. @@ -54,7 +54,7 @@ Um contrato inteligente é um código presente na blockchain Ethereum e funciona - [GitHub](https://github.com/austintgriffith/scaffold-eth) - [Exemplo de dapp](https://punkwallet.io/) -**Crie um aplicativo Eth*: crie aplicativos com a tecnologia Ethereum apenas com um comando.*** +**Crie um aplicativo Eth_: crie aplicativos com a tecnologia Ethereum apenas com um comando._** - [GitHub](https://github.com/paulrberg/create-eth-app) diff --git a/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md b/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md index 81dea175177..b51e17aa68f 100644 --- a/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md +++ b/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/patricia-merkle-trie/index.md @@ -7,7 +7,7 @@ sidebarDepth: 2 Uma árvore Merkle Patricia fornece uma estrutura de dados criptograficamente autenticada que pode ser usada para armazenar todas as ligações `(key, value)`. -Árvores Merkle Patricia são totalmente determinísticas, o que significa que há a garantia de que árvores com as mesmas ligações `(key, value)` são idênticas – até o último byte. Isto significa que elas têm o mesmo hash raiz, fornecendo a máxima eficiência `o(log(n))` para inserções, buscas e exclusões. Além disso, elas são mais simples de entender e codificar do que alternativas mais complexas baseadas em comparação, como as árvores vermelho-pretas. +A Merkle Patricia Tries é totalmente determinística, significando que Tries - testes - com a mesma ligação `(key, value)` são com certeza idênticas - até o último byte. Isto significa que elas têm o mesmo hash raiz, fornecendo a máxima eficiência `o(log(n))` para inserções, buscas e exclusões. Além disso, elas são mais simples de entender e codificar do que alternativas mais complexas baseadas em comparação, como as árvores vermelho-pretas. ## Pré-requisitos {#prerequisites} @@ -25,7 +25,7 @@ Onde `i0 ... in` representa o símbolo do alfabeto (muitas vezes binário ou hex Digamos que você queria usar uma estrutura de dados da árvore radix para persistir em uma ordem em um conjunto de pares de valor-chave. Para encontrar o valor atualmente relacionado com a chave `dog` na árvore, primeiro você converteria `dog` em letras do alfabeto (dando `64 6f 67`), e então desceria pela árvore seguindo o caminho até encontrar o valor. Ou seja, você começa por procurar o hash raiz em uma base de dados texto chave/valor para encontrar o nó raiz da árvore. Ele é representado como uma matriz de chaves apontando para outros nós. Use o valor no índice `6` como uma chave e procure na base chave/valor para obter o nó um nível abaixo. Em seguida, escolha o índice `4` para procurar o próximo valor, depois escolha o índice `6` e assim por diante. Uma vez tendo seguido o caminho: `root-> 6 -> 4 -> 6 -> 15 -> 6 -> 7`, procure o valor do nó e retorne o resultado. -Há uma diferença entre buscar algo na árvore e no banco de dados base subjacente (chave/valor). Ambos definem combinações chave/valor, mas o banco de dados subjacente pode realizar uma busca tradicional de uma chave em 1 etapa. Procurar uma chave na árvore requer várias buscas no banco de dados subjacente para obter o valor final descrito acima. Vamos nos referir a este último como um `path` para eliminar ambiguidade. +Há uma diferença entre buscar algo na árvore e no banco de dados base subjacente (chave/valor). Ambos definem arranjos chave/valor, mas o DB subjacente pode fazer uma tradicional busca de 1 passo pela chave. Procurar uma chave na árvore requer várias buscas no banco de dados subjacente para obter o valor final descrito acima. Vamos nos referir a este último como um `path` para eliminar ambiguidade. As operações de atualização e exclusão em árvores radix são simples, e podem ser definidas da seguinte forma: @@ -62,9 +62,9 @@ As operações de atualização e exclusão em árvores radix são simples, e po return hash(newnode) ``` -Uma árvore Radix "Merkle" é construída ligando os nós usando digests de hash criptográficos gerados deterministicamente. Este endereçamento de conteúdo (em banco de dados de chave/valor `key == keccak256(rlp(value))`) fornece autenticação criptográfica dos dados armazenados. Se o hash raiz de uma determinada árvore for conhecido publicamente, então, qualquer um poderá fornecer uma prova de que a árvore inclui um determinado valor em um caminho específico, fornecendo os hashes de cada nó que se junta a um valor específico para a raiz da árvore. +Uma árvore Radix "Merkle" é construída ligando os nós usando digests de hash criptográficos gerados deterministicamente. Este endereçamento de conteúdo (no BD chave/valor `key == keccak256(rlp(value))`) fornece uma integridade criptográfica garantida do dado armazenado. Se o hash raiz de um Trie - teste - determinado for conhecido publicamente, então, qualquer um com acesso aos dados da folha subjacente poderá fornecer uma prova de que o Trie - teste - inclui um determinado valor em um caminho específico, fornecendo os hashes de cada nódulo que se junta a um valor específico para a raiz da árvore. -É impossível para um atacante fornecer uma prova de um par `(path, value)` que não exista, já que o hash raiz é, em última análise, baseado em todos os hashes abaixo dele. Qualquer modificação subjacente alteraria o hash raiz. +É impossível para um atacante fornecer uma prova de um par `(path, value)` que não exista, já que o hash raiz é, em última análise, baseado em todos os hashes abaixo dele. Qualquer modificação subjacente alteraria o hash raiz. Você pode pensar no hash como uma representação comprimida de informações estruturais sobre os dados, seguros pela proteção pré-imagem da função de hash. Vamos nos referir a uma unidade atômica de uma árvore de radix (por exemplo, um único caractere hexadecimal, ou número binário de 4 bits) como um "nibble". Ao percorrerem um caminho um nibble de cada vez, conforme descrito acima, os nós podem fazer referência a 16 filhos, no máximo, mas incluir um elemento `value`. Portanto, nós os representamos como uma faixa de comprimento 17. Chamamos esses arrays de 17 elementos de "branch nodes". @@ -233,6 +233,8 @@ curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": [ {"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000162e"} ``` +Nota: O `storageRoot` para uma conta Ethereum está vazio pelo padrão se ele não for uma conta de contrato. + ### Árvore de transações {#transaction-trie} Há uma árvore de transações separada para cada bloco, armazenando novamente pares `(key, value)`. Um caminho aqui é: `rlp(transactionIndex)` que representa a chave que corresponde a um valor determinado por: diff --git a/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/rlp/index.md b/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/rlp/index.md index 03b74f18093..af64d513aa2 100644 --- a/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/rlp/index.md +++ b/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/rlp/index.md @@ -35,7 +35,7 @@ A codificação RLP é definida da seguinte forma: - Para um único byte cujo valor está na faixa `[0x00, 0x7f]` (decimal `[0, 127]`), este byte é a sua própria codificação RLP. - Caso contrário, se uma string tem de 0 a 55 bytes de comprimento, a codificação RLP consiste em um único byte com valor **0x80** (dec. 128) mais o comprimento da string seguida pela string. O intervalo do primeiro byte é, portanto, `[0x80, 0xb7]` (dec. `[128, 183]`). - Se uma string tem mais de 55 bytes de comprimento, a codificação RLP consiste em um único byte com valor **0xb7** (dec. 183) mais o comprimento em bytes do comprimento da sequência de caracteres na forma binária, seguido pelo comprimento da string, seguido pela string. Por exemplo, uma string de 1024 bytes de comprimento seria codificada como `\xb9\x04\x00` (dec. `185, 4, 0`) seguida pela string. Aqui, `0xb9` (183 + 2 = 185) como o primeiro byte, seguido pelos 2 bytes `0x0400` (dec. 1024) que denotam o comprimento da string real. O intervalo do primeiro byte é, portanto, `[0x80, 0xb7]` (dec. `[184, 191]`). -- Se a carga total de uma lista (ou seja, o comprimento combinado de todos os seus itens sendo codificados em RLP) tem 0-55 bytes, a codificação RLP consiste em um único byte com valor **0xc0** mais o comprimento da lista seguida pela concatenação das codificações RLP dos itens. O intervalo do primeiro byte é, portanto, `[0x80, 0xb7]` (dec. `[192, 247]`). +- Se o total de carga de uma lista (ou seja, o comprimento combinado de totos os seus itens com codificação RLP) tiver 0 a 55 bytes de comprimento, a codificação RLP consiste em um único byte com valor **0xc0** mais o comprimento da carga seguido da concatenação das codificações dos itens. O intervalo do primeiro byte é, portanto, `[0x80, 0xb7]` (dec. `[192, 247]`). - Se o payload total de uma lista tem mais de 55 bytes de comprimento, a codificação RLP consiste em um único byte com valor **0xf7** mais o comprimento em bytes do payload na forma binária, seguida pelo comprimento do payload, seguido pela concatenação das codificações RLP dos itens. O intervalo do primeiro byte é, portanto, `[0x80, 0xb7]` (dec. `[248, 255]`). Em código, isto é: @@ -75,7 +75,7 @@ def to_binary(x): - o inteiro 0 = `[ 0x80 ]` - o inteiro codificado 0 ('\\x00') = `[ 0x00 ]` - o inteiro codificado 15 ('\\x0f') = `[ 0x00 ]` -- o inteiro codificado 1024 ('\\x04') = `[ 0x82, 0x04, 0x00 ]` +- o inteiro codificado 1024 ('\\x04') = `[ 0x82, 0x04, 0x00 ]` - [define a representação teórica](http://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers) para três, `[ [], [[]], [ [], [[]] ] ] = [ 0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc0, 0xc1, 0xc0 ]` - a string "Lorem ipsum dolor sit amet, consectetur adipisicing elit" = `[ 0xb8, 0x38, 'L', 'o', 'r', 'e', 'm', ' ', ... , 'e', 'l', 'i', 't' ]` @@ -113,7 +113,7 @@ def rlp_decode(input): output = instantiate_str(substr(input, offset, dataLen)) elif type is list: output = instantiate_list(substr(input, offset, dataLen)) - output + rlp_decode(substr(input, offset + dataLen)) + output += rlp_decode(substr(input, offset + dataLen)) return output def decode_length(input): diff --git a/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/ssz/index.md b/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/ssz/index.md index 1f435d3606a..f03378a49e1 100644 --- a/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/ssz/index.md +++ b/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/ssz/index.md @@ -109,7 +109,7 @@ Esse objeto serializado SSZ pode então ser merkleizado, o seja, transformado em Há também casos em que as folhas da árvore não se distribuem naturalmente, de maneira uniforme, como o fazem no exemplo acima. Por exemplo, a folha 4 pode ser um contêiner com vários elementos que exige "profundidade" adicional para serem adicionados à árvore Merkle, criando uma árvore desnivelada. -Em vez de nos referirmos a esses elementos da árvore como folha X, nó X etc., podemos dar a eles índices generalizados, começando com raiz = 1 e contando da esquerda para a direita ao longo de cada nível. Este é o índice generalizado explicado acima. Cada elemento na lista serializada tem um índice generalizado igual a `2**depth + idx` onde idx é sua posição indexada em zero no objeto serializado e a profundidade é o número de níveis na árvore Merkle, que pode ser determinado como a raiz quadrada do número de elementos (folhas). +Em vez de nos referirmos a esses elementos da árvore como folha X, nó X etc., podemos dar a eles índices generalizados, começando com raiz = 1 e contando da esquerda para a direita ao longo de cada nível. Este é o índice generalizado explicado acima. Cada elemento na lista serializada tem um índice genérico igual a `2**profundidade + idx`, onde o idx é a sua posição indexada por zero no objeto serializado e a profundidade é o número de níveis na árvore Merkle, que pode ser determinado como o logaritmo de base dois do número de elementos (folhas). ## Índices generalizados {#generalized-indices} diff --git a/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/web3-secret-storage-definition/index.md b/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/web3-secret-storage-definition/index.md index 8de0c5f952a..70b036fdda7 100644 --- a/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/web3-secret-storage-definition/index.md +++ b/public/content/translations/pt-br/developers/docs/data-structures-and-encoding/web3-secret-storage-definition/index.md @@ -123,18 +123,18 @@ Vetor de teste usando AES-128-CTR e Scrypt: "crypto": { "cipher": "aes-128-ctr", "cipherparams": { - "iv": "83dbcc02d8ccb40e466191a123791e0e" + "iv": "740770fce12ce862af21264dab25f1da" }, - "ciphertext": "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", + "ciphertext": "dd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2", "kdf": "scrypt", "kdfparams": { "dklen": 32, "n": 262144, - "p": 8, - "r": 1, - "salt": "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" + "p": 1, + "r": 8, + "salt": "25710c2ccd7c610b24d068af83b959b7a0e5f40641f0c82daeb1345766191034" }, - "mac": "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" + "mac": "337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c" }, "id": "3198bc9c-6672-5ab3-d995-4942343ae5b6", "version": 3 @@ -143,7 +143,7 @@ Vetor de teste usando AES-128-CTR e Scrypt: **Intermédios**: -`Derived key`: `fac192ceb5fd772906bea3e118a69e8bbb5cc24229e20d8766fd298291bba6bd` `MAC Body`: `bb5cc24229e20d8766fd298291bba6bdd172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c` `MAC`: `2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097` `Cipher key`: `fac192ceb5fd772906bea3e118a69e8b` +`Derived key`: `7446f59ecc301d2d79bc3302650d8a5cedc185ccbb4bf3ca1ebd2c163eaa6c2d` `MAC Body`: `edc185ccbb4bf3ca1ebd2c163eaa6c2ddd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2` `MAC`: `337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c` `Cipher key`: `7446f59ecc301d2d79bc3302650d8a5c` ## Alterações da versão 1 {#alterations-from-v2} diff --git a/public/content/translations/pt-br/developers/docs/evm/index.md b/public/content/translations/pt-br/developers/docs/evm/index.md index 62409a013f9..4636eaae2ce 100644 --- a/public/content/translations/pt-br/developers/docs/evm/index.md +++ b/public/content/translations/pt-br/developers/docs/evm/index.md @@ -10,7 +10,7 @@ O próprio protocolo Ethereum existe apenas com o propósito de manter a operaç ## Pré-requisitos {#prerequisites} -Alguma familiaridade básica com a terminologia comum em ciência da computação, como [bytes](https://wikipedia.org/wiki/Byte), [memória](https://wikipedia.org/wiki/Computer_memory) e [pilha]() é necessária para entender a EVM. Também recomendamos se familiarizar com conceitos de criptografia/cadeia de blocos, como [funções hash](https://wikipedia.org/wiki/Cryptographic_hash_function) e a [árvore Merkle](https://wikipedia.org/wiki/Merkle_tree). +Alguma familiaridade básica com a terminologia comum em ciência da computação, como [bytes](https://wikipedia.org/wiki/Byte), [memória](https://wikipedia.org/wiki/Computer_memory) e [pilha](https://wikipedia.org/wiki/Stack_(abstract_data_type)) é necessária para entender a EVM. Também recomendamos se familiarizar com conceitos de criptografia/cadeia de blocos, como [funções hash](https://wikipedia.org/wiki/Cryptographic_hash_function) e a [árvore Merkle](https://wikipedia.org/wiki/Merkle_tree). ## Do livro-razão para a máquina de estado {#from-ledger-to-state-machine} @@ -64,6 +64,7 @@ Os [clientes de execução Ethereum](/developers/docs/nodes-and-clients/#executi - [evmone](https://github.com/ethereum/evmone) - _C++_ - [ethereumjs-vm](https://github.com/ethereumjs/ethereumjs-vm) - _JavaScript_ - [eEVM](https://github.com/microsoft/eevm) - _C++_ +- [revm](https://github.com/bluealloy/revm) - _Rust_ ## Leitura adicional {#further-reading} diff --git a/public/content/translations/pt-br/developers/docs/evm/opcodes/index.md b/public/content/translations/pt-br/developers/docs/evm/opcodes/index.md index f7fdc77e4bd..de723433193 100644 --- a/public/content/translations/pt-br/developers/docs/evm/opcodes/index.md +++ b/public/content/translations/pt-br/developers/docs/evm/opcodes/index.md @@ -14,157 +14,157 @@ Para operações com custos de gás dinâmico, consulte [gas.md](https://github. 💡 Dica rápida: Para ver linhas inteiras, use `[shift] + scroll` para rolar horizontalmente na área de trabalho. -| Pilha | Nome | Gás | Pilha inicial | Pilha resultante | Memória / Armazenamento | Observações | -| :---: | :------------- | :---------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------- | :------------------------------ | :---------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| 00 | STOP | 0 | | | | halt execution | -| 01 | ADD | 3 | `a, b` | `a + b` | | (u)int256 addition modulo 2\*\*256 | -| 02 | MUL | 5 | `a, b` | `a * b` | | (u)int256 multiplication modulo 2\*\*256 | -| 03 | SUB | 3 | `a, b` | `a - b` | | (u)int256 addition modulo 2\*\*256 | -| 04 | DIV | 5 | `a, b` | `a // b` | | uint256 division | -| 05 | SDIV | 5 | `a, b` | `a // b` | | int256 division | -| 06 | MOD | 5 | `a, b` | `a % b` | | uint256 modulus | -| 07 | SMOD | 5 | `a, b` | `a % b` | | int256 modulus | -| 08 | ADDMOD | 8 | `a, b, N` | `(a + b) % N` | | (u)int256 addition modulo N | -| 09 | MULMOD | 8 | `a, b, N` | `(a * b) % N` | | (u)int256 multiplication modulo N | -| 0A | EXP | [A1](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a1-exp) | `a, b` | `a ** b` | | uint256 exponentiation modulo 2\*\*256 | -| 0B | SIGNEXTEND | 5 | `b, x` | `SIGNEXTEND(x, b)` | | [sign extend](https://wikipedia.org/wiki/Sign_extension) `x` from `(b+1)` bytes to 32 bytes | -| 0C-0F | _invalid_ | | | | | | -| 10 | LT | 3 | `a, b` | `a < b` | | uint256 less-than | -| 11 | GT | 3 | `a, b` | `a > b` | | uint256 greater-than | -| 12 | SLT | 3 | `a, b` | `a < b` | | int256 less-than | -| 13 | SGT | 3 | `a, b` | `a > b` | | int256 greater-than | -| 14 | EQ | 3 | `a, b` | `a == b` | | (u)int256 equality | -| 15 | ISZERO | 3 | `a` | `a == 0` | | (u)int256 iszero | -| 16 | AND | 3 | `a, b` | `a && b` | | bitwise AND | -| 17 | OR | 3 | `a, b` | `a \|\| b` | | bitwise OR | -| 18 | XOR | 3 | `a, b` | `a ^ b` | | bitwise XOR | -| 19 | NOT | 3 | `a` | `~a` | | bitwise NOT | -| 1A | BYTE | 3 | `i, x` | `(x >> (248 - i * 8)) && 0xFF` | | `i`th byte of (u)int256 `x`, from the left | -| 1B | SHL | 3 | `shift, val` | `val << shift` | | shift left | -| 1C | SHR | 3 | `shift, val` | `val >> shift` | | logical shift right | -| 1D | SAR | 3 | `shift, val` | `val >> shift` | | arithmetic shift right | -| 1E-1F | _invalid_ | | | | | | -| 20 | KECCAK256 | [A2](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a2-sha3) | `ost, len` | `keccak256(mem[ost:ost+len-1])` | | keccak256 | -| 21-2F | _invalid_ | | | | | | -| 30 | ADDRESS | 2 | `.` | `address(this)` | | address of executing contract | -| 31 | BALANCE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `addr.balance` | | balance, in wei | -| 32 | ORIGIN | 2 | `.` | `tx.origin` | | address that originated the tx | -| 33 | CALLER | 2 | `.` | `msg.sender` | | address of msg sender | -| 34 | CALLVALUE | 2 | `.` | `msg.value` | | msg value, in wei | -| 35 | CALLDATALOAD | 3 | `idx` | `msg.data[idx:idx+32]` | | read word from msg data at index `idx` | -| 36 | CALLDATASIZE | 2 | `.` | `len(msg.data)` | | length of msg data, in bytes | -| 37 | CALLDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | copy msg data | -| 38 | CODESIZE | 2 | `.` | `len(this.code)` | | length of executing contract's code, in bytes | -| 39 | CODECOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | copy executing contract's bytecode | -| 3A | GASPRICE | 2 | `.` | `tx.gasprice` | | gas price of tx, in wei per unit gas [\*\*](https://eips.ethereum.org/EIPS/eip-1559#gasprice) | -| 3B | EXTCODESIZE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `len(addr.code)` | | size of code at addr, in bytes | -| 3C | EXTCODECOPY | [A4](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a4-extcodecopy) | `addr, dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | copy code from `addr` | -| 3D | RETURNDATASIZE | 2 | `.` | `size` | | size of returned data from last external call, in bytes | -| 3E | RETURNDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | copy returned data from last external call | -| 3F | EXTCODEHASH | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `hash` | | hash = addr.exists ? keccak256(addr.code) : 0 | -| 40 | BLOCKHASH | 20 | `blockNum` | `blockHash(blockNum)` | | | -| 41 | COINBASE | 2 | `.` | `block.coinbase` | | address of miner of current block | -| 42 | TIMESTAMP | 2 | `.` | `block.timestamp` | | timestamp of current block | -| 43 | NUMBER | 2 | `.` | `block.number` | | number of current block | -| 44 | PREVRANDAO | 2 | `.` | `randomness beacon` | | randomness beacon | -| 45 | GASLIMIT | 2 | `.` | `block.gaslimit` | | gas limit of current block | -| 46 | CHAINID | 2 | `.` | `chain_id` | | push current [chain id](https://eips.ethereum.org/EIPS/eip-155) onto stack | -| 47 | SELFBALANCE | 5 | `.` | `address(this).balance` | | balance of executing contract, in wei | -| 48 | BASEFEE | 2 | `.` | `block.basefee` | | base fee of current block | -| 49-4F | _invalid_ | | | | | | -| 50 | POP | 2 | `_anon` | `.` | | remove item from top of stack and discard it | -| 51 | MLOAD | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost` | `mem[ost:ost+32]` | | read word from memory at offset `ost` | -| 52 | MSTORE | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost:ost+32] := val | write a word to memory | -| 53 | MSTORE8 | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost] := val && 0xFF | write a single byte to memory | -| 54 | SLOAD | [A6](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a6-sload) | `key` | `storage[key]` | | read word from storage | -| 55 | SSTORE | [A7](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a7-sstore) | `key, val` | `.` | storage[key] := val | write word to storage | -| 56 | JUMP | 8 | `dst` | `.` | | `$pc := dst` mark that `pc` is only assigned if `dst` is a valid jumpdest | -| 57 | JUMPI | 10 | `dst, condition` | `.` | | `$pc := condition ? dst : $pc + 1` | -| 58 | PC | 2 | `.` | `$pc` | | program counter | -| 59 | MSIZE | 2 | `.` | `len(mem)` | | size of memory in current execution context, in bytes | -| 5A | GAS | 2 | `.` | `gasRemaining` | | | -| 5B | JUMPDEST | 1 | | | mark valid jump destination | a valid jump destination for example a jump destination not inside the push data | -| 5C-5E | _invalid_ | | | | | | -| 5F | PUSH0 | 2 | `.` | `uint8` | | empurra o valor constante 0 para a pilha | -| 60 | PUSH1 | 3 | `.` | `uint8` | | push 1-byte value onto stack | -| 61 | PUSH2 | 3 | `.` | `uint16` | | push 2-byte value onto stack | -| 62 | PUSH3 | 3 | `.` | `uint24` | | push 3-byte value onto stack | -| 63 | PUSH4 | 3 | `.` | `uint32` | | push 4-byte value onto stack | -| 64 | PUSH5 | 3 | `.` | `uint40` | | push 5-byte value onto stack | -| 65 | PUSH6 | 3 | `.` | `uint48` | | push 6-byte value onto stack | -| 66 | PUSH7 | 3 | `.` | `uint56` | | push 7-byte value onto stack | -| 67 | PUSH8 | 3 | `.` | `uint64` | | push 8-byte value onto stack | -| 68 | PUSH9 | 3 | `.` | `uint72` | | push 9-byte value onto stack | -| 69 | PUSH10 | 3 | `.` | `uint80` | | push 10-byte value onto stack | -| 6A | PUSH11 | 3 | `.` | `uint88` | | push 11-byte value onto stack | -| 6B | PUSH12 | 3 | `.` | `uint96` | | push 12-byte value onto stack | -| 6C | PUSH13 | 3 | `.` | `uint104` | | push 13-byte value onto stack | -| 6D | PUSH14 | 3 | `.` | `uint112` | | push 14-byte value onto stack | -| 6E | PUSH15 | 3 | `.` | `uint120` | | push 15-byte value onto stack | -| 6F | PUSH16 | 3 | `.` | `uint128` | | push 16-byte value onto stack | -| 70 | PUSH17 | 3 | `.` | `uint136` | | push 17-byte value onto stack | -| 71 | PUSH18 | 3 | `.` | `uint144` | | push 18-byte value onto stack | -| 72 | PUSH19 | 3 | `.` | `uint152` | | push 19-byte value onto stack | -| 73 | PUSH20 | 3 | `.` | `uint160` | | push 20-byte value onto stack | -| 74 | PUSH21 | 3 | `.` | `uint168` | | push 21-byte value onto stack | -| 75 | PUSH22 | 3 | `.` | `uint176` | | push 22-byte value onto stack | -| 76 | PUSH23 | 3 | `.` | `uint184` | | push 23-byte value onto stack | -| 77 | PUSH24 | 3 | `.` | `uint192` | | push 24-byte value onto stack | -| 78 | PUSH25 | 3 | `.` | `uint200` | | push 25-byte value onto stack | -| 79 | PUSH26 | 3 | `.` | `uint208` | | push 26-byte value onto stack | -| 7A | PUSH27 | 3 | `.` | `uint216` | | push 27-byte value onto stack | -| 7B | PUSH28 | 3 | `.` | `uint224` | | push 28-byte value onto stack | -| 7C | PUSH29 | 3 | `.` | `uint232` | | push 29-byte value onto stack | -| 7D | PUSH30 | 3 | `.` | `uint240` | | push 30-byte value onto stack | -| 7E | PUSH31 | 3 | `.` | `uint248` | | push 31-byte value onto stack | -| 7F | PUSH32 | 3 | `.` | `uint256` | | push 32-byte value onto stack | -| 80 | DUP1 | 3 | `a` | `a, a` | | clone 1st value on stack | -| 81 | DUP2 | 3 | `_, a` | `a, _, a` | | clone 2nd value on stack | -| 82 | DUP3 | 3 | `_, _, a` | `a, _, _, a` | | clone 3rd value on stack | -| 83 | DUP4 | 3 | `_, _, _, a` | `a, _, _, _, a` | | clone 4th value on stack | -| 84 | DUP5 | 3 | `..., a` | `a, ..., a` | | clone 5th value on stack | -| 85 | DUP6 | 3 | `..., a` | `a, ..., a` | | clone 6th value on stack | -| 86 | DUP7 | 3 | `..., a` | `a, ..., a` | | clone 7th value on stack | -| 87 | DUP8 | 3 | `..., a` | `a, ..., a` | | clone 8th value on stack | -| 88 | DUP9 | 3 | `..., a` | `a, ..., a` | | clone 9th value on stack | -| 89 | DUP10 | 3 | `..., a` | `a, ..., a` | | clone 10th value on stack | -| 8A | DUP11 | 3 | `..., a` | `a, ..., a` | | clone 11th value on stack | -| 8B | DUP12 | 3 | `..., a` | `a, ..., a` | | clone 12th value on stack | -| 8C | DUP13 | 3 | `..., a` | `a, ..., a` | | clone 13th value on stack | -| 8D | DUP14 | 3 | `..., a` | `a, ..., a` | | clone 14th value on stack | -| 8E | DUP15 | 3 | `..., a` | `a, ..., a` | | clone 15th value on stack | -| 8F | DUP16 | 3 | `..., a` | `a, ..., a` | | clone 16th value on stack | -| 90 | SWAP1 | 3 | `a, b` | `b, a` | | | -| 91 | SWAP2 | 3 | `a, _, b` | `b, _, a` | | | -| 92 | SWAP3 | 3 | `a, _, _, b` | `b, _, _, a` | | | -| 93 | SWAP4 | 3 | `a, _, _, _, b` | `b, _, _, _, a` | | | -| 94 | SWAP5 | 3 | `a, ..., b` | `b, ..., a` | | | -| 95 | SWAP6 | 3 | `a, ..., b` | `b, ..., a` | | | -| 96 | SWAP7 | 3 | `a, ..., b` | `b, ..., a` | | | -| 97 | SWAP8 | 3 | `a, ..., b` | `b, ..., a` | | | -| 98 | SWAP9 | 3 | `a, ..., b` | `b, ..., a` | | | -| 99 | SWAP10 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9A | SWAP11 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9B | SWAP12 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9C | SWAP13 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9D | SWAP14 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9E | SWAP15 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9F | SWAP16 | 3 | `a, ..., b` | `b, ..., a` | | | -| A0 | LOG0 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len` | `.` | | LOG0(memory[ost:ost+len-1]) | -| A1 | LOG1 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0` | `.` | | LOG1(memory[ost:ost+len-1], topic0) | -| A2 | LOG2 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1) | -| A3 | LOG3 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2) | -| A4 | LOG4 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2, topic3` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2, topic3) | -| A5-EF | _invalid_ | | | | | | -| F0 | CREATE | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len` | `addr` | | addr = keccak256(rlp([address(this), this.nonce])) | -| F1 | CALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | gas, addr, val, argOst, argLen, retOst, retLen | `success` | mem[retOst:retOst+retLen-1] := returndata | | -| F2 | CALLCODE | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, val, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] = returndata | same as DELEGATECALL, but does not propagate original msg.sender and msg.value | -| F3 | RETURN | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | return mem[ost:ost+len-1] | -| F4 | DELEGATECALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | -| F5 | CREATE2 | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len, salt` | `addr` | | addr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] | -| F6-F9 | _invalid_ | | | | | | -| FA | STATICCALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | -| FB-FC | _invalid_ | | | | | | -| FD | REVERT | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | revert(mem[ost:ost+len-1]) | -| FE | INVALID | [AF](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#af-invalid) | | | designated invalid opcode - [EIP-141](https://eips.ethereum.org/EIPS/eip-141) | | -| FF | SELFDESTRUCT | [AB](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#ab-selfdestruct) | `addr` | `.` | | | destroy contract and sends all funds to `addr` | +| Pilha | Nome | Gás | Pilha inicial | Pilha resultante | Memória / Armazenamento | Observações | +|:-----:|:-------------- |:-----------------------------------------------------------------------------------------------:|:------------------------------------------------ |:-------------------------------------------- |:----------------------------------------------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 00 | STOP | 0 | | | | halt execution | +| 01 | ADD | 3 | `a, b` | `a + b` | | (u)int256 addition modulo 2\*\*256 | +| 02 | MUL | 5 | `a, b` | `a * b` | | (u)int256 multiplication modulo 2\*\*256 | +| 03 | SUB | 3 | `a, b` | `a - b` | | (u)int256 addition modulo 2\*\*256 | +| 04 | DIV | 5 | `a, b` | `a // b` | | uint256 division | +| 05 | SDIV | 5 | `a, b` | `a // b` | | int256 division | +| 06 | MOD | 5 | `a, b` | `a % b` | | uint256 modulus | +| 07 | SMOD | 5 | `a, b` | `a % b` | | int256 modulus | +| 08 | ADDMOD | 8 | `a, b, N` | `(a + b) % N` | | (u)int256 addition modulo N | +| 09 | MULMOD | 8 | `a, b, N` | `(a * b) % N` | | (u)int256 multiplication modulo N | +| 0A | EXP | [A1](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a1-exp) | `a, b` | `a ** b` | | uint256 exponentiation modulo 2\*\*256 | +| 0B | SIGNEXTEND | 5 | `b, x` | `SIGNEXTEND(x, b)` | | [sign extend](https://wikipedia.org/wiki/Sign_extension) `x` from `(b+1)` bytes to 32 bytes | +| 0C-0F | _invalid_ | | | | | | +| 10 | LT | 3 | `a, b` | `a < b` | | uint256 less-than | +| 11 | GT | 3 | `a, b` | `a > b` | | uint256 greater-than | +| 12 | SLT | 3 | `a, b` | `a < b` | | int256 less-than | +| 13 | SGT | 3 | `a, b` | `a > b` | | int256 greater-than | +| 14 | EQ | 3 | `a, b` | `a == b` | | (u)int256 equality | +| 15 | ISZERO | 3 | `a` | `a == 0` | | (u)int256 iszero | +| 16 | AND | 3 | `a, b` | `a && b` | | bitwise AND | +| 17 | OR | 3 | `a, b` | `a \|\| b` | | bitwise OR | +| 18 | XOR | 3 | `a, b` | `a ^ b` | | bitwise XOR | +| 19 | NOT | 3 | `a` | `~a` | | bitwise NOT | +| 1A | BYTE | 3 | `i, x` | `(x >> (248 - i * 8)) && 0xFF` | | `i`th byte of (u)int256 `x`, from the left | +| 1B | SHL | 3 | `shift, val` | `val << shift` | | shift left | +| 1C | SHR | 3 | `shift, val` | `val >> shift` | | logical shift right | +| 1D | SAR | 3 | `shift, val` | `val >> shift` | | arithmetic shift right | +| 1E-1F | _invalid_ | | | | | | +| 20 | KECCAK256 | [A2](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a2-sha3) | `ost, len` | `keccak256(mem[ost:ost+len-1])` | | keccak256 | +| 21-2F | _invalid_ | | | | | | +| 30 | ADDRESS | 2 | `.` | `address(this)` | | address of executing contract | +| 31 | BALANCE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `addr.balance` | | balance, in wei | +| 32 | ORIGIN | 2 | `.` | `tx.origin` | | address that originated the tx | +| 33 | CALLER | 2 | `.` | `msg.sender` | | address of msg sender | +| 34 | CALLVALUE | 2 | `.` | `msg.value` | | msg value, in wei | +| 35 | CALLDATALOAD | 3 | `idx` | `msg.data[idx:idx+32]` | | read word from msg data at index `idx` | +| 36 | CALLDATASIZE | 2 | `.` | `len(msg.data)` | | length of msg data, in bytes | +| 37 | CALLDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | copy msg data | +| 38 | CODESIZE | 2 | `.` | `len(this.code)` | | length of executing contract's code, in bytes | +| 39 | CODECOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | copy executing contract's bytecode | +| 3A | GASPRICE | 2 | `.` | `tx.gasprice` | | gas price of tx, in wei per unit gas [\*\*](https://eips.ethereum.org/EIPS/eip-1559#gasprice) | +| 3B | EXTCODESIZE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `len(addr.code)` | | size of code at addr, in bytes | +| 3C | EXTCODECOPY | [A4](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a4-extcodecopy) | `addr, dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | copy code from `addr` | +| 3D | RETURNDATASIZE | 2 | `.` | `size` | | size of returned data from last external call, in bytes | +| 3E | RETURNDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | copy returned data from last external call | +| 3F | EXTCODEHASH | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `hash` | | hash = addr.exists ? keccak256(addr.code) : 0 | +| 40 | BLOCKHASH | 20 | `blockNum` | `blockHash(blockNum)` | | | +| 41 | COINBASE | 2 | `.` | `block.coinbase` | | address of miner of current block | +| 42 | TIMESTAMP | 2 | `.` | `block.timestamp` | | timestamp of current block | +| 43 | NUMBER | 2 | `.` | `block.number` | | number of current block | +| 44 | PREVRANDAO | 2 | `.` | `randomness beacon` | | randomness beacon | +| 45 | GASLIMIT | 2 | `.` | `block.gaslimit` | | gas limit of current block | +| 46 | CHAINID | 2 | `.` | `chain_id` | | push current [chain id](https://eips.ethereum.org/EIPS/eip-155) onto stack | +| 47 | SELFBALANCE | 5 | `.` | `address(this).balance` | | balance of executing contract, in wei | +| 48 | BASEFEE | 2 | `.` | `block.basefee` | | base fee of current block | +| 49-4F | _invalid_ | | | | | | +| 50 | POP | 2 | `_anon` | `.` | | remove item from top of stack and discard it | +| 51 | MLOAD | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost` | `mem[ost:ost+32]` | | read word from memory at offset `ost` | +| 52 | MSTORE | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost:ost+32] := val | write a word to memory | +| 53 | MSTORE8 | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost] := val && 0xFF | write a single byte to memory | +| 54 | SLOAD | [A6](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a6-sload) | `key` | `storage[key]` | | read word from storage | +| 55 | SSTORE | [A7](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a7-sstore) | `key, val` | `.` | storage[key] := val | write word to storage | +| 56 | JUMP | 8 | `dst` | `.` | | `$pc := dst` mark that `pc` is only assigned if `dst` is a valid jumpdest | +| 57 | JUMPI | 10 | `dst, condition` | `.` | | `$pc := condition ? dst : $pc + 1` | +| 58 | PC | 2 | `.` | `$pc` | | program counter | +| 59 | MSIZE | 2 | `.` | `len(mem)` | | size of memory in current execution context, in bytes | +| 5A | GAS | 2 | `.` | `gasRemaining` | | | +| 5B | JUMPDEST | 1 | | | mark valid jump destination | a valid jump destination for example a jump destination not inside the push data | +| 5C-5E | _invalid_ | | | | | | +| 5F | PUSH0 | 2 | `.` | `uint8` | | empurra o valor constante 0 para a pilha | +| 60 | PUSH1 | 3 | `.` | `uint8` | | push 1-byte value onto stack | +| 61 | PUSH2 | 3 | `.` | `uint16` | | push 2-byte value onto stack | +| 62 | PUSH3 | 3 | `.` | `uint24` | | push 3-byte value onto stack | +| 63 | PUSH4 | 3 | `.` | `uint32` | | push 4-byte value onto stack | +| 64 | PUSH5 | 3 | `.` | `uint40` | | push 5-byte value onto stack | +| 65 | PUSH6 | 3 | `.` | `uint48` | | push 6-byte value onto stack | +| 66 | PUSH7 | 3 | `.` | `uint56` | | push 7-byte value onto stack | +| 67 | PUSH8 | 3 | `.` | `uint64` | | push 8-byte value onto stack | +| 68 | PUSH9 | 3 | `.` | `uint72` | | push 9-byte value onto stack | +| 69 | PUSH10 | 3 | `.` | `uint80` | | push 10-byte value onto stack | +| 6A | PUSH11 | 3 | `.` | `uint88` | | push 11-byte value onto stack | +| 6B | PUSH12 | 3 | `.` | `uint96` | | push 12-byte value onto stack | +| 6C | PUSH13 | 3 | `.` | `uint104` | | push 13-byte value onto stack | +| 6D | PUSH14 | 3 | `.` | `uint112` | | push 14-byte value onto stack | +| 6E | PUSH15 | 3 | `.` | `uint120` | | push 15-byte value onto stack | +| 6F | PUSH16 | 3 | `.` | `uint128` | | push 16-byte value onto stack | +| 70 | PUSH17 | 3 | `.` | `uint136` | | push 17-byte value onto stack | +| 71 | PUSH18 | 3 | `.` | `uint144` | | push 18-byte value onto stack | +| 72 | PUSH19 | 3 | `.` | `uint152` | | push 19-byte value onto stack | +| 73 | PUSH20 | 3 | `.` | `uint160` | | push 20-byte value onto stack | +| 74 | PUSH21 | 3 | `.` | `uint168` | | push 21-byte value onto stack | +| 75 | PUSH22 | 3 | `.` | `uint176` | | push 22-byte value onto stack | +| 76 | PUSH23 | 3 | `.` | `uint184` | | push 23-byte value onto stack | +| 77 | PUSH24 | 3 | `.` | `uint192` | | push 24-byte value onto stack | +| 78 | PUSH25 | 3 | `.` | `uint200` | | push 25-byte value onto stack | +| 79 | PUSH26 | 3 | `.` | `uint208` | | push 26-byte value onto stack | +| 7A | PUSH27 | 3 | `.` | `uint216` | | push 27-byte value onto stack | +| 7B | PUSH28 | 3 | `.` | `uint224` | | push 28-byte value onto stack | +| 7C | PUSH29 | 3 | `.` | `uint232` | | push 29-byte value onto stack | +| 7D | PUSH30 | 3 | `.` | `uint240` | | push 30-byte value onto stack | +| 7E | PUSH31 | 3 | `.` | `uint248` | | push 31-byte value onto stack | +| 7F | PUSH32 | 3 | `.` | `uint256` | | push 32-byte value onto stack | +| 80 | DUP1 | 3 | `a` | `a, a` | | clone 1st value on stack | +| 81 | DUP2 | 3 | `_, a` | `a, _, a` | | clone 2nd value on stack | +| 82 | DUP3 | 3 | `_, _, a` | `a, _, _, a` | | clone 3rd value on stack | +| 83 | DUP4 | 3 | `_, _, _, a` | `a, _, _, _, a` | | clone 4th value on stack | +| 84 | DUP5 | 3 | `..., a` | `a, ..., a` | | clone 5th value on stack | +| 85 | DUP6 | 3 | `..., a` | `a, ..., a` | | clone 6th value on stack | +| 86 | DUP7 | 3 | `..., a` | `a, ..., a` | | clone 7th value on stack | +| 87 | DUP8 | 3 | `..., a` | `a, ..., a` | | clone 8th value on stack | +| 88 | DUP9 | 3 | `..., a` | `a, ..., a` | | clone 9th value on stack | +| 89 | DUP10 | 3 | `..., a` | `a, ..., a` | | clone 10th value on stack | +| 8A | DUP11 | 3 | `..., a` | `a, ..., a` | | clone 11th value on stack | +| 8B | DUP12 | 3 | `..., a` | `a, ..., a` | | clone 12th value on stack | +| 8C | DUP13 | 3 | `..., a` | `a, ..., a` | | clone 13th value on stack | +| 8D | DUP14 | 3 | `..., a` | `a, ..., a` | | clone 14th value on stack | +| 8E | DUP15 | 3 | `..., a` | `a, ..., a` | | clone 15th value on stack | +| 8F | DUP16 | 3 | `..., a` | `a, ..., a` | | clone 16th value on stack | +| 90 | SWAP1 | 3 | `a, b` | `b, a` | | | +| 91 | SWAP2 | 3 | `a, _, b` | `b, _, a` | | | +| 92 | SWAP3 | 3 | `a, _, _, b` | `b, _, _, a` | | | +| 93 | SWAP4 | 3 | `a, _, _, _, b` | `b, _, _, _, a` | | | +| 94 | SWAP5 | 3 | `a, ..., b` | `b, ..., a` | | | +| 95 | SWAP6 | 3 | `a, ..., b` | `b, ..., a` | | | +| 96 | SWAP7 | 3 | `a, ..., b` | `b, ..., a` | | | +| 97 | SWAP8 | 3 | `a, ..., b` | `b, ..., a` | | | +| 98 | SWAP9 | 3 | `a, ..., b` | `b, ..., a` | | | +| 99 | SWAP10 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9A | SWAP11 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9B | SWAP12 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9C | SWAP13 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9D | SWAP14 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9E | SWAP15 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9F | SWAP16 | 3 | `a, ..., b` | `b, ..., a` | | | +| A0 | LOG0 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len` | `.` | | LOG0(memory[ost:ost+len-1]) | +| A1 | LOG1 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0` | `.` | | LOG1(memory[ost:ost+len-1], topic0) | +| A2 | LOG2 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1) | +| A3 | LOG3 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2) | +| A4 | LOG4 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2, topic3` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2, topic3) | +| A5-EF | _invalid_ | | | | | | +| F0 | CREATE | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len` | `addr` | | addr = keccak256(rlp([address(this), this.nonce])) | +| F1 | CALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | gas, addr, val, argOst, argLen, retOst, retLen | `success` | mem[retOst:retOst+retLen-1] := returndata | | +| F2 | CALLCODE | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, val, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] = returndata | same as DELEGATECALL, but does not propagate original msg.sender and msg.value | +| F3 | RETURN | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | return mem[ost:ost+len-1] | +| F4 | DELEGATECALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | +| F5 | CREATE2 | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len, salt` | `addr` | | addr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] | +| F6-F9 | _invalid_ | | | | | | +| FA | STATICCALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | +| FB-FC | _invalid_ | | | | | | +| FD | REVERT | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | revert(mem[ost:ost+len-1]) | +| FE | INVALID | [AF](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#af-invalid) | | | designated invalid opcode - [EIP-141](https://eips.ethereum.org/EIPS/eip-141) | | +| FF | SELFDESTRUCT | [AB](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#ab-selfdestruct) | `addr` | `.` | | | destroy contract and sends all funds to `addr` | diff --git a/public/content/translations/pt-br/developers/docs/gas/index.md b/public/content/translations/pt-br/developers/docs/gas/index.md index 2d3458231d1..dd94bfd39df 100644 --- a/public/content/translations/pt-br/developers/docs/gas/index.md +++ b/public/content/translations/pt-br/developers/docs/gas/index.md @@ -24,7 +24,7 @@ Taxas de gas tem que ser pagas na moeda nativa do Ethereum, ether (ETH). Preços Por exemplo, em vez de dizer que seu gás custa 0.000000001 Ether, pode-se dizer que ele custa 1 Gwei. -A palavra 'gwei' é uma contração de 'giga-wei', significando 'bilhão de wei'. Um gwei é igual a um bilhão de wei. O próprio Wei (nomeado em homenagem a [Wei Dai](https://wikipedia.org/wiki/Wei_Dai), criador do [B-Money](https://www.investopedia.com/terms/b/bmoney.asp)) é a menor unidade de ETH. +A palavra 'gwei' é uma contração de 'giga-wei', significando 'bilhão de wei'. Um gwei é igual a um bilhão de wei. O próprio Wei (nomeado em homenagem a [Wei Dai](https://wikipedia.org/wiki/WeiDai), criador do [B-Money](https://www.investopedia.com/terms/b/bmoney.asp)) é a menor unidade de ETH. ## Como são calculadas as taxas de gás? {#how-are-gas-fees-calculated} @@ -55,7 +55,7 @@ Cada bloco tem uma taxa base que funciona como um preço de reserva. Para ser el A taxa base é calculada por uma fórmula que compara o tamanho do bloco anterior (a quantidade de gás utilizada para todas as transações) com o tamanho do alvo. A taxa base aumentará em um máximo de 12,5% por bloco se o tamanho do bloco de destino for excedido. Esse crescimento exponencial torna economicamente inviável que o tamanho do bloco permaneça elevado indefinidamente. | Número do bloco | Gás incluído | Aumento de taxa | Taxa base atual | -| --------------- | -----------: | --------------: | --------------: | +| --------------- | ------------:| ---------------:| ---------------:| | 1 | 15M | 0% | 100 gwei | | 2 | 30M | 0% | 100 gwei | | 3 | 30M | 12,5% | 112,5 gwei | @@ -70,7 +70,7 @@ Conforme a tabela acima, para criar uma transação no bloco número 9, uma cart Também é importante notar que, é improvável que veremos picos prolongados de blocos completos, devido à velocidade com que a taxa base aumenta antes de um bloco completo. | Número do bloco | Gás incluído | Aumento da taxa | Taxa base atual | -| --------------- | -----------: | --------------: | --------------: | +| --------------- | ------------:| ---------------:| ---------------:| | 30 | 30M | 12,5% | 2705,6 gwei | | ... | ... | 12,5% | ... | | 50 | 30M | 12,5% | 28531,3 gwei | diff --git a/public/content/translations/pt-br/developers/docs/networking-layer/network-addresses/index.md b/public/content/translations/pt-br/developers/docs/networking-layer/network-addresses/index.md index 312b531d212..3f9220b964a 100644 --- a/public/content/translations/pt-br/developers/docs/networking-layer/network-addresses/index.md +++ b/public/content/translations/pt-br/developers/docs/networking-layer/network-addresses/index.md @@ -9,7 +9,7 @@ Nós Ethereum precisam se identificar com algumas informações básicas para se ## Pré-Requisitos {#prerequisites} -É necessário ter algum entendimento sobre a [camada de rede](/developers/docs/networking-layer/) do Ethereum para entender esta página. +É necessário ter algum entendimento sobre a [camada de rede](/developers/docs/networking-layer/)do Ethereum para entender esta página. ## Multiaddr {#multiaddr} diff --git a/public/content/translations/pt-br/developers/docs/networking-layer/portal-network/index.md b/public/content/translations/pt-br/developers/docs/networking-layer/portal-network/index.md new file mode 100644 index 00000000000..921bf996809 --- /dev/null +++ b/public/content/translations/pt-br/developers/docs/networking-layer/portal-network/index.md @@ -0,0 +1,82 @@ +--- +title: A Rede Portal +description: Uma visão geral da Rede Portal - uma rede em desenvolvimento para dar suporte a clientes com poucos recursos. +lang: pt-br +--- + +O Ethereum é uma rede composta de computadores que rodam o software Ethereum. Cada um destes computadores é chamado de um 'nódulo'. O software cliente permite a um nódulo enviar e receber dados na rede Ethereum, e verifica os dados contra as regras do protocolo Ethereum. Nódulos mantém um monte de dados históricos no armazenamento dos seus discos e adicionam a eles quando recebem novos pacotes de informações, conhecidos como blocos, de outros nódulos da rede. Isto é necessário para sempre checar que um nódulo tem informação consistente com o resto da rede. Isto significa que rodar um nódulo pode requerer muito espaço em disco. Algumas operações de nódulos podem requerer muita memória RAM também. + +Para resolver este problema de armazenamento, nódulos 'leves' tem sido desenvolvidos para requisitar informações de nódulos completos ao invés de armazenar eles mesmos. Entretanto, isto significa o nódulo leve não verifica as informações independentemente; ao invés disso, confia em outro nódulo. Isto também significa que nós completos são necessários para pegar um trabalho extra para servir estes nós leves. + +A Rede Portal é um novo desenho de rede para o Ethereum que visa resolver o problema de disponibilidade de dados para nódulos 'leves' sem ter que confiar ou colocar pressão extra nos nódulos completos, compartilhando os dados necessários em pequenos pedaços através da rede. + +Mais sobre [nós e clientes](/developers/docs/nodes-and-clients/) + +## Por que nós precisamos da Rede Portal {#why-do-we-need-portal-network} + +Os nódulos da Ethereum armazenam sua própria cópia total ou parcial do blockchain Ethereum. Esta cópia local é usada para validar transações e garantir que o nódulo está seguindo a cadeia correta. Este dado armazenado localmente permite aos nódulos verificarem de maneira independente que os dados de chegada são válidos e corretos sem precisar acreditar em nenhuma outra entidade. + +Esta cópia local do blockchain, além de seu estado associado e do recebimento de dados tomam muito espaço no disco rígido do nódulo. Por exemplo, um disco rígido de 2TB é recomendado para rodar um nó utilizando [Geth](https://geth.ethereum.org) pareado com um cliente de consenso. Usando sincronização instantânea, que armazena apenas dados da cadeia de um conjunto de blocos relativamente recente, Geth tipicamente ocupa cerca de 650GB de espaço em disco, mas cresce cerca de 14GB/semana (você pode podar o nó de volta a 650GB periodicamente). + +Isto significa que rodar nódulos pode ser caro, porque uma grande quantidade de espaço em disco tem de ser dedicada ao Ethereum. Há diversas soluções para este problema no roadmap do Ethereum, incluindo [expiração de histórico](/roadmap/statelessness/#history-expiry), [expiração de estado](/roadmap/statelessness/#state-expiry) e [falta de estado](/roadmap/statelessness/). Entretanto, ainda há muito até que eles sejam implementados. Há também [nódulos leves](/developers/docs/nodes-and-clients/light-clients/) que não gravam suas próprias cópias dos dados da cadeia, eles solicitam os dados que eles precisam dos nódulos completos. Entretanto, isso significa que nódulos leves tem que acreditar em nódulos completos para fornecer dados honestos e também estressa os nódulos completos que tem que servir os dados para as necessidades dos nódulos leves. + +A Rede Portal visa fornecer uma maneira alternativa para nós leves terem seus dados que sem requerer confiança ou adicionar significantemente ao trabalho que tem de ser feito pelos nós completos. Isto será feito com a introdução de uma nova maneira dos nós Ethereum compartilharem dados através da rede. + +## Como a Rede Portal funciona? {#how-does-portal-network-work} + +Nós Ethereum tem protocolos estritos que definem como eles se comunicam com os outros. Clientes de execução se comunicam usando um conjunto de sub-protocolos conhecidos como [DevP2P](/developers/docs/networking-layer/#devp2p), enquanto clientes de consenso usam uma pilha diferente de sub-protocolos chamada [libP2P](/developers/docs/networking-layer/#libp2p). Eles definem os tipos de dados que podem ser passados entre nós. + +![devP2P e libP2P](portal-network-devp2p-libp2p.png) + +Os nós podem também servir dados específicos através da [API JSON-RPC](/developers/docs/apis/json-rpc/), que é como apps e carteiras trocam informações com os nós Ethereum. Entretanto, nenhum destes são protocolos ideias para servir dados para clientes leves. + +Clientes leves não podem atualmente requisitar pedaços específicos da cadeia de dados pelo DevP2P ou libP2P, porque estes protocolos são desenhados somente para habilitar sincronização de cadeias e transmissão de blocos e transações. Clientes leves não querem fazer o download desta informação, porque deixariam de ser 'leves'. + +A API JSON-RPC não é a escolha ideal para requisições de dados de clientes leves também, porque ela confia na conexão para um nó completo específico ou fornecedor de RPC centralizado que pode servir os dados. Isto significa que clientes leves tem que confiar em um específico nó/provedor ser honesto, e também o nó completo pode ter que manipular muitas requisições de muitos clientes leves, adicionando aos requisitos da sua largura de banda. + +A meta da Rede Portal é repensar todo o desenho, construindo especificamente para leveza, fora das limitações de desenho dos clientes Ethereum existentes. + +A ideia central da Rede Portal é pegar os melhores bits da pilha da rede atual habilitando informações necessárias pelos clientes leves, como dados históricos e a identidade da cabeça atual da cadeia para ser servida através de um estilo DevP2P peso leve ponto-a-ponto em uma rede descentralizada, usando um [DHT](https://en.wikipedia.org/wiki/Distributed_hash_table) (similar à Bittorrent). + +A ideia é adicionar pequenas partes do histórico de dados total do Ethereum e algumas responsabilidades específicas de nós para cada nó. Então, requisições são servidas procurando os nós que armazenam o dado específico que foi requisitado e recuperando-o deles. + +Isto inverte o modelo normal de nós leves encontrando um único nó e requisitando a eles filtrar e servir grandes volumes de dados; ao invés disso, eles rapidamente filtram uma grande rede de nós onde cada um manipula pequenas quantidades de dados. + +O objetivo é permitir uma rede descentralizada de clientes Portal peso leve para: + +- rastrear a cabeça da cadeia +- sincronizar dados recentes e históricos da cadeia +- recuperar os dados de estado +- transmitir transações +- executar transações usando a [EVM](/developers/docs/evm/) + +Os benefícios deste desenho de rede são: + +- reduzir a dependência em fornecedores centralizados +- reduzir o uso de banda de internet +- minimizar ou zerar a sincronia +- ser acessível a dispositivos com restrição de recursos (<1GB RAM, <100MB de disco, 1CPU) + +O diagrama abaixo mostra as funções dos clientes existentes que podem ser entregues pela Rede Portal, habilitando ao usuários acessar estas funções em dispositivos com muito poucos recursos. + +![tabela rede portal](portal-network-table2.png) + +## Diversidade de cliente por padrão {#client-diversity-as-default} + +Os desenvolvedores da Rede Portal também fizeram com que o design assumido construísse três clientes separados na Rede Portal desde o primeiro dia. + +Os clientes da Rede Portal são: + +- [Trin](https://github.com/ethereum/trin): escrito em Rust +- [Fluffy](https://nimbus.team/docs/fluffy.html): escrito em Nim +- [Ultralight](https://github.com/ethereumjs/ultralight): escrito em Typescript + +Ter várias implementações de clientes independentes melhora a resiliência e descentralização da rede Ethereum. + +Se um cliente enfrenta problemas de vulnerabilidades, outros clientes podem continuar a operar tranquilamente, evitando o ponto único de falha. Adicionalmente, diversidade na implementação de clientes fomenta inovação e competição, conduzindo melhorias e reduzindo risco de monocultura dentro do ecossistema. + +## Leitura adicional {#futher-reading} + +- [A Rede Portal (Piper Merriam na Devcon Bogota)](https://www.youtube.com/watch?v=0stc9jnQLXA). +- [O desacordo da Rede Portal](https://discord.gg/CFFnmE7Hbs) +- [O website da Rede Portal](https://www.ethportal.net/) diff --git a/public/content/translations/pt-br/developers/docs/networks/index.md b/public/content/translations/pt-br/developers/docs/networks/index.md index ec72e59b0fe..f01cbe3f3da 100644 --- a/public/content/translations/pt-br/developers/docs/networks/index.md +++ b/public/content/translations/pt-br/developers/docs/networks/index.md @@ -38,7 +38,7 @@ As duas redes de testes públicas que os desenvolvedores dos clientes estão atu #### Sepolia {#sepolia} -\*\*\*\*Sepolia é a rede de teste padrão recomendada para desenvolvimento de aplicativos. A rede Sepolia usa um conjunto de validadores autorizados. É bastante novo, o que significa que seu estado e história são bastante pequenos. Isso significa que a rede é rápida para sincronizar e que a execução de um nó requer menos armazenamento. Isso é útil para usuários que desejam ativar rapidamente um nó e interagir diretamente com a rede. +****Sepolia é a rede de teste padrão recomendada para desenvolvimento de aplicativos. A rede Sepolia usa um conjunto de validadores autorizados. É bastante novo, o que significa que seu estado e história são bastante pequenos. Isso significa que a rede é rápida para sincronizar e que a execução de um nó requer menos armazenamento. Isso é útil para usuários que desejam ativar rapidamente um nó e interagir diretamente com a rede. - Conjunto de validadores fechado, controlado pelo cliente & equipes de teste - Nova rede de teste, menos aplicativos implantados que outras redes de teste @@ -56,10 +56,11 @@ As duas redes de testes públicas que os desenvolvedores dos clientes estão atu - [Faucet do QuickNode Sepolia](https://faucet.quicknode.com/drip) - [Grabteeth](https://grabteeth.xyz/) - [Faucet de PoW](https://sepolia-faucet.pk910.de/) -- [Faucet da Carteira da Coinbase | Sepolia](https://coinbase.com/faucets/ethereum-sepolia-faucet) +- [Faucet da Carteira Coinbase | Sepolia](https://coinbase.com/faucets/ethereum-sepolia-faucet) - [Faucet do Alchemy Sepolia](https://sepoliafaucet.com/) - [Faucet do Infura Sepolia](https://www.infura.io/faucet) - [Faucet da Chainstack Sepolia](https://faucet.chainstack.com/sepolia-faucet) +- [Faucet da rede de teste | Sepolia](https://testnet-faucet.com/sepolia/) #### Goerli _(suporte a longo prazo)_ {#goerli} @@ -102,7 +103,7 @@ Uma rede de testes para [Arbitrum](https://arbitrum.io/). - [Faucet do Chainlink](https://faucets.chain.link/) -#### Goerli otimista {#optimistic-goerli} +#### Optimistic Goerli {#optimistic-goerli} Uma rede de testes para [Optimism](https://www.optimism.io/). @@ -111,26 +112,34 @@ Uma rede de testes para [Optimism](https://www.optimism.io/). - [Faucet Paradigm](https://faucet.paradigm.xyz/) - [Coinbase Wallet Faucet | Optimism Goerli](https://coinbase.com/faucets/optimism-goerli-faucet) +#### Starknet Goerli {#starknet-goerli} + +Uma rede de teste para [Starknet](https://www.starknet.io). + +##### Faucets + +- [Faucet da Starknet](https://faucet.goerli.starknet.io) + ## Redes privadas {#private-networks} -Uma rede Ethereum é uma rede privada se seus nós não estiverem conectados a uma rede pública (ex: Rede principal e rede de testes). Neste contexto, privado significa apenas reservado ou isolado, em vez de protegido ou seguro. +Uma rede Ethereum é uma rede privada se seus nódulos não estiverem conectados a uma rede pública (ex: Rede principal e rede de testes). Neste contexto, privado significa apenas reservado ou isolado, em vez de protegido ou seguro. ### Redes de desenvolvimento {#development-networks} -Para desenvolver um aplicativo Ethereum, você deve executá-lo em uma rede privada para ver como funciona antes de implantá-lo. Tal como você pode criar um servidor local em seu computador para desenvolvimento Web, você pode criar uma instância local de cadeia de blocos para testar seu dapp. Isso permite uma iteração muito mais rápida do que uma rede de testes pública. +Para desenvolver um aplicativo Ethereum, você deve executá-lo em uma rede privada para ver como funciona antes de implantá-lo. Tal como você pode criar um servidor local em seu computador para desenvolvimento Web, você pode criar uma instância local de blockchain para testar seu dapp. Isso permite uma iteração muito mais rápida do que uma rede de testes pública. Existem projetos e ferramentas dedicadas a ajudá-lo com isso. Saiba mais sobre [redes de desenvolvimento](/developers/docs/development-networks/). ### Redes de consórcio {#consortium-networks} -O processo de consenso é controlado por um conjunto predefinido de nós confiáveis. Por exemplo, uma rede privada de instituições acadêmicas conhecidas, cada uma administrando um único nó, e os blocos são validados por um limite de signatários dentro da rede. +O processo de consenso é controlado por um conjunto predefinido de nódulos confiáveis. Por exemplo, uma rede privada de instituições acadêmicas conhecidas, cada uma administrando um único nódulo, e os blocos são validados por um limite de signatários na rede. Se uma rede pública Ethereum é como a internet pública, uma rede de consórcio é como uma intranet privada. ## Ferramentas relacionadas {#related-tools} - [Chainlist](https://chainlist.org/) _Lista de redes EVM para conectar carteiras e fornecedores aos identificadores de cadeia e rede apropriados_ -- [/Cadeias baseadas na EVM](https://github.com/ethereum-lists/chains) _repositório do GitHub com metadados de cadeias que alimenta a Chainlist_ +- [/Cadeias baseadas em EVM](https://github.com/ethereum-lists/chains) _Repositório do GitHub com metadados de cadeias que alimenta a Chainlist_ ## Leitura adicional {#further-reading} diff --git a/public/content/translations/pt-br/developers/docs/nodes-and-clients/archive-nodes/index.md b/public/content/translations/pt-br/developers/docs/nodes-and-clients/archive-nodes/index.md index c9cfe4ef61a..9ec5ad14275 100644 --- a/public/content/translations/pt-br/developers/docs/nodes-and-clients/archive-nodes/index.md +++ b/public/content/translations/pt-br/developers/docs/nodes-and-clients/archive-nodes/index.md @@ -70,7 +70,7 @@ Durante a sincronização inicial, os clientes no modo arquivo executarão todas ## Leitura adicional {#further-reading} -- [Nó completo Ethereum vs Nó de arquivo](https://www.quicknode.com/guides/infrastructure/ethereum-full-node-vs-archive-node) — _QuickNode, setembro de 2022_ +- [Nó completo Ethereum vs Nó de arquivo](https://www.quicknode.com/guides/infrastructure/ethereum-full-node-vs-archive-node) — *QuickNode, setembro de 2022* - [Construindo seu próprio nó de arquivo Ethereum](https://tjayrush.medium.com/building-your-own-ethereum-archive-node-72c014affc09) — _Thomas Jay Rush, agosto de 2021_ - [Como configurar Erigon, o RPC do Erigon e TrueBlocks (extração e API) como serviços](https://magnushansson.xyz/blog_posts/crypto_defi/2022-01-10-Erigon-Trueblocks) _– Magnus Hansson, atualizado em setembro de 2022_ diff --git a/public/content/translations/pt-br/developers/docs/nodes-and-clients/client-diversity/index.md b/public/content/translations/pt-br/developers/docs/nodes-and-clients/client-diversity/index.md index 18bad4e622a..f5061c43027 100644 --- a/public/content/translations/pt-br/developers/docs/nodes-and-clients/client-diversity/index.md +++ b/public/content/translations/pt-br/developers/docs/nodes-and-clients/client-diversity/index.md @@ -31,7 +31,7 @@ A diversidade de clientes também oferece resiliência a ataques. Por exemplo, u Um erro em um cliente de consenso com mais de 33% dos nós Ethereum poderia impedir a finalização da camada de consenso, e isso deixaria os utilizadores em dúvida com respeito à probabilidade de as transações não serem revertidas ou alteradas em algum momento. Isso seria muito problemático para muitos dos aplicativos construídos em cima do Ethereum, particularmente o DeFi. - Pior ainda, um bug crítico em um cliente com uma maioria de dois terços poderia fazer com que a cadeia se dividisse e finalizasse incorretamente, gerando um grande conjunto de validadores que ficam presos em uma cadeia inválida. Se quiserem voltar a integrar à cadeia correta, esses validadores enfrentam cortes ou uma lenta e cara retirada e reativação voluntária. A magnitude de uma escala de remoção com o número de nós culpáveis com uma maioria de dois terços reduzido ao máximo (32 ETH). + Pior ainda, um bug crítico em um cliente com uma maioria de dois terços poderia fazer com que a cadeia se dividisse e finalizasse incorretamente, gerando um grande conjunto de validadores que ficam presos em uma cadeia inválida. Se quiserem voltar a integrar à cadeia correta, esses validadores enfrentam cortes ou uma lenta e cara retirada e reativação voluntária. A magnitude de uma escala de remoção com o número de nós culpáveis com uma maioria de dois terços reduzido ao máximo (32 ETH). Embora estes sejam cenários improváveis, o ecossistema Ethereum pode mitigar seus riscos nivelando a distribuição de clientes entre os nós ativos. Idealmente, nenhum cliente de consenso chegaria a uma participação de 33% dos nós totais. diff --git a/public/content/translations/pt-br/developers/docs/nodes-and-clients/index.md b/public/content/translations/pt-br/developers/docs/nodes-and-clients/index.md index 09d985465fe..94a02175359 100644 --- a/public/content/translations/pt-br/developers/docs/nodes-and-clients/index.md +++ b/public/content/translations/pt-br/developers/docs/nodes-and-clients/index.md @@ -136,6 +136,7 @@ Essa tabela resume os diferentes clientes. Todos eles passam por [testes de clie | [Nethermind](http://nethermind.io/) | C#, .NET | Linux, Windows, macOS | Rede principal, Sepolia, Goerli, e outras | Instantâneo (sem servidor), Rápido, Completo | Arquivo, Removido | | [Besu](https://besu.hyperledger.org/en/stable/) | Java | Linux, Windows, macOS | Rede principal, Sepolia, Goerli, e outras | Instantâneo, Rápido, Completo | Arquivo, Removido | | [Erigon](https://github.com/ledgerwatch/erigon) | Go | Linux, Windows, macOS | Rede principal, Sepolia, Goerli, e outras | Completo | Arquivo, Removido | +| [Reth](https://github.com/paradigmxyz/reth) | Rust | Linux, Windows, macOS | Rede principal, Sepolia, Goerli, e outras | Completo | Arquivo, Removido | Para saber mais sobre redes suportadas, leia sobre as [redes Ethereum](/developers/docs/networks/). diff --git a/public/content/translations/pt-br/developers/docs/nodes-and-clients/run-a-node/index.md b/public/content/translations/pt-br/developers/docs/nodes-and-clients/run-a-node/index.md index 3d021ef8e24..b1e0b4587b3 100644 --- a/public/content/translations/pt-br/developers/docs/nodes-and-clients/run-a-node/index.md +++ b/public/content/translations/pt-br/developers/docs/nodes-and-clients/run-a-node/index.md @@ -151,7 +151,7 @@ Aqui estão as páginas de lançamento dos clientes, nas quais você pode encont ##### Clientes de execução - [Besu](https://github.com/hyperledger/besu/releases) -- [Erigon](https://github.com/ledgerwatch/erigon#usage) (não fornece um binário pré-compilado, precisa ser compilado) +- [Erigon](https://github.com/ledgerwatch/erigon/releases) - [Geth](https://geth.ethereum.org/downloads/) - [Nethermind](https://downloads.nethermind.io/) diff --git a/public/content/translations/pt-br/developers/docs/scaling/index.md b/public/content/translations/pt-br/developers/docs/scaling/index.md index 81d495a35cb..74bad9eac6e 100644 --- a/public/content/translations/pt-br/developers/docs/scaling/index.md +++ b/public/content/translations/pt-br/developers/docs/scaling/index.md @@ -21,27 +21,25 @@ Você deveria ter um bom entendimento de todos os tópicos fundamentais. Impleme ## Dimensionamento on-chain {#on-chain-scaling} -Este método de dimensionamento requer alterações no protocolo Ethereum ([rede principal](/glossary/#mainnet) da camada 1). A fragmentação é atualmente o principal objetivo deste método de dimensionamento. +A escalabilidade em cadeia requer mudanças no protocolo do Ethereum ([Mainnet](/glossary/#mainnet) de camada 1). A solução de fragmentação da blockchain era aguardada há muito tempo para escalar o Ethereum. Isso implicava dividir a blockchain em partes discretas (fragmentos), que seriam verificadas por subconjuntos de validadores. No entanto, a técnica de escalabilidade principal adotada foi a de escalar por rollups de camada 2. Ela é suportada pela adição de uma nova forma mais barata de dados anexados aos blocos Ethereum, que foi especialmente criada para tornar os rollups baratos para os usuários. ### Fragmentação {#sharding} -A fragmentação é o processo de dividir um banco de dados horizontalmente para repartir a carga de trabalho. No contexto do Ethereum, a fragmentação reduzirá o congestionamento da rede e aumentará o número de transações por segundo graças à geração de novas cadeias conhecidas como "fragmentos". Isso também irá aliviar a carga para cada validador, que não precisará mais processar a totalidade de todas as transações da rede. - -Saiba mais sobre [fragmentação](/roadmap/danksharding/). +Fragmentação é o processo de dividir um banco de dados. Subconjuntos de validadores seriam responsáveis por seus próprios fragmentos, em vez de manter o controle de todo o Ethereum. A fragmentação esteve no [planejamento](/roadmap/) do Ethereum por muito tempo, com a intenção de ser enviada para prova de participação antes do The Merge (A Fusão). No entanto, o rápido desenvolvimento de [rollups de camada 2](#layer-2-scaling) e a invenção do [Danksharding](/roadmap/danksharding) (adicionando blobs de dados do rollup para blocos do Ethereum que podem ser verificados eficientemente pelos validadores) têm levado a comunidade Ethereum a preferir o dimensionamento centrado por rollup em vez do dimensionamento por fragmentação. Isso também ajudará a manter a lógica de consenso do Ethereum mais simples. ## Dimensionamento off-chain {#off-chain-scaling} -As soluções off-chain são implementadas separadamente da rede principal da camada 1. Ou seja, elas não requerem alterações no protocolo Ethereum Ethereum existente. Algumas soluções, conhecidas como soluções de "camada 2", derivam sua segurança diretamente do consenso da camada 1 do Ethereum, por exemplo, os [optimistic rollups](/developers/docs/scaling/layer-2-rollups/), os [rollups de conhecimento zero](/developers/docs/scaling/zk-rollups/) ou os [canais de estado](/developers/docs/scaling/state-channels/). Outras soluções envolvem a criação de novas cadeias em várias formas que derivam sua segurança separadamente da rede principal, como [sidechains](#sidechains), [validiums](#validium) ou [cadeias Plasma](#plasma). Essas soluções se comunicam com a rede principal, mas derivam sua segurança de forma diferente para obter uma variedade de objetivos. +As soluções off-chain são implementadas separadamente da rede principal da camada 1. Ou seja, elas não requerem alterações no protocolo Ethereum existente. Algumas soluções, conhecidas como soluções de “camada 2”, obtêm sua segurança diretamente do consenso da camada 1 do Ethereum, por exemplo, os [rollups otimistas](/developers/docs/scaling/layer-2-rollups/), os [rollups de conhecimento zero](/developers/docs/scaling/zk-rollups/) ou os [canais de estado](/developers/docs/scaling/state-channels/). Outras soluções envolvem a criação de novas cadeias em várias formas, que obtêm sua segurança separadamente da Mainnet (Rede principal), como [cadeias laterais](#sidechains), [validiums](#validium) ou [cadeias Plasma](#plasma). Essas soluções se comunicam com a Mainnet (Rede principal), mas obtêm sua segurança de forma diferente para alcançar uma variedade de objetivos. ### Dimensionamento da camada 2 {#layer-2-scaling} -Esta categoria de soluções off-chain deriva a sua segurança da rede principal do Ethereum. +Esta categoria de soluções off-chain obtém sua segurança da Mainnet (Rede principal) do Ethereum. -A camada 2 é um termo coletivo para soluções projetadas para ajudar a dimensionar os aplicativos, manipulando para isso as transações fora da rede principal (camada 1) de Ethereum, tirando proveito do robusto modelo de segurança descentralizada fornecido pela rede principal. A velocidade das transações sofre quando a rede está ocupada, o que pode tornar a experiência do usuário ruim para certos tipos de dapps. E à medida que a rede fica mais movimentada, os preços do gás tendem a aumentar devido a que os remetentes das transações tendem a oferecer mais para processar sua transação antes que as dos outros. E essa conjuntura pode tornar o uso do Ethereum bem mais caro. +A camada 2 é um termo coletivo de soluções projetadas para ajudar a dimensionar os aplicativos, gerenciando transações fora da rede principal (camada 1) do Ethereum, aproveitando o robusto modelo de segurança descentralizada da Mainnet (Rede principal). A velocidade das transações é reduzida quando a rede está ocupada, o que pode tornar a experiência do usuário ruim para certos tipos de dapps. À medida que a rede fica mais movimentada, os preços do gás aumentam, pois os remetentes de transações tendem a oferecer mais para processar sua transação antes das dos outros. Isso pode tornar o uso do Ethereum bem mais caro. -A maioria das soluções de camada 2 orbitam ao redor de um servidor, ou cluster de servidores, cada um dos quais pode ser referenciado como um nó, como um validador, como um operador, como um sequenciador de transações, como um produtor de blocos ou como algo semelhante. Dependendo da implementação, esses nós da camada 2 podem ser executados pelos indivíduos, pelas empresas ou pelas entidades que os usam, ou por um operador de terceiros, ou ainda por um grande grupo de indivíduos (da maneira similar à rede principal). Em geral, ao invés de serem enviadas diretamente para a camada 1 (rede principal), as transações são submetidas a esses nós da camada 2. Para algumas soluções, a camada 2 instancia as transações e as agrupa antes de ancorá-las à camada 1. Depois disso, elas são protegidas pela própria camada 1 e não podem ser mais alteradas. Os pormenores de como isso é feito variam significativamente entre diferentes tecnologias de camada 2 e suas diferentes implementações. +A maioria das soluções de camada 2 são centralizadas em torno de um servidor ou cluster de servidores, cada um dos quais pode ser referenciado como um nó, validador, operador, sequenciador, produtor de bloco, ou um termo semelhante. Dependendo da implementação, esses nós da camada 2 podem ser executados pelos indivíduos, empresas ou entidades que os usam, por um operador de terceiros ou por um grande grupo de indivíduos (semelhante à Mainnet). Em geral, as transações são submetidas a esses nós de camada 2, em vez de serem enviadas diretamente para a camada 1 (Mainnet). Para algumas soluções, a instância da camada 2 agrupa-os em grupos antes de ancorá-los na camada 1, na qual ficam protegidos e não podem ser alterados. Os pormenores de como isso é feito variam significativamente entre diferentes tecnologias de camada 2 e implementações. -Uma instância específica da camada 2 pode ser aberta e compartilhada por muitos aplicativos, ou pode ser implantada por um projeto e dedicada especificamente a apoiar apenas seu aplicativos. +Uma instância específica da camada 2 pode ser aberta e compartilhada por muitos aplicativos, ou pode ser implantada por um projeto e dedicada a dar suporte apenas ao seu aplicativo. #### Por que a camada 2 é necessária? {#why-is-layer-2-needed} @@ -54,36 +52,36 @@ Uma instância específica da camada 2 pode ser aberta e compartilhada por muito #### Rollups {#rollups} -Os rollups levam a execução das transações para fora da camada 1 e, posteriormente, tais dados são reportados para a camada 1, onde o consenso é alcançado. Como os dados de transação estão incluídos nos blocos da camada 1, isso permite que os rollups sejam protegidos pela segurança nativa do Ethereum. +Os rollups executam a transação fora da camada 1 e, em seguida, os dados são publicados na camada 1, na qual o consenso é alcançado. Como os dados de transação estão incluídos nos blocos da camada 1, isso permite que os rollups fiquem protegidos pela segurança nativa da Ethereum. -Existem dois tipos de rolllups com diferentes modelos de segurança: +Existem dois tipos de rollups com diferentes modelos de segurança: - **Optimistic rollups**: assumem que as transações são válidas por padrão e só executam computação através de uma [**prova de fraude**](/glossary/#fraud-proof), caso alguém levante alguma objeção. [Mais sobre optimistic-rollups](/developers/docs/scaling/optimistic-rollups/). - **Rollups de conhecimento zero**: executam a computação off-chain e enviam uma [**prova de validade**](/glossary/#validity-proof) para a cadeia. [Mais sobre rollups de conhecimento zero](/developers/docs/scaling/zk-rollups/). #### Canais de Estado {#channels} -Os canais de estado utilizam contratos multisig para permitir que os participantes façam transações de forma rápida e livre off-chain, e em seguida, liquidam a finalidade com a rede principal. Isto minimiza o congestionamento, as taxas e os atrasos na rede. Neste momento, existem dois tipos de canais: canais de estado e canais de pagamento. +Os canais de estado utilizam contratos multisig para permitir que os participantes realizem transações de forma rápida e livre off-chain para, em seguida, liquidar a finalidade com a Mainnet. Isso minimiza o congestionamento, as taxas e os atrasos na rede. Atualmente, existem dois tipos de canais: canais de estado e canais de pagamento. -Saiba mais sobre [canais de estado](/developers/docs/scaling/state-channels/). +Aprenda mais sobre [canais de estado](/developers/docs/scaling/state-channels/). ### Correntes paralelas {#sidechains} -Uma sidechain é uma blockchain independente e compatível com EVM que se executa em paralelo com a rede principal. Essas são compatíveis com Ethereum através de pontes de dois sentidos e são executadas de acordo com as regras de consenso escolhidas e com os parâmetros do bloco. +Uma sidechain (cadeia paralela) é uma blockchain independente e compatível com EVM que roda em paralelo à Mainnet (Rede principal). As sidechains são compatíveis com o Ethereum através de pontes bidirecionais e são executadas conforme as regras de consenso escolhidas e os parâmetros do bloco. Saiba mais sobre [Sidechains](/developers/docs/scaling/sidechains/). ### Plasma {#plasma} -A cadeia Plasma é uma blockchain separada que é ancorada à cadeia principal do Ethereum, e usa provas de fraude (como as [optimistic rollups](/developers/docs/scaling/optimistic-rollups/)) para arbitrar disputas. +A cadeia plasma é uma blockchain separada que é ancorada à cadeia principal do Ethereum e usa provas de fraude (como os [rollups otimistas](/developers/docs/scaling/optimistic-rollups/)) para arbitrar litígios. -Saiba mais sobre [Plasma](/developers/docs/scaling/plasma/). +Aprenda mais sobre o [Plasma](/developers/docs/scaling/plasma/). ### Validium {#validium} Uma cadeia Validium usa provas de validade como rollups de conhecimento zero, mas os dados não são armazenados na cadeia Ethereum da camada 1 principal. Isso pode levar a 10 mil transações por segundo por cadeia Validium, e várias cadeias podem ser executadas em paralelo. -Saiba mais sobre [fragmentação](/developers/docs/scaling/validium/). +Saiba mais sobre o [Validium](/developers/docs/scaling/validium/). ## Por que tantas soluções de dimensionamento são necessárias? {#why-do-we-need-these} @@ -96,7 +94,7 @@ Saiba mais sobre [fragmentação](/developers/docs/scaling/validium/). -_Note que a explicação no vídeo usa o termo "Camada 2" para se referir a todas as soluções de escalonamento off-chain enquanto diferenciamos a "Camada 2" como uma solução off-chain que deriva sua segurança através do consenso principal da camada 1._ +_Observe que a explicação no vídeo usa o termo “Camada 2" para se referir a todas as soluções de escalabilidade off-chain, enquanto nós diferenciamos a “Camada 2" como uma solução off-chain que deriva sua segurança a partir do consenso da Mainnet (Rede principal) de camada 1._ @@ -112,4 +110,4 @@ _Note que a explicação no vídeo usa o termo "Camada 2" para se referir a toda - [Por que os rollups, junto com as fragmentações dos dados, são a única solução sustentável para atingir alto dimensionamento](https://polynya.medium.com/why-rollups-data-shards-are-the-only-sustainable-solution-for-high-scalability-c9aabd6fbb48) - [Que tipo de camada 3 faz sentido?](https://vitalik.eth.limo/general/2022/09/17/layer_3.html) -_Conhece algum recurso da comunidade que o ajudou? Edite essa página e adicione!_ +_Conhece um recurso da comunidade que te ajudou? Edite essa página e adicione!_ diff --git a/public/content/translations/pt-br/developers/docs/scaling/optimistic-rollups/index.md b/public/content/translations/pt-br/developers/docs/scaling/optimistic-rollups/index.md index e1762f53c3a..55b7c4b901a 100644 --- a/public/content/translations/pt-br/developers/docs/scaling/optimistic-rollups/index.md +++ b/public/content/translations/pt-br/developers/docs/scaling/optimistic-rollups/index.md @@ -198,7 +198,7 @@ Os optimistic rollups usam um esquema de taxa de gás, muito parecido com o Ethe 2. **`calldata`**: além da taxa básica de transação, o custo de cada escrita de estado depende do tamanho de `calldata` publicado na L1. Os custos de `calldata` são atualmente regidos por [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), que estipula um custo de 16 gás para bytes diferentes de zero e 4 gás para zero bytes de `calldata`, respectivamente. Para reduzir as taxas do usuário, os operadores de rollup compactam as transações para reduzir o número de bytes `calldata` publicados no Ethereum. -3. **Taxas do operador L2**: este é o valor pago aos nós de rollup como compensação pelos custos computacionais incorridos no processamento de transações, assim como as taxas do minerador no Ethereum. Os nós de rollup cobram taxas de transação mais baixas, pois os L2s têm capacidades de processamento mais altas e não enfrentam congestionamentos de rede que forçam os mineradores no Ethereum a priorizar transações com taxas mais altas. +3. **Taxas do operador L2**: Este é o valor pago aos nódulos de rollup como compensação pelos custos computacionais decorrentes do processamento de transações, muito parecido com as taxas de Gas no Ethereum. Os nódulos de rollup cobram taxas de transação mais baixas, já que as L2s têm capacidades de processamento mais altas e não enfrentam os congestionamentos de rede, que forçam os validadores no Ethereum a priorizar transações com taxas mais altas. Os optimistic rollups aplicam vários mecanismos para reduzir as taxas para os usuários, incluindo transações em lote e compactando `calldata` para reduzir os custos de publicação de dados. Você pode verificar o [rastreador de taxas L2](https://l2fees.info/), para ter uma ideia geral real do custo de uso de optimistic rollups baseados em Ethereum. @@ -229,7 +229,7 @@ Fazer alguns cálculos aproximados sobre esses números pode ajudar a mostrar as Esta é uma estimativa bastante otimista, uma vez que as transações de optimistic rollups não podem abranger um bloco inteiro no Ethereum. No entanto, pode dar uma ideia aproximada de quantos ganhos de dimensionamento os optimistic rollups podem proporcionar aos usuários do Ethereum (as implementações atuais oferecem até 2.000 TPS). -Espera-se que a introdução de [particionamento de dados (sharding)](/roadmap/danksharding/) no Ethereum melhore o dimensionamento do optimistic rollup. Como as transações de rollup devem compartilhar o espaço de blocos (blockspace) com outras transações não-rollup, sua capacidade de processamento é limitada pela taxa de transferência de dados na cadeia principal do Ethereum. O particionamento aumentará o espaço disponível para as cadeias L2, para publicar dados por bloco, aumentando ainda mais a taxa de transferência nos rollups. +Espera-se que a introdução de [fragmentação (sharding) de dados](/roadmap/danksharding/) no Ethereum melhore o dimensionamento do rollup otimista. Como as transações de rollup devem compartilhar o espaço de blocos (blockspace) com outras transações não-rollup, sua capacidade de processamento é limitada pela taxa de transferência de dados na cadeia principal do Ethereum. Danksharding aumentará o espaço disponível para que cadeias L2 publiquem dados por bloco, usando armazenamento de “blob” impermanente e mais barato em vez de `CALLDATA`, que é permanente e caro. ### Prós e contras dos optimistic rollups {#optimistic-rollups-pros-and-cons} diff --git a/public/content/translations/pt-br/developers/docs/scaling/plasma/index.md b/public/content/translations/pt-br/developers/docs/scaling/plasma/index.md index c706aaff4a3..4c6ae6a3d7e 100644 --- a/public/content/translations/pt-br/developers/docs/scaling/plasma/index.md +++ b/public/content/translations/pt-br/developers/docs/scaling/plasma/index.md @@ -150,20 +150,19 @@ Inversamente, as cadeias Plasma derivam sua segurança da rede principal. Isto a ### Plasma vs fragmentação (sharding) {#plasma-vs-sharding} -Tanto as cadeias Plasma quanto as [cadeias de shard](/roadmap/danksharding/) publicam periodicamente provas criptográficas para a rede principal do Ethereum. No entanto, ambas têm propriedades de segurança diferentes. +Tanto as cadeias plasma quanto as cadeias de fragmentos periodicamente publicam provas criptográficas na Mainnet (Rede principal) do Ethereum. No entanto, ambas têm propriedades de segurança diferentes. As cadeias de shard gravam "cabeçalhos de agrupamento" na rede principal contendo informações detalhadas sobre cada shard de dados. Os nós na rede principal verificam e garantem a validade de shards de dados, reduzindo a possibilidade de transições de shards inválidos e protegendo a rede contra atividades maliciosas. A cadeia Plasma é diferente porque a rede principal só recebe informação mínima sobre o estado das cadeias filhas. Isto significa que rede principal não pode verificar eficazmente as transações realizadas em cadeias filhas, tornando-as menos seguras. +**Observe** que fragmentar a blockchain Ethereum não está mais no roteiro. Ela foi substituída por escalabilidade via rollups e [Danksharding](/roadmap/danksharding). + ### Usar a cadeia Plasma {#use-plasma} Vários projetos fornecem implementações da cadeia Plasma que você pode integrar aos seus dapps: -- [OMG Network](https://omg.network/) - [Polygon](https://polygon.technology/) (anteriormente Matic Network) -- [Gluon](https://gluon.network/) -- [LeapDAO](https://ipfs.leapdao.org/) ## Leitura adicional {#further-reading} @@ -173,4 +172,4 @@ Vários projetos fornecem implementações da cadeia Plasma que você pode integ - [Entenda a cadeia Plasma - parte 1: O básico](https://www.theblockcrypto.com/amp/post/10793/understanding-plasma-part-1-the-basics) - [A vida e a morte da cadeia Plasma](https://medium.com/dragonfly-research/the-life-and-death-of-plasma-b72c6a59c5ad#) -_Conhece algum recurso da comunidade que o ajudou? Edite essa página e adicione!_ +_Conhece um recurso da comunidade que te ajudou? Edite essa página e adicione!_ diff --git a/public/content/translations/pt-br/developers/docs/scaling/sidechains/index.md b/public/content/translations/pt-br/developers/docs/scaling/sidechains/index.md index d1a7e0a8235..bc0367f8c04 100644 --- a/public/content/translations/pt-br/developers/docs/scaling/sidechains/index.md +++ b/public/content/translations/pt-br/developers/docs/scaling/sidechains/index.md @@ -18,7 +18,7 @@ As sidechains são blockchains independentes, com diferentes histórias, roteiro Uma das qualidades que tornam as sidechains únicas (ou seja, diferentes do Ethereum) é o algoritmo de consenso usado. As sidechains não contam com o Ethereum para consenso e podem escolher protocolos de consenso alternativos que atendam às suas necessidades. Alguns exemplos de algoritmos de consenso usados nas sidechains incluem: - [Prova de autoridade](https://wikipedia.org/wiki/Proof_of_authority) -- [Prova de participação delegada](https://en.bitcoinwiki.org/wiki/DPoS) +- [Prova de participação delegada](https://en.bitcoin.it/wiki/Delegated_proof_of_stake) - [Tolerância a falhas bizantinas](https://decrypt.co/resources/byzantine-fault-tolerance-what-is-it-explained). Como o Ethereum, as sidechains têm nós de validação que verificam e processam transações, produzem blocos e armazenam o estado da blockchain. Os validadores são também responsáveis por manterem o consenso em toda a rede e protegê-la contra ataques maliciosos. diff --git a/public/content/translations/pt-br/developers/docs/scaling/validium/index.md b/public/content/translations/pt-br/developers/docs/scaling/validium/index.md index e5f5882fb8b..b4976043580 100644 --- a/public/content/translations/pt-br/developers/docs/scaling/validium/index.md +++ b/public/content/translations/pt-br/developers/docs/scaling/validium/index.md @@ -121,7 +121,7 @@ Algumas equipes, no entanto, estão tentando otimizar opcodes de EVM existentes ### 1. Armazenamento de dados off-chain {#off-chain-data-storage} -Projetos de dimensionamento de camada 2, como optimistic rollups e ZK-rollups, negociam o dimensionamento infinito de protocolos de dimensionamento off-chain puros (por exemplo, [Plasma](/developers/docs/scaling/plasma/)) para fins de segurança, publicando alguns dados de transação na L1. Mas isso significa que as propriedades de dimensionamento dos rollups são limitadas pela banda de dados na rede principal do Ethereum (a [fragmentação (sharding) de dados](/roadmap/danksharding/) propõe melhorar a capacidade de armazenamento de dados do Ethereum por este motivo). +Projetos de dimensionamento de camada 2, como optimistic rollups e ZK-rollups, negociam o dimensionamento infinito de protocolos de dimensionamento off-chain puros (por exemplo, [Plasma](/developers/docs/scaling/plasma/)) para fins de segurança, publicando alguns dados de transação na L1. Mas isso significa que as propriedades de dimensionamento dos rollups são limitadas pela largura de banda na Mainnet (Rede principal) do Ethereum (a [fragmentação (sharding) de dados](/roadmap/danksharding/) propõe melhorar a capacidade de armazenamento de dados do Ethereum por este motivo). Os validiums alcançam o dimensionamento mantendo todos os dados de transação off-chain e apenas publicando compromissos do estado (e provas de validade) ao transmitir atualizações de estado para a cadeia principal do Ethereum. A existência de provas de validade, no entanto, dá aos validiums garantias de segurança mais elevadas do que outras soluções de dimensionamento off-chain puras, incluindo Plasma e [sidechains](/developers/docs/scaling/sidechains/). Ao reduzir a quantidade de dados que o Ethereum precisa processar antes de validar transações off-chain, os desenhos de validiums estendem muito a taxa de transferência na rede principal. diff --git a/public/content/translations/pt-br/developers/docs/scaling/zk-rollups/index.md b/public/content/translations/pt-br/developers/docs/scaling/zk-rollups/index.md index 37733d00f40..d3346d0214c 100644 --- a/public/content/translations/pt-br/developers/docs/scaling/zk-rollups/index.md +++ b/public/content/translations/pt-br/developers/docs/scaling/zk-rollups/index.md @@ -1,6 +1,6 @@ --- title: Rollups de conhecimento zero -description: "Uma introdução aos rollups de zero conhecimento: uma solução de dimensionamento usada pela comunidade Ethereum." +description: 'Uma introdução aos rollups de zero conhecimento: uma solução de dimensionamento usada pela comunidade Ethereum.' lang: pt-br --- @@ -12,7 +12,7 @@ Você deve ler e entender mais sobre em nossa página [Ethereum scaling](/develo ## O que são rollups de conhecimento zero? {#what-are-zk-rollups} -**Rollups de conhecimento zero (ZK-rollups)** agrupam (ou acumulam) transações em lotes que são executados off-chain. A computação off-chain reduz a quantidade de dados que devem ser publicados na blockchain. Operadores de ZK-rollups submetem um resumo das mudanças necessárias para representar todas as transações em um lote, ao invés de enviar cada transação individualmente. Eles também produzem [provas de validade](/glossary/#validity-proof) para provar a exatidão de suas mudanças. A prova de validade demonstra com certeza criptográfica que as alterações propostas para o estado do Ethereum são verdadeiramente o resultado final da execução de todas as transações do referido lote. +**Rollups de conhecimento zero (ZK-rollups)** agrupam (ou acumulam) transações em lotes que são executados off-chain. A computação off-chain reduz a quantidade de dados que devem ser publicados na blockchain. Operadores de ZK-rollups submetem um resumo das mudanças necessárias para representar todas as transações em um lote, ao invés de enviar cada transação individualmente. Eles também produzem [provas de validade](/glossary/#validity-proof) para provar a exatidão de suas mudanças. O estado dos ZK-rollups é mantido por um contrato inteligente implantado na rede Ethereum. Para atualizar este estado, os nós ZK-rollup devem enviar uma prova de validade para verificação. Como mencionado, a prova de validade é uma garantia criptográfica de que a mudança de estado proposta pelo rollup é realmente o resultado da execução de um determinado lote de transações. Isso significa que os ZK-rollups só precisam fornecer provas de validade para finalizar as transações no Ethereum, em vez de publicar todos os dados da transação on-chain, como [optimistic rollups](/developers/docs/scaling/optimistic-rollups/). @@ -117,7 +117,7 @@ Antes de aceitar transações, o operador realizará as verificações habituais Uma vez que o nó ZK-rollup tenha transações suficientes, ele as agrega em um lote e compila entradas para o circuito de prova para reunir em uma prova ZK sucinta. Isso pode incluir: -- Uma árvore de Merkle composta de todas as transações no lote. +- A Merkle tree root comprising all the transactions in the batch. - Provas de Merkle de transações para provar a inclusão no lote. - Provas de Merkle para cada par de destinatário-remetente em transações para provar que essas contas são parte da árvore de estado do rollup. - Um conjunto de raízes de estado intermediárias, derivadas da atualização da raiz de estado após a aplicação de atualizações de estado para cada transação (ou seja, diminuindo as contas do remetente e aumentando as contas do destinatário). @@ -232,13 +232,17 @@ Existem várias implementações de ZK-rollups que você pode integrar aos seus Os projetos que trabalham em zkEVMs incluem: -- **[ZKSync](https://docs.zksync.io/zkevm/)**: _o ZkSync 2.0 é um ZK-rollup compatível com EVM sendo desenvolvido pelo Matter Labs, com tecnologia de seu próprio zkEVM._ +- **[Applied ZKP](https://github.com/privacy-scaling-explorations/zkevm-specs)** — _Applied ZKP é um projeto financiado pela Ethereum Foundation para desenvolver um ZK-rollup compatível com EVM e um mecanismo para gerar provas de validade para blocos Ethereum._ -- **[Applied ZKP](https://github.com/privacy-scaling-explorations/zkevm-specs)**: _Applied ZKP é um projeto financiado pela Ethereum Foundation para desenvolver um ZK-rollup compatível com EVM e um mecanismo para gerar provas de validade para blocos Ethereum._ +- **[Polygon zkEVM](https://polygon.technology/solutions/polygon-zkevm)** — _é um ZK-Rollup descentralizado na rede principal do Ethereum que trabalha em uma Máquina Virtual Ethereum de conhecimento zero (zkEVM) e executa transações do Ethereum de maneira transparente, incluindo contratos inteligentes com validações de prova de conhecimento._ - **[Scroll](https://scroll.io/blog/zkEVM)**: _Scroll é uma empresa impulsionada pela tecnologia que trabalha no desenvolvimento de uma solução nativa zkEVM de camada 2 para Ethereum._ -- **[Polygon zkEVM](https://polygon.technology/solutions/polygon-zkevm)**: _é um ZK-Rollup descentralizado na rede principal do Ethereum trabalhando em uma Máquina Virtual Ethereum de conhecimento zero (zkEVM) que executa transações Ethereum de maneira transparente, incluindo contratos inteligentes com validações de prova de conhecimento._ +- **[Taiko](https://taiko.xyz)** - _Taiko é um ZK-rollup descentralizado, equivalente ao Ethereum (um [ZK-EVM do Tipo 1](https://vitalik.ca/general/2022/08/04/zkevm.html))._ + +- **[ZKSync](https://docs.zksync.io/zkevm/)** - _ZkSync Era is an EVM-compatible ZK Rollup built by Matter Labs, powered by its own zkEVM._ + +- **[Starknet](https://starkware.co/starknet/)** - _StarkNet is an EVM-compatible layer 2 scaling solution built by StarkWare._ ## Leitura adicional sobre leitura de ZK-rollups {#further-reading-on-zk-rollups} diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/compiling/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/compiling/index.md index f5a47a51143..5fbdb5fe5fe 100644 --- a/public/content/translations/pt-br/developers/docs/smart-contracts/compiling/index.md +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/compiling/index.md @@ -7,7 +7,7 @@ incomplete: true Você precisa compilar seu contrato para que seu aplicativo web e a máquina virtual Ethereum (EVM) possam entendê-lo. -## Pré-requisitos {#prerequisites} +## Pré-requisitos {#prerequisites} Você pode achar útil ler nossa introdução a [contratos inteligentes](/developers/docs/smart-contracts/) e a [máquina virtual Ethereum](/developers/docs/evm/) antes de ler sobre compilação. diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/composability/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/composability/index.md index d892a3a401a..b13077b0510 100644 --- a/public/content/translations/pt-br/developers/docs/smart-contracts/composability/index.md +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/composability/index.md @@ -45,13 +45,13 @@ Usaremos um exemplo de negociação de arbitragem para ilustrar os benefícios d Se um token estiver sendo negociado mais alto na `troca A` do que na `troca B`, você pode aproveitar a diferença de preço para obter lucro. No entanto, você só pode fazer isso se tiver capital suficiente para financiar a transação (ou seja, comprar o token da `troca B` e vendê-lo na `troca A`). -Em um cenário em que você não tem fundos suficientes para cobrir a negociação, um empréstimo rápido pode ser o ideal. Os [empréstimos relâmpagos](/defi/#flash-loans) são altamente técnicos, mas a ideia básica é que você pode emprestar ativos (sem garantias) e devolvê-los dentro de _uma_ transação. +Em um cenário em que você não tem fundos suficientes para cobrir a negociação, um empréstimo rápido pode ser o ideal. Os [empréstimos relâmpagos](/defi/#flash-loans) são altamente técnicos, mas a ideia básica é que você pode emprestar ativos (sem garantias) e devolvê-los dentro de *uma* transação. Voltando ao nosso exemplo inicial, um trader de arbitragem pode fazer um grande empréstimo relâmpago, comprar tokens da `troca B`, vendê-los na `troca A`, pagar o capital + juros, e manter o lucro, dentro da mesma transação. Essa lógica complexa requer a combinação de chamadas para vários contratos, o que não seria possível se os contratos inteligentes não tivessem interoperabilidade. ## Exemplos de composabilidade na Ethereum {#composability-in-ethereum} -### Troca de tokens {#token-swaps} +### Trocas de tokens {#token-swaps} Se você criar um dapp que exige que as transações sejam pagas em ETH, você pode permitir que os usuários paguem em outros tokens ERC-20 integrando a lógica de troca de token. O código converterá automaticamente o token do usuário em ETH antes que o contrato execute a função chamada. diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/deploying/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/deploying/index.md index ced3ed4ed9c..6b80a29a8b1 100644 --- a/public/content/translations/pt-br/developers/docs/smart-contracts/deploying/index.md +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/deploying/index.md @@ -20,16 +20,14 @@ Finalmente, você precisará compilar seu contrato antes de implantá-lo, então ### O que você precisará {#what-youll-need} -- bytecode do seu contrato - isto é gerado através da [compilação](/developers/docs/smart-contracts/compiling/). +- Bytecode do seu contrato - isto é gerado através da [compilação](/developers/docs/smart-contracts/compiling/). - Ether para gás – você definirá o seu limite de gás como outras transações, então esteja ciente de que a implantação do contrato precisa de muito mais gás do que uma simples transferência de ETH - um script de implantação ou um plugin -- acesso a um [nó Ethereum](/developers/docs/nodes-and-clients/), ou executando o seu próprio, conectando a um nó público, ou usando uma chave API usando um [serviço de nó](/developers/docs/nodes-and-clients/nodes-as-a-service/) como [Infura](https://www.infura.io/) ou [Alchemy](https://docs.alchemy.com/). +- acesso a um [nó Ethereum](/developers/docs/nodes-and-clients/), executando o seu próprio, conectando a um nó público ou por meio de uma chave de API usando um [serviço de nó](/developers/docs/nodes-and-clients/nodes-as-a-service/) ### Como implantar um contrato inteligente {#steps-to-deploy} -Os passos específicos envolvidos dependerão das ferramentas que você usa. Por exemplo, confira a [documentação de hardware sobre a implantação de seus contratos](https://hardhat.org/guides/deploying.html) ou [documentação do Truffle sobre redes e implantação de aplicativos](https://www.trufflesuite.com/docs/truffle/advanced/networks-and-app-deployment). Estas são duas das ferramentas mais populares para a implantação de contratos inteligentes, que envolvem a elaboração de um script para manipular as etapas de implementação. - -Uma vez implantado, o seu contrato terá um endereço Ethereum, como outras [contas](/developers/docs/accounts/). +The specific steps involved will depend on the development framework in question. For example, you can check out [Hardhat's documentation on deploying your contracts](https://hardhat.org/guides/deploying.html) or [Foundry's documentation on deploying and verifying a smart contract](https://book.getfoundry.sh/forge/deploying). Once deployed, your contract will have an Ethereum address like other [accounts](/developers/docs/accounts/) and can be verified using [source code verification tools](/developers/docs/smart-contracts/verifying/#source-code-verification-tools). ## Ferramentas relacionadas {#related-tools} @@ -51,27 +49,26 @@ Uma vez implantado, o seu contrato terá um endereço Ethereum, como outras [con - [GitHub](https://github.com/nomiclabs/hardhat) - [Discord](https://discord.com/invite/TETZs2KK4k) -**Truffle -\*\***_Um ambiente de desenvolvimento, teste de framework, compilação e outras ferramentas._\*\* +**thirdweb - _Implemente facilmente qualquer contrato em qualquer cadeia compatível com EVM, usando um único comando_** -- [trufflesuite.com](https://www.trufflesuite.com/) -- [Documentos em redes e implantação de aplicativos](https://www.trufflesuite.com/docs/truffle/advanced/networks-and-app-deployment) -- [GitHub](https://github.com/trufflesuite/truffle) +- [Documentação](https://portal.thirdweb.com/deploy/) ## Tutoriais relacionados {#related-tutorials} -- [Implantando o seu primeiro contrato inteligente](/developers/tutorials/deploying-your-first-smart-contract/) _– Uma introdução à implantação do seu primeiro contrato inteligente em uma rede de teste da Ethereum._ -- [Hello World | tutorial para contrato inteligente](/developers/tutorials/hello-world-smart-contract/)_ - Um tutorial fácil de seguir para criar & implantar um contrato inteligente básico na Ethereum._ +- [Implementando o seu primeiro contrato inteligente](/developers/tutorials/deploying-your-first-smart-contract/) _– Uma introdução à implementação do seu primeiro contrato inteligente em uma rede de teste da Ethereum._ +- [Hello World | tutorial para contrato inteligente](/developers/tutorials/hello-world-smart-contract/)_ - Um tutorial fácil de seguir para criar & implementar um contrato inteligente básico na Ethereum._ - [Interaja com outros contratos da Solidity](/developers/tutorials/interact-with-other-contracts-from-solidity/) _– Como implantar um contrato inteligente a partir de um contrato existente e interagir com ele._ -- [Como diminuir o tamanho de seu contrato](/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) _- Como reduzir o tamanho do seu contrato para mantê-lo abaixo do limite e economizar gás_ +- [Como diminuir o tamanho de seu contrato](/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) _- Como reduzir o tamanho do seu contrato para mantê-lo abaixo do limite e economizar Gas_ ## Leia mais {#further-reading} - [https://docs.openzeppelin.com/learn/deploying-and-interacting](https://docs.openzeppelin.com/learn/deploying-and-interacting) - _OpenZeppelin_ - [Implementando seus contratos com Hardhat](https://hardhat.org/guides/deploying.html) - _Nomic Labs_ -_Conhece um recurso da comunidade que o ajudou? Edite esta página e adicione-o!_ +_Conhece um recurso da comunidade que te ajudou? Edite essa página e adicione!_ ## Tópicos relacionados {#related-topics} - [Estruturas de desenvolvimento](/developers/docs/frameworks/) - [Executando um nó Ethereum](/developers/docs/nodes-and-clients/run-a-node/) +- [Nódulos como serviço](/developers/docs/nodes-and-clients/nodes-as-a-service) diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/formal-verification/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/formal-verification/index.md index 492c21749f5..caf3accc009 100644 --- a/public/content/translations/pt-br/developers/docs/smart-contracts/formal-verification/index.md +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/formal-verification/index.md @@ -212,16 +212,16 @@ Além disso, nem sempre é possível que os verificadores de programa determinem ### Linguagens de especificação para criação de especificações formais {#specification-languages} -**Act**: \_\*O Act permite a especificação de atualizações de armazenamento, condições de pré/pós e invariáveis do contrato. Seu conjunto de ferramentas também tem backends capazes de comprovar muitas propriedades via Coq, solucionadores SMT, ou hevm.\*\* +**Act**: _*O Act permite a especificação de atualizações de armazenamento, condições de pré/pós e invariáveis do contrato. Seu conjunto de ferramentas também tem backends capazes de comprovar muitas propriedades via Coq, solucionadores SMT, ou hevm.*_ - [GitHub](https://github.com/ethereum/act) - [Documentação](https://ethereum.github.io/act/) -**Scribble** - \_\*Scribble transforma anotações de código na linguagem de especificação Scribble em afirmações concretas que verificam a especificação.\*\* +**Scribble** - _*Scribble transforma anotações de código na linguagem de especificação Scribble em afirmações concretas que verificam a especificação.*_ - [Documentação](https://docs.scribble.codes/) -**Dafny** - \_\*Dafny é uma linguagem de programação pronta para verificação que depende de anotações de alto nível para argumentar e comprovar a exatidão do código.\*\* +**Dafny** - _*Dafny é uma linguagem de programação pronta para verificação que depende de anotações de alto nível para argumentar e comprovar a exatidão do código.*_ - [GitHub](https://github.com/dafny-lang/dafny) @@ -232,15 +232,15 @@ Além disso, nem sempre é possível que os verificadores de programa determinem - [Site](https://www.certora.com/) - [Documentação](https://docs.certora.com/en/latest/index.html) -**Solidity SMTChecker** - \_\*Solidity’s SMTChecker é um verificador de modelos integrado com base no SMT (Teorias do Módulo de Satisfiabilidade) e na resolução de Horn. Ele confirma se o código-fonte de um contrato corresponde às especificações durante a compilação e procura estaticamente por violações de propriedades de segurança.\*\* +**Solidity SMTChecker** - _*Solidity’s SMTChecker é um verificador de modelos integrado com base no SMT (Teorias do Módulo de Satisfiabilidade) e na resolução de Horn. Ele confirma se o código-fonte de um contrato corresponde às especificações durante a compilação e procura estaticamente por violações de propriedades de segurança.*_ - [GitHub](https://github.com/ethereum/solidity) -**solc-verify** - \_\*solc-verify é uma versão estendida do compilador Solidity que pode executar a verificação formal automatizada no código Solidity usando anotações e verificação de programa modular.\*\* +**solc-verify** - _*solc-verify é uma versão estendida do compilador Solidity que pode executar a verificação formal automatizada no código Solidity usando anotações e verificação de programa modular.*_ - [GitHub](https://github.com/SRI-CSL/solidity) -**KEVM** - \_\*KEVM é uma semântica formal da Máquina Virtual Ethereum (EVM) escrita no framework K. KEVM é executável e pode comprovar determinadas declarações relacionadas à propriedade usando a lógica de alcançabilidade.\*\* +**KEVM** - _*KEVM é uma semântica formal da Máquina Virtual Ethereum (EVM) escrita no framework K. KEVM é executável e pode comprovar determinadas declarações relacionadas à propriedade usando a lógica de alcançabilidade.*_ - [GitHub](https://github.com/runtimeverification/evm-semantics) - [Documentação](https://jellopaper.org/) @@ -259,12 +259,12 @@ Além disso, nem sempre é possível que os verificadores de programa determinem ### Ferramentas de execução simbólica para detectar padrões vulneráveis em contratos inteligentes {#symbolic-execution-tools} -**Manticore** - \__Uma ferramenta para analisar a ferramenta de análise de bytecode EVM com base em execução simbólica_.\* +**Manticore** - _*Uma ferramenta para analisar a ferramenta de análise de bytecode EVM com base em execução simbólica.*_ - [GitHub](https://github.com/trailofbits/manticore) - [Documentação](https://github.com/trailofbits/manticore/wiki) -**hevm** - \_\*hevm é um mecanismo de execução simbólico e um verificador de equivalência para bytecode EVM.\*\* +**hevm** - _*hevm é um mecanismo de execução simbólico e um verificador de equivalência para bytecode EVM.*_ - [GitHub](https://github.com/dapphub/dapptools/tree/master/src/hevm) diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/index.md index 282d4433f53..c6e5da0801b 100644 --- a/public/content/translations/pt-br/developers/docs/smart-contracts/index.md +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/index.md @@ -66,7 +66,7 @@ De maneira similar a como uma máquina de venda automática elimina a necessidad ## Sem necessidade de permissão {#permissionless} -Qualquer um pode escrever um contrato inteligente e implantá-lo na rede. Você só precisa aprender a codificar em uma [linguagem de contrato inteligente](/developers/docs/smart-contracts/languages/) e ter ETH suficiente para implantar seu contrato. A implantação de um contrato inteligente é tecnicamente uma transação, portanto, você precisa pagar [Gas](/developers/docs/gas/) da mesma forma que precisa pagar gás por uma simples transferência de ETH. No entanto, os custos de gás para implantação de contrato são muito mais altos. +Qualquer um pode escrever um contrato inteligente e implantá-lo na rede. Você só precisa aprender a codificar em uma [linguagem de contrato inteligente](/developers/docs/smart-contracts/languages/) e ter ETH suficiente para implantar seu contrato. A implantação de um contrato inteligente é tecnicamente uma transação, portanto, você precisa pagar o [gás](/developers/docs/gas/) da mesma forma que precisa pagar o Gas por uma simples transferência de ETH. No entanto, os custos de gás para implantação de contrato são muito mais altos. A Ethereum tem linguagens que o desenvolvedor terá facilidade de usar para escrever contratos inteligentes: @@ -85,9 +85,9 @@ Saiba mais sobre a [composição do contrato inteligente](/developers/docs/smart ## Limitações {#limitations} -Os contratos inteligentes, por si só, não conseguem obter informações sobre eventos do "mundo-real" porque não podem enviar solicitações HTTP. Isto é por concepção. A sua concepção é a de que as informações externas podem pôr em causa o consenso, que é importante para a segurança e a descentralização. +Os contratos inteligentes sozinhos não podem obter informações sobre eventos do "mundo real", porque não podem recuperar dados de fontes off-chain. Isso significa que eles não podem responder a eventos no mundo real. Isto é, por concepção. A sua concepção é a de que as informações externas podem pôr em causa o consenso, que é importante para a segurança e a descentralização. -Há maneiras de contornar isso usando [oráculos](/developers/docs/oracles/). +No entanto, é importante que aplicações blockchain possam usar dados off-chain. A solução são os [oráculos](/developers/docs/oracles/), que são instrumentos que ingerem dados off-chain e os disponibilizam para contratos inteligentes. Outra limitação de contratos inteligentes é o tamanho máximo do contrato. Um contrato inteligente pode ser um máximo de 24KB ou ficará sem gás. Isso pode ser contornado usando [O Padrão de Diamante](https://eips.ethereum.org/EIPS/eip-2535). @@ -103,13 +103,8 @@ Os contratos multisig (com múltiplas assinaturas) são contas de contrato intel - [GitHub](https://github.com/OpenZeppelin/openzeppelin-contracts) - [Fórum da Comunidade](https://forum.openzeppelin.com/c/general/16) -**DappSys -** **_Blocos de código seguros, simples e flexíveis para contratos inteligentes._** - -- [Dappsys](https://dappsys.readthedocs.io/) -- [GitHub](https://github.com/dapphub/dappsys) - ## Leitura adicional {#further-reading} -- [Contratos Inteligentes: A Tecnologia Blockchain que substituirá Advogados](https://blockgeeks.com/guides/smart-contracts/) _– Blockgeeks_ -- [Melhores Práticas para Desenvolvimento de Contrato Inteligente](https://yos.io/2019/11/10/smart-contract-development-best-practices/) _– 10 de Novembro de 2019 - Yos Riady_ -- [Contratos claros - um guia sobre padrões de contrato inteligente & práticas](https://www.wslyvh.com/clean-contracts/) _– Jul 30 2020 - wslyvh_ +- [Coinbase: O que é um contrato inteligente?](https://www.coinbase.com/learn/crypto-basics/what-is-a-smart-contract) +- [Chainlink: O que é um contrato inteligente?](https://chain.link/education/smart-contracts) +- [Vídeo: Simplesmente Explicado - Contratos Inteligentes](https://youtu.be/ZE2HxTmxfrI) diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/languages/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/languages/index.md index 2e1d944815c..5e0177ca32e 100644 --- a/public/content/translations/pt-br/developers/docs/smart-contracts/languages/index.md +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/languages/index.md @@ -35,7 +35,7 @@ Conhecimento anterior de linguagens de programação, especialmente de JavaScrip - [Portal da linguagem Solidity](https://soliditylang.org/) - [Solidity como exemplo](https://docs.soliditylang.org/en/latest/solidity-by-example.html) - [GitHub](https://github.com/ethereum/solidity/) -- [Solidity Gitter Chatroom](https://gitter.im/ethereum/solidity) ponte para [Solidity Matrix Chatroom](https://matrix.to/#/#ethereum_solidity:gitter.im) +- [Solidity Gitter Chatroom](https://gitter.im/ethereum/solidity/) ponte para [Solidity Matrix Chatroom](https://matrix.to/#/#ethereum_solidity:gitter.im) - [Dicas](https://reference.auditless.com/cheatsheet) - [Blog da Solidity](https://blog.soliditylang.org/) - [Solidity Twitter](https://twitter.com/solidity_lang) diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/libraries/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/libraries/index.md index 2986d153316..a017c2ac84a 100644 --- a/public/content/translations/pt-br/developers/docs/smart-contracts/libraries/index.md +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/libraries/index.md @@ -16,7 +16,7 @@ Geralmente, você pode encontrar dois tipos de blocos de construção em bibliot ### Comportamentos {#behaviors} -Ao escrever contratos inteligentes, há uma boa chance de você escrever padrões semelhantes repetidamente, como atribuir um endereço de administrador \__ para realizar operações protegidas em um contrato, ou adicionando um botão de emergência \_pause_ em caso de um problema inesperado. +Ao escrever contratos inteligentes, há uma boa chance de você escrever padrões semelhantes repetidamente, como atribuir um endereço de administrador __ para realizar operações protegidas em um contrato, ou adicionando um botão de emergência _pause_ em caso de um problema inesperado. As bibliotecas inteligentes de contratos geralmente fornecem implementações reutilizáveis destes comportamentos como [bibliotecas](https://solidity.readthedocs.io/en/v0.7.2/contracts.html#libraries) ou via [herança](https://solidity.readthedocs.io/en/v0.7.2/contracts.html#inheritance) em Solidity. @@ -102,6 +102,11 @@ Por último, ao decidir se deve incluir uma biblioteca, considere a sua utiliza - [GitHub](https://github.com/HQ20/contracts) +**thirdweb Solidity SDK -** **_Fornece as ferramentas necessárias para criar contratos inteligentes e personalizados com eficiência_** + +- [Documentação](https://portal.thirdweb.com/solidity/) +- [GitHub](https://github.com/thirdweb-dev/contracts) + ## Tutoriais relacionados {#related-tutorials} - [Considerações de segurança para os desenvolvedores da Ethereum](/developers/docs/smart-contracts/security/) _– Um tutorial sobre considerações de segurança ao criar contratos inteligentes, incluindo o uso da biblioteca._ @@ -109,4 +114,4 @@ Por último, ao decidir se deve incluir uma biblioteca, considere a sua utiliza ## Leitura adicional {#further-reading} -_Conhece algum recurso da comunidade que o ajudou? Edite essa página e adicione!_ +_Conhece um recurso da comunidade que te ajudou? Edite essa página e adicione!_ diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/security/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/security/index.md index daf7a2f23bf..0a1a5d2f798 100644 --- a/public/content/translations/pt-br/developers/docs/smart-contracts/security/index.md +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/security/index.md @@ -470,13 +470,13 @@ Se você planeja consultar um oráculo on-chain para preços de ativos, consider ### Ferramentas para monitorar contratos inteligentes {#smart-contract-monitoring-tools} -- **[OpenZeppelin Defender Sentinels](https://docs.openzeppelin.com/defender/sentinel)** - _Uma ferramenta para monitorar e responder automaticamente a eventos, funções e parâmetros de transação em seus contratos inteligentes._ +- **[OpenZeppelin Defender Sentinels](https://docs.openzeppelin.com/defender/v1/sentinel)** - _Uma ferramenta para monitorar e responder automaticamente a eventos, funções e parâmetros de transação em seus contratos inteligentes._ - **[Alerta leve e em tempo real](https://tenderly.co/alerting/)** - _Uma ferramenta para receber notificações em tempo real quando eventos incomuns ou inesperados acontecem em seus contratos inteligentes ou carteiras._ ### Ferramentas para administração segura de contratos inteligentes {#smart-contract-administration-tools} -- **[Administrador do OpenZeppelin Defender](https://docs.openzeppelin.com/defender/admin)** - _Interface para gerenciar a administração de contrato inteligente, incluindo controles de acesso, atualizações e pausas._ +- **[Administrador do OpenZeppelin Defender](https://docs.openzeppelin.com/defender/v1/admin)** - _Interface para gerenciar a administração de contrato inteligente, incluindo controles de acesso, atualizações e pausas._ - **[Safe](https://safe.global/)** - _Carteira de contrato inteligente em execução na Ethereum, que requer um número mínimo de pessoas para aprovar uma transação antes que ela possa ocorrer (M-de-N)._ @@ -504,6 +504,8 @@ Se você planeja consultar um oráculo on-chain para preços de ativos, consider - **[HashEx](https://hashex.org/)** – _O HashEx se dedica a blockchain e auditoria de contrato inteligente para garantir a segurança de criptomoedas, fornecendo serviços como desenvolvimento de contrato inteligente, teste de penetração e consultoria em blockchain._ +- **[Code4rena](https://code4rena.com/)** - _Plataforma de auditoria competitiva que incentiva especialistas em segurança de contratos inteligentes a encontrar vulnerabilidades e ajudar a tornar a web3 mais segura._ + ### Plataformas de recompensa de bugs {#bug-bounty-platforms} - **[Immunefi](https://immunefi.com/)** - _Plataforma de recompensa por bugs para contratos inteligentes e projetos DeFi, onde os pesquisadores de segurança revisam o código, divulgam vulnerabilidades, recebem pagamentos e tornam a criptografia mais segura._ diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/testing/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/testing/index.md index fa18a71775e..12fb8e32535 100644 --- a/public/content/translations/pt-br/developers/docs/smart-contracts/testing/index.md +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/testing/index.md @@ -1,265 +1,299 @@ --- title: Testes de contratos inteligentes -description: Uma visão geral das técnicas e considerações para testar contratos inteligentes Ethereum +description: Uma visão geral das técnicas e considerações para testar contratos inteligentes Ethereum. lang: pt-br --- -Testar [contratos inteligentes](/developers/docs/smart-contracts/) é uma das mais importantes medidas para melhorar a [segurança do contrato inteligente](/developers/docs/smart-contracts/security/). Ao contrário do software tradicional, os contratos inteligentes normalmente não podem ser atualizados após o lançamento, tornando imperativo testar rigorosamente antes de implantar contratos na rede Ethereum. +Blockchains públicas como Ethereum são imutáveis, dificultando alterações de código de contratos inteligentes após sua implementação. Existem [padrões de atualização de contrato](/developers/docs/smart-contracts/upgrading/) para realizar "atualizações virtuais", mas são difíceis de implementar e requer um consenso social. Além disso, uma atualização só pode corrigir um erro _após_ que é descoberto se um invasor descobrir a vulnerabilidade primeiro, seu contrato inteligente corre o risco sofrer um exploit. -## O que é teste de contrato inteligente? {#what-is-smart-contract-testing} - -Teste de contrato inteligente significa realizar uma análise e avaliação detalhada de um contrato inteligente para avaliar a qualidade de seu código-fonte durante o ciclo de desenvolvimento. Testar um contrato inteligente facilita a identificação de bugs e vulnerabilidades, e reduz a possibilidade de erros de software que podem levar a onerosas explorações. +Por estas razões, testar contratos inteligentes antes de [implementar](/developers/docs/smart-contracts/deploying/) à rede principal é o requisito mínimo para [segurança](/developers/docs/smart-contracts/security/). Existem muitas técnicas para testar contratos e avaliar a corretude de código; qual escolher depende de suas necessidades. No entanto, um conjunto de testes feito a partir de diferentes ferramentas e abordagens é ideal para pegar pequenas e grandes falhas de segurança no código do contrato. -O teste de contrato inteligente assume muitas formas, com diferentes métodos oferecendo benefícios. As estratégias para testar contratos inteligentes da Ethereum podem ser classificadas em duas grandes categorias: **teste automatizado** e **teste manual**. +## Pré-requisitos {#prerequisites} -### Teste automatizado {#automated-testing} +Esta página explica como testar contratos inteligentes antes de implantar na rede Ethereum. Pressupõe-se que você esteja familiarizado com [contratos inteligentes](/developers/docs/smart-contracts/). -O teste automatizado envolve o uso de ferramentas automatizadas para realizar testes com script de contratos inteligentes. Essa técnica depende de software automatizado que pode executar testes repetidos para encontrar defeitos em contratos inteligentes. +## O que é teste de contrato inteligente? {#what-is-smart-contract-testing} -O teste automatizado é eficiente, usa menos recursos e promete níveis mais altos de cobertura do que a análise manual. As ferramentas de teste automatizadas também podem ser configuradas com dados de teste, permitindo-lhes comparar comportamentos previstos com resultados reais. +O teste de contrato inteligente é o processo de verificação de que o código de um contrato inteligente funciona conforme o esperado. Testar é útil para verificar se um contrato inteligente específico atende aos requisitos de confiabilidade, usabilidade e segurança. -### Teste manual {#manual-testing} +Embora as abordagens variem, a maioria dos métodos de teste exige a execução de um contrato inteligente com uma pequena amostra dos dados que se espera manipular. Se o contrato produzir resultados corretos para dados da amostra, presume-se que esteja funcionando corretamente. A maioria das ferramentas de teste fornece recursos para escrever e executar [casos de teste](https://en.m.wikipedia.org/wiki/Test_case) para verificar se a execução de um contrato corresponde aos resultados esperados. -O teste manual é auxiliado por humanos e envolve um indivíduo que executa as etapas de teste manualmente. As auditorias de código, em que desenvolvedores e/ou auditores examinam cada linha de código do contrato, é um exemplo de teste manual para contratos inteligentes. +### Por que é importante testar contratos inteligentes? {#importance-of-testing-smart-contracts} -O teste manual de contratos inteligentes requer habilidade considerável e um investimento considerável de tempo, dinheiro e esforço. Além disso, o teste manual às vezes pode ser suscetível a problemas de erro humano. +Como os contratos inteligentes geralmente gerenciam ativos financeiros de alto valor, pequenos erros de programação podem e geralmente levam a [perdas massivas para os usuários](https://rekt.news/leaderboard/). Rigorous testing can, however, help you discover defects and issues in a smart contract's code early and fix them before launching on Mainnet. -Entretanto, aplicar testes manuais a contratos inteligentes também pode ser benéfico. As auditorias de código aproveitam a inteligência humana para encontrar defeitos no código do contrato que podem não ser detectados durante os testes automatizados. +Embora seja possível atualizar um contrato se um bug for descoberto, as atualizações são complexas e podem [ resultar em erros](https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/) se tratadas de forma inadequada. A atualização de um contrato vai contra o princípio da imutabilidade e sobrecarrega os usuários com suposições de confiança adicionais. Por outro lado, um plano abrangente para testar seu contrato reduz os riscos de segurança do contrato inteligente e reduz a necessidade de realizar atualizações lógicas complexas após a implantação. -O teste manual de seus contratos inteligentes também pode revelar vulnerabilidades que existem fora do código, mas ainda podem afetá-lo. Por exemplo, uma auditoria de contrato inteligente pode descobrir vulnerabilidades decorrentes da interação inadequada com componentes off-chain. +## Métodos para testar contratos inteligentes {#methods-for-testing-smart-contracts} -## Por que é importante testar contratos inteligentes? {#benefits-of-smart-contract-testing} +Methods for testing Ethereum smart contracts fall under two broad categories: **automated testing** and **manual testing**. Testes automatizados e testes manuais tem seus prós e contras, mas você pode combinar ambos para criar um plano robusto para analisar seus contratos. -Testar contratos inteligentes é importante pelos seguintes motivos: +### Teste automatizado {#automated-testing} -### 1. Contratos inteligentes são aplicativos de alto valor {#smart-contracts-are-high-value-applications} +O teste automatizado usa ferramentas que verificam automaticamente um código de contratos inteligentes em busca de erros na execução. O benefício do teste automatizado vem do uso de [scripts](https://www.techtarget.com/whatis/definition/script?amp=1) para orientar a avaliação das funcionalidades do contrato. Os scripts de testes podem ser programados para serem executados repetidamente com o mínimo de intervenção humana, tornando o teste automatizado mais eficiente do que as abordagens manuais de teste. -Contratos inteligentes geralmente lidam com ativos financeiros de alto valor, especialmente em setores como [finanças descentralizadas (DeFi)](/defi/) e itens valiosos, como [tokens não fungíveis (NFTs)](/nft/). Como tal, pequenas vulnerabilidades em contratos inteligentes podem e geralmente levam a perdas maciças e irrecuperáveis para os usuários. Testes abrangentes podem, no entanto, expor erros no código do contrato inteligente e reduzir os riscos de segurança antes da implantação. +O teste automatizado é particularmente útil quando os testes são repetitivos e demorados; difícil de realizar manualmente; suscetíveis a erro humano; ou envolvem a avaliação de funções contratuais críticas. Mas as ferramentas de teste automatizadas podem ter desvantagens - elas podem perder certos bugs e produzir muitos [falsos positivos](https://www.contrastsecurity.com/glossary/false-positive). Portanto, combinar testes automatizados com testes manuais para contratos inteligentes é ideal. -### 2. Contratos inteligentes são imutáveis {#smart-contracts-are-immutable} +### Teste manual {#manual-testing} -Os contratos inteligentes implantados na [Ethereum Virtual Machine (EVM)](/developers/docs/evm/) são imutáveis por padrão. Enquanto os desenvolvedores tradicionais podem ser usados para corrigir bugs de software após o lançamento, o desenvolvimento da Ethereum deixa pouco espaço para corrigir falhas de segurança uma vez que um contrato inteligente está ativo na blockchain. +O teste manual é auxiliado por humanos e envolve a execução de cada caso de teste em seu conjunto de testes, um após o outro, ao analisar a corretude de um contrato inteligente. Isso é diferente do teste automatizado, no qual você pode executar simultaneamente vários testes isolados em um contrato e obter um relatório mostrando todos os testes que falharam e os que foram aprovados. -Embora existam mecanismos de atualização para contratos inteligentes, como padrões de proxy, estes podem ser difíceis de implementar. Além de reduzir a imutabilidade e introduzir complexidade, as atualizações geralmente exigem processos de governança complexos. +O teste manual pode ser realizado por um único indivíduo seguindo um plano de teste escrito que cobre diferentes cenários de teste. Você também pode ter vários indivíduos ou grupos interagindo com um contrato inteligente durante um período especificado como parte do teste manual. Os testadores compararão o comportamento real do contrato com o comportamento esperado, sinalizando qualquer diferença como um bug. -Na maioria das vezes, as atualizações devem ser consideradas o último recurso e evitadas, a menos que sejam necessárias. A detecção de potenciais vulnerabilidades e falhas em seu contrato inteligente durante a fase de pré-lançamento reduz a necessidade de uma atualização lógica. +Um teste manual eficaz requer recursos consideráveis ​​(habilidade, tempo, dinheiro e esforço) e é possível, devido a erro humano, perder certos erros durante a execução dos testes. Mas o teste manual também pode ser benéfico - por exemplo, um testador humano (por exemplo, um auditor) pode usar a intuição para detectar casos extremos que uma ferramenta de teste automatizada perderia. ## Teste automatizado para contratos inteligentes {#automated-testing-for-smart-contracts} -### 1. Teste funcional {#functional-testing} +### Teste unitário {#unit-testing-for-smart-contracts} -Testes funcionais verifica a funcionalidade de um contrato inteligente e fornece garantia de que cada função no código funciona conforme o esperado. Teste funcional requer entender como seu contrato inteligente deve se comportar em determinadas condições. Em seguida, você pode testar cada função executando cálculos com valores selecionados e comparando a saída retornada com a saída esperada. +O teste unitário avalia as funções do contrato separadamente e verifica se cada componente funciona corretamente. Testes unitários bons devem ser simples, rápidos de executar e fornecer uma ideia clara do que deu errado se os testes falharem. -Testes funcionais abrange três métodos: **teste unitário**, **teste de integração**, e **teste de sistema**. +Os testes unitários são úteis para verificar se as funções retornam os valores esperados e se o armazenamento do contrato é atualizado corretamente após a execução da função. Além disso, a execução de testes unitários após fazer alterações em uma base de código de contratos garante que a adição de nova lógica não introduza erros. Abaixo estão algumas diretrizes para executar testes unitários eficazes: -#### Teste unitário +#### Diretrizes para testes unitários de contratos inteligentes {#unit-testing-guidelines} -Teste unitário envolve testar componentes individuais em um contrato inteligente para correção. Um teste unitário é simples, rápido de executar e fornece uma ideia clara do que deu errado se o teste falhar. +##### 1. Entenda a lógica de negócios e o fluxo de trabalho de seus contratos -Testes unitário são cruciais para o desenvolvimento de contratos inteligentes, especialmente se você precisar adicionar uma nova lógica ao código. Você pode verificar o comportamento de cada função e confirmar que ela é executada como esperado. +Antes de escrever testes unitários, é bom saber quais funcionalidades um contrato inteligente oferece e como os usuários acessarão e usarão essas funções. Isso é particularmente útil para executar [testes de caminho feliz](https://en.m.wikipedia.org/wiki/Happy_path) que determinam se as funções em um contrato retornam a saída correta para entradas válidas do usuário. Explicaremos esse conceito usando este exemplo (resumido) de [um contrato de leilão](https://docs.soliditylang.org/en/v0.8.17/solidity-by-example.html?highlight=Auction%20contract#simple-open-auction) -Executar um teste unitário muitas vezes requer criar _asserções_— simples e informais instruções especificando requisitos para um contrato inteligente. Testes unitários podem então ser usados para testar cada asserção e ver se ela se mantém verdadeira sob execução. +``` +constructor( + uint biddingTime, + address payable beneficiaryAddress + ) { + beneficiary = beneficiaryAddress; + auctionEndTime = block.timestamp + biddingTime; + } -Exemplos de asserções relacionadas a contratos incluem: +function bid() external payable { -i. Somente o administrador pode pausar o contrato + if (block.timestamp > auctionEndTime) + revert AuctionAlreadyEnded(); -ii. "Não administradores não podem cunhar novos tokens" + if (msg.value <= highestBid) + revert BidNotHighEnough(highestBid); -iii. "O contrato reverte em erros" + if (highestBid != 0) { + pendingReturns[highestBidder] += highestBid; + } + highestBidder = msg.sender; + highestBid = msg.value; + emit HighestBidIncreased(msg.sender, msg.value); + } -#### Teste de Integração + function withdraw() external returns (bool) { + uint amount = pendingReturns[msg.sender]; + if (amount > 0) { + pendingReturns[msg.sender] = 0; -O teste de integração é um nível superior ao dos testes unitários na hierarquia de testes. Em testes de integração, os componentes individuais do contrato inteligente são testados juntos. + if (!payable(msg.sender).send(amount)) { + pendingReturns[msg.sender] = amount; + return false; + } + } + return true; + } -Esta abordagem detecta erros decorrentes de interações entre diferentes componentes de um contrato ou em vários contratos. Você deve usar este método se você tiver um contrato complexo com várias funções ou um que interfaces com outros contratos. +function auctionEnd() external { + if (block.timestamp < auctionEndTime) + revert AuctionNotYetEnded(); + if (ended) + revert AuctionEndAlreadyCalled(); -Testes de integração podem ser úteis para garantir que coisas como a [herança](https://docs.soliditylang.org/en/v0.8.12/contracts.html#inheritance) e a injeção de dependência funcionem corretamente. + ended = true; + emit AuctionEnded(highestBidder, highestBid); -#### Teste de sistema + beneficiary.transfer(highestBid); + } +} +``` -Os testes do sistema são a fase final dos testes funcionais de contratos inteligentes. Um sistema avalia o contrato inteligente como um produto totalmente integrado para ver se ele executa conforme especificado nos requisitos técnicos. +Este é um contrato de leilão simples projetado para receber lances durante o período de submissão de ofertas. Se a variável `highestBid` aumentar, o licitante anterior mais alto receberá seu dinheiro; uma vez terminado o período de licitação, o objeto `beneficiary` aciona o contrato para obter seu dinheiro. -Você pode pensar neste estágio como verificar o fluxo de ponta a ponta do seu contrato inteligente do ponto de vista do usuário. Uma boa maneira de realizar testes de sistema em um contrato inteligente é implementá-lo em um ambiente semelhante a produção, como uma [testnet](/developers/docs/networks/#ethereum-testnets) ou uma [rede de desenvolvimento](/developers/docs/development-networks/). +Testes unitários para um contrato como este cobriria diferentes funções que um usuário poderia chamar quando interagindo com o contrato. Um exemplo seria um teste unitário que checa se o usuário pode colocar uma ordem enquanto o leilão está em andamento (ou seja, chamadas para `bid()` com sucesso) ou checar se um usuário pode colocar uma ordem mais alta que o atual `highestBid`. -Aqui, os usuários finais podem realizar o teste são executados e relatar quaisquer problemas com a lógica de negócios do contrato e a funcionalidade no geral. O teste do sistema é importante porque você não pode alterar o código uma vez que o contrato é implantado no ambiente EVM principal. +Entendendo o fluxo operacional do contrato também ajuda a escrever testes unitários que checam se a execução atende os requisitos. Por exemplo, o contrato de leilão especifica que os usuários não podem colocar ordens quando o leilão terminou (ou seja, quando `auctionEndTime` é menor que `block.timestamp`). Portanto, o desenvolvedor deve rodar um teste unitário que checa se chamadas para a função `bid()` tiveram sucesso ou falharam quando o leilão terminou (ou seja, quando `auctionEndTime` > `block.timestamp`). -### 2. Análise estática/dinâmica {#static-dynamic-analysis} +##### 2. Avalie todas as suposições relacionadas à execução do contrato -Análise estática e análise dinâmica são dois métodos automatizados de teste para avaliar as qualidades de segurança dos contratos inteligentes. No entanto, ambas as técnicas utilizam diferentes abordagens para encontrar defeitos no código de contratos. +É importante documentar quaisquer suposições sobre a execução do contrato e escrever testes unitários para verificar a validade destas suposições. Além de oferecer proteção contra execução inesperada, testar afirmações força você a pensar sobre operações que poderiam quebrar o modelo de segurança do contrato inteligente. Uma dica útil é ir além dos "testes do usuário feliz" e escrever testes negativos que checam se a função falha com as entradas erradas. -#### Análise estática +Muitos frameworks de teste unitário permitem você criar afirmações - simples declarações que declaram o que um contrato pode e não pode fazer - e rodar testes para ver se estas afirmações funcionam durante a execução. Um desenvolvedor trabalhando no contrato de leilão descrito anteriormente poderia fazer as seguintes afirmações sobre o seu comportamento antes de rodar testes negativos: -Análise estática examina o código-fonte ou bytecode de um contrato inteligente antes da execução. Isso significa que você pode depurar código de contrato sem na verdade executar o programa. Os analistas estáticos podem detectar vulnerabilidades comuns nos contratos inteligentes da Ethereum e ajudar na conformidade com as melhores práticas. +- Usuários não podem colocar ordens quando o leilão acabou ou não começou. -#### Análise dinâmica +- O contrato de leilão reverte se a ordem é abaixo do limite aceitável. -Técnicas de análise dinâmicas requerem a execução do contrato inteligente em um ambiente de tempo de execução para identificar problemas no seu código. Analisadores de código dinâmicos observam os comportamentos dos contratos durante a execução e geram um relatório detalhado de vulnerabilidades identificadas e violações de propriedades. +- Usuários que falham em vencer o leilão são creditados com seus fundos -A difusão é um exemplo de uma técnica de análise dinâmica para testar os contratos. Durante os testes de difusão, um difusor alimenta seu contrato inteligente com dados incorretos e inválidos e monitora como o contrato responde a essas entradas. +**Nota**: Uma outra maneira de testar suposições é escrever testes que disparam [modificadores de função](https://docs.soliditylang.org/en/v0.8.16/contracts.html#function-modifiers) em um contrato, especialmente declarações`require`, `assert`, e `if…else`. -Como qualquer programa, os contratos inteligentes dependem de entradas fornecidas pelos usuários para executar funções. E, enquanto assumimos que os usuários fornecerão entradas corretas, nem sempre esse é o caso. +##### 3. Medida de cobertura do código -Em alguns casos, enviar valores de entrada incorretos para um contrato inteligente pode causar vazamentos de recursos, falhas ou piores, levar à execução de código não pretendida. Campanhas difusas identificam tais problemas previamente, permitindo que você elimine a vulnerabilidade. +[Cobertura de código](https://en.m.wikipedia.org/wiki/Code_coverage) é uma métrica de teste que rastreia o número de ramificações, linhas e comandos no seu código executados durante os testes. Testes devem ter boa cobertura de código, caso contrário você pode ter "falsos negativos" que acontecem quando um contrato passa todos os testes, mas vulnerabilidades ainda existem no código. Obtendo alta cobertura de código, entretanto, dá a segurança que todos os comandos/funções em um contrato inteligente foram suficientemente testados por exatidão. -## Testes manuais para contratos inteligentes {#manual-testing-for-smart-contracts} +##### 4. Use frameworks de teste bem desenvolvidos -### 1. Auditorias de código {#code-audits} +A qualidade das ferramentas usada para rodar testes unitários para o seu contrato inteligente é crucial. Um framework de teste ideal é aquele que é regularmente mantido; fornece recursos úteis (por exemplo, capacidades de log e relatórios); e tem de ter sido extensivamente usado por outros desenvolvedores. -Uma auditoria de código é uma avaliação detalhada do código-fonte de um contrato inteligente para descobrir possíveis falhas de pontos, falhas de segurança e práticas de desenvolvimento ruins. Embora as auditorias de código possam ser automatizadas, nos referimos à análise de código com ajuda humana. +Frameworks de teste unitário para contratos inteligentes em Solidity vêm em diferentes linguagens (geralmente JavaScript, Python e Rust). Veja alguns dos guias abaixo para informações sobre como começar a rodar testes unitários com diferentes frameworks de teste: -Auditorias de código requerem uma mentalidade de invasor para mapear possíveis vetores de ataque em contratos inteligentes. Mesmo se você executar auditorias automatizadas, analisar cada linha de código-fonte é um requisito mínimo para escrever contratos inteligentes seguros. +- **[Rodando testes unitários com Brownie](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html)** +- **[Rodando testes unitários com Foundry](https://book.getfoundry.sh/forge/writing-tests)** +- **[Rodando testes unitários com Waffle](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-tests)** +- **[Rodando testes unitários com Remix](https://remix-ide.readthedocs.io/en/latest/unittesting.html#write-tests)** +- **[Rodando testes unitários com Ape](https://docs.apeworx.io/ape/stable/userguides/testing.html)** +- **[Rodando testes unitários com Hardhat](https://hardhat.org/hardhat-runner/docs/guides/test-contracts)** -Você também pode encomendar uma auditoria de segurança para dar aos usuários maiores garantias de segurança dos contratos inteligentes. Auditorias se beneficiam de uma análise extensiva realizada por profissionais de cibersegurança e detectam possíveis vulnerabilidades ou bugs que possam comprometer a funcionalidade do contrato inteligente. +### Teste de Integração {#integration-testing-for-smart-contracts} -### 2. Recompensa por bugs {#bug-bounties} +Enquanto o teste unitário depura funções de contrato isoladamente, testes integrados avaliam os componentes de um contrato inteligente como um todo. Teste de integração pode detectar defeitos vindos de chamadas entre contratos ou interações entre diferentes funções no mesmo contrato inteligente. Por exemplo, testes de integração podem ajudar a checar se coisas como [herança](https://docs.soliditylang.org/en/v0.8.12/contracts.html#inheritance) e injeção de dependência funcionam devidamente. -A recompensa por bugs é uma reconhecimento financeiro dado a um indivíduo que descobre uma vulnerabilidade ou bug no código de um programa e reporta aos desenvolvedores. As recompensas por bugs são semelhantes às auditorias, uma vez que envolve pedir que outras pessoas ajudem a encontrar defeitos em contratos inteligentes. A principal diferença é que os programas de recompensas por bugs estão abertos para uma comunidade mais ampla de desenvolvedores/hacker. +Teste de integração é útil se o seu contrato adota uma arquitetura modular ou interfaces com outros contratos on-chain durante a execução. One way of running integration tests is to [fork the blockchain](/glossary/#fork) at a specific height (using a tool like [Forge](https://book.getfoundry.sh/forge/fork-testing) or [Hardhat](https://hardhat.org/hardhat-network/docs/guides/forking-other-networks) and simulate interactions between your contract and deployed contracts. -Programas de recompensa por bugs frequentemente atraem uma ampla classe de hackers éticos e profissionais de segurança independentes com habilidades e experiência exclusivas. Isso pode ser uma vantagem em relação às auditorias de contratos inteligentes, que dependem principalmente de equipes que podem possuir conhecimentos especializados limitados ou estreitos. +O blockchain que sofreu fork irá se comportar similarmente à Mainnet e ter contas com estados e saldos associados. Mas ele age somente como um ambiente de área local de desenvolvimento restrita, significando que você não precisará de ETH real para transações, por exemplo, nem suas modificações irão afetar o protocolo Ethereum real. -## Testes vs. Verificação formal {#testing-vs-formal-verification} +### Teste baseado em propriedade {#property-based-testing-for-smart-contracts} -Ao passo que testar ajuda a confirmar se um contrato retorna os resultados esperados para algumas entradas de dados, isso não pode comprovar de forma conclusiva o mesmo para entradas não utilizadas durante os testes. Testar um contrato inteligente não pode garantir "correção funcional", o que significa que não pode mostrar que um programa se comporta conforme necessário para _todos os_ conjuntos de valores e condições de entrada. +Teste baseado em propriedade é o processo de checar que um contrato inteligente satisfaz algumas propriedades definidas. Propriedades afirmam fatos sobre o comportamento de um contrato esperado continuar verdadeiro em diferentes cenários - um exemplo de propriedade de contrato inteligente poderia ser "Operações aritméticas no contrato nunca sofrem overflow ou underflow." -Como tal, os desenvolvedores são incentivados a incorporar **verificação formal** em sua abordagem para avaliar a exatidão dos contratos inteligentes. A verificação formal usa [métodos formais](https://www.brookings.edu/techstream/formal-methods-as-a-path-toward-better-cybersecurity/)— técnicas matematicamente rigorosas para especificar e verificar softwares. +**Análise estática** e **análise dinâmica** são duas técnicas comuns de execução de teste baseado em propriedade, e ambas podem verificar que o código para um programa (um contrato inteligente no caso) satisfaz algumas propriedades pré-definidas. Algumas ferramentas de teste baseadas em propriedade vem com regras pré-definidas sobre propriedades esperadas de contratos e checam o código contra estas regras, enquanto outras permitem você criar propriedades customizadas para um contrato inteligente. -A verificação formal é considerada importante para contratos inteligentes, porque ajuda os desenvolvedores a testar formalmente suposições relacionadas a contratos inteligentes. Isso é feito criando especificações formais que descrevem as propriedades de um contrato inteligente e verificam que um modelo formal do contrato inteligente corresponde à especificação. Esta abordagem aumenta a confiança de que um contrato inteligente executará funções apenas como definido na lógica de negócios e nada mais. +#### Análise estática {#static-analysis} -[Saiba mais sobre verificação formal de contratos inteligentes](/developers/docs/smart-contracts/formal-verification) +Um analisador estático pega como entrada o código-fonte de um contrato inteligente e retorna resultados declarando se o contrato satisfaz a propriedade ou não. Diferente da análise dinâmica, análise estática não envolve executar um contrato para analisá-lo por exatidão. Análise estática gera razões alternativas sobre todos os caminhos possíveis que um contrato inteligente poderia tomar durante a execução (ou seja, examinando a estrutura do código-fonte para determinar o que significaria para a operação do contrato em tempo de execução). -## Testando ferramentas e bibliotecas {#testing-tools-and-libraries} +Testes [Linting](https://www.perforce.com/blog/qac/what-lint-code-and-why-linting-important) e [estático](https://www.techtarget.com/whatis/definition/static-analysis-static-code-analysis) são métodos comuns de rodar análise estática em contratos. Ambos requerem analisar representações de baixo nível da execução de um contrato, como [árvores de sintaxe abstrata](https://en.m.wikipedia.org/wiki/Abstract_syntax_tree) e [gráficos de controle de fluxo](https://www.geeksforgeeks.org/software-engineering-control-flow-graph-cfg/amp/) retornados pelo compilador. -### Ferramentas de testes unitários {#unit-testing-tools} +Na maioria dos casos, análise estática é útil para detectar problemas de segurança como uso de construtores inseguros, erros de sintaxe, ou violações de padrões de código no código de contratos. Entretanto, analisadores estáticos são conhecidos por geralmente serem instáveis em detectar vulnerabilidades mais profundas, e podem produzir excessivos falsos positivos. -**Solidity-Coverage** - _Ferramenta de cobertura de código em Solidity útil para testar contratos inteligentes._ +#### Análise dinâmica {#dynamic-analysis} -- [GitHub](https://github.com/sc-forks/solidity-coverage) +Análise dinâmica gera entradas simbólicas (por exemplo, em [execução simbólica](https://en.m.wikipedia.org/wiki/Symbolic_execution)) ou entradas concretas (por exemplo, em [fuzzing](https://owasp.org/www-community/Fuzzing)) para funções de contratos inteligentes para ver se qualquer trace de execução violou propriedades específicas. Esta forma de teste baseado em propriedades difere dos testes unitários no tocante a casos de teste cobrem múltiplos cenários e um programa manipula a geração de casos de teste. -**Waffle** - _Um framework para desenvolvimento avançado de contratos inteligentes e testes (baseado em ethers.js)_. +[Fuzzing](https://halborn.com/what-is-fuzz-testing-fuzzing/) é um exemplo de análise técnica dinâmica para verificar propriedades arbitrárias em contratos inteligentes. Um fuzzer invoca funções em um contrato alvo com variações randômicas ou mal formadas de um valor de entrada definido. Se um contrato inteligente entra em estado de erro (por exemplo, uma afirmação 'where' falha), o problema é indicado e as entradas que geraram esta execução para o caminho da vulnerabilidade são produzidas em um relatório. -- [Documentação](https://ethereum-waffle.readthedocs.io/en/latest/) -- [GitHub](https://github.com/TrueFiEng/Waffle) -- [Site](https://getwaffle.io/) +Fuzzing é útil para avaliação de um mecanismo de validação de entrada de contratos inteligentes, já que manipulação imprópria de entradas inesperadas pode resultar em execução não pretendida e produzir efeitos perigosos. Esta forma de teste baseado em propriedade pode ser ideal por muitas razões: -**Remix Tests** - _Ferramenta para testar contratos inteligentes em Solidity. Funciona abaixo do plugin Remix IDE "Solidity Unit Testing" usado para escrever e executar casos de teste para um contrato._ +1. **Escrever casos de teste para cobrir muitos cenários é difícil.** Um teste de propriedade somente requer que você defina o comportamento e faixa de dados com a qual testar o comportamento - o programa automaticamente gera casos de teste baseados na propriedade definida. -- [Documentação](https://remix-ide.readthedocs.io/en/latest/unittesting.html) -- [GitHub](https://github.com/ethereum/remix-project/tree/master/libs/remix-tests) +2. **Sua suíte de testes pode não cobrir suficientemente todos os caminhos possíveis dentro do programa. ** Até com 100% de cobertura, é possível perder alguns casos limítrofes. -**OpenZeppelin Test Environment -** _ Biblioteca de asserções para teste de contrato inteligente Ethereum. Certifique-se de que seus contratos se comportam como esperado!_ +3. **Testes unitários provam que um contrato executa corretamente para dados de amostra, mas se o contrato executa corretamente para entradas fora das amostras, permanece desconhecido.** Testes de propriedade executam um contrato alvo com múltiplas variações de uma dado valor de entrada para encontrar traços de execução que causaram falhas de afirmação. Por isso, um teste proprietário fornece mais garantias que um contrato execute corretamente para uma larga classe de dados de entrada. -- [GitHub](https://github.com/OpenZeppelin/openzeppelin-test-helpers) -- [Documentação](https://docs.openzeppelin.com/test-helpers) +### Orientações para rodar teste baseado em propriedade para contratos inteligentes {#running-property-based-tests} -**Framework para teste de contrato inteligente Truffle** - _Framework de testes automatizado para tornar os testes de seus contratos mais simples._ +Executar testes baseados em propriedade geralmente começa com a definição da propriedade (por exemplo, ausência de [overflows de inteiro](https://github.com/ConsenSys/mythril/wiki/Integer-Overflow)) ou com coleções de propriedades que você quer verificar em um contrato inteligente. Você pode também precisar definir uma faixa de valores dentro da qual o programa pode gerar dados para entradas de transação quando escrevendo os testes de propriedade. -- [Documentação](https://trufflesuite.com/docs/truffle/testing/testing-your-contracts/) -- [Site](https://trufflesuite.com/) +Uma vez configurado propriamente, a ferramenta de teste de propriedade irá executar as suas funções do contrato inteligente com entradas aleatoriamente geradas. Se houver quaisquer violações de afirmações, você deve receber um relatório com os dados de entrada concretos que violaram a propriedade sendo avaliada. Veja alguns dos guias abaixo para começar com testes baseados em propriedade com diferentes ferramentas: -**Framework para testes unitário Brownie** - _Brownie utiliza Pytest, um framework de testes rico em recursos que permite que você escreva pequenos testes com código mínimo, dimensiona bem para projetos grandes e é altamente extensível._ +- **[Análise estática de contratos inteligentes com Slither](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/slither#slither)** +- **[Teste baseado em propriedade com Brownie](https://eth-brownie.readthedocs.io/en/stable/tests-hypothesis-property.html)** +- **[Contratos Fuzzing com Foundry](https://book.getfoundry.sh/forge/fuzz-testing)** +- **[Contratos Fuzzing com Echidna](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna#echidna-tutorial)** +- **[Execução simbólica de contratos inteligentes com Manticore](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore#manticore-tutorial)** +- **[Execução simbólica de contratos inteligentes com Mythril](https://mythril-classic.readthedocs.io/en/master/tutorial.html)** -- [Documentação](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html) -- [GitHub](https://github.com/eth-brownie/brownie) +## Testes manuais para contratos inteligentes {#manual-testing-for-smart-contracts} -**Foundry testes** - _Foundry oferece o Forge, um framework de testes da Ethereum rápido e flexível capaz de executar testes unitários simples, verificações de otimização de gás e fusão de contratos._ +Teste manual de contratos inteligentes frequentemente vêm mais tarde no ciclo de desenvolvimento, após rodar testes automatizados. Essa forma de teste avalia o contrato inteligente como um produto totalmente integrado para ver se ele executa conforme especificado nos requisitos técnicos. -- [GitHub](https://github.com/foundry-rs/foundry/tree/master/forge) -- [Documentação](https://book.getfoundry.sh/forge/) +### Testando contratos no blockchain local {#testing-on-local-blockchain} -**Etheno** - _Ferramenta de teste de Ethereum All-in-one compreendendo um multiplexador de RPC JSON, ferramenta de ferramentas de análise e ferramenta de integração de teste. Etheno elimina a complexidade da criação de ferramentas de análise como Manticore e Echidna em grandes projetos multicontratos._ +Enquanto testes automatizados realizados em um ambiente local de desenvolvimento podem fornecer informações úteis de depuração, você irá querer saber como seus contrato inteligente se comporta em um ambiente de produção. Entretanto, implantar na cadeia principal do Ethereum incorre em taxas de gas - sem mencionar que você ou seus usuários podem perder dinheiro real se o seu contrato inteligente ainda tem falhas. -- [GitHub](https://github.com/crytic/etheno) +Testar seu contrato em um blockchain local (também conhecido como uma [rede de desenvolvimento](/developers/docs/development-networks/)) é uma alternativa recomendada em relação a testar na Mainnet. Um blockchain local é uma cópia do blockchain Ethereum rodando localmente no seu computador que simula o comportamento da camada de execução do Ethereum. Como tal, você pode programar transações para interagir com um contrato sem incorrer em custo significante. -**Estrutura de testes e desenvolvimento Woke** — _Scripts de teste e implantação com dicas, fuzzer, suporte para depuração, cobertura de código e teste cross-chain em Python._ +Rodar contratos em blockchain local pode ser útil como forma de teste de integração manual. [Contratos inteligentes são altamente combináveis](/developers/docs/smart-contracts/composability/), permitindo você integrar com protocolos existentes - mais você ainda precisará garantir que interações on-chain assim tão complexas produzam os resultados corretos. -- [Documentação](https://ackeeblockchain.com/woke/docs/latest/testing-framework/overview/) -- [GitHub](https://github.com/Ackee-Blockchain/woke) +[Mais sobre redes de desenvolvimento.](/developers/docs/development-networks/) -### Ferramentas de análise estática {#static-analysis-tools} +### Testando contratos nas redes de teste {#testing-contracts-on-testnets} -**Mythril** — _Ferramenta de avaliação de bytecode de EVM para detectar vulnerabilidades de contrato usando análise concolic e análise de fluxo de controle._ +Uma rede de teste ou testnet funciona exatamente como o Ethereum Mainnet, exceto que ela usa Ether (ETH) sem valor no mundo real. Implantar seu contrato em uma [testnet](/developers/docs/networks/#ethereum-testnets) significa que qualquer um pode interagir com ele (por exemplo, via o front-end do dapp) sem colocar fundos em risco. -- [GitHub](https://github.com/ConsenSys/mythril-classic) -- [Documentação](https://mythril-classic.readthedocs.io/en/master/about.html) +Esta forma de teste manual é útil para avaliação do fluxo fim-a-fim da sua aplicação do ponto de vista do usuário. Aqui, testadores beta podem também realizar execuções experimentais e reportar qualquer problema com a lógica de negócios do contrato e funcionalidade geral. -**Slither** — _Estrutura de análise estática do Solidity baseado em Python para encontrar vulnerabilidades, aprimorando a compreensão de código e escrevendo análises personalizadas para contratos inteligentes._ +Implantar na testnet depois de testar no blockchain local é ideal desde que o primeiro é mais perto do comportamento da Máquina Virtual Ethereum. Portanto, é comum para muitos projetos nativos do Ethereum implantar dapps nas testnets para avaliar a operação dos contratos inteligentes em condições de vida real. -- [GitHub](https://github.com/crytic/slither) +[Mais sobre redes de teste do Ethereum.](/developers/docs/development-networks/#public-beacon-testchains) + +## Testes vs. Verificação formal {#testing-vs-formal-verification} -**Rattle** — _Estrutura de análise estática de bytecode de EVM concebido para trabalhar em contratos inteligentes implementados._ +Ao passo que testar ajuda a confirmar se um contrato retorna os resultados esperados para algumas entradas de dados, isso não pode comprovar de forma conclusiva o mesmo para entradas não utilizadas durante os testes. Testar um contrato inteligente, portanto, não pode garantir "correção funcional" (o que significa que não pode mostrar que um programa se comporta conforme necessário para _todos os_ conjuntos de valores de entrada). -- [GitHub](https://github.com/crytic/rattle) +Verificação formal é uma abordagem para avaliação da correção do software checando se um modelo formal do programa bate com a especificação formal. Um modelo formal é uma representação matemática abstrata de um programa, enquanto uma especificação formal define as propriedades de um programa (por exemplo, afirmações lógicas sobre a execução do programa). -### Ferramentas de análise dinâmica {#dynamic-analysis-tools} +Pelo fato de propriedades serem escritas em termos matemáticos, é possível verificar que um modelo formal (matemático) do sistema satisfaz uma especificação usando regras lógicas de inferência. Por isso, ferramentas de verificação formal são ditas produzir 'provas matemáticas' da correção de um sistema. -**Echidna** — _Difusor de contrato rápido para detectar vulnerabilidades em contratos inteligentes por meio de testes baseados em propriedades._ +Diferente de testar, verificações formais podem ser usadas para verificar se a execução de um contrato inteligente satisfaz uma especificação formal para _todas_ as execuções (por exemplo, não ter falhas) sem necessitar executá-lo com dados de amostra. Não apenas isto reduz tempo gasto em rodar dezenas de testes unitários, mas é também mais efetivo na caça por vulnerabilidades escondidas. Dito isto, técnicas de verificação formal se baseiam em um espectro dependendo da sua dificuldade de implementação e utilidade. -- [GitHub](https://github.com/crytic/echidna/) +[Saiba mais sobre verificação formal de contratos inteligentes.](/developers/docs/smart-contracts/formal-verification) -**Harvey** — _Ferramenta automatizada de difusão útil para detectar violações de propriedades em código de contrato inteligente._ +## Testes vs auditorias e recompensas por bugs {#testing-vs-audits-bug-bounties} -- [Website](https://consensys.net/diligence/fuzzing/) +Como mencionado, testes rigorosos raramente podem garantir a ausência de bugs em um contrato; abordagens de verificação formal podem fornecer garantias mais fortes da correção, mas atualmente são difíceis de usar e incorrem em custos consideráveis. -**Mantícora** — _Estrutura de execução simbólica dinâmica para analisar o bytecode de EVM._ +Ainda assim, você pode aumentar a possibilidade de encontrar vulnerabilidades de contrato pegando uma revisão independente de código. [Auditorias de contratos inteligentes](https://www.immunebytes.com/blog/what-is-a-smart-contract-audit/) e [recompensas por bugs](https://medium.com/immunefi/a-defi-security-standard-the-scaling-bug-bounty-9b83dfdc1ba7) são duas maneiras de ter outros analisando os seus contratos. -- [GitHub](https://github.com/trailofbits/manticore) -- [Documentação](https://github.com/trailofbits/manticore/wiki) +Auditorias são realizadas por auditores experientes em encontrar casos de falhas de segurança e práticas pobres de desenvolvimento em contratos inteligentes. Uma auditoria irá geralmente incluir testes (e possivelmente verificação formal) assim como revisão manual de todo o código. -### Serviços de auditoria de contrato inteligente {#smart-contract-auditing-services} +Por outro lado, um programa de recompensas por bug geralmente envolve oferta de recompensa financeira para um indivíduo (geralmente descrito como um [whitehat hackers](https://en.wikipedia.org/wiki/White_hat_(computer_security))) que descobre uma vulnerabilidade em um contrato inteligente e divulga-a para os desenvolvedores. As recompensas por bugs são semelhantes às auditorias, uma vez que envolve pedir que outras pessoas ajudem a encontrar defeitos em contratos inteligentes. -**ConsenSys Diligence** — _Serviço de auditoria inteligente de contratos que ajuda projetos no ecossistema da blockchain e garante que seus protocolos estejam prontos para serem lançados e criados para proteger os usuários._ +A maior diferença é que programas de recompensa por bug são abertos a uma maior comunidade de desenvolvedores/hackers e atraem uma vasta classe de hackers éticos e profissionais de segurança independentes com habilidades únicas e experiência. Isso pode ser uma vantagem em relação às auditorias de contratos inteligentes, que dependem principalmente de equipes que podem possuir conhecimentos especializados limitados ou estreitos. + +## Testando ferramentas e bibliotecas {#testing-tools-and-libraries} + +### Ferramentas de testes unitários {#unit-testing-tools} -- [Site](https://consensys.net/diligence/) +- **[solidity-coverage](https://github.com/sc-forks/solidity-coverage)** - _Ferramenta de cobertura de código para contratos inteligentes escritos em Solidity._ -**CertiK** — _Empresa de segurança de blockchain pioneira no uso de tecnologia de verificação formal de ponta em contratos inteligentes e redes blockchain._ +- **[Waffle](https://ethereum-waffle.readthedocs.io/en/latest/)** - _Framework para desenvolvimento avançado de contratos inteligentes e teste (baseado no ethers.js)_. -- [Site](https://www.certik.com/) +- **[Remix Tests](https://github.com/ethereum/remix-project/tree/master/libs/remix-tests)** - _Ferramenta para testar contratos inteligentes em Solidity. Funciona abaixo do plugin Remix IDE "Solidity Unit Testing" usado para escrever e executar casos de teste para um contrato._ -**Trail of Bits** — _Empresa de segurança virtual que combina pesquisa de segurança com uma mentalidade de invasores para reduzir riscos e fortalecer o código._ +- **[Auxiliar para Teste do OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-test-helpers)** - _Biblioteca de asserções para teste de contrato inteligente Ethereum. Certifique-se de que seus contratos se comportam como esperado!_ -- [Site](https://www.trailofbits.com/) +- **[Framework de teste de unidade do Brownie](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html)** - _Brownie utiliza Pytest, uma estrutura de teste rica em recursos que permite que você escreva pequenos testes com o mínimo de código, escala bem para grandes projetos e é altamente extensível._ -**PeckShield** — _Empresa de segurança de blockchain que oferece produtos e serviços para a segurança, privacidade e usabilidade de todo o ecossistema blockchain._ +- **[Froundry Testes](https://github.com/foundry-rs/foundry/tree/master/forge)** - _Foundry oferece o Forge, um framework de teste no Ethereum rápido e flexível, capaz de executar testes de unidade simples, verificações de otimização de gás e mutações (fuzzing) em contratos._ -- [Site](https://peckshield.com/) +- **[Hardhat Testes](https://hardhat.org/hardhat-runner/docs/guides/test-contracts)** - _Framework para testar contratos inteligentes com base no ethers.js, Mocha e Chai._ -**QuantStamp** — _Serviço de auditoria que facilita a adoção geral da tecnologia blockchain por meio de serviços de segurança e avaliação de riscos._ +- **[ApeWorx](https://docs.apeworx.io/ape/stable/userguides/testing.html)** - _Desenvolvimento baseado em Python e framework de teste para contratos inteligentes voltados para a Máquina Virtual Ethereum._ -- [Site](https://quantstamp.com/) +### Ferramentas de teste baseadas em propriedades {#property-based-testing-tools} -**OpenZeppelin** — _Empresa de segurança de contrato inteligente, que fornece auditorias de segurança para sistemas distribuídos._ +#### Ferramentas de análise estática {#static-analysis-tools} -- [Site](https://www.openzeppelin.com/security-audits) +- **[Slither](https://github.com/crytic/slither)** - _Framework com base no Python de análise estática estabelecida no Solidity para encontrar vulnerabilidades, aprimorar a compreensão do código e escrever análises personalizadas para contratos inteligentes._ -**Nethermind** — _Serviços de auditoria Solidity e Cairo, que garantem a integridade de contratos inteligentes e a segurança dos usuários pelo Ethereum e Starknet._ +- **[Ethlint](https://ethlint.readthedocs.io/en/latest/)** - _Analisador (linter) para garantir as práticas recomendadas de estilo e segurança para a linguagem de programação de contrato inteligente Solidity._ -- [Site](https://nethermind.io/smart-contracts-audits) +#### Ferramentas de análise dinâmica {#dynamic-analysis-tools} -### Plataformas de recompensa por bugs {#bug-bounty-platforms} +- **[Echidna](https://github.com/crytic/echidna/)** - _Fuzzer (analisador) de contrato para detectar vulnerabilidades em contratos inteligentes por meio de testes baseados em propriedade._ -**Immunefi** — _Plataforma de recompensa por bugs para contratos inteligentes e projetos DeFi, na qual pesquisadores de segurança revisam o código, divulgam vulnerabilidades, são pagos e tornam as criptomoedas mais seguras._ +- **[Diligence Fuzzing](https://consensys.net/diligence/fuzzing/)** - _ Ferramenta de análise automatizada útil para detectar violações de propriedade no código de contrato inteligente._ -- [Website](https://immunefi.com/) +- **[Manticore](https://manticore.readthedocs.io/en/latest/index.html)** - _Framework de execução simbólica dinâmica para análise de bytecode na EVM._ -**HackerOne** — _Coordenação de vulnerabilidades e plataforma de recompensas por bug que conecta empresas com testadores de infiltração e pesquisadores de cibersegurança._ +- **[Mithril](https://github.com/ConsenSys/mythril-classic)** - _ Ferramenta para diagnóstico de bytecode na EVM para detectar vulnerabilidades de contrato usando análise de contaminação, análise simbólica e verificação de fluxo de controle._ -- [Website](https://www.hackerone.com/) +- **[Diligence Scribble](https://consensys.net/diligence/scribble/)** - _ Scribble é uma linguagem de especificação e ferramenta de verificação do tempo de execução, que possibilita anotar contratos inteligentes com propriedades, o que permite testar automaticamente os contratos com ferramentas como Diligence Fuzzing ou MythX._ ## Tutoriais relacionados {#related-tutorials} -- [Configuração de integração contínua do Solidity e Truffle](/developers/tutorials/solidity-and-truffle-continuous-integration-setup/) _ – Como configurar Travis ou Circle CI para testes de Truffle juntamente com plugins úteis._ -- [Visão geral de testes de produtos](/developers/tutorials/guide-to-smart-contract-security-tools/) _ – Uma visão geral e comparação de diferentes produtos de teste_ +- [Uma visão geral e comparação de diferentes produtos de teste](/developers/tutorials/guide-to-smart-contract-security-tools/) \_ - [Como usar o Echidna para testar contratos inteligentes](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/) - [Como usar o Manticore para encontrar bugs em contratos inteligentes](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/) - [Como utilizar o Slither para encontrar bugs nos contratos inteligentes](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) -- [Como simular contratos do Solidity para teste](/developers/tutorials/how-to-mock-solidity-contracts-for-testing/) -- [Como migrar do Truffle Tests para o ambiente de teste OpenZeppelin](https://docs.openzeppelin.com/test-environment/0.1/migrating-from-truffle) -- [Como testar os contratos depois que eles foram implantados em uma rede](https://fulldecent.blogspot.com/2019/04/testing-deployed-ethereum-contracts.html) -- [Aprenda sobre desenvolvimento de Blockchain, Solidity e Web3 de pilha completa com JavaScript no YouTube](https://www.youtube.com/watch?v=gyMwXuJrbJQ) -- [Curso de Contrato Inteligente, Solidity e Blockchain no YouTube](https://www.youtube.com/watch?v=M576WGiDBdQ) +- [Como simular contratos Solidity para teste](/developers/tutorials/how-to-mock-solidity-contracts-for-testing/) +- [How to run unit tests in Solidity using Foundry](https://www.rareskills.io/post/foundry-testing-solidity) ## Leitura adicional {#further-reading} -- [Um guia completo para testar contratos inteligentes do Ethereum](https://iamdefinitelyahuman.medium.com/an-in-depth-guide-to-testing-ethereum-smart-contracts-2e41b2770297) — _Ben Hauser_ -- [Como testar os contratos inteligentes do Ethereum](https://betterprogramming.pub/how-to-test-ethereum-smart-contracts-35abc8fa199d) — _Alex Roan_ +- [Um guia detalhado para testar contratos inteligentes do Ethereum](https://iamdefinitelyahuman.medium.com/an-in-depth-guide-to-testing-ethereum-smart-contracts-2e41b2770297) +- [Como testar contratos inteligentes do Ethereum](https://betterprogramming.pub/how-to-test-ethereum-smart-contracts-35abc8fa199d) +- [Guia de teste de unidade do MolochDAO para desenvolvedores](https://github.com/MolochVentures/moloch/tree/4e786db8a4aa3158287e0935dcbc7b1e43416e38/test#moloch-testing-guide) +- [Como testar contratos inteligentes como um astro do rock](https://forum.openzeppelin.com/t/test-smart-contracts-like-a-rockstar/1001) diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/upgrading/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/upgrading/index.md new file mode 100644 index 00000000000..0ea6b7aca97 --- /dev/null +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/upgrading/index.md @@ -0,0 +1,165 @@ +--- +title: Atualizando contratos inteligentes +description: Uma visão geral dos padrões de atualização de contratos inteligentes no Ethereum +lang: pt-br +--- + +Contratos inteligentes no Ethereum são programas auto-executados que rodam em Máquina Virtual Ethereum (EVM). Estes programas são imutáveis por desenho, o que evita quaisquer atualizações na lógica de negócios uma vez que o contrato é implantado. + +Enquanto imutabilidade é necessária para falta de confiança, descentralização, e segurança de contratos inteligentes, ela pode ser um problema em certos casos. Por exemplo, código imutável pode tornar impossível desenvolvedores consertar contratos vulneráveis. + +Entretanto, mais pesquisas sobre melhoria de contratos inteligentes tem levado à introdução de vários padrões de atualização. Estes padrões de atualização permitem a desenvolvedores atualizar contratos inteligentes (enquanto preservam a imutabilidade) colocando lógica de negócio em diferentes contratos. + +## Pré-requisitos {#prerequisites} + +Você deve ter um bom entendimento de [contratos inteligentes](/developers/docs/smart-contracts/), [anatomia de contratos inteligentes](/developers/docs/smart-contracts/anatomy/), e a [Máquina Virtual Ethereum (EVM)](/developers/docs/evm/). Este guia também presume que os leitores entendam de programação de contratos inteligentes. + +## O que é uma atualização de contrato inteligente? {#what-is-a-smart-contract-upgrade} + +Uma atualização de contrato inteligente envolve mudar a lógica de negócios de um contrato inteligente enquanto preserva o estado do contrato. É importante esclarecer que capacidade de atualização e mutabilidade não são o mesmo, especialmente no contexto de contratos inteligentes. + +Você ainda não pode mudar um programa implantado em um endereço na rede Ethereum. Mas você pode alterar o código que é executado quando usuários interagem com um contrato inteligente. + +Isto pode ser feito por meio dos seguintes métodos: + +1. Criando múltiplas versões de um contrato inteligente e migrando o estado (ou seja, os dados) de um contrato antigo para uma nova instância do contrato. + +2. Criando contratos separados para armazenar lógica de negócios e estado. + +3. Usando padrões de proxy para delegar chamadas de função de um contrato de proxy imutável para um contrato de lógica modificável. + +4. Criando um contrato principal imutável que faz interface e confia em contratos satélites flexíveis para executar funções específicas. + +5. Usando o padrão diamante para delegar chamadas de função de um contrato proxy para contratos lógicos. + +### Mecanismo de atualização 1: Migração de contrato {#contract-migration} + +Migração de contrato é baseada no versionamento - a ideia de criar e gerenciar estados únicos do mesmo software. Migração de contrato envolve implantar uma nova instância de um contrato inteligente existente e transferir o storage e saldos para o novo contrato. + +O recém-implantado contrato terá um storage vazio, permitindo você recuperar dados do contrato antigo e escrevê-lo na nova implementação. Depois disso, você precisará atualizar todos os contratos que interagiram com o contrato antigo para refletir o novo endereço. + +O último passo na migração do contrato é convencer usuários a mudar para o novo contrato. A nova versão do contrato irá reter saldos de usuários e endereços, que preserva a imutabilidade. Se for um contrato baseado em token, você também precisará contatar a corretora para descartar o contrato antigo e usar o novo contrato. + +Migração de contrato é uma medida relativamente direta e segura para atualização de contratos inteligentes sem quebrar interações de usuários. Entretanto, migrar manualmente o storage do usuário e saldos para o novo contrato é demorado e pode incorrer em altos gastos com gas. + +[Mais sobre migração de contrato.](https://blog.trailofbits.com/2018/10/29/how-contract-migration-works/) + +### Mecanismo de atualização 2: Separação de dados {#data-separation} + +Um outro método para atualização de contratos inteligentes é separar a lógica de negócios e o armazenamento de dados em contratos separados. Isto significa usuários interagirem com a lógica do contrato, enquanto dados são armazenados na storage do contrato. + +O contrato lógico contém o código executado quando usuários interagem com a aplicação. Ele também mantém o endereço de storage do contrato e interage com ele para pegar e configurar os dados. + +Enquanto isso, o storage do contrato mantém o estado associado com o contrato inteligente, como saldos de usuários e endereços. Note que o storage do contrato é de propriedade da lógica do contrato e é configurado com o endereço do último na implantação. Isto evita contratos não autorizados de chamar o storage do contrato ou atualizar seus dados. + +Por padrão, o storage do contrato é imutável - mas você pode substituir o contrato lógico que ele aponta para uma nova implementação. Isto irá mudar o código que roda na EVM, enquanto mantém o storage o saldos intactos. + +Usando este método de atualização requer atualizar o endereço do contrato lógico na storage do contrato. Você tem também que configurar o novo contrato lógico com o endereço do storage do contrato, por razões já explicadas anteriormente. + +O padrão de separação de dados é discutivelmente mais fácil de implementar comparado à migração de contrato. Entretanto, você terá de gerenciar múltiplos contratos e implementar esquemas complexos de autorização para proteger contratos inteligentes de atualizações maliciosas. + +### Mecanismo de atualização 3: Padrões de proxy {#proxy-patterns} + +O padrão de proxy também usa separação de dados para manter lógica de negócio e dados em contratos separados. Entretanto, em um padrão de proxy, o storage do contrato (chamado de proxy) chama o contrato lógico durante a execução do código. Isto é o contrário do método de separação de dados, onde o contrato lógico chama o contrato de storage. + +Isto é o que acontece em um padrão proxy: + +1. Usuários interagem com o contrato de proxy, que armazena dados, mas não mantém a lógica de negócio. + +2. O contrato proxy armazena os endereços do contrato lógico e delega todas as chamadas de função para o contrato lógico (que mantém a lógica de negócio) usando a função `delegatecall`. + +3. Depois de a chamada ser direcionada para o contrato lógico, os dados retornados do contrato lógico é recuperado e retornado ao usuário. + +Usar padrões de proxy requer um entendimento da função **delegatecall**. Basicamente, `delegatecall` é um opcode que permite um contrato chamar outro contrato, enquanto a execução real do código acontece no contexto do contrato chamado. Uma implicação de usar `delegatecall` em padrões proxy é que o contrato proxy lê e escreve no seu storage e executa lógica armazenada no contrato lógico como se chamando uma função interna. + +Da [Documentação Solidity](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html#delegatecall-callcode-and-libraries): + +> _Existe uma variante especial de chamada de mensagem, chamada **delegatecall** que é idêntica à chamada de mensagem, exceto pelo fato de que o código no endereço alvo é executado no contexto (ou seja, no endereço) do contrato chamador e `msg.sender` e `msg.value` não mudam seus valores._ _Isto significa que um contrato pode dinamicamente carregar código de um endereço diferente em tempo de execução. Storage, endereço atual e saldo ainda se referem ao contrado chamador, somente o código é pego do endereço chamado._ + +O contrato proxy sabe invocar `delegatecall` sempre quando um usuário chama a função, porque ele tem uma funçaõ `fallback` construída dentro dele. Em programação Solidity a [função fallback](https://docs.soliditylang.org/en/latest/contracts.html#fallback-function) é executada quando uma chamada de função não encontra funções especificadas em um contrato. + +Fazer o padrão proxy trabalhar requer escrever uma função fallback customizada que especifique como o contrato proxy deve manipular chamadas de função que ele não suporta. Neste caso, a função de fallback do proxy é programada para iniciar um delegatecall and re-rotear a requisição do usuário para a implementação atual do contrato lógico. + +O contrato proxy é imutável por padrão, mas novos contratos lógicos com lógicas de negócio atualizadas podem ser criados. Fazer a atualização é então uma questão de mudança de endereço do contrato lógico referenciado no contrato proxy. + +Ao apontar o contrato proxy para um novo contrato lógico, o código executado quando os usuários chamam a função do contrato proxy é alterado. Isso nos permite atualizar a lógica do contrato sem pedir para os usuários interagirem com o novo contrato. + +Padrões proxy são um método popular para atualização de contratos inteligentes porque eles eliminam as dificuldades associadas com migração de contrato. No entanto, os padrões de proxy são mais complicados de usar e podem introduzir falhas críticas, como [conflitos do seletor de funções](https://medium.com/nomic-foundation-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357), se usado indevidamente. + +[Mais sobre padrões de proxy](https://blog.openzeppelin.com/proxy-patterns/). + +### Mecanismo de atualização 4: Padrão de estratégia {#strategy-pattern} + +Esta técnica é influenciada pelo [padrão de estratégia](https://en.wikipedia.org/wiki/Strategy_pattern), que encoraja criar programas de software que fazem interface com outros programas para implementar recursos específicos. Aplicar padrão de estratégia para desenvolvimento Ethereum significaria construir um contrato inteligente que chama funções de outros contratos. + +O contrato principal neste caso contém o núcleo da lógica de negócio, mas faz interface com outros contratos inteligentes ("contratos satélites") para executar certas funções. Este contrato principal também armazena o endereço para cada contrato satélite e pode alternar entre diferentes implementações de contrato satélite. + +Você pode construir um novo contrato satélite e configurar o contrato principal com o novo endereço. Isto permite você mudar _estratégias_ (ou seja, implementar nova lógica) para um contrato inteligente. + +Apesar de similar ao padrão de proxy discutido anteriormente, o padrão de estratégia é diferente porque o contrato principal, com o qual usuários interagem, mantém a lógica de negócios. Usar este padrão te dá a oportunidade de introduzir mudanças limitadas a um contrato inteligente sem afetar a infraestrutura principal. + +A principal desvantagem é que este padrão é mais útil para implantar atualizações menores. Além disso, se o contrato for comprometido (por exemplo, via um hack), você não pode usar este método de atualização. + +### Mecanismo de atualização 5: Padrão Diamante {#diamond-pattern} + +O padrão diamante pode ser considerado uma melhoria do padrão proxy. Padrões diamante diferem dos padrões proxy porque o contrato proxy diamante pode delegar chamadas de função para mais de um contrato lógico. + +Os contratos lógicos no padrão diamante são conhecidos como _facets_. Para fazer o padrão diamante funcionar, você precisa criar um mapeamento no contrato proxy que mapeie [funções seletoras](https://docs.soliditylang.org/en/latest/abi-spec.html#function-selector) para endereços facet diferentes. + +Quando um usuário faz uma chamada de função, o contrato proxy checa o mapeamento para encontrar o facet responsável por executar aquela função. Então ele invoca `delegatecall` (usando a função fallback) e redireciona a chamada para o devido contrato lógico. + +O padrão de atualização diamante tem algumas desvantagens sobre os padrões tradicionais de atualização proxy: + +1. Ele permite você atualizar uma pequena parte do contrato sem alterar todo o código. Usar o padrão proxy para atualizações requer criar um contrato lógico inteiramente novo, mesmo para pequenas atualizações. + +2. Todos os contratos inteligentes (incluindo contratos lógicos usados nos padrões proxy) tem 24KB de limite de tamanho, o que pode ser uma limitação - especialmente para contratos complexos que requerem mais funções. O padrão diamante facilita resolver este problema dividindo funções por múltiplos contratos lógicos. + +3. Padrões proxy adotam uma abordagem de pegar todos para controle de acesso. Uma entidade com acesso a funções de atualização pode mudar o contrato _inteiro_. Mas o padrão diamante habilita uma abordagem de permissões modulares, onde você pode restringir entidades para atualizar certas funções dentro de um contrato inteligente. + +[Mais sobre padrão diamante](https://eip2535diamonds.substack.com/p/introduction-to-the-diamond-standard?s=w). + +## Prós e contras da atualização de contratos inteligentes {#pros-and-cons-of-upgrading-smart-contracts} + +| Prós | Contras | +| ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Uma atualização de contrato inteligente pode tornar mais fácil corrigir vulnerabilidades descobertas na fase pós-implantação. | A atualização de contratos inteligentes nega a ideia de imutabilidade do código, o qual tem implicações sobre descentralização e segurança. | +| Os desenvolvedores podem usar atualizações lógicas para adicionar novas funcionalidades para aplicações descentralizadas. | Os usuários devem confiar nos desenvolvedores para não modificar contratos inteligentes de forma arbitrária. | +| As atualizações de contratos inteligentes podem melhorar a segurança para os usuários finais, pois os bugs podem ser corrigidos rapidamente. | A funcionalidade de atualização de programação em contratos inteligentes adiciona outra camada de complexidade e aumenta a possibilidade de falhas críticas. | +| As atualizações de contrato dá aos desenvolvedores mais liberdade para experimentar diferentes recursos e melhorar os dapps ao longo do tempo. | A oportunidade para atualizar contratos inteligentes pode encorajar os desenvolvedores a lançar projetos mais rapidamente sem fazer a devida diligência durante a fase de desenvolvimento. | +| | O controle de acesso inseguro ou a centralização em contratos inteligentes podem tornar mais fácil por atores maliciosos a execução de atualizações não autorizadas. | + +## Considerações para atualizar contratos inteligentes {#considerations-for-upgrading-smart-contracts} + +1. Use mecanismos seguros de controle/autorização de acesso para evitar atualizações não autorizadas de contratos inteligentes, especialmente ao usar padrões de proxy, padrões de estratégia ou separação de dados. Um exemplo é restringir o acesso à função de atualização, de modo que apenas o proprietário do contrato possa chamá-lo. + +2. A atualização de contratos inteligentes é uma atividade complexa e requer um alto nível de diligência para impedir a introdução de vulnerabilidades. + +3. Reduza as suposições de confiança ao descentralizar o processo de implementação de atualizações. As estratégias possíveis incluem usar um [contrato de carteira multi-sig](/developers/docs/smart-contracts/#multisig), para controlar atualizações ou exigir [membros de um DAO](/dao/) para votar na aprovação da atualização. + +4. Esteja ciente dos custos envolvidos na atualização de contratos. Por uma razão que, ao copiar o estado (por exemplo, saldos do usuário) de um contrato antigo para um novo contrato durante a migração do contrato pode exigir mais do que uma transação, o que significa mais taxas de gás. + +5. Considere implementar **bloqueios de tempo** para proteger os usuários. Um bloqueio de tempo se refere a um atraso aplicado de mudanças em um sistema. Os bloqueios de tempo podem ser combinados com um sistema de governança multi-sig para controlar as atualizações: se uma ação proposta atingir o limite de aprovação necessária, ela não será executada até que o período de atraso predefinido termine. + +Os bloqueios de tempo dão aos usuários algum tempo para sair do sistema, se eles discordarem de uma mudança proposta (por exemplo, atualização lógica ou novos esquemas de taxas). Sem bloqueios de tempo, os usuários precisam confiar nos desenvolvedores para não implementar alterações arbitrárias em um contrato inteligente sem aviso prévio. A desvantagem aqui é que os bloqueios de tempo restringem a capacidade de corrigir vulnerabilidades rapidamente. + +## Recursos {#resources} + +**Plugins de atualização do OpenZeppelin - _Um conjunto de ferramentas para implantar e proteger contratos inteligentes atualizáveis._** + +- [GitHub](https://github.com/OpenZeppelin/openzeppelin-upgrades) +- [Documentação](https://docs.openzeppelin.com/upgrades) + +## Tutoriais {#tutorials} + +- [Atualizando seus contratos inteligentes | Tutorial do YouTube](https://www.youtube.com/watch?v=bdXJmWajZRY) por Patrick Collins +- [Tutorial de migração de contrtos inteligentes Ethereum](https://medium.com/coinmonks/ethereum-smart-contract-migration-13f6f12539bd) por Austin Griffith +- [Usando o padrão de proxy UUPS para atualizar contratos inteligentes](https://blog.logrocket.com/author/praneshas/) por Pranesh A.S +- [Tutorial Web3: Escreva o contrato inteligente atualizável (proxy) usando OpenZeppelin](https://dev.to/yakult/tutorial-write-upgradeable-smart-contract-proxy-contract-with-openzeppelin-1916) por fangjun.eth + +## Leitura adicional {#further-reading} + +- [O estado das atualizações de contratos inteligentes](https://blog.openzeppelin.com/the-state-of-smart-contract-upgrades/) por Santiago Palladino +- [Várias maneiras de atualizar um contrato inteligente Solidity](https://cryptomarketpool.com/multiple-ways-to-upgrade-a-solidity-smart-contract/) - Blog do Crypto Market Pool +- [Aprenda: Atualizando contratos inteligentes](https://docs.openzeppelin.com/learn/upgrading-smart-contracts) - Documentos do OpenZeppelin +- [Padrões de proxy para capacidade de atualização de contratos Solidity: Proxies Transparentes vs UUPS](https://mirror.xyz/0xB38709B8198d147cc9Ff9C133838a044d78B064B/M7oTptQkBGXxox-tk9VJjL66E1V8BUF0GF79MMK4YG0) por Naveen Sahu +- [Como funcionam as atualizações por diamantes](https://dev.to/mudgen/how-diamond-upgrades-work-417j) de Nick Mudge diff --git a/public/content/translations/pt-br/developers/docs/smart-contracts/verifying/index.md b/public/content/translations/pt-br/developers/docs/smart-contracts/verifying/index.md new file mode 100644 index 00000000000..f1bea65fc45 --- /dev/null +++ b/public/content/translations/pt-br/developers/docs/smart-contracts/verifying/index.md @@ -0,0 +1,107 @@ +--- +title: Verificando contratos inteligentes +description: Uma visão geral da verificação do código-fonte de contratos inteligentes no Ethereum +lang: pt-br +--- + +[Contratos inteligentes](/developers/docs/smart-contracts/) são projetados para serem "sem confiança", ou seja, usuários não precisam ter que confiar em terceiros (ex. desenvolvedores e empresas) antes de interagir com um contrato. Como um requisito para a não necessidade de confiança, usuários e outros desenvolvedores precisam ser capazes de verificar o código-fonte de um contrato inteligente. A verificação do código-fonte assegura aos usuários e desenvolvedores que o código do contrato publicado é o mesmo código em execução no endereço do contrato na blockchain Ethereum. + +É importante fazer a distinção entre "verificação de código-fonte" e "[verificação formal](/developers/docs/smart-contracts/formal-verification/)". Verificação do código-fonte, que será explicada em detalhes abaixo, refere-se à verificação de que um determinado código-fonte de um contrato inteligente em uma linguagem de alto nível (ex. Solidity) compila com o mesmo bytecode a ser executado no endereço do contrato. Por outro lado, verificação formal descreve a verificação da corretude de um contrato inteligente, assegurando que o contrato se comporta como o esperado. Embora dependa do contexto, a verificação do contrato geralmente se refere à verificação do código-fonte. + +## O que é verificação do código-fonte? {#what-is-source-code-verification} + +Antes de fazer o deploy de um contrato inteligente na [Máquina Virtual do Ethereum (EVM)](/developers/docs/evm/), desenvolvedores [compilam](/developers/docs/smart-contracts/compiling/) o código-fonte do contrato —instruções [escritas em Solidity](/developers/docs/smart-contracts/languages/) ou outra linguagem de programação de alto nível— para bytecode. Como a EVM não pode interpretar instruções de alto nível, compilar o código-fonte para bytecode (ou seja, de baixo nível, instruções de máquina) é necessário para executar a lógica do contrato na EVM. + +A verificação do código-fonte é a comparação entre o código-fonte do contrato inteligente e o bytecode compilado usado durante a criação do contrato para detectar quaisquer diferenças. A verificação de contratos inteligentes é importante visto que o código do contrato anunciado pode diferir do que é executado na blockchain. + +A verificação do contrato inteligente permite investigar o que um contrato faz através da linguagem de alto nível em que é escrito, sem ter que ler código de máquina. Funções, valores, e geralmente os nomes de variáveis e comentários permanecem os mesmos do código-fonte original em que é compilado e feito o deploy. Isso torna a leitura do código muito mais fácil. A verificação da origem também incentiva a documentação do código, para que os usuários finais saibam o que um contrato inteligente é projetado para fazer. + +### O que é a verificação total? {#full-verification} + +Há algumas partes do código-fonte que não afetam o bytecode compilado, como comentários ou nomes de variáveis. Isso significa que dois códigos-fonte com diferentes nomes de variáveis e comentários conseguiriam verificar o mesmo contrato. Com isso, um ator malicioso consegue adicionar comentários enganosos ou dar nomes de variáveis enganosas dentro do código-fonte e obter o contrato verificado com um código-fonte diferente do código-fonte original. + +It is possible to avoid this by appending extra data to the bytecode to serve as a _cryptographic guarantee_ for the exactness of the source code, and as a _fingerprint_ of the compilation information. A informação necessária está disponível em [Metadados de contrato Solidity](https://docs.soliditylang.org/en/v0.8.15/metadata.html), e o hash desse arquivo é adicionado ao bytecode do contrato. Você pode conferi-lo em ação no [playground de metadados](https://playground.sourcify.dev). + +O arquivo de metadados contém informações sobre a compilação do contrato incluindo o código-fonte e seus hashes. Significa que, se alguma das configurações de compilação ou até mesmo um byte em um dos arquivos de origem mudar, o arquivo de metadados muda. Consequentemente, o hash do arquivo de metadados, o qual é anexado ao bytecode, também muda. Isso significa que se o bytecode de um contrato + seu hash de metadados correspondem ao determinado código-fonte e as configurações de compilação, nós podemos ter certeza de que é o mesmo código-fonte usando na compilação original, nem mesmo um único byte de diferença. + +Esse é tipo de verificação que se aproveita do hash é referenciado como **[verificação total](https://docs.sourcify.dev/docs/full-vs-partial-match/)** (também "verificação perfeita"). Se os hashes de metadados não coincidirem ou não forem considerados na verificação, essa seria uma "correspondência parcial", que atualmente é a maneira mais comum de se verificar contratos. É possível [inserir código malicioso](https://samczsun.com/hiding-in-plain-sight/) que não apareceria no código-fonte verificado sem a verificação total. A maioria dos desenvolvedores não está ciente da verificação completa e não mantém o arquivo de metadados de sua compilação, portanto, a verificação parcial tem sido o método de fato para verificar os contratos até agora. + +## Por que a verificação do código-fonte é importante? {#importance-of-source-code-verification} + +### Ausência de confiança {#trustlessness} + +A ausência da necessidade de confiança é provavelmente a maior premissa para contratos inteligentes e [aplicações descentralizadas (dapps)](/developers/docs/dapps/). Os contratos inteligentes são "imutáveis" e não podem ser alterados; um contrato executará apenas a lógica de negócio definida no código no momento do deploy. Isto significa que os desenvolvedores e empresas não podem manipular o código de um contrato após o deploy no Ethereum. + +Para que um contrato inteligente seja ausente de confiança, o código do contrato deve estar disponível para verificação independente. Embora o bytecode compilado de cada contrato inteligente esteja disponível publicamente na blockchain, uma linguagem de baixo nível é difícil de entender — tanto para desenvolvedores quanto para usuários. + +Projetos reduzem as suposições de confiança publicando o código-fonte de seus contratos. But this leads to another problem: it is difficult to verify that the published source code matches the contract bytecode. Nesse cenário, o valor da ausência de confiança é perdido porque os usuários precisam confiar nos desenvolvedores para não mudar a lógica de negócios de um contrato (ex. alterando o bytecode) antes do deploy na blockchain. + +As ferramentas de verificação do código-fonte fornecem garantias de que os arquivos do código-fonte do contrato inteligente correspondem ao código de montagem. O resultado é um ecossistema sem necessidade de confiança, no qual os usuários não dependem de confiar em terceiros uma vez que podem verificar o código antes de depositar fundos em um contrato. + +### Segurança do usuário {#user-safety} + +Em contratos inteligentes, geralmente há muito dinheiro envolvido. Isso pede por altas garantias de segurança e verificação da lógica de um contrato inteligente antes de usá-lo. O problema é que desenvolvedores inescrupulosos podem enganar usuários inserindo código malicioso em um contrato inteligente. Sem a verificação, contratos inteligentes maliciosos podem ter [backdoors](https://www.trustnodes.com/2018/11/10/concerns-rise-over-backdoored-smart-contracts), controversos mecanismos de controle de acesso, vulnerabilidades exploráveis, e outras coisas que comprometem a segurança dos usuários e que passariam despercebidas. + +Publicar os arquivos de código-fonte de um contrato inteligente torna mais fácil para interessados, como auditores, avaliar o contrato quanto a possíveis vetores de ataque. Com várias partes verificando independentemente o contrato inteligente, os usuários têm maiores garantias quanto à sua segurança. + +## Como verificar o código-fonte para contratos inteligentes Ethereum {#source-code-verification-for-ethereum-smart-contracts} + +[Implantar um contrato inteligente no Ethereum](/developers/docs/smart-contracts/deploying/) requer o envio de uma transação com o payload de dados (bytecode compilado) para um endereço especial. O payload de dados é gerado compilando o código-fonte, além dos [argumentos do construtor](https://docs.soliditylang.org/en/v0.8.14/contracts.html#constructor) da instância do contrato anexado aos dados do payload na transação. A compilação é determinística, o que significa que sempre produz a mesma saída (ou seja, bytecode de contrato), se os mesmos arquivos de origem e configurações de compilação (por exemplo, versão do compilador, otimizador) forem usados. + +![Um diagrama mostrando a verificação do código-fonte do contrato inteligente](./source-code-verification.png) + +A verificação de um contrato inteligente basicamente envolve os seguintes passos: + +1. Insira os arquivos de origem e as configurações de compilação em um compilador. + +2. O compilador gera o bytecode do contrato + +3. Obtenha o bytecode do contrato implantado em um dado endereço + +4. Compare o bytecode implantado com o bytecode recompilado. Se os códigos corresponderem, o contrato é verificado com o código-fonte fornecido e as configurações de compilação. + +5. Além disso, se os hashes de metadados no final do bytecode corresponderem, será uma correspondência completa. + +Note que esta é uma descrição simplista de verificação e há muitas exceções que não funcionariam com isso, como ter [variáveis imutáveis](https://docs.sourcify.dev/docs/immutables/). + +## Ferramentas de verificação de código-fonte {#source-code-verification-tools} + +O processo tradicional de verificação de contratos pode ser complexo. Isto é porque nós temos ferramentas para verificar o código-fonte para contratos inteligentes implantados no Ethereum. Estas ferramentas automatizam grandes partes da verificação de código-fonte e também selecionam contratos verificados para os benefícios dos usuários. + +### Etherscan {#etherscan} + +Embora mais conhecido como um [observador da blockchain do Ethereum](/developers/docs/data-and-analytics/block-explorers/), o Etherscan também oferece um [serviço de verificação de código-fonte](https://etherscan.io/verifyContract) para desenvolvedores e usuários de contratos inteligentes. + +O Etherscan permite que você recompile o bytecode do contrato a partir do payload de dados original (código-fonte, endereço da biblioteca, configurações do compilador, endereço do contrato, etc.) Se o bytecode recompilado está associado ao bytecode (e aos parâmetros do construtor) do contrato on-chain, então [o contrato é verificado](https://info.etherscan.com/types-of-contract-verification/). + +Uma vez verificado, o código-fonte do seu contrato recebe um rótulo "Verificado" e é publicado no Etherscan, para que outros auditem. Ele também é adicionado à seção [Contratos Verificados](https://etherscan.io/contractsVerified/) - um repositório de contratos inteligentes com códigos-fonte verificados. + +Etherscan é a ferramenta mais usada para verificação de contratos. No entanto, a verificação de contrato do Etherscan tem uma desvantagem: ele falha ao comparar o **hash de metadados** do bytecode on-chain e o bytecode recompilado. Portanto, as correspondências no Etherscan são correspondências parciais. + +[Mais sobre a verificação de contratos no Etherscan](https://medium.com/etherscan-blog/verifying-contracts-on-etherscan-f995ab772327). + +### Sourcify {#sourcify} + +[Sourcify](https://sourcify.dev/#/verifier) é outra ferramenta para verificação de contratos que é de código aberto e descentralizada. Não é um observador de blocos e apenas verifica contratos em [diferentes redes baseadas em EVM](https://docs.sourcify.dev/docs/chains). Ele atua como uma infraestrutura pública para que outras ferramentas construam sobre ele, e tem como objetivo permitir interações de contrato mais amigáveis a humanos usando o [ABI](/developers/docs/smart-contracts/compiling/#web-applications) e [NatSpec](https://docs.soliditylang.org/en/v0.8.15/natspec-format.html) encontrados no arquivo de metadados. + +Ao contrário do Etherscan, o Sourcify suporta correspondências completas com o hash de metadados. Os contratos verificados são servidos em seu [repositório público](https://docs.sourcify.dev/docs/repository/) HTTP e [IPFS](https://docs.ipfs.io/concepts/what-is-ipfs/#what-is-ipfs), que é um [armazenamento descentralizado](https://web3.storage/docs/concepts/content-addressing/) endereçado ao conteúdo. Isso permite buscar o arquivo de metadados de um contrato sobre IPFS, pois o hash de metadados incluído é um hash IPFS. + +Adicionalmente, também é possível recuperar os arquivos de código-fonte por IPFS, pois os hashes IPFS desses arquivos também são encontrados nos metadados. Um contrato pode ser verificado fornecendo o arquivo de metadados e os arquivos da origem por meio de sua API ou [UI](https://sourcify.dev/#/verifier) ou usando os plugins. A ferramenta de monitoramento Sourcify também escuta as criações de contratos em novos blocos e tenta verificar os contratos se os seus metadados e arquivos de origem são publicados no IPFS. + +[Mais sobre a verificação de contratos no Sourcify](https://blog.soliditylang.org/2020/06/25/sourcify-faq/). + +### Tenderly {#tenderly} + +A [plataforma Tenderly](https://tenderly.co/) permite desenvolvedores Web3 criem, testem, monitorem e operem contratos inteligentes. Ao combinar ferramentas de depuração com observabilidade e blocos de construção de infraestrutura, o Tenderly ajuda os desenvolvedores a acelerar o desenvolvimento de contratos inteligentes. Para habilitar totalmente os recursos do Tenderly, os desenvolvedores precisam [realizar a verificação do código-fonte](https://docs.tenderly.co/monitoring/contract-verification) usando vários métodos. + +É possível verificar um contrato de forma privada ou pública. Se verificado privadamente, o contrato inteligente ficará visível apenas para você (e outros membros do seu projeto). A verificação de um contrato publicamente o torna visível para todos que usam a plataforma Tenderly. + +Você pode verificar seus contratos usando o [Painel](https://docs.tenderly.co/monitoring/smart-contract-verification/verifying-a-smart-contract), [Plugin Tenderly da Hardhat](https://docs.tenderly.co/monitoring/smart-contract-verification/verifying-contracts-using-the-tenderly-hardhat-plugin) ou [CLI](https://docs.tenderly.co/monitoring/smart-contract-verification/verifying-contracts-using-cli). + +Ao verificar contratos através do Painel, você precisa importar o arquivo de origem ou o arquivo de metadados gerado pelo compilador Solidity, o endereço/rede e as configurações do compilador. + +O uso do plugin Tenderly da Hardhat permite mais controle sobre o processo de verificação com menos esforço, permitindo escolher entre verificação automática (sem código) e manual (baseado no código). + +## Leitura adicional {#further-reading} + +- [Verificando o código-fonte do contrato](https://programtheblockchain.com/posts/2018/01/16/verifying-contract-source-code/) diff --git a/public/content/translations/pt-br/developers/docs/transactions/gas-tx.png b/public/content/translations/pt-br/developers/docs/transactions/gas-tx.png index 0ffd5869b72..3b347370158 100644 Binary files a/public/content/translations/pt-br/developers/docs/transactions/gas-tx.png and b/public/content/translations/pt-br/developers/docs/transactions/gas-tx.png differ diff --git a/public/content/translations/pt-br/developers/docs/transactions/index.md b/public/content/translations/pt-br/developers/docs/transactions/index.md index da8aa151a31..cd6142a6138 100644 --- a/public/content/translations/pt-br/developers/docs/transactions/index.md +++ b/public/content/translations/pt-br/developers/docs/transactions/index.md @@ -1,6 +1,6 @@ --- title: Transações -description: "Uma visão geral das transações no Ethereum: como elas funcionam, sua estrutura de dados e como enviá-las através de um aplicativo." +description: 'Uma visão geral das transações no Ethereum: como elas funcionam, sua estrutura de dados e como enviá-las através de um aplicativo.' lang: pt-br --- diff --git a/public/content/translations/pt-br/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md b/public/content/translations/pt-br/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md index 588e248d0ba..c7750f6ae7d 100644 --- a/public/content/translations/pt-br/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md +++ b/public/content/translations/pt-br/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md @@ -4,16 +4,15 @@ description: Uma introdução ao desenvolvimento do Ethereum, especialmente úti author: Marc Garreau lang: pt-br tags: - - "primeiros passos" - "python" - "web3.py" skill: beginner published: 2020-09-08 -source: Snake charmers +source: O encantador de cobras sourceUrl: https://snakecharmers.ethereum.org/a-developers-guide-to-ethereum-pt-1/ --- -Você ouviu falar sobre Ethereum e agora está pronto para saber mais? Este post cobrirá rapidamente alguns conceitos básicos de blockchain e, em seguida, fará com que você interaja com um nó simulado do Ethereum – lendo dados do bloco, verificando saldos da conta e enviando transações. Em todo o caminho, vamos destacar as diferenças entre as maneiras tradicionais de desenvolver aplicativos e este novo paradigma descentralizado. +Então, você ouviu falar sobre esta coisa do Ethereum e está pronto para se aventurar no buraco do coelho? Este post cobrirá rapidamente alguns conceitos básicos de blockchain e, em seguida, fará com que você interaja com um nó simulado do Ethereum – lendo dados do bloco, verificando saldos da conta e enviando transações. Em todo o caminho, vamos destacar as diferenças entre as maneiras tradicionais de desenvolver aplicativos e este novo paradigma descentralizado. ## Pré-requisitos de software {#soft-prerequisites} @@ -21,8 +20,8 @@ Este post espera ser acessível a muitos desenvolvedores. Usaremos [ferramentas Suposições: -- você pode utilizar um terminal, -- você já escreveu algumas linhas de código Python, +- Você pode utilizar um terminal, +- Você já escreveu algumas linhas de código Python, - A versão 3.6 ou superior do Python está instalada no seu computador (uso de um [ambiente virtual](https://realpython.com/effective-python-environment/#virtual-environments) é fortemente recomendado) e - você já usou o `pip`, instalador de pacotes do Python. Novamente, se algum destes pré-requisitos não for verdadeiro, ou se você não planeja reproduzir o código apresentado neste artigo, é provável que você ainda possa acompanhar sem maiores problemas. @@ -35,7 +34,6 @@ Há muitas maneiras de descrever o Ethereum, mas no fundo é uma blockchain. As "number": 1234567, "hash": "0xabc123...", "parentHash": "0xdef456...", - "miner": "0xa1b2c3...", ..., "transactions": [...] } @@ -59,11 +57,11 @@ Esta nova pilha de tecnologia descentralizada gerou novas ferramentas de desenvo Os desenvolvedores do Python que querem interagir com o Ethereum provavelmente usem a [Web3.py](https://web3py.readthedocs.io/). Web3.py é uma biblioteca que simplifica muito a forma como você se conecta a um nó Ethereum, e depois envia e recebe dados dele. -Nota: "Nó Ethereum" e "Cliente Ethereum" são usados de forma intercambiável. Em ambos os casos, refere-se ao software que um participante da rede Ethereum executa. Este software pode ler dados de blocos, receber atualizações quando novos blocos são adicionados à cadeia ("minerado"), transmitir novas transações e muito mais. +Nota: "Nó Ethereum" e "Cliente Ethereum" são usados de forma intercambiável. Em ambos os casos, refere-se ao software que um participante da rede Ethereum executa. Este software pode ler dados de blocos, receber atualizações quando novos blocos são adicionados à cadeia, transmitir novas transações e mais. Tecnicamente, o cliente é o software, o nódulo é o computador que executa o software. [Clientes Ethereum](/developers/docs/nodes-and-clients/) podem ser configurados para serem acessíveis por [IPC](https://wikipedia.org/wiki/Inter-process_communication), HTTPS ou Websockets, então Web3. y precisará espelhar esta configuração. Web3.py refere-se a estas opções de conexão como **provedores**. Você vai querer escolher um dos três provedores para vincular a instância da Web3.py ao seu nó. -![Um diagrama que mostra como web3.py usa o IPC para conectar o seu aplicativo a um nó Ethereum](./web3py-and-nodes.png) +![Um diagrama mostrando como web3.py usa IPC para conectar seu aplicativo a um nódulo Ethereum](./web3py-and-nodes.png) _Configure o nó Ethereum e o Web3.py para se comunicarem através do mesmo protocolo, por exemplo, o IPC neste diagrama._ @@ -86,29 +84,31 @@ Neste guia, vamos trabalhar apenas com um interpretador de Python. Não criaremo Primeiro, instale [IPython](https://ipython.org/) para explorar em um ambiente amigável. IPython propõe, entre outros, um recurso de autopreenchimento com tab, o que facilita a navegação no Web3.py. ```bash -$ pip install ipython +pip install ipython ``` Web3.py é publicado sob o nome `web3`. Instale-o assim: ```bash -$ pip install web3 +pip install web3 ``` Mais uma coisa: vamos simular uma blockchain mais tarde, o que requer mais algumas dependências. Você pode instalar por meio de: ```bash -$ pip install 'web3[tester]' +pip install 'web3[tester]' ``` Você está pronto para começar! +Nota: o pacote `web3[tester]` funciona até Python 3.10.xx + ## Crie uma sandbox {#spin-up-a-sandbox} -Abra um novo ambiente Python executando o `ipython` no seu terminal. Isso é comparável a executar `python`, mas vem com mais "efeitos especiais". +Abra um novo ambiente Python executando o `ipython` no seu terminal. Isso é como executar `python`, mas vem com mais "efeitos especiais". ```bash -$ ipython +ipython ``` Isso mostrará algumas informações sobre as versões do Python e do IPython que você está executando, então você deve ver um prompt esperando por uma entrada: @@ -117,7 +117,7 @@ Isso mostrará algumas informações sobre as versões do Python e do IPython qu In [1]: ``` -Você está olhando para um shell interativo do Python agora. Essencialmente, é uma sandbox para utilizar. If you’ve made it this far, its time to import Web3.py: +Você está olhando para um shell interativo do Python agora. Essencialmente, é um ambiente de testes para brincar. Se você chegou até aqui, é hora de importar Web3.py: ```python In [1]: from web3 import Web3 @@ -127,7 +127,7 @@ In [1]: from web3 import Web3 Além de ser um gateway para Ethereum, o módulo [Web3](https://web3py.readthedocs.io/en/stable/overview.html#base-api) oferece algumas funções práticas. Vamos ver algumas. -Em um aplicativo Ethereum, você normalmente precisará converter denominações de moeda. O módulo Web3 fornece alguns métodos auxiliares só para isso: [fromWei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.fromWei) e [toWei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toWei). +Em um aplicativo Ethereum, você normalmente precisará converter denominações de moeda. O módulo web3 fornece alguns métodos auxiliares apenas para isso: [from_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.from_wei) e [to_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.to_wei). Observação: os computadores são notoriamente pouco eficazes para lidar com números decimais. Para contornar isso, os desenvolvedores costumam armazenar valores em dólares em centavos. Por exemplo, um item com preço de $5,99 pode ser armazenado no banco de dados como 599. @@ -143,10 +143,10 @@ Um padrão similar é usado ao lidar com transações em ether. No entant Tente converter alguns valores de e para wei. Note que [existem nomes para muitas das denominações](https://web3py.readthedocs.io/en/stable/examples.html#converting-currency-denominations) entre ether e wei. Um dos mais conhecidos entre eles é o **gwei**, já que é frequentemente como as taxas de transação são representadas. ```python -In [2]: Web3.toWei(1, 'ether') +In [2]: Web3.to_wei(1, 'ether') Out[2]: 1000000000000000000 -In [3]: Web3.fromWei(500000000, 'gwei') +In [3]: Web3.from_wei(500000000, 'gwei') Out[3]: Decimal('0.5') ``` @@ -175,14 +175,14 @@ O nó simulado é chamado [eth-tester](https://github.com/ethereum/eth-tester) e In [4]: w3 = Web3(Web3.EthereumTesterProvider()) ``` -Agora você está pronto para navegar pela cadeia! Isso não é algo que as pessoas falam. É algo que eu acabei de inventar. Façamos um tour rápido. +Agora você está pronto para navegar pela cadeia! Disso as pessoas não falam. É algo que eu acabei de inventar. Façamos um tour rápido. ## O tour rápido {#the-quick-tour} Primeiro, uma verificação: ```python -In [5]: w3.isConnected() +In [5]: w3.is_connected() Out[5]: True ``` @@ -201,7 +201,7 @@ Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...] ``` -Se você executar esse comando, você deverá ver uma lista de dez strings que começam com `0x`. Cada um é um **endereço público** e é, em alguns aspectos, análogo ao número da conta em uma conta corrente. Você forneceria este endereço a alguém que quisesse mandar ether para você. +Se você executar esse comando, você deverá ver uma lista de dez variáveis que começam com `0x`. Cada um é um **endereço público** e é, em alguns aspectos, análogo ao número da conta em uma conta corrente. Você forneceria este endereço a alguém que quisesse mandar ether para você. Como mencionado, o provedor de teste pré-carregou cada uma dessas contas com algum ether. Vamos descobrir quanto há na primeira conta: @@ -213,7 +213,7 @@ Out[7]: 1000000000000000000000000 São muitos zeros! Antes de você ir rindo até o banco falso, lembre-se daquela lição anterior sobre denominações de moeda. Os valores de ether são representados na menor denominação, wei. Converta para ether: ```python -In [8]: w3.fromWei(1000000000000000000000000, 'ether') +In [8]: w3.from_wei(1000000000000000000000000, 'ether') Out[8]: Decimal('1000000') ``` @@ -236,30 +236,30 @@ Out[9]: AttributeDict({ Sãp fornecidas muitas informações sobre um bloco, mas há apenas alguns pontos para salientar aqui: -- O número de bloco é zero — não importa quanto tempo você configurou o provedor de teste. Ao contrário da rede Ethereum real, que minera um novo bloco aproximadamente a cada 15 segundos, essa simulação esperará até que você a instrua a fazer alguma coisa. +- O número de bloco é zero — não importa quanto tempo você configurou o provedor de teste. Ao contrário da rede Ethereum real, que minera um novo bloco aproximadamente a cada 12 segundos, essa simulação esperará até que você a instrua a fazer alguma coisa. - `transactions` é uma lista vazia, pelo mesmo motivo: ainda não fizemos nada. Este primeiro bloco é um **bloco vazio**, apenas para iniciar a cadeia. - Observe que o `parentHash` é apenas um monte de bytes vazios. Isso significa que ele é o primeiro bloco da cadeia, também conhecido como **bloco de início**. ## Parada n.º 2 do tour: [transações](/developers/docs/transactions/) {#tour-stop-3-transactions} -Estamos presos no bloco zero até que haja uma transação para minerar, então vamos começar. Envie um teste com ether de uma conta para outra: +Estamos parados no bloco zero até que haja uma transação para minerar, então vamos começar. Envie um teste com ether de uma conta para outra: ```python In [10]: tx_hash = w3.eth.send_transaction({ 'from': w3.eth.accounts[0], 'to': w3.eth.accounts[1], - 'value': w3.toWei(3, 'ether'), + 'value': w3.to_wei(3, 'ether'), 'gas': 21000 }) ``` -Normalmente, esse é o ponto em que você espera que sua transação seja minerada em um novo bloco. O processo completo envolve algo como isto: +Esse é normalmente o ponto em que você espera (vários segundos) até que sua transação seja minerada em um novo bloco. O processo completo envolve algo como isto: -1. Envie uma transação e espere pelo hash da transação. A transação fica "pendente" até que seja minerada. `tx_hash = w3.eth.send_transaction({ … })` +1. Envie uma transação e espere pelo hash da transação. Até que o bloco que contém a transação seja criado e transmitido, a transação fica "pendente" `tx_hash = w3.eth.send_transaction({ … })` 2. Aguarde a mineração da transação: `w3.eth.wait_for_transaction_receipt(tx_hash)` 3. Continue a lógica do aplicativo. Para visualizar a transação bem-sucedida: `w3.eth.get_transaction(tx_hash)` -Nosso ambiente simulado adicionará a transação a um novo bloco instantaneamente, para que possamos ver a transação imediatamente: +Nosso ambiente simulado adicionará a transação a um novo bloco instantaneamente para que possamos ver a transação imediatamente: ```python In [11]: w3.eth.get_transaction(tx_hash) @@ -274,19 +274,21 @@ Out[11]: AttributeDict({ }) ``` -You’ll see some familiar details here: the `from`, `to`, and `value` fields should match the inputs of our `send_transaction` call. A outra parte tranquilizadora é que esta transação foi incluída como a primeira transação (`'transactionIndex': 0`) dentro do bloco número 1. +Você verá alguns detalhes familiares aqui: os campos `de`, `para` e `valor` devem corresponder às entradas da chamada `sendTransaction`. A outra parte tranquilizadora é que esta transação foi incluída como a primeira transação (`'transactionIndex': 0`) dentro do bloco número 1. Também podemos ver facilmente o sucesso dessa transação, verificando o saldo das duas contas envolvidas. Três ether deveriam ter sido enviados de uma conta para outra. ```python In [12]: w3.eth.get_balance(w3.eth.accounts[0]) -Out[12]: 999996999999999999969000 +Out[12]: 999996999979000000000000 In [13]: w3.eth.get_balance(w3.eth.accounts[1]) Out[13]: 1000003000000000000000000 ``` -O último parece bem! O saldo foi de 1.000.000 a 1.000.003 ether. Mas o que aconteceu com a primeira conta? Parece ter perdido um pouco mais de três ether. Infelizmente, nada na vida é gratuito, e o uso da rede pública Ethereum requer que você compense os seus pares pelo papel de apoio deles. A small transaction fee was deducted from the account making the transaction to the tune of 31000 wei. +O último parece bem! O saldo foi de 1.000.000 a 1.000.003 ether. Mas o que aconteceu com a primeira conta? Parece ter perdido um pouco mais que três ether. Infelizmente, nada na vida é gratuito, e o uso da rede pública Ethereum requer que você compense os seus pares pelo papel de apoio deles. Uma pequena taxa de transação foi deduzida da conta que submeteu a transação - esta taxa é a quantidade de gás queimado (21000 unidades de gás para uma transferência ETH) multiplicado por uma taxa base, que varia de acordo com a atividade da rede, mais a gorjeta que vai para o validador que inclui a transação em um bloco. + +Mais sobre [gás](/developers/docs/gas/#post-london) Observação: na rede pública, as taxas de transação são variáveis baseadas na demanda da rede e na rapidez com que você gostaria que uma transação fosse processada. Se você estiver interessado em ver como as taxas são calculadas, veja minha publicação anterior sobre como transações são incluídas em um bloco. diff --git a/public/content/translations/pt-br/developers/tutorials/all-you-can-cache/index.md b/public/content/translations/pt-br/developers/tutorials/all-you-can-cache/index.md new file mode 100644 index 00000000000..7a99bcf4de1 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/all-you-can-cache/index.md @@ -0,0 +1,867 @@ +--- +title: "Tudo que você puder armazenar em cache" +description: Aprenda como criar e usar um contrato de cache para transações de roll-up mais baratas +author: Ori Pomerantz +tags: + - "camada 2" + - "armazenamento em cache" + - "armazenamento" +skill: intermediate +published: 2022-09-15 +lang: pt-br +--- + +Ao usar roll-ups, o custo de um byte na transação é muito mais caro que o custo de um slot de armazenamento. Portanto, faz sentido armazenar em cache o máximo de informações possível na cadeia. + +Neste artigo, você aprenderá como criar e usar um contrato de armazenamento em cache de forma que qualquer valor de parâmetro, provável de ser usado diversas vezes, será armazenado em cache e ficará disponível para uso (depois da primeira vez) com um número muito menor de bytes, e como escrever código off-chain para usar esse cache. + +Se você quiser pular o artigo e somente ver o código-fonte, [consulte-o aqui](https://github.com/qbzzt/20220915-all-you-can-cache). A pilha de desenvolvimento é [Foundry](https://book.getfoundry.sh/getting-started/installation). + +## Design Geral {#overall-design} + +Para fins de simplicidade, vamos supor que todos os parâmetros de transação são `uint256`, com 32 bytes de tamanho. Quando recebemos uma transação, fazemos o parse em cada parâmetro deste modo: + +1. Se o primeiro byte for `0xFF`, pegue os 32 bytes seguintes como um valor de parâmetro e escreva-o no cache. + +2. Se o primeiro byte for `0xFE`, pegue os próximos 32 bytes como um valor de parâmetro, mas _não_ o escreva no cache. + +3. Para qualquer outro valor, pegue os primeiros quatro bits como o número de bytes adicionais, e os últimos quatro bits como os bits mais significantes da chave do cache. Veja aqui alguns exemplos: + + | Bytes em calldata | Chave da cache | + |:----------------- | --------------:| + | 0x0F | 0x0F | + | 0x10,0x10 | 0x10 | + | 0x12,0xAC | 0x02AC | + | 0x2D,0xEA, 0xD6 | 0x0DEAD6 | + +## Manipulação do cache {#cache-manipulation} + +A cache é implementada em [`Cache.sol`](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol). Vamos passar por ele linha a linha. + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + + +contract Cache { + + bytes1 public constant INTO_CACHE = 0xFF; + bytes1 public constant DONT_CACHE = 0xFE; +``` + +Essas constantes são usadas para interpretar os casos especiais nos quais fornecemos todas as informações, independentemente de as querermos escritas no cache ou não. Escrever no cache requer duas operações [`SSTORE`](https://www.evm.codes/#55) nos slots de armazenamento previamente não utilizados, ao custo de 22.100 gás cada. Portanto, deixamos isso opcional. + +```solidity + + mapping(uint => uint) public val2key; +``` + +Um [mapeamento](https://www.geeksforgeeks.org/solidity-mappings/) entre os valores e suas chaves. Esta informação é necessária para codificar valores antes de você enviar a transação. + +```solidity + // Location n has the value for key n+1, because we need to preserve + // zero as "not in the cache". + uint[] public key2val; +``` + +Podemos usar uma matriz para mapear das chaves aos valores, pois atribuímos as chaves e, para simplificar, fazemos isso de modo sequencial. + +```solidity + function cacheRead(uint _key) public view returns (uint) { + require(_key <= key2val.length, "Reading uninitialize cache entry"); + return key2val[_key-1]; + } // cacheRead +``` + +Ler um valor da cache. + +```solidity + // Write a value to the cache if it's not there already + // Only public to enable the test to work + function cacheWrite(uint _value) public returns (uint) { + // If the value is already in the cache, return the current key + if (val2key[_value] != 0) { + return val2key[_value]; + } +``` + +Não faz sentido colocar o mesmo valor no cache mais de uma vez. Se o valor já está lá, apenas retorne a chave existente. + +```solidity + // Since 0xFE is a special case, the largest key the cache can + // hold is 0x0D followed by 15 0xFF's. If the cache length is already that + // large, fail. + // 1 2 3 4 5 6 7 8 9 A B C D E F + require(key2val.length+1 < 0x0DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + "cache overflow"); +``` + +Não acho que iremos algum dia ter um cache tão grande (cerca de 1,8\*1037 entradas, o que exigiria cerca de 1027 TB de armazenamento). No entanto, eu sou velho o suficiente para lembrar que ["640kB sempre será o suficiente"](https://quoteinvestigator.com/2011/09/08/640k-enough/). Este teste é muito barato. + +```solidity + // Write the value using the next key + val2key[_value] = key2val.length+1; +``` + +Adicione a busca reversa (do valor para a chave). + +```solidity + key2val.push(_value); +``` + +Adicione a busca para frente (da chave para o valor). Como atribuímos valores de modo sequencial, podemos apenas adicioná-los depois do último valor da matriz. + +```solidity + return key2val.length; + } // cacheWrite +``` + +Retorne o novo tamanho de `key2val`, que é a célula onde o novo valor está armazenado. + +```solidity + function _calldataVal(uint startByte, uint length) + private pure returns (uint) +``` + +Essa função lê um valor de calldata de tamanho arbitrário (até 32 bytes, o tamanho da palavra). + +```solidity + { + uint _retVal; + + require(length < 0x21, + "_calldataVal length limit is 32 bytes"); + require(length + startByte <= msg.data.length, + "_calldataVal trying to read beyond calldatasize"); +``` + +A função é interna, por isso, se o resto do código for escrito corretamente, esses testes não serão obrigatórios. Porém, como eles não custam muito, podemos tê-los de qualquer forma. + +```solidity + assembly { + _retVal := calldataload(startByte) + } +``` + +Este código está em [Yul](https://docs.soliditylang.org/en/v0.8.16/yul.html). Ele lê um valor de 32 bytes do calldata. Isso funciona até mesmo se o calldata parar antes `startByte+32`, pois o espaço não inicializado na EVM é considerado como zero. + +```solidity + _retVal = _retVal >> (256-length*8); +``` + +Não queremos necessariamente um valor de 32 bytes. Isso elimina os bytes em excesso. + +```solidity + return _retVal; + } // _calldataVal + + + // Read a single parameter from the calldata, starting at _fromByte + function _readParam(uint _fromByte) internal + returns (uint _nextByte, uint _parameterValue) + { +``` + +Leia um único parâmetro do calldata. Observe que precisamos retornar não somente o valor que lemos, mas também a localização do próximo byte, pois os parâmetros podem estar na faixa de comprimento de 1 byte a 33 bytes. + +```solidity + // The first byte tells us how to interpret the rest + uint8 _firstByte; + + _firstByte = uint8(_calldataVal(_fromByte, 1)); +``` + +O Solidity tenta reduzir o número de bugs proibindo [conversões de tipo implícitas](https://docs.soliditylang.org/en/v0.8.16/types.html#implicit-conversions) potencialmente perigosas. Um rebaixamento, por exemplo, de 256 bits para 8 bits, precisa ser explícito. + +```solidity + + // Read the value, but do not write it to the cache + if (_firstByte == uint8(DONT_CACHE)) + return(_fromByte+33, _calldataVal(_fromByte+1, 32)); + + // Read the value, and write it to the cache + if (_firstByte == uint8(INTO_CACHE)) { + uint _param = _calldataVal(_fromByte+1, 32); + cacheWrite(_param); + return(_fromByte+33, _param); + } + + // If we got here it means that we need to read from the cache + + // Number of extra bytes to read + uint8 _extraBytes = _firstByte / 16; +``` + +Pegue o [nibble](https://en.wikipedia.org/wiki/Nibble) inferior e combine-o com os outros bytes para ler o valor do cache. + +```solidity + uint _key = (uint256(_firstByte & 0x0F) << (8*_extraBytes)) + + _calldataVal(_fromByte+1, _extraBytes); + + return (_fromByte+_extraBytes+1, cacheRead(_key)); + + } // _readParam + + + // Read n parameters (functions know how many parameters they expect) + function _readParams(uint _paramNum) internal returns (uint[] memory) { +``` + +Poderíamos pegar o número de parâmetros que temos do calldata propriamente dito, mas as funções que nos chamam sabem quantos parâmetros elas esperam. É mais fácil que elas nos contem. + +```solidity + // The parameters we read + uint[] memory params = new uint[](_paramNum); + + // Parameters start at byte 4, before that it's the function signature + uint _atByte = 4; + + for(uint i=0; i<_paramNum; i++) { + (_atByte, params[i]) = _readParam(_atByte); + } +``` + +Leia os parâmetros até que você tenha o número de que precisa. Se ultrapassarmos o fim do calldata, `_readParams` reverterá a chamada. + +```solidity + + return(params); + } // readParams + + // For testing _readParams, test reading four parameters + function fourParam() public + returns (uint256,uint256,uint256,uint256) + { + uint[] memory params; + params = _readParams(4); + return (params[0], params[1], params[2], params[3]); + } // fourParam +``` + +Uma grande vantagem do Foundry é que ele permite que os testes sejam escritos no Solidity ([veja o teste de cache abaixo](#testing-the-cache)). Isto faz testes unitários muito mais fáceis. Essa é uma função que lê quatro parâmetros e retorna-os para que o teste possa verificar que eles estão corretos. + +```solidity + // Get a value, return bytes that will encode it (using the cache if possible) + function encodeVal(uint _val) public view returns(bytes memory) { +``` + +`encodeVal` é uma função que o código off-chain chama para ajudar a criar o calldata que usa o cache. Ela recebe um único valor e retorna os bytes que o codificam. Essa função é uma `view`, portanto, ela não requer uma transação e, quando chamada externamente, não custa nenhum gás. + +```solidity + uint _key = val2key[_val]; + + // The value isn't in the cache yet, add it + if (_key == 0) + return bytes.concat(INTO_CACHE, bytes32(_val)); +``` + +Na [EVM](/developers/docs/evm/) todo o armazenamento não inicializado é considerado como zero. Então, se buscarmos a chave de um valor que não está lá, obteremos zero. Nesse caso, os bytes que o codificaram são `INTO_CACHE` (portanto, ele será armazenado em cache da próxima vez), seguido do valor real. + +```solidity + // If the key is <0x10, return it as a single byte + if (_key < 0x10) + return bytes.concat(bytes1(uint8(_key))); +``` + +Bytes únicos são os mais fáceis. Somente usamos [`bytes.concat`](https://docs.soliditylang.org/en/v0.8.16/types.html#the-functions-bytes-concat-and-string-concat) para transformar um tipo de `bytes` em uma matriz de bytes que pode ser de qualquer tamanho. Apesar do nome, isso funciona bem quando fornecemos somente um argumento. + +```solidity + // Two byte value, encoded as 0x1vvv + if (_key < 0x1000) + return bytes.concat(bytes2(uint16(_key) | 0x1000)); +``` + +Quando temos uma chave que é inferior a 163, podemos expressá-la em dois bytes. Primeiro, convertemos `_key`, que é um valor de 256 bits, para um valor de 16 bits e usamos um cálculo lógico para adicionar o número de bytes extras ao primeiro byte. Então, convertemos o byte em um valor `bytes2`, que pode ser convertido para `bytes`. + +```solidity + // There is probably a clever way to do the following lines as a loop, + // but it's a view function so I'm optimizing for programmer time and + // simplicity. + + if (_key < 16*256**2) + return bytes.concat(bytes3(uint24(_key) | (0x2 * 16 * 256**2))); + if (_key < 16*256**3) + return bytes.concat(bytes4(uint32(_key) | (0x3 * 16 * 256**3))); + . + . + . + if (_key < 16*256**14) + return bytes.concat(bytes15(uint120(_key) | (0xE * 16 * 256**14))); + if (_key < 16*256**15) + return bytes.concat(bytes16(uint128(_key) | (0xF * 16 * 256**15))); +``` + +Os outros valores (3 bytes, 4 bytes, etc.) são manipulados da mesma maneira, apenas com diferentes tamanhos de campo. + +```solidity + // If we get here, something is wrong. + revert("Error in encodeVal, should not happen"); +``` + +Se chegarmos até aí, significa que temos a chave que não é inferior a 16\*25615. Porém, `cacheWrite` limita as chaves, portanto, não conseguimos nem mesmo chegar a 14\*25616 (o que teria o primeiro byte de 0xFE, que se pareceria com `DONT_CACHE`). Mas ele não nos custa tanto para adicionar um teste caso um futuro programador introduza um bug. + +```solidity + } // encodeVal + +} // Cache +``` + +### Testando o cache {#testing-the-cache} + +Uma das vantagens do Foundry é que [ele deixa você escrever testes em Solidity](https://book.getfoundry.sh/forge/tests), o que facilita escrever testes de unidade. Os testes para a classe `Cache` estão [aqui](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/Cache.t.sol). Como o código de teste pode ser repetitivo, assim como os testes tendem a ser, este artigo explica apenas as partes interessantes. + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Test.sol"; + + +// Need to run `forge test -vv` for the console. +import "forge-std/console.sol"; +``` + +Isso é apenas um modelo necessário para usar o pacote de teste e `console.log`. + +```solidity +import "src/Cache.sol"; +``` + +Precisamos conhecer o contrato que estamos testando. + +```solidity +contract CacheTest is Test { + Cache cache; + + function setUp() public { + cache = new Cache(); + } +``` + +A função `setUp` é chamada antes de cada teste. Nesse caso, acabamos de criar um novo cache, de modo que nossos testes não sejam afetados um pelo outro. + +```solidity + function testCaching() public { +``` + +Testes são funções cujos nomes começam com `test`. Essa função verifica a funcionalidade básica do cache, escrevendo valores e lendo-os novamente. + +```solidity + for(uint i=1; i<5000; i++) { + cache.cacheWrite(i*i); + } + + for(uint i=1; i<5000; i++) { + assertEq(cache.cacheRead(i), i*i); +``` + +Isto é como você faz teste realmente, usando as funções [`assert...`](https://book.getfoundry.sh/reference/forge-std/std-assertions). Nesse caso, nós verificamos que o valor que escrevemos é o mesmo que lemos. Podemos descartar o resultado de `cache.cacheWrite`, pois sabemos que as chaves do cache são atribuídos linearmente. + +```solidity + } + } // testCaching + + + // Cache the same value multiple times, ensure that the key stays + // the same + function testRepeatCaching() public { + for(uint i=1; i<100; i++) { + uint _key1 = cache.cacheWrite(i); + uint _key2 = cache.cacheWrite(i); + assertEq(_key1, _key2); + } +``` + +Primeiro, escrevemos cada valor duas vezes para o cache e nos certificamos de que as chaves são as mesmas (ou seja, a segunda escrita não aconteceu realmente). + +```solidity + for(uint i=1; i<100; i+=3) { + uint _key = cache.cacheWrite(i); + assertEq(_key, i); + } + } // testRepeatCaching +``` + +Na teoria poderia haver um bug que não afetasse escritas em cache consecutivas. Então, fazemos aqui algumas escritas que não sejam consecutivas e observamos que os valores ainda não foram reescritos. + +```solidity + // Read a uint from a memory buffer (to make sure we get back the parameters + // we sent out) + function toUint256(bytes memory _bytes, uint256 _start) internal pure + returns (uint256) +``` + +Leia uma palavra de 256 bits de um buffer de `bytes memory`. Essa função utilitária nos deixa verificar que recebemos os resultados corretos quando executamos uma chamada de função que usa o cache. + +```solidity + { + require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); + uint256 tempUint; + + assembly { + tempUint := mload(add(add(_bytes, 0x20), _start)) + } +``` + +O Yul não suporta estruturas de dados além de `uint256`, então quando você se refere a uma estrutura de dados mais sofisticada, como um buffer de memória `_bytes`, você obtém o endereço dessa estrutura. O Solidity armazena valores `bytes memory` como uma palavra de 32 bytes que contém o tamanho, seguida dos bytes reais, então, para obter o número de bytes `_start`, precisamos calcular `_bytes+32+_start`. + +```solidity + + return tempUint; + } // toUint256 + + // Function signature for fourParams(), courtesy of + // https://www.4byte.directory/signatures/?bytes4_signature=0x3edc1e6d + bytes4 constant FOUR_PARAMS = 0x3edc1e6d; + + // Just some constant values to see we're getting the correct values back + uint256 constant VAL_A = 0xDEAD60A7; + uint256 constant VAL_B = 0xBEEF; + uint256 constant VAL_C = 0x600D; + uint256 constant VAL_D = 0x600D60A7; +``` + +Algumas constantes de que precisamos para os testes. + +```solidity + function testReadParam() public { +``` + +Chame `fourParams()`, uma função que usa `readParams`, para testar nós podemos ler parâmetros corretamente. + +```solidity + address _cacheAddr = address(cache); + bool _success; + bytes memory _callInput; + bytes memory _callOutput; +``` + +Não podemos usar o mecanismo de ABI normal para chamar uma função usando o cache, por isso, precisamos usar o mecanismo de baixo nível [`
      .call()`](https://docs.soliditylang.org/en/v0.8.16/types.html#members-of-addresses). Esse mecanismo pega um `bytes memory` como entrada e retorna aquele (assim como o valor booleano) como saída. + +```solidity + // First call, the cache is empty + _callInput = bytes.concat( + FOUR_PARAMS, +``` + +É útil para o mesmo contrato suportar ambas funções em cache (para chamadas diretamente de transações) e funções não em cache (para chamadas de outros contratos inteligentes). Para fazer isso nós precisamos continuar a confiar no mecanismo Solidity para chamar a função correta, ao invés de pôr tudo em [uma função `fallback`](https://docs.soliditylang.org/en/v0.8.16/contracts.html#fallback-function). Fazer isso torna a componibilidade muito mais fácil. Um único byte seria suficiente para identificar a função na maioria dos casos, por isso, estamos desperdiçando três bytes (16\*3=48 gás). No entanto, no momento em que escrevo este artigo, 48 gás custam 0,07 centavos de dólar, o que é um custo razoável para um código mais simples e menos sujeito a bugs. + +```solidity + // First value, add it to the cache + cache.INTO_CACHE(), + bytes32(VAL_A), +``` + +O primeiro valor: Um sinalizador dizendo que é um valor que precisa ser escrito na cache, seguido pelos 32 bytes do valor. Os outros três valores são similares, exceto que `VAL_B` não é escrito no cache e `VAL_C` é ambos o terceiro e quarto parâmetros. + +```solidity + . + . + . + ); + (_success, _callOutput) = _cacheAddr.call(_callInput); +``` + +É aqui que realmente chamamos o contrato `Cache`. + +```solidity + assertEq(_success, true); +``` + +Nós esperamos que a chamada tenha sucesso. + +```solidity + assertEq(cache.cacheRead(1), VAL_A); + assertEq(cache.cacheRead(2), VAL_C); +``` + +Nós começamos com uma cache vazia e então adicionamos `VAL_A` seguida de `VAL_C`. Nós esperaríamos a primeira ter a chave 1, e a segunda ter a 2. + +``` + assertEq(toUint256(_callOutput,0), VAL_A); + assertEq(toUint256(_callOutput,32), VAL_B); + assertEq(toUint256(_callOutput,64), VAL_C); + assertEq(toUint256(_callOutput,96), VAL_C); +``` + +A saída é composta pelos quatro parâmetros. Aqui, verificamos que está correto. + +```solidity + // Second call, we can use the cache + _callInput = bytes.concat( + FOUR_PARAMS, + + // First value in the Cache + bytes1(0x01), +``` + +As chaves de cache abaixo de 16 correspondem a apenas um byte. + +```solidity + // Second value, don't add it to the cache + cache.DONT_CACHE(), + bytes32(VAL_B), + + // Third and fourth values, same value + bytes1(0x02), + bytes1(0x02) + ); + . + . + . + } // testReadParam +``` + +Os testes depois da chamada são idênticos a aqueles depois da primeira chamada. + +```solidity + function testEncodeVal() public { +``` + +Esta função é similar a `testReadParam`, exceto que ao invés de escrever os parâmetros explicitamente, nós usamos `encodeVal()`. + +```solidity + . + . + . + _callInput = bytes.concat( + FOUR_PARAMS, + cache.encodeVal(VAL_A), + cache.encodeVal(VAL_B), + cache.encodeVal(VAL_C), + cache.encodeVal(VAL_D) + ); + . + . + . + assertEq(_callInput.length, 4+1*4); + } // testEncodeVal +``` + +O único teste adicional em `testEncodeVal()` é verificar que o comprimento de `_callInput` está correto. Para a primeira chamada, ele é 4+33\*4. Para a segunda, na qual cada valor já está no cache, ele é 4+1\*4. + +```solidity + // Test encodeVal when the key is more than a single byte + // Maximum three bytes because filling the cache to four bytes takes + // too long. + function testEncodeValBig() public { + // Put a number of values in the cache. + // To keep things simple, use key n for value n. + for(uint i=1; i<0x1FFF; i++) { + cache.cacheWrite(i); + } +``` + +A função `testEncodeVal` acima somente escreve quatro valores na cache, então [a parte da função que lida com valores multi-byte](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol#L144-L171) não é checada. Porém, esse código é complicado e sujeito a erros. + +A primeira parte dessa função é um loop que escreve todos os valores de 1 até 0x1FFF para o cache em ordem, a fim de podermos codificar esses valores e saber para onde eles estão indo. + +```solidity + . + . + . + + _callInput = bytes.concat( + FOUR_PARAMS, + cache.encodeVal(0x000F), // One byte 0x0F + cache.encodeVal(0x0010), // Two bytes 0x1010 + cache.encodeVal(0x0100), // Two bytes 0x1100 + cache.encodeVal(0x1000) // Three bytes 0x201000 + ); +``` + +Teste valores de um byte, dois bytes e três bytes. Não testamos além disso, pois levaria tempo demais para escrever entradas de pilha suficientes (pelo menos 0x10000000, cerca de um quarto de bilhão). + +```solidity + . + . + . + . + } // testEncodeValBig + + + // Test what with an excessively small buffer we get a revert + function testShortCalldata() public { +``` + +Teste o que acontece no caso anormal em que não há parâmetros suficientes. + +```solidity + . + . + . + (_success, _callOutput) = _cacheAddr.call(_callInput); + assertEq(_success, false); + } // testShortCalldata +``` + +Como ele é revertido, o resultado deve ser `false`. + +``` + // Call with cache keys that aren't there + function testNoCacheKey() public { + . + . + . + _callInput = bytes.concat( + FOUR_PARAMS, + + // First value, add it to the cache + cache.INTO_CACHE(), + bytes32(VAL_A), + + // Second value + bytes1(0x0F), + bytes2(0x1234), + bytes11(0xA10102030405060708090A) + ); +``` + +Esta função pega quatro parâmetros perfeitamente legítimos, exceto que a cache está vazia, então não há valores lá para ler. + +```solidity + . + . + . + // Test what with an excessively long buffer everything works file + function testLongCalldata() public { + address _cacheAddr = address(cache); + bool _success; + bytes memory _callInput; + bytes memory _callOutput; + + // First call, the cache is empty + _callInput = bytes.concat( + FOUR_PARAMS, + + // First value, add it to the cache + cache.INTO_CACHE(), bytes32(VAL_A), + + // Second value, add it to the cache + cache.INTO_CACHE(), bytes32(VAL_B), + + // Third value, add it to the cache + cache.INTO_CACHE(), bytes32(VAL_C), + + // Fourth value, add it to the cache + cache.INTO_CACHE(), bytes32(VAL_D), + + // And another value for "good luck" + bytes4(0x31112233) + ); +``` + +Esta função envia cinco valores. Sabemos que o quinto valor é ignorado porque não é uma entrada de cache válida, o que causaria uma reversão se não tivesse sido incluída. + +```solidity + (_success, _callOutput) = _cacheAddr.call(_callInput); + assertEq(_success, true); + . + . + . + } // testLongCalldata + +} // CacheTest + +``` + +## Uma amostra do aplicativo {#a-sample-app} + +Escrever testes em Solidity é tudo muito bem, mas no final do dia, um dapp precisa ser capaz de processar requisições de fora da cadeia para ser útil. Este artigo demonstra como usar o cache em um dapp com `WORM`, que significa “escrever uma vez, ler várias” (em inglês, "Write Once, Read Many"). Se uma chave ainda não estiver escrita, você pode escrever um valor para ela. Se a chave já estiver escrita, você terá uma reversão. + +### O contrato {#the-contract} + +[Este é o contrato](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/WORM.sol). Ele repete, em grande parte, o que já fizemos com `Cache` e `CacheTest`, então abrangeremos somente as partes que são interessantes. + +```solidity +import "./Cache.sol"; + +contract WORM is Cache { +``` + +A maneira mais fácil de usar `Cache` é herdá-lo no seu próprio contrato. + +```solidity + function writeEntryCached() external { + uint[] memory params = _readParams(2); + writeEntry(params[0], params[1]); + } // writeEntryCached +``` + +Essa função é similar a `fourParam` no `CacheTest` acima. Como nós não seguimos as especificações da ABI, é melhor não declarar nenhum parâmetro dentro da função. + +```solidity + // Make it easier to call us + // Function signature for writeEntryCached(), courtesy of + // https://www.4byte.directory/signatures/?bytes4_signature=0xe4e4f2d3 + bytes4 constant public WRITE_ENTRY_CACHED = 0xe4e4f2d3; +``` + +O código externo que chama `writeEntryCached` precisará construir manualmente o calldata, ao invés de usar `worm.writeEntryCached`, porque nós não seguimos as especificações da ABI. Tendo o valor desta constante só facilita escrevê-la. + +Observe que, apesar de definirmos `WRITE_ENTRY_CACHED` como uma variável de estado, para lê-la externamente é necessário usar a função getter, `worm.WRITE_ENTRY_CACHED()`. + +```solidity + function readEntry(uint key) public view + returns (uint _value, address _writtenBy, uint _writtenAtBlock) +``` + +A função de leitura é uma `view`, então ela não requer uma transação e não custa gas. Como resultado, não há benefício de usar cache para o parâmetro. Com funções view é melhor usar o mecanismo padrão, que é mais simples. + +### O código de teste {#the-testing-code} + +[Este é o código de teste para o contrato](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/WORM.t.sol). Novamente, vamos ver somente o que é interessante. + +```solidity + function testWReadWrite() public { + worm.writeEntry(0xDEAD, 0x60A7); + + vm.expectRevert(bytes("entry already written")); + worm.writeEntry(0xDEAD, 0xBEEF); +``` + +[Este (`vm.expectRevert`)](https://book.getfoundry.sh/cheatcodes/expect-revert#expectrevert) é como especificamos em um teste Foundry que a próxima chamada deve falhar, assim como a razão dessa falha. Isto se aplica quando nós usamos a sintaxe `.()` ao invés de construir o calldata e chamar o contrato usando interface de baixo nível (`.call()`, etc.). + +```solidity + function testReadWriteCached() public { + uint cacheGoat = worm.cacheWrite(0x60A7); +``` + +Aqui nós usamos o fato de `cacheWrite` retornar a chave da cache. Isto não é algo que nós esperaríamos usar em produção, porque `cacheWrite` altera o estado, e por isso pode ser chamado apenas durante a transação. Transações não têm valores de retorno. Se elas têm resultados, esses resultados devem ser supostamente emitidos como eventos. Assim, o valor de retorno de `cacheWrite` é somente acessível do código on-chain, e o código on-chain não precisa armazenar parâmetros em cache. + +```solidity + (_success,) = address(worm).call(_callInput); +``` + +É assim que contamos ao Solidity que, enquanto `.call()` tem dois valores de retorno, só nos importamos com o primeiro. + +```solidity + (_success,) = address(worm).call(_callInput); + assertEq(_success, false); +``` + +Como usamos a função de baixo nível `
      .call()`, não podemos usar `vm.expectRevert()` e temos de olhar para o valor de êxito booleano que obtivemos da chamada. + +```solidity + event EntryWritten(uint indexed key, uint indexed value); + + . + . + . + + _callInput = bytes.concat( + worm.WRITE_ENTRY_CACHED(), worm.encodeVal(a), worm.encodeVal(b)); + vm.expectEmit(true, true, false, false); + emit EntryWritten(a, b); + (_success,) = address(worm).call(_callInput); +``` + +Essa é a maneira que verificamos que o código [emite um evento corretamente](https://book.getfoundry.sh/cheatcodes/expect-emit) no Foundry. + +### O cliente {#the-client} + +Uma coisa que você não obtém com testes no Solidity é código JavaScript, que você pode cortar e colar no seu próprio aplicativo. Para escrever este código, implantei WORM na [Optimism Goerli](https://community.optimism.io/docs/useful-tools/networks/#optimism-goerli), a nova rede de teste da [Optimism](https://www.optimism.io/). Ela está no endereço [`0xd34335b1d818cee54e3323d3246bd31d94e6a78a`](https://goerli-optimism.etherscan.io/address/0xd34335b1d818cee54e3323d3246bd31d94e6a78a). + +[Você pode ver o código JavaScript para o cliente aqui](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/javascript/index.js). Para usá-lo: + +1. Clone o repositório git: + + ```sh + git clone https://github.com/qbzzt/20220915-all-you-can-cache.git + ``` + +2. Instale os pacotes necessários: + + ```sh + cd javascript + yarn + ``` + +3. Copie o arquivo de configuração: + + ```sh + cp .env.example .env + ``` + +4. Edite `.env` para a sua configuração: + + | Parâmetro | Valor | + | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | MNEMÔNICO | O mnemônico para uma conta que tem ETH suficiente para pagar por uma transação. [Você consegue ETH grátis para a rede Optimism Goerli aqui](https://optimismfaucet.xyz/). | + | OPTIMISM_GOERLI_URL | URL da Optimism Goerli. O endpoint público, `https://goerli.optimism.io`, tem taxa limitada mas suficiente para o que precisamos aqui | + +5. Rode `index.js`. + + ```sh + node index.js + ``` + + Primeiro, esse exemplo de aplicativo escreve uma entrada para WORM, exibindo o calldata e um link para a transação no Etherscan. Em seguida, ele lê novamente essa entrada e exibe a chave que usou e os valores na entrada (valor, bloco, número e autor). + +A maioria dos clientes é Javascript Dapp normal. Então, novamente, passaremos apenas pelas partes interessantes. + +```javascript +. +. +. +const main = async () => { + const func = await worm.WRITE_ENTRY_CACHED() + + // Need a new key every time + const key = await worm.encodeVal(Number(new Date())) +``` + +Um dado slot pode ser apenas escrito uma vez, então usamos o carimbo de data/hora para ter certeza de que não vamos reutilizar esses slots. + +```javascript +const val = await worm.encodeVal("0x600D") + +// Write an entry +const calldata = func + key.slice(2) + val.slice(2) +``` + +Ethers espera que o dado da chamada seja uma cadeia de caracteres hexadecimal, `0x` seguida de um número par de dígitos hexadecimais. Como `key` e `val` começam com `0x`, precisamos remover esses cabeçalhos. + +```javascript +const tx = await worm.populateTransaction.writeEntryCached() +tx.data = calldata + +sentTx = await wallet.sendTransaction(tx) +``` + +Como no código de teste Solidity, não podemos chamar uma função em cache normalmente. Ao invés disso, nós precisamos usar um mecanismo de nível mais baixo. + +```javascript + . + . + . + // Read the entry just written + const realKey = '0x' + key.slice(4) // remove the FF flag + const entryRead = await worm.readEntry(realKey) + . + . + . +``` + +Para ler entradas, podemos usar o mecanismo normal. Não há necessidade de armazenar em cache parâmetros com funções `view`. + +## Conclusão {#conclusion} + +O código neste artigo é uma prova de conceito, a finalidade é tornar a ideia fácil de entender. Para um sistema pronto para produção, recomenda-se implementar funcionalidades adicionais: + +- Manipular valores que não são `uint256`. Por exemplo, cadeias de caracteres. +- Em vez de um cache global, talvez ter um mapeamento entre usuários e caches. Usuários diferentes usam valores diferentes. +- Valores usados para endereços são distintos daqueles usados para outras finalidades. Pode fazer sentido ter um cache separado só para endereços. +- Atualmente, as chaves de cache estão em um algoritmo do tipo “o primeiro que chega tem a chave menor”. Os primeiros dezesseis valores podem ser enviados como um único byte. Os próximos 4.080 valores podem ser enviados como dois bytes. Os próximos milhões de valores são três bytes, etc. Um sistema de produção deveria manter contadores de uso nas entradas de cache e reorganizá-las para que os dezesseis _mais comuns_ valores sejam um byte, os próximos 4080 valores mais comuns sejam dois bytes, etc. + + No entanto, essa é uma operação potencialmente perigosa. Imagine a seguinte sequência de eventos: + + 1. Noam Naive chama `encodeVal` para codificar o endereço para o qual ele quer enviar tokens. Este endereço é um dos primeiros usados na aplicação, então o valor codificado é 0x06. Trata-se de uma função `view`, e não uma transação, então ela diz respeito unicamente a Noam e ao nó que ele usa, e ninguém mais sabe disso + + 2. Owen Owner executa a operação de reordenação de cache. Muito poucas pessoas realmente usam esse endereço, por isso, ele é agora codificado como 0x201122. Para um valor diferente, 1018, é atribuído 0x06. + + 3. Noam Naive envia seus tokens para 0x06. Eles vão para o endereço `0x0000000000000000000000000de0b6b3a7640000`, e já que ninguém sabe a chave privada para esse endereço, eles ficam presos lá. Noam _não está contente_. + + Existem maneiras de resolver esse problema, e o problema relacionado às transações que estão na mempool durante a reordenação do cache, mas você deve estar atento a isso. + +Demonstrei o processo de armazenamento em cache aqui com o Optimism, porque sou funcionário da Optimism e esse é o roll-up que conheço melhor. Mas deve funcionar com qualquer rollup que cobre um mínimo custo por processamento interno, de modo que em comparação com escrever os dados da transação na L1 é a maior despesa. diff --git a/public/content/translations/pt-br/developers/tutorials/create-and-deploy-a-defi-app/index.md b/public/content/translations/pt-br/developers/tutorials/create-and-deploy-a-defi-app/index.md new file mode 100644 index 00000000000..5b726fa0266 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/create-and-deploy-a-defi-app/index.md @@ -0,0 +1,481 @@ +--- +title: Criar e promover um Aplicativo DeFi +description: Deposite tokens ERC20 para o contrato inteligente e crie fazenda de tokens +author: "strykerin" +tags: + - "solidity" + - "defi" + - "web3" + - "truffle" + - "ganache" + - "Contratos Inteligentes" +skill: intermediate +lang: pt-br +published: 2020-12-31 +source: github.com +sourceUrl: https://github.com/strykerin/DeFi-Token-Farm +--- + +Neste tutorial, construiremos um aplicativo DeFi com Solidity onde os usuários podem depositar um token ERC20 no contrato inteligente e ele cunhará e transferirá os Tokens Farm para eles. Os usuários podem posteriormente retirar seus tokens ERC20 queimando seu Farm Token em contrato inteligente e os tokens ERC20 serão transferidos de volta para eles. + +## Instale o Truffle e o Ganache {#install-truffle-and-ganache} + +Se esta for a primeira vez que você está escrevendo um contrato inteligente, você precisará configurar seu ambiente primeiro. Vamos usar duas ferramentas:[Truffle](https://www.trufflesuite.com/) and [Ganache](https://www.trufflesuite.com/ganache). + +O Truffle é um ambiente de desenvolvimento e estrutura de teste para o desenvolvimento de contratos inteligentes para o Ethereum. Com o Truffle, é fácil construir e implantar contratos inteligentes na blockchain. O Ganache nos permite criar uma blockchain Ethereum local para testar contratos inteligentes. Ele simula os recursos da rede real e as primeiras 10 contas são financiadas com 100 ether de teste, tornando a implantação e o teste do contrato inteligente gratuitos e fáceis. O Ganache está disponível como um aplicativo de desktop e uma ferramenta de linha de comandos. Para este artigo, usaremos o aplicativo de desktop de interface do usuário. + +![Aplicativo de área de trabalho Ganache UI](https://cdn-images-1.medium.com/max/2360/1*V1iQ5onbLbT5Ib2QaiOSyg.png)_Aplicativo de desktop Ganache UI_ + +Para criar o projeto, execute os seguintes passos + +```bash +mkdir your-project-name +cd your-project-name +truffle init +``` + +Isso criará um projeto em branco para o desenvolvimento e implantação de nossos contratos inteligentes. A estrutura do projeto criada é a seguinte: + +- A Pasta para os contratos inteligentes de solidez: `contracts` + +- `migrações`: Pasta para os scripts de implantação + +- `test`: Pasta para testar nossos contratos inteligentes + +- `truffle-config.js`: Arquivo de configuração do Truffle + +## Criar o token ERC20 {#create-the-erc20-token} + +Primeiro, precisamos criar seu token ERC20 que usaremos para apostar no contrato inteligente. Para criar nosso token fungível, primeiro precisamos instalar a biblioteca OpenZeppelin. Esta biblioteca contém as implementações de padrões como o ERC20 e o ERC721. Para instalá-lo, execute os passos: + +```bash +npm install @openzeppelin/contracts +``` + +Usando a biblioteca OpenZeppelin, podemos criar nosso token ERC20 gravando em `contracts/MyToken.sol` com o seguinte código solidity: + +```solidity +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract MyToken is ERC20 { + constructor() public ERC20("MyToken", "MTKN"){ + _mint(msg.sender, 1000000000000000000000000); + } +} +``` + +No código acima em: + +- Linha 3: Importamos o contrato ERC20.sol do openzeppelin que contém a implementação para este padrão de token. + +- Linha 5: Herdamos do contrato ERC20.sol. + +- Linha 6: Estamos chamando o construtor ERC20.sol e passando os parâmetros name e symbol como `"MyToken"` e `"MTKN"` respectivamente. + +- Linha 7: Estamos cunhando e transferindo 1 milhão de tokens para a conta que está implantando o contrato inteligente (estamos usando os 18 decimais padrão para o token ERC20, o que significa que, se quisermos cunhar 1 token, você o representará como 1000000000000000000, 1 com 18 zeros). + +Podemos ver abaixo a implementação do construtor ERC20.sol onde o campo `_decimals` está definido como 18: + +```solidity +string private _name; +string private _symbol; +uint8 private _decimals; + +constructor (string memory name_, string memory symbol_) public { + _name = name_; + _symbol = symbol_; + _decimals = 18; +} +``` + +## Compilar o token ERC20 {#compile-the-erc20-token} + +Para compilar nosso contrato inteligente, devemos primeiro verificar nossa versão do compilador de solidez. Você pode verificar isso executando o comando: + +```bash +truffle version +``` + +A versão padrão é a `Solidity v0.5.16`. Como nosso token é escrito usando a versão solidity `0.6.2`, se executarmos o comando para compilar nossos contratos, obteremos um erro do compilador. Para especificar qual versão do compilador de solidez será usada, acesse o arquivo `truffle-config. s` e são definidos para a versão desejada do compilador como vistos abaixo: + +```javascript +// Configure your compilers +compilers: { + solc: { + version: "^0.8.0", // Fetch exact version from solc-bin (default: truffle's version) + // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) + // settings: { // See the solidity docs for advice about optimization and evmVersion + // optimizer: { + // enabled: false, + // runs: 200 + // }, + // evmVersion: "byzantium" + // } + } +} +``` + +Agora podemos compilar nosso contrato inteligente executando o seguinte comando: + +```bash +truffle compile +``` + +## Instalar Token ERC20 {#deploy-erc20-token} + +Depois de compilado, podemos publicar nosso token. + +Na pasta de `migrations`, crie um arquivo chamado `2_deploy_Tokens.js`. Este arquivo é onde implantaremos nosso token ERC20 e nosso contrato inteligente FarmToken. O código abaixo é usado para publicar nosso contrato MyToken.sol: + +```javascript +const MyToken = artifacts.require("MyToken") + +module.exports = async function (deployer, network, accounts) { + // Deploy MyToken + await deployer.deploy(MyToken) + const myToken = await MyToken.deployed() +} +``` + +Abra o Ganache e selecione a opção "Quickstart" para iniciar uma blockchain local de Ethereum. Para publicar nosso contrato, execute: + +```bash +truffle migrate +``` + +O endereço usado para implantar nossos contratos é o primeiro da lista de endereços que o Ganache nos mostra. Para verificar isso, podemos abrir o aplicativo de trabalho Ganache e podemos verificar se o saldo de ether para a primeira conta foi reduzido devido ao custo de ether para a implantação dos nossos contratos inteligentes: + +![Aplicativo de desktop Ganache Ui](https://cdn-images-1.medium.com/max/2346/1*1iJ9VRlyLuza58HL3DLfpg.png)_Aplicativo de desktop Ganache Ui_ + +Para verificar que 1 milhão de tokens MyToken foram enviados para o endereço de deploy, podemos utilizar o Truffle Console para interagir com o nosso contrato inteligente que foi publicado. + +> [Truffle Console é um console básico interativo conectando-se a qualquer cliente Ethereum.](https://www.trufflesuite.com/docs/truffle/getting-started/using-truffle-develop-and-the-console) + +Para interagir com nosso contrato inteligente, execute o seguinte comando: + +```bash +truffle console +``` + +Agora podemos escrever os seguintes comandos no terminal: + +- Obter o contrato inteligente: `meuToken = await MyToken.deployed()` + +- Obter o array de contas de Ganache: `contas = aguardar web3.eth.getAccounts()` + +- Obter o saldo para a primeira conta: `balance = await myToken.balanceOf(contas[0])` + +- Formate o saldo de 18 decimals: `web3.utils.fromWei(balance.toString())` + +Executando os comandos acima, vamos ver que o primeiro endereço tem na verdade 1 milhão de MyTokens: + +![Primeiro endereço tem 1000000 MyTokens](https://cdn-images-1.medium.com/max/2000/1*AQlj9A7dw-qtY4QAD3Bpxw.png) + +_Primeiro endereço tem 1000000 MyTokens_ + +## Criando FarmToken Smart Contract {#create-farmtoken-smart-contract} + +O contrato inteligente FarmToken terá 3 funções: + +- `balance()`: Obter o balanço do MyToken no contrato inteligente FarmToken. + +- `deposit(uint256 _amount)`: Transfira MyToken em nome do usuário para o contrato inteligente FarmToken e então importe FarmToken para o usuário. + +- `withdraw(uint256 _amount)`: Queimar FarmTokens do usuário e transferir MyTokens para o endereço do usuário. + +Vamos dar uma olhada no construtor do FarmToken: + +```solidity +pragma solidity ^0.6.2; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/utils/Address.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract FarmToken is ERC20 { + using Address for address; + using SafeMath for uint256; // As of Solidity v0.8.0, mathematical operations can be done safely without the need for SafeMath + using SafeERC20 for IERC20; + + IERC20 public token; + + constructor(address _token) + public + ERC20("FarmToken", "FRM") + { + token = IERC20(_token); + } +``` + +- Linhas 3-6: Estamos importando os seguintes contratos do openzeppelin: IERC20.sol, Address.sol, SafeERC20.sol e ERC20.sol. + +- Linha 8: O FarmToken vai herdar do contrato ERC20. + +- Linhas 14-19: O construtor FarmToken receberá como parâmetro o endereço do contrato MyToken e atribuiremos seu contrato à nossa variável pública chamada `token`. + +Vamos implementar a função `balance()`. Ele não receberá parâmetros e retornará o saldo do MyToken neste contrato inteligente. Ela está implementada como mostrado abaixo: + +```solidity +function balance() public view returns (uint256) { + return token.balanceOf(address(this)); +} +``` + +Para a função `deposit(uint256 _amount)`, ele receberá como parâmetro a quantia que o usuário deseja depositar e irá fazer a cunhagem e transferir FarmTokens para o usuário: + +```solidity +function deposit(uint256 _amount) public { + // Amount must be greater than zero + require(_amount > 0, "amount cannot be 0"); + + // Transfer MyToken to smart contract + token.safeTransferFrom(msg.sender, address(this), _amount); + + // Mint FarmToken to msg sender + _mint(msg.sender, _amount); +} +``` + +Para a função `withdraw(uint256 _amount)`, nós vamos receber como parâmetro a quantidade de FarmTokens que o usuário deseja queimar e então vamos transferir a mesma quantidade de MyTokens de volta para o usuário: + +```solidity +function withdraw(uint256 _amount) public { + // Burn FarmTokens from msg sender + _burn(msg.sender, _amount); + + // Transfer MyTokens from this smart contract to msg sender + token.safeTransfer(msg.sender, _amount); +} +``` + +Como implantar um contrato inteligente. Para fazer isso, vamos voltar para o arquivo `2_deploy_Tokens.js` e adicionar o novo contrato a ser implantado: + +```javascript +const MyToken = artifacts.require("MyToken") +const FarmToken = artifacts.require("FarmToken") + +module.exports = async function (deployer, network, accounts) { + // Deploy MyToken + await deployer.deploy(MyToken) + const myToken = await MyToken.deployed() + + // Deploy Farm Token + await deployer.deploy(FarmToken, myToken.address) + const farmToken = await FarmToken.deployed() +} +``` + +Note que ao implantar o FarmToken, passamos como parâmetro o endereço do contrato MyToken implantado. + +Agora, rode `truffle compilar` e `truffle migrar` para implantar nossos contratos. + +Vamos testar o nosso contrato inteligente. Em vez de usar o `truffle console` para interagir com o nosso contrato inteligente, criaremos um script para automatizar esse processo. Crie uma pasta chamada `scripts` e adicione o seguinte arquivo `getMyTokenBalance.js`. Ele irá verificar o saldo dos MyTokens no contrato inteligente do Farmtoken: + +```javascript +const MyToken = artifacts.require("MyToken") +const FarmToken = artifacts.require("FarmToken") + +module.exports = async function (callback) { + myToken = await MyToken.deployed() + farmToken = await FarmToken.deployed() + balance = await myToken.balanceOf(farmToken.address) + console.log(web3.utils.fromWei(balance.toString())) + callback() +} +``` + +Para executar esse script, execute o seguinte comando na linha de comando: + +```bash +truffle exec .\scripts\getMyTokenBalance.js +``` + +Vamos obter o resultado esperado que é 0. Se você receber um erro sobre o FarmToken ainda não foi implantado, a rede truffle não recebeu a versão mais recente do seu código de contratos. Apenas feche o ganache, reinicie o programa rapidamente e certifique-se de executar `a migração de um truffle`. + +Agora, vamos fazer o staking do MyToken para o contrato inteligente. Desde a função `deposit(uint256 _amount)` chama a função `safeTransferFrom` do ERC20, primeiro o usuário deve aprovar o contrato inteligente para transferir MyToken em nome do usuário. Então, no script abaixo, primeiro aprovaremos esta etapa e então chamaremos a função: + +```javascript +const MyToken = artifacts.require("MyToken") +const FarmToken = artifacts.require("FarmToken") + +module.exports = async function (callback) { + const accounts = await new web3.eth.getAccounts() + const myToken = await MyToken.deployed() + const farmToken = await FarmToken.deployed() + + // Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner through transferFrom. + // This is zero by default. + const allowanceBefore = await myToken.allowance( + accounts[0], + farmToken.address + ) + console.log( + "Amount of MyToken FarmToken is allowed to transfer on our behalf Before: " + + allowanceBefore.toString() + ) + + // In order to allow the Smart Contract to transfer to MyToken (ERC-20) on the accounts[0] behalf, + // we must explicitly allow it. + // We allow farmToken to transfer x amount of MyToken on our behalf + await myToken.approve(farmToken.address, web3.utils.toWei("100", "ether")) + + // Validate that the farmToken can now move x amount of MyToken on our behalf + const allowanceAfter = await myToken.allowance(accounts[0], farmToken.address) + console.log( + "Amount of MyToken FarmToken is allowed to transfer on our behalf After: " + + allowanceAfter.toString() + ) + + // Verify accounts[0] and farmToken balance of MyToken before and after the transfer + balanceMyTokenBeforeAccounts0 = await myToken.balanceOf(accounts[0]) + balanceMyTokenBeforeFarmToken = await myToken.balanceOf(farmToken.address) + console.log("*** My Token ***") + console.log( + "Balance MyToken Before accounts[0] " + + web3.utils.fromWei(balanceMyTokenBeforeAccounts0.toString()) + ) + console.log( + "Balance MyToken Before TokenFarm " + + web3.utils.fromWei(balanceMyTokenBeforeFarmToken.toString()) + ) + + console.log("*** Farm Token ***") + balanceFarmTokenBeforeAccounts0 = await farmToken.balanceOf(accounts[0]) + balanceFarmTokenBeforeFarmToken = await farmToken.balanceOf(farmToken.address) + console.log( + "Balance FarmToken Before accounts[0] " + + web3.utils.fromWei(balanceFarmTokenBeforeAccounts0.toString()) + ) + console.log( + "Balance FarmToken Before TokenFarm " + + web3.utils.fromWei(balanceFarmTokenBeforeFarmToken.toString()) + ) + // Call Deposit function from FarmToken + console.log("Call Deposit Function") + await farmToken.deposit(web3.utils.toWei("100", "ether")) + console.log("*** My Token ***") + balanceMyTokenAfterAccounts0 = await myToken.balanceOf(accounts[0]) + balanceMyTokenAfterFarmToken = await myToken.balanceOf(farmToken.address) + console.log( + "Balance MyToken After accounts[0] " + + web3.utils.fromWei(balanceMyTokenAfterAccounts0.toString()) + ) + console.log( + "Balance MyToken After TokenFarm " + + web3.utils.fromWei(balanceMyTokenAfterFarmToken.toString()) + ) + + console.log("*** Farm Token ***") + balanceFarmTokenAfterAccounts0 = await farmToken.balanceOf(accounts[0]) + balanceFarmTokenAfterFarmToken = await farmToken.balanceOf(farmToken.address) + console.log( + "Balance FarmToken After accounts[0] " + + web3.utils.fromWei(balanceFarmTokenAfterAccounts0.toString()) + ) + console.log( + "Balance FarmToken After TokenFarm " + + web3.utils.fromWei(balanceFarmTokenAfterFarmToken.toString()) + ) + + // End function + callback() +} +``` + +Para rodar esse script: `truffle exec .\scripts\transferMyTokenToFarmToken.js`. Você deve ver no seu console: + +![output do transferMyTokenToFarmToken.js](https://cdn-images-1.medium.com/max/2000/1*MoekE2QCw7vB98u5dl7ang.png) + +_output do transferMyTokenToFarmToken.js_ + +Como podemos ver, depositamos MyTokens com sucesso no contrato inteligente já que a primeira conta agora tem FarmTokens. + +Para retirar: + +```javascript +const MyToken = artifacts.require("MyToken") +const FarmToken = artifacts.require("FarmToken") + +module.exports = async function (callback) { + const accounts = await new web3.eth.getAccounts() + const myToken = await MyToken.deployed() + const farmToken = await FarmToken.deployed() + + // Verify accounts[0] and farmToken balance of MyToken before and after the transfer + balanceMyTokenBeforeAccounts0 = await myToken.balanceOf(accounts[0]) + balanceMyTokenBeforeFarmToken = await myToken.balanceOf(farmToken.address) + console.log("*** My Token ***") + console.log( + "Balance MyToken Before accounts[0] " + + web3.utils.fromWei(balanceMyTokenBeforeAccounts0.toString()) + ) + console.log( + "Balance MyToken Before TokenFarm " + + web3.utils.fromWei(balanceMyTokenBeforeFarmToken.toString()) + ) + + console.log("*** Farm Token ***") + balanceFarmTokenBeforeAccounts0 = await farmToken.balanceOf(accounts[0]) + balanceFarmTokenBeforeFarmToken = await farmToken.balanceOf(farmToken.address) + console.log( + "Balance FarmToken Before accounts[0] " + + web3.utils.fromWei(balanceFarmTokenBeforeAccounts0.toString()) + ) + console.log( + "Balance FarmToken Before TokenFarm " + + web3.utils.fromWei(balanceFarmTokenBeforeFarmToken.toString()) + ) + + // Call Deposit function from FarmToken + console.log("Call Withdraw Function") + await farmToken.withdraw(web3.utils.toWei("100", "ether")) + + console.log("*** My Token ***") + balanceMyTokenAfterAccounts0 = await myToken.balanceOf(accounts[0]) + balanceMyTokenAfterFarmToken = await myToken.balanceOf(farmToken.address) + console.log( + "Balance MyToken After accounts[0] " + + web3.utils.fromWei(balanceMyTokenAfterAccounts0.toString()) + ) + console.log( + "Balance MyToken After TokenFarm " + + web3.utils.fromWei(balanceMyTokenAfterFarmToken.toString()) + ) + + console.log("*** Farm Token ***") + balanceFarmTokenAfterAccounts0 = await farmToken.balanceOf(accounts[0]) + balanceFarmTokenAfterFarmToken = await farmToken.balanceOf(farmToken.address) + console.log( + "Balance FarmToken After accounts[0] " + + web3.utils.fromWei(balanceFarmTokenAfterAccounts0.toString()) + ) + console.log( + "Balance FarmToken After TokenFarm " + + web3.utils.fromWei(balanceFarmTokenAfterFarmToken.toString()) + ) + + // End function + callback() +} +``` + +Para rodar esse script: `truffle exec .\scripts\transferMyTokenToFarmToken.js`. Como podemos ver no output abaixo, nós conseguimos de volta os MyTokens com sucesso e acabamos com os FarmTokens: + +![output do withdrawMyTokenFromTokenFarm.js](https://cdn-images-1.medium.com/max/2000/1*jHYlTFg0NgGbhASpsRvc0w.png) + +_output do withdrawMyTokenFromTokenFarm.js_ + +## Referências {#references} + +[Contratos - OpenZeppelin Docs](https://docs.openzeppelin.com/contracts/3.x/) + +[Ferramentas Suplentes para Contratos Inteligentes Common Suite](https://www.trufflesuite.com/) + +[Ganache | Truffle Suite](https://www.trufflesuite.com/ganache) + +[O que é DeFi? Um guia para iniciantes (atualizado em 2021) (99bitcoins.com)](https://99bitcoins.com/what-is-defi/) + +[DeFi - A classificação da finança descentraliza no DeFi Llama](https://defillama.com/) diff --git a/public/content/translations/pt-br/developers/tutorials/deploying-your-first-smart-contract/index.md b/public/content/translations/pt-br/developers/tutorials/deploying-your-first-smart-contract/index.md new file mode 100644 index 00000000000..4d78c0a3e2e --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/deploying-your-first-smart-contract/index.md @@ -0,0 +1,99 @@ +--- +title: Implementando seu primeiro contrato inteligente +description: Uma introdução à implantação do seu primeiro contrato inteligente em uma rede de teste Ethereum +author: "jdourlens" +tags: + - "contratos inteligentes" + - "remix" + - "solidity" + - "implementação" +skill: beginner +lang: pt-br +published: 2020-04-03 +source: EthereumDev +sourceUrl: https://ethereumdev.io/deploying-your-first-smart-contract/ +address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" +--- + +Acho que você está tão animado quanto nós para [implantar](/developers/docs/smart-contracts/deploying/) e interagir com o seu primeiro [contrato inteligente](/developers/docs/smart-contracts/) na blockchain Ethereum. + +Não se preocupe, pois como este é o nosso primeiro contrato inteligente, vamos publicá-lo em uma [rede de testes local](/developers/docs/networks/), assim não custa nada para você implementar e brincar com ele o quanto quiser. + +## Escrevendo nosso contrato {#writing-our-contract} + +O primeiro passo é [visitar a Remix](https://remix.ethereum.org/) e criar um novo arquivo. Na parte superior esquerda da interface Remix adicione um novo arquivo e digite o nome do arquivo desejado. + +![Adicionando um novo arquivo na interface Remix](./remix.png) + +No novo arquivo, vamos colar o seguinte código. + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity >=0.5.17; + +contract Counter { + + // Public variable of type unsigned int to keep the number of counts + uint256 public count = 0; + + // Function that increments our counter + function increment() public { + count += 1; + } + + // Not necessary getter to get the count value + function getCount() public view returns (uint256) { + return count; + } + +} +``` + +Se você está acostumado com programação, você pode facilmente adivinhar o que este programa faz. Aqui está uma explicação linha a linha: + +- Linha 4: Definimos um contrato com o nome `Counter`. +- Linha 7: Nosso contrato armazena um inteiro não assinado chamado `count` começando com 0. +- Linha 10: A primeira função vai modificar o estado do contrato e `increment()` nossa variável `count`. +- Linha 15: A segunda função é apenas um getter para ser capaz de ler o valor da variável `count` fora do contrato inteligente. Observe que, como definimos nossa variável `count` como pública, isso não é necessário, mas é mostrado como um exemplo. + +Tudo isso para o nosso primeiro contrato inteligente simples. Como você deve saber, ele se parece com uma classe de linguagens OOP (Object-Oriented Programming, programação orientada a objetos) como Java ou C++. Agora é hora de brincar com o nosso contrato. + +## Implantando nosso contrato {#deploying-our-contract} + +Como escrevemos nosso primeiro contrato inteligente, nós agora faremos deploy para a blockchain para poder brincar com ele. + +[Implantar o contrato inteligente no blockchain](/developers/docs/smart-contracts/deploying/) é, na verdade, apenas enviar uma transação que contém o código do contrato inteligente compilado sem especificar os destinatários. + +Primeiro, vamos [compilar o contrato](/developers/docs/smart-contracts/compiling/) clicando no ícone de compilação no lado esquerdo: + +![O ícone de compilação na barra de ferramentas Remix](./remix-compile-button.png) + +Em seguida, clique no botão de compilação: + +![O botão de compilação no compilador do solidity Remix](./remix-compile.png) + +Você pode escolher selecionar a opção "Compilação automática", para que o contrato sempre seja compilado quando você salvar o conteúdo no editor de texto. + +Em seguida, navegue para a tela de implantação e execução de transações: + +![O ícone de compilação na barra de ferramentas do Remix](./remix-deploy.png) + +Assim que você estiver na tela de transações "deploy and run" verifique se o nome do seu contrato aparece e clique em Deploy. Como você pode ver no topo da página, o ambiente atual é o "Javascript VM", o que significa que iremos implantar e interagir com nosso contrato inteligente em uma blockchain de teste local para podermos testar mais rápido e sem quaisquer custos. + +![O botão de deploy no compilador do solidity Remix](./remix-deploy-button.png) + +Quando você clicar no botão "Deploy", você verá seu contrato aparecer abaixo. Clique na seta à esquerda para expandi-la, para que possamos ver o conteúdo de nosso contrato. Esta é nossa variável `counter`, nossa função `increment()` e a getter `getCounter()`. + +Se você clicar no botão `count` ou `getCount`, ele recuperará o conteúdo da variável `count` do contrato e o exibirá. Como ainda não chamamos a função `increment`, ela deve exibir 0. + +![O botão de função no compilador do solidity Remix](./remix-function-button.png) + +Vamos agora chamar a função `increment` clicando no botão. Você verá logs das transações que são feitas aparecendo no parte inferior da janela. Você verá que os logs são diferentes quando estiver pressionando o botão para recuperar os dados em vez do botão `increment`. Isso porque a leitura de dados na blockchain não necessita de quaisquer transações (escritas) ou taxas. Porque somente modificar o estado do blockchain requer fazer uma transação: + +![Um log de transações](./transaction-log.png) + +Após pressionar o botão de incremento que gerará uma transação para chamar nossa função `increment()` se clicarmos novamente nos botões count ou getCount, iremos ler o estado recém-atualizado de nosso contrato inteligente com a variável de contagem maior que 0. + +![Estado recentemente atualizado do contrato inteligente](./updated-state.png) + +No próximo tutorial, explicaremos [como você pode adicionar eventos aos seus contratos inteligentes](/developers/tutorials/logging-events-smart-contracts/). Eventos de registro são uma maneira conveniente para depurar seu contrato inteligente e entender o que está acontecendo durante a chamada de uma função. diff --git a/public/content/translations/pt-br/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md b/public/content/translations/pt-br/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md new file mode 100644 index 00000000000..ed91278fc09 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md @@ -0,0 +1,163 @@ +--- +title: "Reduzir contratos para combater o limite de tamanho do contrato" +description: O que você pode fazer para evitar que seus contratos inteligentes fiquem muito grandes? +author: Markus Waas +lang: pt-br +tags: + - "solidez" + - "smart contracts" + - "armazenamento" + - "truffle" +skill: intermediate +published: 2020-06-26 +source: soliditydeveloper.com +sourceUrl: https://soliditydeveloper.com/max-contract-size +--- + +## Por que há um limite? {#why-is-there-a-limit} + +Em [22 de novembro de 2016](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/) o fork Spurius Dragon introduziu a [EIP-170](https://eips.ethereum.org/EIPS/eip-170) que adicionou um limite de tamanho do contrato inteligente de 24.576 kb. Para você como desenvolvedor de Solidity isso significa que quando você adiciona mais e mais funcionalidade ao seu contrato, em algum momento você alcançará o limite e quando implantado verá o erro: + +`Aviso: O código do contrato excede 24576 bytes (um limite introduzido no Dragão Purioso). This contract may not be deployable on Mainnet. Considere habilitar o otimizador (com um valor baixo de "execução"!), desligar as strings de reverter ou usar bibliotecas.` + +Este limite foi introduzido para impedir ataques de negação de serviço (DOS). Qualquer apelo a um contrato é relativamente barato. No entanto, o impacto de uma chamada de contrato para os nós da Ethereum aumenta de forma desproporcionada, dependendo do tamanho do código do contrato chamado (lendo o código do disco, pré-processando o código, adicionando dados à prova de Merkle). Sempre que você tiver uma situação em que o agressor requer poucos recursos para causar muito trabalho para os outros, você tem o potencial para ataques DOS. + +Originalmente, tratava-se de um problema menor, porque um limite de tamanho natural do contrato é o limite de gas por bloco. Obviamente, um contrato precisa ser implementado dentro de uma transação que tenha todo o bytecode do contrato. Se você incluir apenas essa transação em um bloco, você pode usar todo esse gas, mas não é infinito. Desde a [London Upgrade](/history/#london), o limite de gas de bloco tem sido capaz de variar entre 15M e 30M de unidades, de acordo com a demanda da rede. + +## Começando a luta {#taking-on-the-fight} + +Infelizmente, não há maneira fácil de obter o tamanho do bytecode dos seus contratos. Uma ótima ferramenta para ajudá-lo é o plugin [truffle-contract-size](https://github.com/IoBuilders/truffle-contract-size) se você estiver usando o Truffle. + +1. `npm install truffle-contract-size` +2. Adicione o plugin ao _truffle-config.js_: `plugins: ["truffle-contract-size"]` +3. Execute `truffle rodando contract-size` + +Isso irá ajudá-lo a descobrir como suas mudanças estão afetando o tamanho total do contrato. + +A seguir, analisaremos alguns métodos ordenados pelo seu potencial impacto. Pense nisso em termos de perda de peso. A melhor estratégia para alguém atingir o seu peso alvo (no nosso caso 24kb) é concentrar-se primeiro nos grandes métodos de impacto. Na maioria dos casos, só de ajustar a sua dieta já ajudará, mas às vezes é necessário de um pouco mais. Então você pode adicionar algum exercício (impacto médio) ou até suplementos (impacto pequeno). + +## Grande impacto {#big-impact} + +### Separe os seus contratos {#separate-your-contracts} + +Esta deve ser sempre sua primeira abordagem. Como você pode separar o contrato em vários contratos menores? Geralmente isso te força a criar uma boa arquitetura para seus contratos. Os contratos menores são sempre preferidos por uma perspectiva de legibilidade de código. Para dividir contratos, pergunte a si mesmo: + +- Quais as funções que devem estar juntas? Cada conjunto de funções pode ser o melhor em seu próprio contrato. +- Que funções não requerem leitura do estado do contrato ou apenas um subconjunto específico do estado? +- Você pode dividir o armazenamento e a funcionalidade? + +### Bibliotecas {#libraries} + +Uma maneira simples de mover o código de funcionalidade para longe do armazenamento é usando [uma biblioteca](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#libraries). Não declarar as funções da biblioteca como internas, como essas, serão [adicionadas ao contrato](https://ethereum.stackexchange.com/questions/12975/are-internal-functions-in-libraries-not-covered-by-linking) diretamente durante a compilação. Mas se usarmos funções públicas, elas estarão então de fato, num contrato separado de biblioteca. Considere [o uso de](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#using-for) para fazer o uso de bibliotecas mais convenientes. + +### Proxies {#proxies} + +Uma estratégia mais avançada seria um sistema de procuração. As bibliotecas usam `DELEGATECALL` na parte traseira, que simplesmente executa a função de outro contrato com o estado do contrato de chamada. Confira [esta postagem no blog](https://hackernoon.com/how-to-make-smart-contracts-upgradable-2612e771d5a2) para saber mais sobre sistemas de proxy. Eles lhe dão mais funcionalidade, por exemplo, permitem a atualização, mas também adicionam muita complexidade. Eu não adicionaria aquelas apenas para reduzir os tamanhos dos contratos, a menos que fosse a sua única opção por qualquer motivo. + +## Médio impacto {#medium-impact} + +### Remover funções {#remove-functions} + +Este deveria ser óbvio. Funções aumentam um pouco o tamanho de um contrato. + +- **Externo**: Frequentemente adicionamos muitas funções de exibição por motivos de conveniência. Está perfeitamente tudo bem até que você atinja o limite de tamanho. Então talvez queiram realmente pensar na eliminação de todos que não os absolutamente essenciais. +- **Interno**: Você também pode remover funções internas/privadas e simplesmente inserir o código, desde que a função seja chamada apenas uma vez. + +### Evitar variáveis adicionais {#avoid-additional-variables} + +Uma mudança simples assim: + +```solidity +function get(uint id) returns (address,address) { + MyStruct memory myStruct = myStructs[id]; + return (myStruct.addr1, myStruct.addr2); +} +``` + +```solidity +function get(uint id) returns (address,address) { + return (myStructs[id].addr1, myStructs[id].addr2); +} +``` + +faz diferença de **0.28kb**. Você pode encontrar muitas situações semelhantes nos seus contratos e isso pode realmente somar quantias significativas. + +### Encurtar mensagem de erro {#shorten-error-message} + +Mensagens de reversão longa e, em particular, muitas mensagens de reversão diferentes podem bloquear o contrato. Em vez disso, use códigos de erro curtos e decodifique-os no contrato. Uma mensagem longa poderia ser muito mais curta: + +```solidity +require(msg.sender == owner, "Only the owner of this contract can call this function"); + +``` + +```solidity +require(msg.sender == owner, "OW1"); +``` + +### Use erros personalizados ao invés de mensagens de erro + +Erros personalizados foram introduzidos no [Solidity 0.8.4](https://blog.soliditylang.org/2021/04/21/custom-errors/). Eles são uma ótima maneira de reduzir o tamanho de seus contratos, porque são codificados por ABI como seletores (assim como as funções são). + +```solidity +error Unauthorized(); + +if (msg.sender != owner) { + revert Unauthorized(); +} +``` + +### Considere um valor de baixa execução no otimizador {#consider-a-low-run-value-in-the-optimizer} + +Você também pode alterar as configurações do otimizador. O valor padrão de 200 significa que está tentando otimizar o bytecode como se uma função fosse chamada 200 vezes. Se você alterá-lo para 1, basicamente diga ao otimizador para otimizar em caso de executar cada função apenas uma vez. Uma função otimizada para rodar apenas uma vez significa que ela é otimizada para a própria implantação. Esteja ciente de que **isso aumenta o custo do [gás](/developers/docs/gas/) por executar as funções**, então você pode querer não otimizá-la. + +## Pequeno impacto {#small-impact} + +### Evite passar instruções para funções {#avoid-passing-structs-to-functions} + +Se você estiver usando o [ABIEncoderV2](https://solidity.readthedocs.io/en/v0.6.10/layout-of-source-files.html#abiencoderv2), ele pode ajudar a não passar de structs para uma função. Em vez de passar o parâmetro como uma estrutura... + +```solidity +function get(uint id) returns (address,address) { + return _get(myStruct); +} + +function _get(MyStruct memory myStruct) private view returns(address,address) { + return (myStruct.addr1, myStruct.addr2); +} +``` + +```solidity +function get(uint id) returns(address,address) { + return _get(myStructs[id].addr1, myStructs[id].addr2); +} + +function _get(address addr1, address addr2) private view returns(address,address) { + return (addr1, addr2); +} +``` + +... passe os parâmetros necessários diretamente. Neste exemplo, salvamos outro **0.1kb**. + +### Declarar a visibilidade correta para funções e variáveis {#declare-correct-visibility-for-functions-and-variables} + +- Funções ou variáveis que são chamadas apenas do lado de fora? Declará-las como `externas` em vez de `públicas`. +- Funções ou variáveis apenas chamadas dentro do contrato? Declará-las como `private` ou `internal` em vez de `public`. + +### Remover modificadores {#remove-modifiers} + +Os modificadores, especialmente quando usados intencionalmente, podem ter um impacto significativo no tamanho do contrato. Considere removê-los e, em vez disso, usar funções. + +```solidity +modifier checkStuff() {} + +function doSomething() checkStuff {} +``` + +```solidity +function checkStuff() private {} + +function doSomething() { checkStuff(); } +``` + +Essas dicas devem ajudá-lo a reduzir significativamente o tamanho do contrato. Mais uma vez, nunca é demais salientar que se foca sempre na divisão dos contratos, se possível para o maior impacto. diff --git a/public/content/translations/pt-br/developers/tutorials/eip-1271-smart-contract-signatures/index.md b/public/content/translations/pt-br/developers/tutorials/eip-1271-smart-contract-signatures/index.md new file mode 100644 index 00000000000..36a492a687b --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/eip-1271-smart-contract-signatures/index.md @@ -0,0 +1,127 @@ +--- +title: "EIP-1271: Assinatura e verificação de contratos inteligentes" +description: Uma visão geral de geração de assinatura de contratos inteligentes e verificação com a EIP-1271. Também passaremos pela implementação da EIP-1271 usada no Safe (anteriormente Gnosis Safe) para fornecer um exemplo concreto de contrato inteligente para que desenvolvedores possam construir por cima dele. +author: Nathan H. Leung +lang: pt-br +tags: + - "eip-1271" + - "contratos inteligentes" + - "verificando" + - "assinatura" +skill: intermediate +published: 2023-01-12 +--- + +A norma [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) permite a contratos inteligentes verificarem assinaturas. + +Neste tutorial, forneceremos uma visão geral das assinaturas digitais, noções básicas sobre a EIP-1271, e a implementação específica da EIP-1271 usada pelo [Safe](https://safe.global/) (previamente Gnosis Safe). Tudo isso pode servir como ponto de partida para a implementação da EIP-1271 nos seus próprios contratos. + +## O que é assinatura? + +Nesse contexto, uma assinatura (mais precisamente, uma “assinatura digital”) é uma mensagem, acompanhada de um tipo de prova de que a mensagem veio de uma pessoa, remetente ou endereço específico. + +Por exemplo, uma assinatura digital pode se parecer com isto: + +1. Mensagem: “Quero me conectar a este website com minha carteira Ethereum.” +2. Assinante: Meu endereço é `0x000…` +3. Prova: Aqui está uma prova de que eu, `0x000…`, realmente criei esta mensagem inteira (isto é geralmente algo criptográfico). + +É importante observar que uma assinatura digital inclui ambos, uma “mensagem” e uma “assinatura”. + +Por quê? Por exemplo, se você me der um contrato para assinar, e eu retirar a página de assinatura e devolver somente a minha assinatura sem o resto do contrato, o contrato não seria válido. + +Da mesma maneira, uma assinatura digital não significa nada sem uma mensagem associada! + +## Por que a EIP-1271 existe? + +Para criar uma assinatura digital para uso em blockchains baseados em Ethereum, você geralmente precisa de uma chave secreta que ninguém mais conhece. Isto é o que faz sua assinatura, sua (ninguém mais pode criar a mesma assinatura sem o conhecimento da chave secreta). + +Sua conta Ethereum (ou seja, conta de propriedade externa / EOA) tem uma chave privada associada a ela quando um website ou dapp pergunta por sua assinatura (por exemplo: “Log in with Ethereum”). + +Um app pode [verificar uma assinatura](https://docs.alchemy.com/docs/how-to-verify-a-message-signature-on-ethereum) que você criou usando uma biblioteca de terceiros, como ethers.js [sem conhecer sua chave privada](https://en.wikipedia.org/wiki/Public-key_cryptography) e estar confiante de que foi _você_ quem criou a assinatura. + +> De fato, como as assinaturas digitais EOA usam criptografia de chave pública, elas podem ser geradas e verificadas **off-chain**! É assim que a votação em DAO sem gás funciona — em vez de submeter votos on-chain, as assinaturas digitais podem ser criadas e verificadas off-chain usando bibliotecas criptográficas. + +Enquanto as contas EOA têm uma chave privada, as contas de contrato inteligente não têm nenhum tipo de chave privada ou secreta (portanto, “Entrar com Ethereum”, etc. não pode funcionar nativamente com contas de contratos inteligentes). + +O problema que a EIP-1271 visa resolver: como podemos dizer que uma assinatura de contrato inteligente é válida se o contrato inteligente não tem um “segredo” que ele possa incorporar na assinatura? + +## Como a EIP-1271 funciona? + +Contratos inteligentes não têm chaves privadas que possam ser usadas para assinar mensagens. Então, como podemos saber se uma assinatura é autêntica? + +Bem, uma ideia é que podemos _perguntar_ ao contrato inteligente se uma assinatura é autêntica! + +O que o EIP-1271 faz é padronizar a ideia de "perguntar" ao contrato inteligente se uma dada assinatura é válida. + +Um contrato que implementa EIP-1271 deve ter uma função chamada `isValidSignature` que recebe a mensagem e a assinatura. O contrato pode então executar alguma lógica de validação (a especificação não força nada específico aqui) e então retornar um valor indicando se a assinatura é válida ou não. + +Se `isValidSignature` retornar um resultado válido, isso é basicamente o contrato dizendo “sim, eu aprovo esta assinatura + mensagem!” + +### Interface + +Aqui está a interface exata na especificação da EIP-1271 (falaremos sobre o parâmetro `_hash` abaixo, mas por enquanto, pense nele como a mensagem que está sendo verificada): + +```jsx +pragma solidity ^0.5.0; + +contract ERC1271 { + + // bytes4(keccak256("isValidSignature(bytes32,bytes)") + bytes4 constant internal MAGICVALUE = 0x1626ba7e; + + /** + * @dev Should return whether the signature provided is valid for the provided hash + * @param _hash Hash of the data to be signed + * @param _signature Signature byte array associated with _hash + * + * MUST return the bytes4 magic value 0x1626ba7e when function passes. + * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5) + * MUST allow external calls + */ + function isValidSignature( + bytes32 _hash, + bytes memory _signature) + public + view + returns (bytes4 magicValue); +} +``` + +## Exemplo de implementação da EIP-1271: Safe + +Os contratos podem implementar `isValidSignature` de várias maneiras — a especificação somente não diz muito sobre a implementação exata. + +Um contrato importante que implementa a EIP-1271 é o Safe (anteriormente Gnosis Safe). + +No código do Safe, `isValidSignature` [ é implementada](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol) para que assinaturas possam ser criadas e verificadas de [duas maneiras](https://ethereum.stackexchange.com/questions/122635/signing-messages-as-a-gnosis-safe-eip1271-support): + +1. Mensagens on-chain + 1. Criação: um proprietário Safe cria uma nova transação Safe para “assinar” a mensagem, passando a mensagem como um dado na transação. Uma vez que proprietários suficientes assinam a transação para alcançar o limite multisig, a transação é enviada e executada. Na transação, há uma função Safe chamada, que adiciona a mensagem à lista de mensagens “aprovadas”. + 2. Verificação: chame `isValidSignature` no contrato Safe, e transmita a mensagem para verificar enquanto parâmetro da mensagem e [ um parâmetro vazio como parâmetro da assinatura](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol#L32) (i.e. `0x`). O Safe verá que o parâmetro da assinatura está vazio e, em vez de verificar a assinatura criptograficamente, ele saberá que deve prosseguir e verificar se a mensagem está na lista de mensagens “aprovadas”. +2. Mensagens off-chain: + 1. Criação: um proprietário Safe cria uma mensagem off-chain, e então consegue outros proprietários Safe para assinar a mensagem, cada um individualmente, até que haja assinaturas suficientes para conseguir a aprovação pelo limite do multisig. + 2. Verificação: chama `isValidSignature`. No parâmetro da mensagem, passa a mensagem para ser verificada. No parâmetro da assinatura, passa cada assinatura individual de proprietário Safe todas concatenadas juntas. O Safe irá checar que há assinaturas suficientes para atingir o limite **e** que cada assinatura é válida. Acontecendo isso, ele retornará um valor indicando verificação da assinatura com sucesso. + +## O que é exatamente o parâmetro `_hash`? Por que não passar a mensagem inteira? + +Você pode ter notado que a função `isValidSignature` na interface [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) não pega a mensagem propriamente dita, mas, em vezés disso, um parâmetro `_hash`. O que isto significa é que ao invés de passar a mensagem inteira de tamanho arbitrário para `isValidSignature`, nós passamos um hash de 32-bytes da mensagem (geralmente keccak256). + +Cada byte de calldata — ou seja, dados de parâmetro da função passados para uma função de contrato inteligente — [custa16 gás (4 gás se zero byte)](https://eips.ethereum.org/EIPS/eip-2028), então, isso pode economizar um monte de gás se a mensagem for longa. + +### Especificações EIP-1271 anteriores + +Existem outras especificações EIP-1271 por aí, que têm uma função `isValidSignature` com um primeiro parâmetro do tipo `bytes` (tamanho arbitrário, em vez de tamanho fixo `bytes32`) e nome de parâmetro `message`. Essa é uma [versão mais antiga](https://github.com/safe-global/safe-contracts/issues/391#issuecomment-1075427206) da norma EIP-1271. + +## Como o EIP-1271 poderia ser implementado nos meus próprios contratos? + +A especificação é bem aberta aqui. A implementação Safe tem algumas boas ideias: + +- Você pode considerar assinaturas EOA do "proprietário" do contrato serem válidas. +- Você poderia armazenar uma lista de mensagens aprovadas e somente considerar estas serem válidas. + +No final, depende de você, como desenvolvedor do contrato! + +## Conclusão + +A [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) é uma norma versátil que permite contratos inteligentes verificar assinaturas. Ele abre a porta para contratos inteligentes que funcionam mais como EOAs - por exemplo fornecendo uma maneira de se "conectar via Ethereum" para trabalhar com contratos inteligentes - e ele pode ser implementado de várias maneiras (Safe tendo uma implementação interessante e não trivial a se considerar). diff --git a/public/content/translations/pt-br/developers/tutorials/erc-721-vyper-annotated-code/index.md b/public/content/translations/pt-br/developers/tutorials/erc-721-vyper-annotated-code/index.md new file mode 100644 index 00000000000..960c69543fb --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/erc-721-vyper-annotated-code/index.md @@ -0,0 +1,632 @@ +--- +title: "Passo a passo do contrato Vyper ERC-721" +description: Ryuya Nakamura's ERC-721 contrato e como funciona +author: Ori Pomerantz +lang: pt-br +tags: + - "vyper" + - "erc-721" + - "python" +skill: beginner +published: 2021-04-01 +--- + +## Introdução {#introduction} + +O [ERC-721](/developers/docs/standards/tokens/erc-721/) padrão é usado para manter a propriedade de tokens não fungíveis (NFT). [ERC-20](/developers/docs/standards/totens/erc-20/) os tokens se comportam como uma mercadoria, porque não há diferença entre os totens individuais. Em contraste com isso, ERC-721 tokens são projetados para ativos semelhantes, mas não idênticos, como diferentes [cat cartoons](https://www.cryptokitties.co/) ou títulos de diferentes imóveis. + +Neste artigo, vamos analisar o [contrato ERC-721 de Ryuya Nakamura](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy). Este contrato é escrito em [Vyper](https://vyper.readthedocs.io/en/latest/index.html), a Python-like linguagem de contrato projetada para tornar é mais difícil escrever código inseguro do que na solidez. + +## O Contrato {#contract} + +```python +# @dev Implementation of ERC-721 non-fungible token standard. +# @author Ryuya Nakamura (@nrryuya) +# Modified from: https://github.com/vyperlang/vyper/blob/de74722bf2d8718cca46902be165f9fe0e3641dd/examples/tokens/ERC721.vy +``` + +Comentários em Vyper, como em Python, começam com um hash (`#`) e continuam até o final da linha. Comentários que incluem `@` são usados ​​por [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) para produzir documentação legível para humanos. + +```python +from vyper.interfaces import ERC721 + +implements: ERC721 +``` + +A interface ERC-721 é construída na linguagem Vyper. [você pode ver o código definido aqui](https://github.com/vyperlang/vyper/blob/master/vyper/builtin_interfaces/ERC721.py). A definição da interface é escrita em Python, em vez de Vyper, porque as interfaces são usadas não apenas dentro da blockchain, mas também ao enviar à blockchain uma transação de um cliente externo, que pode ser escrito em Python. + +A primeira linha importa a ‘interface’, e o segundo especifica o que estamos incrementando aqui. + +### A interface ERC721Receiver {#receiver-interface} + +```python +# Interface for the contract called by safeTransferFrom() +interface ERC721Receiver: + def onERC721Received( +``` + +ERC-721 suporta dois tipos de transferência: + +- ` transfere de `, que permite ao remetente especifique qualquer endereço de destino e coloca a responsabilidade para a transferência no remetente. Isso significa que você pode transferir para um endereço inválido, caso em que o NFT será perdido para sempre. +- `safeTransferFrom`, que verifica se o endereço de destino é um contrato. Se for assim, o contrato ERC-721 pergunta ao contrato receptor se deseja receber o NFT. + +Para responder ` transferência segura de ` solicita um recebimento contrato deve implementar `ERC721 recebedor `. + +```python + _operator: address, + _from: address, +``` + +O endereço `_de ` é o proprietário atual do token. O endereço `_operador` é aquele que solicitou a transferência (esses dois podem não ser o mesmo devido às provisões). + +```python + _tokenId: uint256, +``` + +ERC-721 token IDs está 256 bits. Normalmente, elas são criados por meio de uma execução de hash da descrição que o token representa. + +```python + _data: Bytes[1024] +``` + +O requerimento pode ter até 1024 bytes de dados do usuário. + +```python + ) -> bytes32: view +``` + +Para evitar casos em que um contrato acidentalmente aceita uma transferência o valor de retorno não é um booleano, mas 256 bits com um valor específico. + +Essa função é uma `view`, o que significa que pode ler o estado da blockchain, mas não modificá-lo. + +### Eventos {#events} + +Os [eventos](https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e) são emitidos para informar usuários e servidores fora da blockchain de eventos. Observe que o conteúdo dos eventos não está disponível para contratos na blockchain. + +```python +# @dev Emits when ownership of any NFT changes by any mechanism. This event emits when NFTs are +# created (`from` == 0) and destroyed (`to` == 0). Exception: during contract creation, any +# number of NFTs may be created and assigned without emitting Transfer. At the time of any +# transfer, the approved address for that NFT (if any) is reset to none. +# @param _from Sender of NFT (if address is zero address it indicates token creation). +# @param _to Receiver of NFT (if address is zero address it indicates token destruction). +# @param _tokenId The NFT that got transferred. +event Transfer: + sender: indexed(address) + receiver: indexed(address) + tokenId: indexed(uint256) +``` + +Isso é similar para o evento ERC-20 Transfer, exceto que informamos um `tokenId` em vez de um valor. Ninguém possui o endereço zero, portanto, por convenção, o usamos para relatar a criação e a destruição de tokens. + +```python +# @dev This emits when the approved address for an NFT is changed or reaffirmed. The zero +# address indicates there is no approved address. When a Transfer event emits, this also +# indicates that the approved address for that NFT (if any) is reset to none. +# @param _owner Owner of NFT. +# @param _approved Address that we are approving. +# @param _tokenId NFT which we are approving. +event Approval: + owner: indexed(address) + approved: indexed(address) + tokenId: indexed(uint256) +``` + +Uma aprovação ERC-721 é semelhante a uma permissão ERC-20. Um endereço específico é autorizado a transferir um determinado símbolo. Isso fornece um mecanismo para os contratos responderem quando aceitam um token. Os contratos não podem ouvir os eventos, portanto, se você apenas transferir o token para eles, eles não “saberão” disso. Desta forma, primeiro, o proprietário envia uma aprovação e, em seguida, envia uma solicitação ao contrato: “Aprovei para você transferir o token X, faça…”. + +Esse é o designe escolhido por fazer o ERC-721 padrão semelhante ao padrão ERC-20. Como os tokens ERC-721 não são fungíveis, um contrato também pode identificar que obteve um token específico olhando a propriedade do token. + +```python +# @dev This emits when an operator is enabled or disabled for an owner. The operator can manage +# all NFTs of the owner. +# @param _owner Owner of NFT. +# @param _operator Address to which we are setting operator rights. +# @param _approved Status of operator rights(true if operator rights are given and false if +# revoked). +event ApprovalForAll: + owner: indexed(address) + operator: indexed(address) + approved: bool +``` + +Às vezes, é útil ter um _operador_ que pode gerenciar todos os tokens da conta de um tipo específico (aqueles gerenciados por um contrato específico), semelhante a uma procuração. Por exemplo, eu posso querer dar tal poder a um contrato que verifica se Eu não tenho contatado ele por seis meses, e se assim for distribuo os meus bens aos meus herdeiros (se um deles o pedir, contrata não pode fazer nada sem ser chamado por uma transação). No ERC-20, podemos simplesmente atribuir uma provisão alta a um contrato de herança, mas isso não funciona para ERC-721, pois os tokens não são fungíveis. Isso é o equivalente. + +O valor `approved` nos informa se o evento é para uma aprovação ou a retirada de uma aprovação. + +### Variáveis ​​de Estado {#state-vars} + +Essas variáveis contêm o estado atual dos tokens: os quais estão disponíveis e a quem os possui. A maioria delas são objetos `HashMap`, [mapeamentos unidirecionais que existem entre dois tipos](https://vyper.readthedocs.io/en/latest/types.html#mappings). + +```python +# @dev Mapping from NFT ID to the address that owns it. +idToOwner: HashMap[uint256, address] + +# @dev Mapping from NFT ID to approved address. +idToApprovals: HashMap[uint256, address] +``` + +As identidades de usuários e contratos no Ethereum são representados por endereços de 160 bits. Essas duas variáveis mapeiam IDs de tokens para seus proprietários e aqueles aprovados a transferi-los (no máximo um para cada). No Ethereum, os dados não inicializados são sempre zero, pois, se não houver proprietário ou transferidor aprovado, o valor desse token será zero. + +```python +# @dev Mapping from owner address to count of his tokens. +ownerToNFTokenCount: HashMap[address, uint256] +``` + +Essa variável possui a contagem de tokens para cada proprietário. Não há mapeamento de proprietários para tokens, então, a única forma de identificar os tokens que um proprietário específico possui é olhar para trás no histórico de eventos da blockchain e ver os eventos `Transfer` apropriados. Podemos usar essa variável para saber quando temos todos os NFTs e não precisaremos mais olhar ainda mais no tempo. + +Observe que esse algoritmo funciona apenas para interfaces do usuário e servidores externos. Código em execução na blockchain em si não pode ler eventos passados. + +```python +# @dev Mapping from owner address to mapping of operator addresses. +ownerToOperators: HashMap[address, HashMap[address, bool]] +``` + +Uma conta pode ter mais de um único operador. Um simples `HashMap` é insuficiente para mantê-los, pois cada chave gera um único valor. Em vez disso, você pode usar `HashMap[address, bool]` como valor. Por padrão, o valor para cada endereço é `False`, o que significa que ele não é um operador. Você pode definir valores como `True` conforme necessário. + +```python +# @dev Address of minter, who can mint a token +minter: address +``` + +Novos tokens têm de ser criados de alguma forma. Neste contrato há uma única entidade que está autorizada a fazê-lo, o `minter`. É provável que isso seja suficiente para um jogo, por exemplo. Para outros propósitos, pode ser necessário criar uma lógica de negócio mais complicada. + +```python +# @dev Mapping of interface id to bool about whether or not it's supported +supportedInterfaces: HashMap[bytes32, bool] + +# @dev ERC165 interface ID of ERC165 +ERC165_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000001ffc9a7 + +# @dev ERC165 interface ID of ERC721 +ERC721_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000080ac58cd +``` + +[ERC-165](https://eips.ethereum.org/EIPS/eip-165) especifica um mecanismo para um contrato divulgar como aplicações podem se comunicar com ele, com os quais ERCs ele está em conformidade. Neste caso, o contrato está em conformidade com ERC-165 e ERC-721. + +### Funções {#functions} + +Estas são as funções que realmente implementam o ERC-721. + +#### Construtor {#constructor} + +```python +@external +def __init__(): +``` + +No Vyper, assim como no Python, a função construtora é chamada `__init__`. + +```python + """ + @dev Contract constructor. + """ +``` + +No Python e no Vyper, você também pode criar um comentário especificando uma string de múltiplas linhas (que começa e termina com `"""`), e não usá-lo de qualquer forma. Esses comentários também podem incluir [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html). + +```python + self.supportedInterfaces[ERC165_INTERFACE_ID] = True + self.supportedInterfaces[ERC721_INTERFACE_ID] = True + self.minter = msg.sender +``` + +Para acessar variáveis de estado, você usa `self.` (novamente, o mesmo que em Python). + +#### Exibir funções {#views} + +São funções que não modificam o estado da blockchain e, por isso, podem ser executadas gratuitamente se chamadas externamente. Se as funções de exibição forem chamadas por um contrato, elas ainda têm de ser executadas em cada nó e, portanto, custam gás. + +```python +@view +@external +``` + +Essas palavras-chave anteriores a uma definição de função que começam com um sinal de (`@`) são chamadas de _decoradores_. Elas especificam as circunstâncias em que uma função pode ser chamada. + +- `@view` especifica que esta função é um modo de exibição. +- `@external` especifica que essa função em particular pode ser chamada por transações e por outros contratos. + +```python +def supportsInterface(_interfaceID: bytes32) -> bool: +``` + +Ao contrário do Python, o Vyper é uma [linguagem de tipo estática](https://wikipedia.org/wiki/Type_system#Static_type_checking). Você não pode declarar uma variável ou um parâmetro de função, sem identificar os tipos de [dados](https://vyper.readthedocs.io/en/latest/types.html). Neste caso, o parâmetro de entrada é `bytes32`, um valor de 256 bits (256 bits é o tamanho da palavra nativa da [Máquina Virtual do Ethereum](/developers/docs/evm/)). A saída é um booleano valor. Por convenção, os nomes dos parâmetros da função começam com um sublinhado (`_`). + +```python + """ + @dev Interface identification is specified in ERC-165. + @param _interfaceID Id of the interface + """ + return self.supportedInterfaces[_interfaceID] +``` + +Retorne o valor do `self.supportedInterfaces` HashMap, o qual é definido no construtor (`__init__`). + +```python +### VIEW FUNCTIONS ### +``` + +Estas são as funções de visualização que fornecem informações sobre os tokens disponíveis para usuários e outros contratos. + +```python +@view +@external +def balanceOf(_owner: address) -> uint256: + """ + @dev Returns the number of NFTs owned by `_owner`. + Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid. + @param _owner Address for whom to query the balance. + """ + assert _owner != ZERO_ADDRESS +``` + +Esta linha [afirma](https://vyper.readthedocs.io/en/latest/statements.html#assert) que `_owner` não é zero. Se for zero, há um erro e a operação é anulada. + +```python + return self.ownerToNFTokenCount[_owner] + +@view +@external +def ownerOf(_tokenId: uint256) -> address: + """ + @dev Returns the address of the owner of the NFT. + Throws if `_tokenId` is not a valid NFT. + @param _tokenId The identifier for an NFT. + """ + owner: address = self.idToOwner[_tokenId] + # Throws if `_tokenId` is not a valid NFT + assert owner != ZERO_ADDRESS + return owner +``` + +Na Máquina Virtual do Ethereum (EVM) qualquer armazenamento que não tenha um valor armazenado nele é zero. Se não houver token em `_tokenId`, o valor de `self.idToOwner[_tokenId]` é zero. Naquilo caso a função reverta. + +```python +@view +@external +def getApproved(_tokenId: uint256) -> address: + """ + @dev Get the approved address for a single NFT. + Throws if `_tokenId` is not a valid NFT. + @param _tokenId ID of the NFT to query the approval of. + """ + # Throws if `_tokenId` is not a valid NFT + assert self.idToOwner[_tokenId] != ZERO_ADDRESS + return self.idToApprovals[_tokenId] +``` + +Observe que `getApproved` _pode_ retornar zero. Se o token for válido, ele retorna `self.idToApprovals[_tokenId]`. Se não houver aprovador, esse valor é zero. + +```python +@view +@external +def isApprovedForAll(_owner: address, _operator: address) -> bool: + """ + @dev Checks if `_operator` is an approved operator for `_owner`. + @param _owner The address that owns the NFTs. + @param _operator The address that acts on behalf of the owner. + """ + return (self.ownerToOperators[_owner])[_operator] +``` + +Esta função checa se `_operator` tem permissão para gerenciar todos os tokens de `_owner` neste contrato. Como pode haver vários operadores, este é um Hashmap de dois níveis. + +#### Funções Auxiliares de Transferência {#transfer-helpers} + +Essas funções implementam operações que fazem parte da transferência ou gerenciamento de tokens. + +```python + +### TRANSFER FUNCTION HELPERS ### + +@view +@internal +``` + +Este decorador, `@internal`, significa que a função é somente acessível de outras funções dentro do mesmo contrato. Por convenção, estes nomes de função também começam com um sublinhado (`_`). + +```python +def _isApprovedOrOwner(_spender: address, _tokenId: uint256) -> bool: + """ + @dev Returns whether the given spender can transfer a given token ID + @param spender address of the spender to query + @param tokenId uint256 ID of the token to be transferred + @return bool whether the msg.sender is approved for the given token ID, + is an operator of the owner, or is the owner of the token + """ + owner: address = self.idToOwner[_tokenId] + spenderIsOwner: bool = owner == _spender + spenderIsApproved: bool = _spender == self.idToApprovals[_tokenId] + spenderIsApprovedForAll: bool = (self.ownerToOperators[owner])[_spender] + return (spenderIsOwner or spenderIsApproved) or spenderIsApprovedForAll +``` + +Há três maneiras na qual um endereço pode ser permitido a transferir um token: + +1. O endereço é o proprietário do token +2. O endereço é aprovado a gastar o token +3. O endereço é um operador do proprietário do token + +A função acima pode ser uma view porque ela não muda o estado. Para reduzir custos operacionais, qualquer função que _possa_ ser uma view, _deve_ ser uma view. + +```python +@internal +def _addTokenTo(_to: address, _tokenId: uint256): + """ + @dev Add a NFT to a given address + Throws if `_tokenId` is owned by someone. + """ + # Throws if `_tokenId` is owned by someone + assert self.idToOwner[_tokenId] == ZERO_ADDRESS + # Change the owner + self.idToOwner[_tokenId] = _to + # Change count tracking + self.ownerToNFTokenCount[_to] += 1 + + +@internal +def _removeTokenFrom(_from: address, _tokenId: uint256): + """ + @dev Remove a NFT from a given address + Throws if `_from` is not the current owner. + """ + # Throws if `_from` is not the current owner + assert self.idToOwner[_tokenId] == _from + # Change the owner + self.idToOwner[_tokenId] = ZERO_ADDRESS + # Change count tracking + self.ownerToNFTokenCount[_from] -= 1 +``` + +Quando há um problema com uma transferência, anulamos a chamada. + +```python +@internal +def _clearApproval(_owner: address, _tokenId: uint256): + """ + @dev Clear an approval of a given address + Throws if `_owner` is not the current owner. + """ + # Throws if `_owner` is not the current owner + assert self.idToOwner[_tokenId] == _owner + if self.idToApprovals[_tokenId] != ZERO_ADDRESS: + # Reset approvals + self.idToApprovals[_tokenId] = ZERO_ADDRESS +``` + +Altere o valor apenas se necessário. Variáveis de estado vivem no armazenamento. Escrever para o storage é uma das operações mais caras que a EVM (Máquina Virtual Ethereum) faz (em termos de [gas](/developers/docs/gas/)). Portanto, é uma boa ideia minimizá-lo, mesmo escrevendo o valor existente tem um custo alto. + +```python +@internal +def _transferFrom(_from: address, _to: address, _tokenId: uint256, _sender: address): + """ + @dev Execute transfer of a NFT. + Throws unless `msg.sender` is the current owner, an authorized operator, or the approved + address for this NFT. (NOTE: `msg.sender` not allowed in private function so pass `_sender`.) + Throws if `_to` is the zero address. + Throws if `_from` is not the current owner. + Throws if `_tokenId` is not a valid NFT. + """ +``` + +Nós temos esta função interna porque há duas maneiras de transferir tokens (normal e segura), mas nós queremos somente uma única localização no código onde nós fazemos isso para facilitar auditoria. + +```python + # Check requirements + assert self._isApprovedOrOwner(_sender, _tokenId) + # Throws if `_to` is the zero address + assert _to != ZERO_ADDRESS + # Clear approval. Throws if `_from` is not the current owner + self._clearApproval(_from, _tokenId) + # Remove NFT. Throws if `_tokenId` is not a valid NFT + self._removeTokenFrom(_from, _tokenId) + # Add NFT + self._addTokenTo(_to, _tokenId) + # Log the transfer + log Transfer(_from, _to, _tokenId) +``` + +Para emitir um evento em Vyper você usa uma declaração de `log` ([veja aqui para mais detalhes](https://vyper.readthedocs.io/en/latest/event-logging.html#event-logging)). + +#### Funções de Transferência {#transfer-funs} + +```python + +### TRANSFER FUNCTIONS ### + +@external +def transferFrom(_from: address, _to: address, _tokenId: uint256): + """ + @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved + address for this NFT. + Throws if `_from` is not the current owner. + Throws if `_to` is the zero address. + Throws if `_tokenId` is not a valid NFT. + @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else + they maybe be permanently lost. + @param _from The current owner of the NFT. + @param _to The new owner. + @param _tokenId The NFT to transfer. + """ + self._transferFrom(_from, _to, _tokenId, msg.sender) +``` + +Esta função deixa você transferir para um endereço arbitrário. A não ser que o endereço é um usuário, ou um contrato que sabe como transferir tokens, qualquer token que você transferir ficará preso no endereço e inútil. + +```python +@external +def safeTransferFrom( + _from: address, + _to: address, + _tokenId: uint256, + _data: Bytes[1024]=b"" + ): + """ + @dev Transfers the ownership of an NFT from one address to another address. + Throws unless `msg.sender` is the current owner, an authorized operator, or the + approved address for this NFT. + Throws if `_from` is not the current owner. + Throws if `_to` is the zero address. + Throws if `_tokenId` is not a valid NFT. + If `_to` is a smart contract, it calls `onERC721Received` on `_to` and throws if + the return value is not `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. + NOTE: bytes4 is represented by bytes32 with padding + @param _from The current owner of the NFT. + @param _to The new owner. + @param _tokenId The NFT to transfer. + @param _data Additional data with no specified format, sent in call to `_to`. + """ + self._transferFrom(_from, _to, _tokenId, msg.sender) +``` + +Tudo bem fazer a transferência primeiro, porque se der um problema, vamos revertê-la de qualquer maneira, a fim de anular tudo o que foi feito durante a chamada. + +```python + if _to.is_contract: # check if `_to` is a contract address +``` + +Primeiro cheque para ver se o endereço é um contrato (se ele tem código). Se não, assuma que ele é um endereço de usuário e o usuário será capaz de usar o token ou transferi-lo. Mas não deixe que isso engane você com uma falsa sensação de segurança. Você pode perder tokens, mesmo com `safeTransferFrom`, se você transferi-los para um endereço que ninguém conhece a chave privada. + +```python + returnValue: bytes32 = ERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data) +``` + +Chame o contrato-alvo para ver se ele pode receber tokens ERC-721. + +```python + # Throws if transfer destination is a contract which does not implement 'onERC721Received' + assert returnValue == method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes32) +``` + +Se o destino é um contrato, mas um que não aceita tokens ERC-721 (ou que decide não aceitar esta transferência em particular), reverta. + +```python +@external +def approve(_approved: address, _tokenId: uint256): + """ + @dev Set or reaffirm the approved address for an NFT. The zero address indicates there is no approved address. + Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner. + Throws if `_tokenId` is not a valid NFT. (NOTE: This is not written the EIP) + Throws if `_approved` is the current owner. (NOTE: This is not written the EIP) + @param _approved Address to be approved for the given NFT ID. + @param _tokenId ID of the token to be approved. + """ + owner: address = self.idToOwner[_tokenId] + # Throws if `_tokenId` is not a valid NFT + assert owner != ZERO_ADDRESS + # Throws if `_approved` is the current owner + assert _approved != owner +``` + +Por convenção, se você não quiser ter um aprovador, designe o endereço zero, não você mesmo. + +```python + # Check requirements + senderIsOwner: bool = self.idToOwner[_tokenId] == msg.sender + senderIsApprovedForAll: bool = (self.ownerToOperators[owner])[msg.sender] + assert (senderIsOwner or senderIsApprovedForAll) +``` + +Para configurar um aprovador você pode ou ser o proprietário, ou um operador autorizado pelo proprietário. + +```python + # Set the approval + self.idToApprovals[_tokenId] = _approved + log Approval(owner, _approved, _tokenId) + + +@external +def setApprovalForAll(_operator: address, _approved: bool): + """ + @dev Enables or disables approval for a third party ("operator") to manage all of + `msg.sender`'s assets. It also emits the ApprovalForAll event. + Throws if `_operator` is the `msg.sender`. (NOTE: This is not written the EIP) + @notice This works even if sender doesn't own any tokens at the time. + @param _operator Address to add to the set of authorized operators. + @param _approved True if the operators is approved, false to revoke approval. + """ + # Throws if `_operator` is the `msg.sender` + assert _operator != msg.sender + self.ownerToOperators[msg.sender][_operator] = _approved + log ApprovalForAll(msg.sender, _operator, _approved) +``` + +#### Cunhar novos tokens e destruir os existentes {#mint-burn} + +A conta que criou o contrato é o `minter`, o superusuário autorizado a cunhar novos NFTs. No entanto, mesmo isso não é autorizado para queimar tokens existentes. Somente o proprietário, ou uma entidade autorizada pelo proprietário, podem fazer isso. + +```python +### MINT & BURN FUNCTIONS ### + +@external +def mint(_to: address, _tokenId: uint256) -> bool: +``` + +Esta função sempre retorna `True`, porque se a operação falhar, ela é revertida. + +```python + """ + @dev Function to mint tokens + Throws if `msg.sender` is not the minter. + Throws if `_to` is zero address. + Throws if `_tokenId` is owned by someone. + @param _to The address that will receive the minted tokens. + @param _tokenId The token id to mint. + @return A boolean that indicates if the operation was successful. + """ + # Throws if `msg.sender` is not the minter + assert msg.sender == self.minter +``` + +Somente o minter (a conta que criou o contrato ERC-721) pode cunhar novos tokens. Isso pode ser um problema no futuro se você quiser mudar a identidade do minter. Em um contrato de produção, provavelmente seria desejável ter uma função que permita ao minter transferir privilégios de minter para uma outra pessoa. + +```python + # Throws if `_to` is zero address + assert _to != ZERO_ADDRESS + # Add NFT. Throws if `_tokenId` is owned by someone + self._addTokenTo(_to, _tokenId) + log Transfer(ZERO_ADDRESS, _to, _tokenId) + return True +``` + +Por convenção, a cunhagem de novos tokens conta como uma transferência do endereço zero. + +```python + +@external +def burn(_tokenId: uint256): + """ + @dev Burns a specific ERC721 token. + Throws unless `msg.sender` is the current owner, an authorized operator, or the approved + address for this NFT. + Throws if `_tokenId` is not a valid NFT. + @param _tokenId uint256 id of the ERC721 token to be burned. + """ + # Check requirements + assert self._isApprovedOrOwner(msg.sender, _tokenId) + owner: address = self.idToOwner[_tokenId] + # Throws if `_tokenId` is not a valid NFT + assert owner != ZERO_ADDRESS + self._clearApproval(owner, _tokenId) + self._removeTokenFrom(owner, _tokenId) + log Transfer(owner, ZERO_ADDRESS, _tokenId) +``` + +Qualquer pessoa autorizada a transferir um token, tem permissão para queimá-lo. Enquanto uma queima aparece equivalente à transferência para o endereço zero, o endereço zero não recebe de verdade o token. Isso permite-nos liberar todo o armazenamento usado pelo token, o que pode reduzir o custo de gás da transação. + +# Usando este contrato {#using-contract} + +Ao contrário do Solidity, o Vyper não tem herança. Esta é uma escolha de design deliberada para tornar o código mais claro e, com isso, mais fácil de proteger. Portanto, para criar seu próprio contrato Vyper ERC-721, você usa [este contrato](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy) e o modifica para implementar a lógica comercial que você desejar. + +# Conclusão {#conclusion} + +Recapitulando, aqui estão algumas das ideias mais importantes neste contrato: + +- Para receber os tokens ERC-721 com uma transferência segura, os contratos têm de implementar a interface `ERC721Receiver`. +- Mesmo que você use a transferência segura, os tokens ainda podem ficar presos se você os enviar para um endereço cuja chave privada. +- Quando há um problema com uma operação, é uma boa ideia fazer o `revert` da chamada, em vez de apenas retornar um valor de falha. +- Os tokens ERC-721 existem quando eles têm um proprietário. +- Existem três formas de ser autorizado a transferir um NFT. Você pode ser o proprietário, ser aprovado para um token específico, ou ser um operador para todos os tokens do proprietário. +- Eventos passados são visíveis apenas fora da blockchain. O código executando dentro da blockchain não pode visualizá-los. + +Agora, você está pronto para implementar contratos Vyper seguros. diff --git a/public/content/translations/pt-br/developers/tutorials/erc20-annotated-code/index.md b/public/content/translations/pt-br/developers/tutorials/erc20-annotated-code/index.md new file mode 100644 index 00000000000..a1180674191 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/erc20-annotated-code/index.md @@ -0,0 +1,796 @@ +--- +title: "Demonstração do Contrato ERC-20" +description: O que é o contrato OpenZeppelin ERC-20 e por que está lá? +author: Ori Pomerantz +lang: pt-br +tags: + - "solidez" + - "erc-20" +skill: beginner +published: 2021-03-09 +--- + +## Introdução {#introduction} + +Um dos usos mais comuns do Ethereum é a criação por um grupo de pessoas de um token negociável que, de certa forma, criam sua própria moeda. Essas moedas seguem a norma [ERC-20](/developers/docs/standards/tokens/erc-20/). Essa norma possibilita a criação de ferramentas, como os pools de liquidez e carteiras, que funcionam com todos os tokens ERC-20. Neste artigo, analisaremos a [Implementação do OpenZeppelin Solidity ERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol), assim como a [definição de interface](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol). + +Este é o código-fonte anotado. Se você deseja implementar ERC-20, [leia este tutorial](https://docs.openzeppelin.com/contracts/2.x/erc20-supply). + +## A 'Interface' {#the-interface} + +O objetivo de uma norma como a ERC-20 é permitir que as implementações das várias moedas sejam interoperáveis entre aplicativos, como carteiras e corretoras descentralizadas. Para atingirmos tal objetivo, criamos uma ['interface'](https://www.geeksforgeeks.org/solidity-basics-of-interface/). Qualquer código que necessite utilizar o contrato pode usar as mesmas definições de interface e ser compatível com todos os contratos de token que o usem, seja uma carteira de criptomoedas como a MetaMask, um aplicativo descentralizado como o Etherscan.io, ou um contrato diferente como um pool de liquidez. + +![Ilustração da interface ERC-20](erc20_interface.png) + +Se você é um programador experiente, provavelmente se lembra de ver constructos semelhantes em [Java](https://www.w3schools.com/java/java_interface.asp) ou mesmo em [arquivos de cabeçalho em C](https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html). + +Essa é a definição da [interface ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) do OpenZeppelin. Ela é uma tradução do [padrão legível para humanos](https://eips.ethereum.org/EIPS/eip-20) em código Solidity. Obviamente, a interface por si só não define _como_ fazer algo. Isso é explicado no código-fonte do contrato abaixo. + +  + +```solidity +// SPDX-License-Identifier: MIT +``` + +Os arquivos Solidity devem incluir um identificador de licença. [Você pode ver a lista de licenças aqui](https://spdx.org/licenses/). Se você necessitar de uma licença diferente, explique nos comentários. + +  + +```solidity +pragma solidity >=0.6.0 <0.8.0; +``` + +A linguagem Solidity continua evoluindo rapidamente, e novas versões podem não ser compatíveis com o código antigo. ([confira aqui](https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html)). Portanto, é uma boa ideia especificar não apenas uma versão mínima da linguagem, mas também uma versão máxima com a qual você testou o código. + +  + +```solidity +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +``` + +O `@dev` no comentário faz parte do [formato NatSpec](https://docs.soliditylang.org/en/develop/natspec-format.html), usado para produzir a documentação a partir de um código-fonte. + +  + +```solidity +interface IERC20 { +``` + +Convenientemente, nomes de Interface começam com `I`. + +  + +```solidity + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); +``` + +Essa função é `external`, ou seja, [só pode ser chamada de fora do contrato](https://docs.soliditylang.org/en/v0.7.0/cheatsheet.html#index-2). Ela retorna o fornecimento total de tokens no contrato. Esse valor é retornado usando o tipo mais comum no Ethereum, 256 bits não assinado (256 bits é o tamanho de fonte nativo da EVM). Essa função também é uma `view`, ou seja, ela não pode alterar o estado, portanto, ela pode ser executada em apenas um nó em vez de fazer com que todos os nós da blockchain a executem. Esse tipo de função não gera transação e não custa [gás](/developers/docs/Gas/). + +**Observação:** Em teoria, pode-se ter a impressão de que o criador do contrato conseguiria trapacear retornando uma quantia menor do fornecimento total do que a quantia real, fazendo com que cada moeda valha mais do que realmente vale. De qualquer forma, este medo ignora a verdadeira natureza da blockchain. Tudo que acontece na blockchain pode ser verificado em cada nó. Para conseguir isso, cada contrato da linguagem de código e armazenamento esta disponível em cada nó. Embora não seja obrigatório publicar o código Solidity, mas ninguém confiará em você a menos que publique o código-fonte e a versão do Solidity usados na compilação, para que ele possa ser comparado com o código de linguagem da máquina que você forneceu. Por exemplo, confira [este contrato](https://etherscan.io/address/0xa530F85085C6FE2f866E7FdB716849714a89f4CD#code). + +  + +```solidity + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); +``` + +Como o próprio nome já diz, `balanceOf` retorna o saldo de uma conta. Contas de Ethereum são identificadas em Solidity usando `address`, que contem 160 bits. Também são `external` e `view`. + +  + +```solidity + /** + * @dev Moves `amount` tokens from the caller's account to `recipient`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address recipient, uint256 amount) external returns (bool); +``` + +A função `transfer` transfere as moedas de um chamador para outro endereço. Isso envolve uma mudança de estado, então não é um `view`. Quando um usuário chama essa função, ele cria uma transação a um custo cobrada em gás. Ele também emite um evento, `Transfer`, para informar a todos na blockchain sobre esse evento. + +Essa função possui duas saídas para dois chamadores diferentes: + +- Os usuários que chamam a função diretamente de uma interface de usuário. Normalmente o usuário envia uma transação e não espera por uma resposta, que pode demorar uma quantidade indefinida de tempo. O usuário pode ver o que ocorreu procurando pelo recibo da transação (identificado pela transação hash) ou procurando pelo evento `transfer`. +- Outros contratos, nos quais chamam a função como parte de uma transação inteira. Esses contratos obtêm o resultado imediatamente, pois eles executam a mesma transação, para usar o valor de retorno da função. + +O mesmo tipo de saída é criado por outras funções que mudam o estado do contrato. + +  + +As provisões permitem que uma conta gaste tokens que pertencem a um proprietário diferente. Isso é útil, por exemplo, para contratos que agem como vendedores. Contratos não podem monitorar eventos, portanto, se um comprador quiser transferir diretamente, tokens para o contrato do vendedor, esse contrato não saberá se foi pago. Em vez disso, o comprador permite que o contrato do vendedor gaste uma certa quantia, e o vendedor transfere essa quantia. Isso é feito por meio de uma função do contrato do vendedor, para que o contrato do vendedor possa saber se a operação foi bem-sucedida. + +```solidity + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. Isso é + * zero por padrão. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); +``` + +A função `allowance` permite que qualquer pessoa consulte qual é a provisão que um endereço (`owner`) permite que outro endereço (`spender`) gaste. + +  + +```solidity + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. Uma solução possível para mitigar esta corrida + * é primeiramente reduzir a tolerância do remetente para 0 e definir o + * valor desejado depois: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emite um evento de {Approval}. + */ + function approve(address spender, uint256 amount) external returns (bool); +``` + +A função `approve` cria uma provisão. Certifique-se de ler a mensagem sobre como ela pode ser usada indevidamente. No Ethereum, você controla a ordem de suas próprias transações, mas não é possível controlar a ordem na qual as transações de outras pessoas serão executadas, a menos que você não envie sua própria transação até ver a transação de outro lado ser executada. + +  + +```solidity + /** + * @dev Moves `amount` tokens from `sender` to `recipient` using the + * allowance mechanism. O valor é então deduzido do rendimento do chamador. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); +``` + +Por fim, `transferFrom` é utilizado pelo cliente para realmente gastar a provisão. + +  + +```solidity + + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `Valor` é a nova permissão. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} +``` + +Esses eventos são emitidos quando o estado do contrato ERC-20 é alterado. + +## O contrato real {#the-actual-contract} + +Este é o contrato que implementa o padrão ERC-20, [retirado daqui](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol). Ele não é destinado a ser usado tal como é, mas você pode [herdar](https://www.tutorialspoint.com/solidity/solidity_inheritance.htm) dele para estendê-lo para algo utilizável. + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.0 <0.8.0; +``` + +  + +### Importar declarações {#import-statements} + +Além das definições de interface acima, o contrato de definição importa outros dois arquivos: + +```solidity + +import "../../GSN/Context.sol"; +import "./IERC20.sol"; +import "../../math/SafeMath.sol"; +``` + +- `GSN/Context.sol` são as definições necessárias para usar [OpenGSN](https://www.opengsn.org/), um sistema que permite que usuários sem ether possam usar a blockchain. Observe que esta é uma versão antiga. Se você quiser integrá-la com o OpenGSN [use este tutorial](https://docs.opengsn.org/javascript-client/tutorial.html). +- [A biblioteca SafeMath](https://ethereumdev.io/using-safe-math-library-to-prevent-from-‘overflows’/), que é usada para fazer adições e subtrações sem estouros. Isso é necessário, pois, do contrário, uma pessoa pode ter um token, dois tokens, e então ter 2^256-1 tokens. + +  + +Este comentário explica o propósito do contrato. + +```solidity +/** + * @dev Implementation of the {IERC20} interface. + * + * This implementation is agnostic to the way tokens are created. Isto significa +* que um mecanismo de oferta deve ser adicionado em um contrato derivado usando {_mint}. + * For a generic mechanism see {ERC20PresetMinterPauser}. + * + * TIP: For a detailed writeup see our guide + * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How + * to implement supply mechanisms]. + * + * We have followed general OpenZeppelin guidelines: functions revert instead + * of returning `false` on failure. Esse comportamento é, no entanto, convencional + * e não entra em conflito com as expectativas das aplicações do ERC20. + * + * Additionally, an {Approval} event is emitted on calls to {transferFrom}. + * This allows applications to reconstruct the allowance for all accounts just + * by listening to said events. Outras implementações do EIP podem não emitir + * esses eventos, pois não é exigido pela especificação. + * + * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} + * functions have been added to mitigate the well-known issues around setting + * allowances. Veja {IERC20-approve}. + */ + +``` + +### Definição de contrato {#contract-definition} + +```solidity +contract ERC20 is Context, IERC20 { +``` + +Esta linha especifica a herança, neste caso de `IERC20` acima e `Context`, para OpenGSN. + +  + +```solidity + + using SafeMath for uint256; + +``` + +Essa linha anexa a biblioteca `SafeMath` ao tipo `uint256`. Você pode encontrar essa biblioteca [aqui](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol). + +### Definições de variáveis {#variable-definitions} + +Essas definições especificam as variáveis de estado do contrato. Existem variáveis declaradas como `private`, mas isso apenas significa que outros contratos na blockchain não as podem ler. _Não há segredos na blockchain_, o software em cada nó possui o estado de cada contrato em cada bloco. Por convenção, as variáveis de estado são denominadas `_`. + +As duas primeiras variáveis são [mapeamentos](https://www.tutorialspoint.com/solidity/solidity_mappings.html), ou seja, se comportam mais ou menos da mesma forma que [matrizes associativas](https://wikipedia.org/wiki/Associative_array), com exceção das chaves, que são valores numéricos. O armazenamento é alocado apenas para as entradas que possuem valores diferentes do padrão (zero). + +```solidity + mapping (address => uint256) private _balances; +``` + +O primeiro mapeamento, `_balances`, é composta por endereços e seus respectivos saldos desse token. Para acessar o saldo, utilize a sintaxe: `_balances[
      ]`. + +  + +```solidity + mapping (address => mapping (address => uint256)) private _allowances; +``` + +Esta variável, `_allowances`, armazena as margens explicadas anteriormente. O primeiro índice é o proprietário das moedas, e o segundo é o contrato com a provisão. Para acessar a quantia que o endereço A pode gastar na conta do endereço B, use `_allowances[B][A]`. + +  + +```solidity + uint256 private _totalSupply; +``` + +Como o nome sugere, essa variável mantém registro do fornecimento total de tokens. + +  + +```solidity + string private _name; + string private _symbol; + uint8 private _decimals; +``` + +Essas três variáveis são usadas para melhorar a legibilidade. As duas primeiras são autoexplicativas, mas `_decimals` não. + +De um lado, o Ethereum não possui ponto flutuante ou variáveis fracionadas. De outro, as pessoas gostam de poder dividir tokens. Uma das razões pelas quais as pessoas estabeleceram o uso do ouro como moeda foi devido à dificuldade de trocá-lo quando alguém queria, por exemplo, comprar vaca pelo valor de um pato. + +A solução é manter o registro dos inteiros, mas em vez de contar o token real, contar o token fracionário, que praticamente não tem valor. No caso do ether, a moeda fracionária é chamada de wei, e 10^18 WEI é igual a um ETH. No momento da criação deste artigo, 10.000.000.000.000 WEI equivalem a cerca de um centavo de Dólar ou Euro. + +Os aplicativos precisam saber como exibir o saldo do token. Se um usuário tiver 3.141.000.000.000.000.000 WEI, seria equivalente a 3,14 ETH? 31,41 ETH? 3,141 ETH? No caso do ETH, é definido 10^18 WEI para o ETH, mas para sua moeda, você pode escolher um valor diferente. Se dividir uma moeda não fizer sentido, você pode usar um valor `_decimals` de zero. Se você quiser utilizar o mesmo padrão utilizado em ETH, use o valor **18**. + +### O Constructor {#the-constructor} + +```solidity + /** + * @dev Sets the values for {name} and {symbol}, initializes {decimals} with + * a default value of 18. + * + * To select a different value for {decimals}, use {_setupDecimals}. + * + * All three of these values are immutable: they can only be set once during + * construction. + */ + constructor (string memory name_, string memory symbol_) public { + _name = name_; + _symbol = symbol_; + _decimals = 18; + } +``` + +O construtor é chamado quando o contrato é criado pela primeira vez. Por convenção, os parâmetros da função são denominados `_`. + +### Funções da interface do usuário {#user-interface-functions} + +```solidity + /** + * @dev Returns the name of the token. + */ + function name() public view returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5,05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * ether and wei. Esse é o valor {ERC20} usado, a menos que {_setupDecimals} seja + * chamado. + * + * NOTE: This information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * {IERC20-balanceOf} and {IERC20-transfer}. + */ + function decimals() public view returns (uint8) { + return _decimals; + } +``` + +Essas funções, `nome`, `symbol` e `decimals`, ajudam as interfaces do usuário a conhecer o seu contrato para poderem exibi-lo corretamente. + +O tipo do retorno é `string memory`, o que significa que retorna uma string que é armazenada na memória. Variáveis, como ‘strings’, podem ser armazenadas em três locais: + +| | Tempo de vida | Acesso ao contrato | Custo em gás | +| ------------- | ----------------- | ------------------ | ------------------------------------------------------------------------ | +| Memória | Chamada da função | Leitura/gravação | Dezenas ou centenas (maior para locais mais altos) | +| Calldata | Chamar Função | Somente leitura | Não pode ser usada como retorno, apenas como tipo de parâmetro de função | +| Armazenamento | Até ser alterado | Ler/Escrever | Alto (800 para leitura, 20 mil para gravação) | + +Neste caso, `memory` é a melhor escolha. + +### Informação de leitura do token {#read-token-information} + +Essas funções fornecem informações sobre o token, seja o fornecimento total ou o saldo de uma conta. + +```solidity + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view override returns (uint256) { + return _totalSupply; + } +``` + +A função `totalSupply` retorna o fornecimento total de tokens. + +  + +```solidity + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf(address account) public view override returns (uint256) { + return _balances[account]; + } +``` + +Leia o saldo de uma conta. Observe que qualquer um pode obter o saldo da conta de outra pessoa. Não há motivo para esconder essa informação, pois ela está disponível em todos os nós. _Não há segredos na blockchain._ + +### Transferência de tokens {#transfer-tokens} + +```solidity + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `recipient` cannot be the zero address. + * - the caller must have a balance of at least `amount`. + */ + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { +``` + +A função `transfer` é chamada para transferir os tokens do remetente para um destinatário. Observe que mesmo que ela retorne um valor booleano, o valor é sempre **true**. Se a transferência falhar, o contrato anulará a chamada. + +  + +```solidity + _transfer(_msgSender(), recipient, amount); + return true; + } +``` + +A função `_transfer` faz o trabalho real. Ela é uma função privada que só pode ser chamada por outras funções de contrato. Por convenção, funções privadas são denominadas `_`, assim como as variáveis de estado. + +Normalmente, usamos `msg.sender` no Solidity para o remetente de mensagens. No entanto, isso rompe a [OpenGSN](http://opengsn.org/). Caso queiramos permitir transações sem Eth com nosso token, precisamos usar `_msgSender()`. Ela retornará `msg.sender` para transações normais, mas para transações sem Eth, ela indicará o signatário original e não o contrato que repassou a mensagem. + +### Funções de margem {#allowance-functions} + +Estas são as funções que implementam a funcionalidade da margem: `allowance`, `approve`, `transferFrom`, e `_approve`. Além disso, a implementação do OpenZeppelin vai além do padrão básico, para poder incluir alguns recursos que melhoram a segurança: `increaseAllowance`, e `decreaseAllowance`. + +#### A função allowance {#allowance} + +```solidity + /** + * @dev See {IERC20-allowance}. + */ + function allowance(address owner, address spender) public view virtual override returns (uint256) { + return _allowances[owner][spender]; + } +``` + +A função `allowance` permite que todo mundo confira qualquer margem. + +#### A função approve {#approve} + +```solidity + /** + * @dev See {IERC20-approve}. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 amount) public virtual override returns (bool) { +``` + +Essa função é chamada para criar uma provisão. Ela é semelhante à função `transfer` acima: + +- A função apenas chama uma função interna (neste caso, `_approve`) que realmente faz o trabalho. +- A função retorna `true` (se for bem-sucedida) ou é revertida (se falhar). + +  + +```solidity + _approve(_msgSender(), spender, amount); + return tu; +} +``` + +Usamos funções internas para minimizar a quantidade de lugares onde as mudanças de estado ocorrem. _Qualquer_ função que mude o estado constitui um risco de segurança em potencial que precisa ser auditado para segurança. Dessa forma, temos menos chances de errar. + +#### A função transferFrom {#transferFrom} + +Essa é a função que um gastador chama para gastar uma margem. Isso requer duas operações: transfira o valor sendo gasto e reduza a margem nesse valor. + +```solidity + /** + * @dev See {IERC20-transferFrom}. + * + * Emits an {Approval} event indicating the updated allowance. Isso não é + * necessário para o EIP. Veja a nota no início do {ERC20}. + * + * Requirements: + * + * - `sender` and `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + * - the caller must have allowance for ``sender``'s tokens of at least + * `amount`. + */ + function transferFrom(address sender, address recipient, uint256 amount) public virtual + override returns (bool) { + _transfer(sender, recipient, amount); +``` + +  + +A chamada da função `a.sub(b, "message")` faz duas coisas. Primeiro, ela calcula `a-b`, que é a nova margem. Em seguida, ela verifica se esse resultado não é negativo. Se for negativo, a chamada é revertida com a mensagem fornecida. Observe que, quando uma chamada reverte qualquer processamento feito anteriormente a essa chamada, ela é ignorada para não precisarmos desfazer a `_transfer`. + +```solidity + _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, + "ERC20: transfer amount exceeds allowance")); + return true; + } +``` + +#### Adições de segurança do OpenZeppelin {#openzeppelin-safety-additions} + +É perigoso definir uma margem que não seja zero como outro valor que não seja zero, porque você só controla a ordem de suas próprias transações, mas não as de outras pessoas. Imagine que você tenha dois usuários: Alice, que é ingênua, e Bill, que é desonesto. Alice quer solicitar um serviço de Bill que, segundo ela, custa cinco tokens — então, ela dá a Bill uma provisão de cinco tokens. + +Então, algo muda e o preço de Bill aumenta para dez tokens. Alice, que ainda quer o serviço, envia uma transação que define a provisão de Bill para dez. No momento em que Bill vê essa nova transação no pool de transações, ele envia uma transação que gasta os cinco tokens de Alice e com uma tarifa de gás muito mais alta que, portanto, será minerada mais rápido. Dessa forma, Bill pode gastar os cinco primeiros tokens e, quando a nova provisão de Alice for minerada, pode gastar mais dez por um preço total de quinze tokens, mais do que Alice queria autorizar. Essa técnica é chamada de [front-running](https://consensys.github.io/smart-contract-best-practices/attacks/#front-running) + +| Transação de Alice | Nonce de Alice | Transação de Bill | Nonce de Bill | A provisão de Bill | Total faturado por Bill de Alice | +| ------------------ | -------------- | ----------------------------- | ------------- | ------------------ | -------------------------------- | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| | | transferFrom(Alice, Bill, 5) | 10.123 | 0 | 5 | +| approve(Bill, 10) | 11 | | | 10 | 5 | +| | | transferFrom(Alice, Bill, 10) | 10.124 | 0 | 15 | + +Para evitar esse problema, essas duas funções (`increaseAllowance` e `reduaseAllowance`) permitem que você modifique a provisão por um valor específico. Então, se Bill já tinha gastado cinco tokens, ele só poderá gastar mais cinco tokens. Dependendo do tempo disponível, há duas maneiras de proceder, sendo que as duas acabam com Bill obtendo os dez tokens: + +A: + +| Transação de Alice | Nonce de Alice | Transação de Bill | Nonce de Bill | Permissão de Bill | Cobrança Total de Alice | +| -------------------------- | --------------:| ---------------------------- | -------------:| -----------------:| ----------------------- | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 | +| increaseAllowance(Bill, 5) | 11 | | | 0+5 = 5 | 5 | +| | | transferFrom(Alice, Bill, 5) | 10,124 | 0 | 10 | + +B: + +| Transação de Alice | Nonce de Alice | Transação de Bill | Nonce de Bill | Permissão de Bill | Cobrança Total de Alice | +| -------------------------- | --------------:| ----------------------------- | -------------:| -----------------:| -----------------------:| +| approve(Bill, 5) | 10 | | | 5 | 0 | +| increaseAllowance(Bill, 5) | 11 | | | 5+5 = 10 | 0 | +| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 10 | + +```solidity + /** + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { + _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); + return true; + } +``` + +A função `a.add(b)` é uma adição segura. No caso improvável de `um`+`b`>=`2^256`, ele não é contornado da mesma maneira que uma adição normal. + +```solidity + + /** + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `subtractedValue`. + */ + function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { + _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, + "ERC20: decreased allowance below zero")); + return true; + } +``` + +### Funções que modificam informações do token {#functions-that-modify-token-information} + +Essas são as quatro funções que realmente funcionam: `_transfer`, `_mint`, `_burn`, e `_appro`. + +#### A função \_transfer {#\_transfer} + +```solidity + /** + * @dev Moves tokens `amount` from `sender` to `recipient`. + * + * This is internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * Requirements: + * + * - `sender` cannot be the zero address. + * - `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + */ + function _transfer(address sender, address recipient, uint256 amount) internal virtual { +``` + +Esta função, `_transfer`, transfere moedas de uma conta para outra. Ela é chamada por `transfer` (para transferências da própria conta do remetente) e `transferFrom` (para usar as provisões a serem transferidas da conta de outra pessoa). + +  + +```solidity + require(sender != address(0), "ERC20: transfer from the zero address"); + require(recipient != address(0), "ERC20: transfer to the zero address"); +``` + +Na verdade, ninguém possui o endereço zero no Ethereum (ou seja, ninguém conhece uma chave privada cuja chave pública correspondente tenha sido transformada no endereço zero). Quando as pessoas usam esse endereço, geralmente se trata de um bug de software, portanto, falhamos se o endereço zero é usado como o remetente ou o destinatário. + +  + +```solidity + _beforeTokenTransfer(sender, recipient, amount); + +``` + +Existem duas maneiras de usar esse contrato: + +1. Use-o como um modelo para o seu próprio código +1. [Herde a partir daqui](https://www.bitdegree.org/learn/solidity-inheritance) e substitua apenas as funções que você precisa modificar + +O segundo método é muito melhor, porque o código OpenZeppelin ERC-20 já foi auditado e comprovado como seguro. Ao usar a herança, é fácil distinguir quais são as funções que você modificou e, para confiar nos seus contratos, as pessoas só precisam auditar essas funções específicas. + +Geralmente, é útil executar uma função toda vez que os tokens mudam de mãos. No entanto,`_transfer` é uma função muito importante e é possível escrevê-la de forma não segura (veja abaixo). Portanto, é melhor não substituí-la. A solução é `_beforeTokenTransfer`, uma [função hook](https://wikipedia.org/wiki/Hooking). Você pode substituir essa função e ela será chamada em cada transferência. + +  + +```solidity + _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); + _balances[recipient] = _balances[recipient].add(amount); +``` + +Essas são as linhas que realmente executam a transferência. Observe que não há **nada** entre elas, e que subtraímos o valor transferido do remetente antes de adicioná-lo ao destinatário. Isso é importante, pois se tivesse ocorrido uma chamada para um contrato diferente nesse meio tempo, ela poderia ter sido utilizada para enganar esse contrato. Dessa forma, a transferência é atômica, ou seja, nada pode acontecer enquanto ela está em execução. + +  + +```solidity + emit Transfer(sender, recipient, amount); + } +``` + +Essa função emite o evento `Transfer`. Os eventos não são acessíveis para contratos inteligentes, mas o código executado fora da blockchain pode ouvir os eventos e reagir a eles. Por exemplo, uma carteira pode monitorar quando o proprietário obtém mais tokens. + +#### As funções \_mint e \_burn {#\_mint-and-\_burn} + +Essas duas funções (`_mint` e `_burn`) modificam o fornecimento total de moedas. Elas são internas e não há nenhuma função que as chame nesse contrato, portanto, elas só são úteis se você herdar do contrato e adicionar sua própria lógica para decidir em que condições gerar novos tokens ou usar os tokens já existentes. + +**OBSERVAÇÃO:** Todos os tokens ERC-20 têm sua própria lógica comercial que dita o gerenciamento de tokens. Por exemplo, um contrato de fornecimento fixo só pode chamar `_mint` no construtor e nunca chamar `_burn`. Um contrato que vende tokens chamará `_mint` quando for pago, e provavelmente chamará `_burn` em algum momento para evitar hiperinflação. + +```solidity + /** @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * Requirements: + * + * - `to` cannot be the zero address. + */ + function _mint(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: mint to the zero address"); + _beforeTokenTransfer(address(0), account, amount); + _totalSupply = _totalSupply.add(amount); + _balances[account] = _balances[account].add(amount); + emit Transfer(address(0), account, amount); + } +``` + +Certifique-se de atualizar o `_totalSupply` quando o número total de tokens mudar. + +  + +``` + /** + * @dev Destroys `amount` tokens from `account`, reducing the + * total supply. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * Requirements: + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. + */ + function _burn(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: burn from the zero address"); + + _beforeTokenTransfer(account, address(0), amount); + + _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); + _totalSupply = _totalSupply.sub(amount); + emit Transfer(account, address(0), amount); + } +``` + +A função `_burn` é quase idêntica à `_mint`, exceto que ela funciona na direção inversa. + +#### A função \_approve {#\_approve} + +Essa é a função que especifica as provisões. Observe que ela permite que um proprietário especifique uma provisão superior ao saldo atual do proprietário. Isso não tem problema, pois o saldo é verificado no momento da transferência, quando ele poderia diferir do saldo no momento da criação da provisão. + +```solidity + /** + * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + */ + function _approve(address owner, address spender, uint256 amount) internal virtual { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = amount; +``` + +  + +Emita um evento `Approval`. Dependendo de como o aplicativo é escrito, o contrato do gastador pode ser informado sobre a aprovação, seja pelo proprietário, seja pelo servidor que realiza esses eventos. + +```solidity + emit Approval(owner, spender, amount); + } + +``` + +### Modificando as variáveis decimais {#modify-the-decimals-variable} + +```solidity + + + /** + * @dev Sets {decimals} to a value other than the default one of 18. + * + * WARNING: This function should only be called from the constructor. A maioria dos + * aplicativos que interagem com contratos das moedas não esperarão que + * {decimals} altere, e pode funcionar incorretamente se ele o fizer. + */ + function _setupDecimals(uint8 decimals_) internal { + _decimals = decimals_; + } +``` + +Essa função modifica a variável `_decimals` utilizada para dizer às ‘interfaces’ de usuário como interpretar o valor. Você deve chamá-la a partir do construtor. Seria desonesto chamá-la em qualquer ponto subsequente, ainda mais que aplicativos não são projetados para lidar com isso. + +### Ganchos {#hooks} + +```solidity + + /** + * @dev Hook that is called before any transfer of tokens. This includes + * minting and burning. + * + * Calling conditions: + * + * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens + * will be to transferred to `to`. + * - when `from` is zero, `amount` tokens will be minted for `to`. + * - when `to` is zero, `amount` of ``from``'s tokens will be burned. + * - `from` and `to` are never both zero. + * + * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + */ + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } +} +``` + +Essa é a função hook a ser chamada durante as transferências. Ela está vazia, mas se precisar dela para fazer algo, basta sobrescrevê-la. + +# Conclusão {#conclusion} + +Resumindo, aqui estão algumas das ideias mais importantes neste contrato (na minha opinião, pode ser que as suas não sejam as mesmas): + +- _Não há segredos na blockchain_. Qualquer informação que um contrato inteligente possa acessar está disponível para o mundo inteiro. +- Você pode controlar a ordem de suas transações, mas não quando transações de outras pessoas estão em andamento. É por isso que alterar uma provisão pode ser perigoso, porque permite que o gastador gaste a soma das duas provisões. +- Valores do tipo `uint256` aproximados. Em outras palavras, _0-1=2^256-1_. Se esse não for o comportamento desejado, você precisa verificá-lo (ou usar a biblioteca SafeMath que faz isso por você). Observe que isso foi alterado em [Solidity 0.8.0](https://docs.soliditylang.org/en/breaking/080-breaking-changes.html). +- Faça todas as mudanças de estado de um tipo específico e em um local específico, pois isso facilita a auditoria. Esse é o motivo pelo qual temos, por exemplo, `_approve`, chamado por `approve`, `transferFrom`, `increaseAllowance` e `decreaseAllowance` +- Mudanças de estado devem ser atômicas, sem qualquer outra ação no meio (como se pode ver em `_transfer`). Isso ocorre, pois, durante a mudança de estado, o estado é inconsistente. Por exemplo, entre o tempo que você deduz do saldo do remetente e o tempo de adicionar ao saldo do beneficiário, há menos tokens existentes do que deveria haver. Isto pode ser potencialmente explorado mal-intencionadamente se houver operações entre eles, especialmente chamadas para um contrato diferente. + +Agora que você já viu como o contrato do OpenZeppelin ERC-20 é escrito, e especialmente como ele se tornou mais seguro, escreva seus próprios contratos e aplicativos seguros. diff --git a/public/content/translations/pt-br/developers/tutorials/erc20-with-safety-rails/index.md b/public/content/translations/pt-br/developers/tutorials/erc20-with-safety-rails/index.md new file mode 100644 index 00000000000..e0ffcd80edf --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/erc20-with-safety-rails/index.md @@ -0,0 +1,213 @@ +--- +title: ERC-20 com Trilhos de Segurança +description: Como ajudar pessoas para evitar erros tolos +author: Ori Pomerantz +lang: pt-br +tags: + - "erc-20" +skill: intermediate +published: 2022-08-15 +--- + +## Introdução {#introduction} + +Uma das melhores coisas sobre o Ethereum é que não há autoridade central que possa modificar ou desfazer transações. Um dos maiores problemas do Ethereum é que não há autoridade central com o poder de desfazer erros de usuário ou transações ilícitas. Neste artigo, você aprenderá sobre alguns dos erros comuns que usuários cometem com tokens [ERC-20](/developers/docs/standards/tokens/erc-20/), assim como criar contratos ERC-20 que ajudam usuários a evitar esses erros, ou que dão a uma autoridade central algum poder (por exemplo, congelar contas). + +Observe que, apesar de usarmos o [contrato de token ERC-20 da OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20), este artigo não o explica em maiores detalhes. Você pode encontrar esta informação [aqui](/developers/tutorials/erc20-annotated-code). + +Se você quiser ver o código-fonte completo: + +1. Abra o [Remix IDE](https://remix.ethereum.org/). +2. Clique o ícone de clonar o github (![clone github icon](icon-clone.png)). +3. Clone o repositório github `https://github.com/qbzzt/20220815-erc20-safety-rails`. +4. Abra **contracts > erc20-safety-rails.sol**. + +## Criando um contrato ERC-20 {#creating-an-erc-20-contract} + +Antes que nós possamos adicionar funcionalidade de trilhos de segurança, nós precisamos de um contrato ERC-20. Neste artigo, usaremos o [o Assistente de contratos da OpenZeppelin](https://docs.openzeppelin.com/contracts/4.x/wizard). Abra-o em outro navegador e siga estas instruções: + +1. Selecione **ERC20**. +2. Entre estas configurações: + + | Parâmetro | Valor | + | ------------------------- | ---------------- | + | Nome | SafetyRailsToken | + | Símbolo | SAFE | + | Pré-cunhagem | 1.000 | + | Recursos | Nenhum | + | Controle de acesso | Proprietário | + | Capacidade de atualização | Nenhum | + +3. Suba e clique **Open in Remix** (para o Remix) ou **Download** para usar um ambiente diferente. Vou presumir que você está usando o Remix. Se você estiver usando algo diferente, faça as mudanças apropriadas. +4. Agora, temos um contrato ERC-20 totalmente funcional. Você pode expandir `.deps` e `npm` para ver o código importado. +5. Compile, implante e brinque com o contrato para ver se ele funciona como um contrato ERC-20. Se você precisar aprender como usar o Remix, [use este tutorial](https://remix.ethereum.org/?#activate=udapp,solidity,LearnEth). + +## Erros comuns {#common-mistakes} + +### Os erros {#the-mistakes} + +Às vezes, os usuários enviam tokens para o endereço errado. Embora não consigamos ler a mente dos usuários para saber o que querem fazer, há dois tipos de erros que ocorrem muitas vezes e são fáceis de detectar: + +1. Enviar os tokens para o próprio endereço do contrato. Por exemplo, [token Optimism's OP](https://optimism.mirror.xyz/qvd0WfuLKnePm1Gxb9dpGchPf5uDz5NSMEFdgirDS4c) acabou acumulando [mais de 120.000](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000042#tokentxns) tokens OP em menos de dois meses. Isso representa uma quantia de dinheiro significativa, que presumimos que as pessoas tenham simplesmente perdido. + +2. Enviar os tokens para um endereço vazio, um que não corresponde a uma [conta de propriedade externa](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs) ou um [contrato inteligente](/developers/docs/smart-contracts). Enquanto eu não tenho estatísticas de quão frequente isso acontece, [um incidente poderia ter custado 20.000.000 de tokens](https://gov.optimism.io/t/message-to-optimism-community-from-wintermute/2595). + +### Evitando transferências {#preventing-transfers} + +O contrato OpenZeppelin ERC-20 inclui [um hook, `_beforeTokenTransfer`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol#L364-L368), que é chamado antes de um token ser transferido. Por padrão, esse hook não faz nada, mas podemos pendurar nossas próprias funcionalidades, como verificações que são anuladas se houver um problema. + +Para usar o hook, adicione esta função depois do construtor: + +```solidity + function _beforeTokenTransfer(address from, address to, uint256 amount) + internal virtual + override(ERC20) + { + super._beforeTokenTransfer(from, to, amount); + } +``` + +Algumas partes desta função podem ser novas se você não estiver muito familiarizado com o Solidity: + +```solidity + internal virtual +``` + +A palavra-chave `virtual` significa que conforme herdamos funcionalidades do `ERC20` e substituímos essa função, outros contratos podem herdar de nós e substituir essa função. + +```solidity + override(ERC20) +``` + +Temos que especificar explicitamente que estamos [substituindo](https://docs.soliditylang.org/en/v0.8.15/contracts.html#function-overriding) a definição de token ERC20 de `_beforeTokenTransfer`. Em geral, definições explícitas são muito melhores, do ponto de vista da segurança, do que as implícitas — você não pode se esquecer de que fez algo se isso estive bem na sua frente. Esta também é a razão que nós precisamos para especificar que superclasses `_beforeTokenTransfer` nós estamos sobrepondo. + +```solidity + super._beforeTokenTransfer(from, to, amount); +``` + +Esta linha chama a função `_beforeTokenTransfer` do contrato ou contratos que herdamos e que a possui. Neste caso, isto é somente `ERC20`, `Ownable` não tem esse hook. Mesmo que, atualmente, o `ERC20._beforeTokenTransfer` não faça nada, nós o chamamos caso a funcionalidade seja adicionada no futuro (e nós então decidimos reimplantar o contrato, porque contratos não mudam depois da implantação). + +### Codificando os requisitos {#coding-the-requirements} + +Nós queremos adicionar estes requisitos para a função: + +- O endereço `to` não pode ser igual a `address(this)`, o endereço do contrato ERC-20 propriamente dito. +- O endereço `to` não pode ser vazio, ele tem de ser: + - Uma conta de propriedade externa (EOA). Nós não podemos checar se um endereço é um EOA diretamente, mas nós podemos checar o saldo em ETH de um endereço. EOAs quase sempre têm um saldo, mesmo que não estejam mais sendo usados — é difícil esvaziá-los até o último wei. + - Um contrato inteligente. Testar se um endereço é um contrato inteligente é um pouco mais difícil. Há um opcode que checa o tamanho do código externo, chamado [`EXTCODESIZE`](https://www.evm.codes/#3b), mas ele não é disponível diretamente em Solidity. Para isso, temos que usar [Yul](https://docs.soliditylang.org/en/v0.8.15/yul.html), que é um assembly da EVM. Há outros valores do Solidity que poderíamos usar ([`
      .code` e `
      .codehash`](https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#members-of-address-types)), mas eles são mais caros. + +Vamos passar sobre o código novo, linha a linha: + +```solidity + require(to != address(this), "Can't send tokens to the contract address"); +``` + +Este é o primeiro requisito, verificar se `to` e `this(address)` não são a mesma coisa. + +```solidity + bool isToContract; + assembly { + isToContract := gt(extcodesize(to), 0) + } +``` + +É assim que verificamos se um endereço é um contrato. Não podemos receber saídas diretamente do Yul, então, em vez disso, definimos uma variável para manter o resultado (`isToContract` neste caso). A maneira como o Yul trabalha é considerando cada opcode como uma função. Então, primeiro chamamos [`EXTCODESIZE`](https://www.evm.codes/#3b) para obter o tamanho do contrato e, em seguida, usamos [`GT`](https://www.evm.codes/#11) para verificar se não é zero (estamos lidando com inteiros sem sinal, então claro que ele não pode ser negativo). Então, escrevemos o resultado em `isToContract`. + +```solidity + require(to.balance != 0 || isToContract, "Can't send tokens to an empty address"); +``` + +Por fim, temos a verificação real de endereços vazios. + +## Acesso administrativo {#admin-access} + +Algumas vezes é útil ter um administrador que pode desfazer erros. Para reduzir o potencial de abuso, esse administrador pode ser um [multisig](https://blog.logrocket.com/security-choices-multi-signature-wallets/) para que várias pessoas tenham que concordar com uma ação. Neste artigo, teremos dois recursos administrativos: + +1. Congelar e descongelar contas. Isto pode ser útil, por exemplo, quando uma conta for comprometida. +2. Limpeza de ativos. + + Às vezes, fraudadores enviam tokens fraudulentos para o contrato do token real para ganhar legitimidade. Por exemplo, [veja aqui](https://optimistic.etherscan.io/token/0x2348b1a1228ddcd2db668c3d30207c3e1852fbbe?a=0x4200000000000000000000000000000000000042). O contrato ERC-20 legítimo é [0x4200....0042](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000042). A fraude que finge ser o contrato é [0x234....bbe](https://optimistic.etherscan.io/address/0x2348b1a1228ddcd2db668c3d30207c3e1852fbbe). + + Também é possível que pessoas enviem tokens ERC-20 legítimos para nosso contrato por erro, que é outra razão para querer ter uma maneira de tirá-los de lá. + +OpenZeppelin fornece dois mecanismos para habilitar acesso administrativo: + +- [`Ownable`](https://docs.openzeppelin.com/contracts/4.x/access-control#ownership-and-ownable) contratos tem um único priprietário. Funções que tem o [modifier](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) `onlyOwner` só podem ser chamadas por este proprietário. Os proprietários podem transferir a propriedade para outra pessoa ou renunciar a ela completamente. Os direitos de todas as outras contas são geralmente idênticas. +- Os contratos [`AccessControl`](https://docs.openzeppelin.com/contracts/4.x/access-control#role-based-access-control) têm [controle de acesso baseado em função (RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control). + +Por simplicidade, neste artigo usamos `Ownable`. + +### Congelando e descongelando contratos {#freezing-and-thawing-contracts} + +Congelar e descongelar contratos requer várias mudanças: + +- Um [mapeamento](https://www.tutorialspoint.com/solidity/solidity_mappings.htm) de endereços em [booleanos](https://en.wikipedia.org/wiki/Boolean_data_type) para manter o controle de quais endereços estão congelados. Todos os valores são inicialmente zero, o que, para valores booleanos, é interpretado como falso. Isto é o que queremos porque, por padrão, as contas não são congeladas. + + ```solidity + mapping(address => bool) public frozenAccounts; + ``` + +- [Eventos](https://www.tutorialspoint.com/solidity/solidity_events.htm) para informar qualquer pessoa interessada, quando uma conta é congelada ou descongelada. Tecnicamente falando, os eventos não são necessários para essas ações, mas ajuda o código fora da cadeia a ser capaz de ouvir esses eventos e saber o que está acontecendo. É considerado uma boa conduta para um contrato inteligente emiti-los quando acontece algo que pode ser relevante para outra pessoa. + + Os eventos são indexados, então, será possível pesquisar todas as vezes que uma conta foi congelada ou descongelada. + + ```solidity + // When accounts are frozen or unfrozen + event AccountFrozen(address indexed _addr); + event AccountThawed(address indexed _addr); + ``` + +- Funções para congelar e descongelar contas. Essas duas funções são praticamente idênticas, por isso, analisaremos apenas a função de congelamento. + + ```solidity + function freezeAccount(address addr) + public + onlyOwner + ``` + + As funções marcadas como [`public`](https://www.tutorialspoint.com/solidity/solidity_contracts.htm) podem ser chamadas a partir de outros contratos inteligentes ou diretamente por uma transação. + + ```solidity + { + require(!frozenAccounts[addr], "Account already frozen"); + frozenAccounts[addr] = true; + emit AccountFrozen(addr); + } // freezeAccount + ``` + + Se a conta já estiver congelada, reverta-a. Caso contrário, congele-a e envie um evento `emit`. + +- Mude o `_beforeTokenTransfer` para evitar que o dinheiro seja movido de uma conta congelada. Note que o dinheiro ainda pode ser transferido para a conta congelada. + + ```solidity + require(!frozenAccounts[from], "The account is frozen"); + ``` + +### Limpeza de ativos {#asset-cleanup} + +Para liberar os tokens ERC-20 mantidos por este contrato, precisamos chamar uma função no contrato do token ao qual eles fazem parte, [`transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer) ou [`approve`](https://eips.ethereum.org/EIPS/eip-20#approve). Nesse caso, não faz sentido desperdiçar gás em provisões. Vale mais a pena transferir diretamente. + +```solidity + function cleanupERC20( + address erc20, + address dest + ) + public + onlyOwner + { + IERC20 token = IERC20(erc20); +``` + +Essa é a sintaxe para criar um objeto para um contrato quando recebemos o endereço. Podemos fazer isso porque temos a definição de tokens ERC20 como parte do código-fonte (veja a linha 4) e esse arquivo inclui [a definição para IERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol), a interface para um contrato OpenZeppelin ERC-20. + +```solidity + uint balance = token.balanceOf(address(this)); + token.transfer(dest, balance); + } +``` + +Esta é uma função de limpeza, portanto, provavelmente não queremos deixar nenhum token. Em vez de obter o saldo do usuário manualmente, podemos também automatizar o processo. + +## Conclusão {#conclusion} + +Esta não é uma solução perfeita — não há solução perfeita para o problema do “usuário que cometeu um erro”. No entanto, usar esses tipos de verificações pode, pelo menos, evitar alguns erros. A capacidade de congelar contas, embora seja perigosa, pode ser usada para limitar os danos de certos ataques ao negar ao hacker os fundos roubados. diff --git a/public/content/translations/pt-br/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md b/public/content/translations/pt-br/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md new file mode 100644 index 00000000000..922ce204baa --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md @@ -0,0 +1,154 @@ +--- +title: Introdução ao Desenvolvimento Ethereum +description: "Este é um guia para iniciantes no desenvolvimento do Ethereum. Iremos levá-lo desde a criação de um endpoint de API, para fazer uma solicitação de linha de comando, para escrever seu primeiro script web3! Não é necessário ter experiência em desenvolvimento de blockchain!" +author: "Elan Halpern" +tags: + - "javascript" + - "ethers.js" + - "nódulos" + - "consultando" + - "alchemy" +skill: beginner +lang: pt-br +published: 2020-10-30 +source: Médio +sourceUrl: https://medium.com/alchemy-api/getting-started-with-ethereum-development-using-alchemy-c3d6a45c567f +--- + +![Logos do Ethereum e Alchemy](./ethereum-alchemy.png) + +Este é um guia de iniciantes para começar com o desenvolvimento na Ethereum. Neste tutorial, usaremos a [Alchemy](https://alchemyapi.io/), a plataforma líder de desenvolvedores de blockchain, capacitando milhões de usuários em 70% dos principais aplicativos de blockchain, incluindo Maker, 0x, MyEtherWallet, Dharma e Kyber. A Alchemy nos dará acesso a um ponto de extremidade de API na cadeia do Ethereum para que possamos ler e escrever transações. + +Ajudaremos você a se inscrever na Alchemy para escrever o seu primeiro script web3! Não é necessário ter experiência em desenvolvimento de blockchain! + +## 1. Inscreva-se para obter uma conta gratuita da Alchemy {#sign-up-for-a-free-alchemy-account} + +Criar uma conta em Alchemy é fácil, [inscreva-se gratuitamente aqui](https://auth.alchemyapi.io/signup). + +## 2. Criar um app Alchemy {#create-an-alchemy-app} + +Para se comunicar com a chain da Ethereum e usar os produtos da Alchemy, você precisa de uma chave de API para autenticar as suas solicitações. + +Você pode [criar chaves de API a partir do painel de controle](http://dashboard.alchemyapi.io/). Para fazer uma nova chave, navegue até "Create app" como mostrado abaixo: + +Um agradecimento especial ao [_ShapeShift_](https://shapeshift.com/) _por nos permitir mostrar seu painel!_ + +![Painel de controle Alchemy](./alchemy-dashboard.png) + +Preencha os detalhes em "Create app" para obter sua nova chave. Aqui você também pode ver os apps criados anteriormente, bem como os criados pela sua equipe. Pegue chaves existentes clicando em "View Key" para qualquer app. + +![Criar app com um Alchemy screenshot](./create-app.png) + +Você também pode extrair chaves de API existentes, passando o mouse sobre “Aplicativos” e selecionando uma. Você pode “Visualizar chave” aqui, bem como “Editar aplicativo” na lista de permissões de domínios específicos, ver várias ferramentas de desenvolvedor e visualizar análises. + +![Gif mostrando a um usuário como requisitar chaves API](./pull-api-keys.gif) + +## 3. Fazer uma requisição via Command line {#make-a-request-from-the-command-line} + +Interagir com a blockchain Ethereum através de Alchemy, usando JSON-RPC e curl. + +Para solicitações manuais, recomendamos interagir com `JSON-RPC` via solicitações de `POST`. Simplesmente passe no header `Content-Type: application/json` e sua query como corpo do `POST` com os seguintes campos: + +- `jsonrpc`: Atualmente, somente a versão `2.0` do JSON-RPC é suportada. +- `method`: O método ETH API. [Veja a referência da API.](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc) +- `params`: Uma lista de parâmetros para passar ao método. +- `id`: A ID da sua solicitação. Será retornado pela resposta para que você possa manter o controle sobre qual solicitação uma resposta pertence. + +Aqui está um exemplo que você pode executar a partir da linha de comando, para recuperar o preço atual do gás: + +```bash +curl https://eth-mainnet.alchemyapi.io/v2/demo \ +-X POST \ +-H "Content-Type: application/json" \ +-d '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}' +``` + +_**NOTA:** Substitua [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-mainnet.alchemyapi.io/jsonrpc/demo) por sua própria chave de API `https://eth-mainnet.alchemyapi.io/v2/**sua-chave-api`._ + +**Resultados:** + +```json +{ "id": 73,"jsonrpc": "2.0","result": "0x09184e72a000" // 10000000000000 } +``` + +## 4. Configure seu Cliente Web3 {#set-up-your-web3-client} + +**Se você tem um cliente existente,** mude o URL do seu provedor de nó atual para uma URL de Alchemy com a sua chave API: `“https://eth-mainnet.alchemyapi.io/v2/your-api-key"` + +**_NOTA:_** Os scripts abaixo precisam ser executados em um **contexto de nó** ou **salvo em um arquivo**. Não é executado na linha de comando. Se você ainda não instalou o Node ou o NPM, confira este rápido [guia de configuração para macs](https://app.gitbook.com/@alchemyapi/s/alchemy/guides/alchemy-for-macs). + +Há inúmeras [bibliotecas Web3](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries) que você pode integrar com Alchemy. No entanto, nós recomendamos usar [Alchemy Web3](https://docs.alchemy.com/reference/api-overview), um drop-in substituto para web3.js, construída e configurada para trabalhar sem interrupções com Alchemy. Isto fornece múltiplas vantagens, tais como novas tentativas automáticas e um suporte robusto a WebSocket. + +Para instalar AlchemyWeb3.js, **navegue até o diretório do seu projeto** e execute: + +**Com o Yarn:** + +``` +yarn add @alch/alchemy-web3 +``` + +**Com NPM:** + +``` +yarn add @alch/alchemy-web3 +``` + +Para interagir com a infraestrutura dos nós de Alchemy, execute em NodeJS ou adicione isso a um arquivo JavaScript: + +```js +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3( + "https://eth-mainnet.alchemyapi.io/v2/your-api-key" +) +``` + +## 5. Escreva seu primeiro script Web3! {#write-your-first-web3-script} + +Agora vamos colocar a mão na massa com um pouco de programação na Web3. Vamos escrever um script simples que exibe o número de bloco mais recente da Rede principal do Ethereum. + +**1. Se você ainda não fez, no seu terminal, crie um novo diretório e cd do projeto dentro dele:** + +``` +mkdir web3-example +cd web3-example +``` + +**2. Instale a dependência do Alchemy web3 (ou qualquer web3) em seu projeto, se você ainda não tiver:** + +``` +npm install @alch/alchemy-web3 +``` + +**3. Crie um arquivo chamado `index.js` e adicione o seguinte conteúdo:** + +> Por fim, você deve substituir `demo` pela sua chave de API HTTP do Alchemy. + +```js +async function main() { + const { createAlchemyWeb3 } = require("@alch/alchemy-web3") + const web3 = createAlchemyWeb3("https://eth- mainnet.alchemyapi.io/v2/demo") + const blockNumber = await web3.eth.getBlockNumber() + console.log("The latest block number is " + blockNumber) +} +main() +``` + +Não está familiarizado com programação assíncrona? Confira este [post no Medium](https://medium.com/better-programming/understanding-async-await-in-javascript-1d81bb079b2c). + +**4. Executá-lo em seu terminal usando o nó** + +``` +node index.js +``` + +**5. Agora você deve ver a saída do último número de bloco no seu console!** + +``` +O último número de bloco é 11043912 +``` + +**Eba! Parabéns! Você acabou de escrever o seu primeiro script web3 usando Alchemy 🎉** + +Não tem certeza do que fazer a seguir? Experimente implementar seu primeiro contrato inteligente e colocar a mão na massa com um pouco de programação Solidity em nosso [Guia de contratos inteligentes “Olá, mundo”](https://docs.alchemyapi.io/tutorials/hello-world-smart-contract), ou teste seus conhecimentos sobre painel de controle com o [Aplicativo de demonstração do painel](https://docs.alchemyapi.io/tutorials/demo-app)! + +_[Cadastre-se com o Alchemy](https://auth.alchemyapi.io/signup) gratuitamente, confira [a nossa documentação](https://docs.alchemyapi.io/), e para receber as últimas notícias, siga-nos no [Twitter](https://twitter.com/AlchemyPlatform)_. diff --git a/public/content/translations/pt-br/developers/tutorials/guide-to-smart-contract-security-tools/index.md b/public/content/translations/pt-br/developers/tutorials/guide-to-smart-contract-security-tools/index.md new file mode 100644 index 00000000000..877be8a219b --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/guide-to-smart-contract-security-tools/index.md @@ -0,0 +1,105 @@ +--- +title: Um guia para ferramentas de segurança de contratos inteligentes +description: Uma visão geral de três diferentes técnicas de análise de testes e programas +author: "Trailofbits" +lang: pt-br +tags: + - "solidez" + - "smart contracts" + - "segurança" +skill: intermediate +published: 2020-09-07 +source: Construindo contratos seguros +sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis +--- + +We are going to use three distinctive testing and program analysis techniques: + +- **Análise estática com [Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/).** Todos os caminhos do programa são aproximados e analisados ao mesmo tempo, por meio de diferentes apresentações de programa (por exemplo, um control-flow-graph) +- **Fuzzing com [Echidna](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/).** O código é executado com uma geração pseudo-aleatória de transações. O fuzzer tentará encontrar uma sequência de transações para violar uma determinada propriedade. +- **A execução simbólica com a [Manticore](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/).** Uma técnica de verificação formal, que traduz cada caminho de execução para uma fórmula matemática, na qual as restrições de cima podem ser verificadas. + +Cada técnica tem vantagens e armadilhas, e será útil em [casos específicos](#determining-security-properties): + +| Técnica | Ferramenta | Uso | Velocidade | Erros perdidos | Alarmes falso | +| ------------------ | ---------- | ------------------------------------ | ---------- | -------------- | ------------- | +| Análise estática | Slither | CLI & scripts | segundos | moderado | baixo | +| Fuzzing | Echidna | Propriedades da Solidity | minutos | baixo | nenhum | +| Execução simbólica | Manticore | Propriedades & scripts & da Solidity | horas | nenhum\* | nenhum | + +\* se todos os caminhos forem explorados sem tempo limite + +**Slither** analisa contratos em poucos segundos, no entanto análise estática pode levar a alarmes falsos e será menos adequada para verificações complexas (e.. verificações aritméticas). Execute o Slither por meio da API para acesso com botão de comando para detectores internos ou por meio da API para verificações definidas pelo usuário. + +O **Echidna** precisa ser executado por vários minutos e só produzirá verdadeiros positivos. O Echidna verifica as propriedades de segurança fornecidas pelo usuário escritas em Solidity. Ele pode perder erros, pois é baseado em exploração aleatória. + +O **Manticore** executa a análise com maior peso. Como o Echidna, o Manticore verifica as propriedades fornecidas pelo usuário. Será necessário mais tempo de execução, mas isso poderá comprovar a validade de uma propriedade e não relatará alarmes falsos. + +## Fluxo de trabalho sugerido {#suggested-workflow} + +Comece com os detectores internos do Slither para garantir que nenhum bug simples esteja presente agora ou seja introduzido mais tarde. Use o Slither para verificar propriedades relacionadas a herança, dependências de variáveis e questões estruturais. À medida que a base de código cresce, use o Echidna para testar propriedades mais complexas da máquina de estado. Revisite o Slither para desenvolver verificações personalizadas de proteções indisponíveis na Solidity, como proteger contra uma função que está sendo substituída. Finalmente, use o Manticore para realizar a verificação direcionada de propriedades de segurança críticas, por exemplo, operações aritméticas. + +- Use a CLI do Slither para capturar problemas comuns +- Use o Echidna para testar as propriedades de segurança de alto nível do seu contrato +- Use o Slither para escrever verificações estáticas personalizadas +- Use o Manticore quando quiser uma garantia aprofundada de propriedades de segurança críticas + +**Uma nota sobre testes de unidade**. Testes de unidade são necessários para construir softwares de alta qualidade. No entanto, estas técnicas não são as mais adequadas para encontrar falhas de segurança. Normalmente, eles são usados para testar comportamentos positivos de código (ou seja, o código funciona conforme o esperado no contexto normal), enquanto as falhas de segurança tendem a residir em casos de risco que os desenvolvedores não consideraram. No nosso estudo sobre dezenas de revisões inteligentes de segurança do contrato, a [cobertura do teste de unidade não teve efeito sobre o número ou gravidade das falhas de segurança](https://blog.trailofbits.com/2019/08/08/246-findings-from-our-smart-contract-audits-an-executive-summary/) que encontramos no código do nosso cliente. + +## Determinando propriedades de segurança {#determining-security-properties} + +Para testar e verificar efetivamente seu código, você deve identificar as áreas que precisam de atenção. Como seus recursos gastos com a segurança são limitados, é importante otimizar seus esforços para determinar o escopo das partes fracas ou de grande valor da sua base de código. A modelagem de ameaças pode ajudar nisso. Considere revisar: + +- [Avaliação de risco rápida](https://infosec.mozilla.org/guidelines/risk/rapid_risk_assessment.html) (nossa abordagem preferida quando o tempo é curto) +- [Guia de modelagem de ameaças do sistema centralizado de dados](https://csrc.nist.gov/publications/detail/sp/800-154/draft) (também conhecido como NIST 800-154) +- [Modelagem de ameaças Shostack](https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack/dp/1118809998) +- [STRIDE](https://wikipedia.org/wiki/STRIDE_(security)) / [DREAD](https://wikipedia.org/wiki/DREAD_(risk_assessment_model)) +- [PASTA](https://wikipedia.org/wiki/Threat_model#P.A.S.T.A.) +- [Uso de asserções](https://blog.regehr.org/archives/1091) + +### Componentes {#components} + +Saber o que você deseja verificar também ajudará a escolher a ferramenta certa. + +As vastas áreas que são frequentemente relevantes para os contratos inteligentes incluem: + +- **Máquina de estado.** A maioria dos contratos pode ser representada como uma máquina de estado. Recomendamos verificar que: (1) nenhum estado inválido pode ser alcançado, (2) se um estado é válido, que ele seja alcançável e (3) nenhum estado bloqueia o contrato. + + - Echidna e Manticore são as ferramentas para testar as especificações da máquina. + +- **Controles de acesso.** Se o seu sistema tiver usuários privilegiados (por exemplo, um proprietário, controladores, …), você deve garantir que (1) cada usuário pode executar apenas as ações autorizadas e (2) nenhum usuário pode bloquear ações de um usuário com mais privilégios. + + - Slither, Echidna e Manticore podem verificar se há controles de acesso corretos. Por exemplo, o Slither pode verificar que apenas as funções da lista de permissões não possuem o modificador onlyOwner. O Echidna e a Manticore são úteis para um controle de acesso mais complexo, como uma autorização dada apenas se o contrato atingir um determinado estado. + +- **Operações aritméticas.** É essencial verificar a solidez das operações aritméticas. Usar o `SafeMath` em todo lugar é um bom passo para evitar overflow/underflow, no entanto, ainda é importante considerar outras falhas aritméticas, incluindo problemas de arredondamento e falhas que atrapalham o contrato. + + - A Manticore é a melhor escolha aqui. O Echidna pode ser utilizado se a aritmética estiver fora do escopo da solução SMT. + +- **Exatidão da herança.** Os contratos do Solidity dependem fortemente de várias heranças. Erros como uma função de sombreamento faltando uma chamada `super` e uma ordem de linearização c3 interpretada erradamente podem ser facilmente introduzidos. + + - O Slither é a ferramenta que garante a detecção desses problemas. + +- **Interações externas.** Os contratos interagem entre si, e não se deve confiar em alguns contratos externos. Por exemplo, se o seu contrato depende de oráculos externos, ele permanecerá seguro se metade dos oráculos disponíveis estiverem comprometidos? + + - A Manticore e o Echidna são a melhor escolha para testar as interações externas com seus contratos. A Manticore possui um mecanismo integrado para o stub de contratos externos. + +- **Conformidade padrão.** As normas do Ethereum (por exemplo, ERC20) têm um histórico de falhas em seu design. Esteja ciente das limitações da norma no qual você está construindo. + - Slither, Echidna e Manticore vão ajudar você a detectar desvios de uma determinada norma. + +### Folha de dicas de ferramentas {#tool-selection-cheatsheet} + +| Componentes | Ferramentas | Exemplos | +| --------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Máquina de estado | Echidna, Manticore | | +| Controle de acesso | Slither, Echidna, Manticore | [Slither exercise 2](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/slither/exercise2.md), [Echidna exercício 2](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/Exercise-2.md) | +| Operações aritméticas | Manticore, Echidna | [Echidna exercício 1](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/Exercise-1.md), [Manticore exercícios 1 a 3](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises) | +| Exatidão da herança | Slither | [Slither exercício 1](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/slither/exercise1.md) | +| Interações externas | Manticore, Echidna | | +| Conformidade padrão | Slither, Echidna, Manticore | [`slither-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) | + +Outras áreas terão de ser verificadas dependendo dos seus objetivos, mas essas áreas gerais são um bom começo para qualquer sistema de contrato inteligente. + +Nossas auditorias públicas contêm exemplos de propriedades verificadas ou testadas. Considere a leitura das seções `Teste Automatizado e Verificação` dos seguintes relatórios para revisar as propriedades de segurança em situações reais: + +- [0x](https://github.com/trailofbits/publications/blob/master/reviews/0x-protocol.pdf) +- [Balanceador](https://github.com/trailofbits/publications/blob/master/reviews/BalancerCore.pdf) diff --git a/public/content/translations/pt-br/developers/tutorials/hello-world-smart-contract-fullstack/index.md b/public/content/translations/pt-br/developers/tutorials/hello-world-smart-contract-fullstack/index.md new file mode 100644 index 00000000000..83b560c08ac --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/hello-world-smart-contract-fullstack/index.md @@ -0,0 +1,1540 @@ +--- +title: Contrato inteligente "Hello World" para iniciantes - Fullstack +description: Tutorial introdutório sobre como escrever e implementar um contrato inteligente simples no Ethereum. +author: "nstrike2" +tags: + - "solidity" + - "hardhat" + - "alchemy" + - "contratos inteligentes" + - "implementação" + - "blockexplorer" + - "front-end" + - "transações" +skill: beginner +lang: pt-br +published: 2021-10-25 +--- + +Este guia é para você que é iniciante em desenvolvimento de blockchain e não sabe por onde começar ou como implantar e interagir com contratos inteligentes. Nós iremos passar por criação e implantação de um contrato inteligente simples na rede de teste Goerli, usando [MetaMask](https://metamask.io), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org), e [Alchemy](https://alchemyapi.io/eth). + +Você irá precisar de uma conta Alchemy para completar este tutorial. [Registre-se para uma conta grátis](https://www.alchemy.com/). + +E claro, se você tiver alguma dúvida em qualquer momento, não hesite em entrar no [Discord da Alchemy](https://discord.gg/gWuC7zB)! + +## Parte 1 - Criando e Implantando seu Contrato Inteligente usando Hardhat {#part-1} + +### Conectar-se à rede Ethereum {#connect-to-the-ethereum-network} + +Existem muitas maneiras de fazer solicitações à cadeia de Ethereum. Para simplificar, usaremos uma conta gratuita na Alchemy, uma plataforma de desenvolvedores de blockchain e API que nos permite comunicar com a cadeia Ethereum sem termos que executar nosso próprio nó. A Alchemy também possui ferramentas de desenvolvedor para monitoração e análise. Neste tutorial, vamos aproveitá-las para entender o que está acontecendo nos bastidores da implantação do nosso contrato inteligente. + +### Crie o seu app e sua chave API {#create-your-app-and-api-key} + +Assim que criar uma conta na Alchemy, você poderá gerar uma chave API criando um app. Isso nos permitirá fazer solicitações na rede de teste Goerli. Se você não estiver familiarizado com redes de teste, você pode [ler o guia da Alchemy para escolher uma rede](https://docs.alchemyapi.io/guides/choosing-a-network). + +No painel da Alchemy, encontre o item **Apps** no menu suspenso na barra de navegação e selecione **Criar aplicativo**. + +![Criar um aplicativo Hello World](./hello-world-create-app.png) + +Dê ao seu app o nome “_Olá, Mundo_” e escreva uma breve descrição. Selecione **Staging** como o seu ambiente, e **Goerli** como a sua rede. + +![criar uma visualização do app hello world](./create-app-view-hello-world.png) + +_Observação: certifique-se de selecionar **Goerli**, ou este tutorial não funcionará._ + +Clique em **Criar app**. Seu app aparecerá na tabela abaixo. + +### Cria uma conta Ethereum {#create-an-ethereum-account} + +Você precisa de uma conta Ethereum para enviar e receber transações. Nós usaremos MetaMask, a carteira virtual no navegador que permite usuários gerenciarem o endereço da sua conta Ethereum. + +Você pode baixar e criar uma conta MetaMask gratuitamente [neste link](https://metamask.io/download.html). Quando você estiver criando uma conta, ou se já tiver uma conta, certifique-se de mudar para a “Rede de teste Goerli”, no canto superior direito (para que não estejamos lidando com dinheiro real). + +### Etapa 4: Adicionar ether de um faucet {#step-4-add-ether-from-a-faucet} + +Para implantar nosso contrato inteligente na rede de teste, precisaremos de alguns ETHs falsos. Para conseguir ETH da rede Goerli, vá para o Goerli faucet e entre o endereço da sua conta Goerli. Note that Goerli faucets can be a bit unreliable recently - see the [test networks page](/developers/docs/networks/#goerli) for a list of options to try: + +_Nota: devido a tráfego de rede, isto pode demorar um pouco._ + +### Etapa 5: Verificar seu saldo {#step-5-check-your-balance} + +Para garantir que o ETH está na sua carteira, vamos fazer uma chamada [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) usando a [ferramenta de composição da Alchemy](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Ele mostrará a quantidade de ETH em nossa carteira. Para saber mais, confira o [Breve tutorial da Alchemy sobre como usar a ferramenta de composição](https://youtu.be/r6sjRxBZJuU). + +Insira o endereço da sua conta MetaMask e clique em **Send Request**. Você verá a resposta que se parece com o pedação de código abaixo. + +```json +{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" } +``` + +> _Nota: Este resultado é em wei, não ETH. Lembre-se de que "Wei" é a menor unidade de ether._ + +Ufa! O nosso dinheiro falso está todo lá. + +### Etapa 6: Dar início a nosso projeto {#step-6-initialize-our-project} + +Primeiro, precisamos criar uma pasta para o nosso projeto. Navegue para a sua linha de comando e entre o seguinte. + +``` +mkdir hello-world +cd hello-world +``` + +Agora que estamos dentro da pasta do nosso projeto, vamos usar o comando `npm init `para inicializar o projeto. + +> Se você não tem npm instalado ainda, siga [essas instruções para instalar o Node.js e o npm](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm). + +Para finalidade deste tutorial, não importa como você responde às questões de inicialização. Aqui está como nós fizemos para referência: + +``` +package name: (hello-world) +version: (1.0.0) +description: hello world smart contract +entry point: (index.js) +test command: +git repository: +keywords: +author: +license: (ISC) + +About to write to /Users/.../.../.../hello-world/package.json: + +{ + "name": "hello-world", + "version": "1.0.0", + "description": "hello world smart contract", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} +``` + +Aprove o package.json e estaremos prontos para começar! + +### Passo 7: Baixar Hardhat {#step-7-download-hardhat} + +Hardhat é um ambiente de desenvolvimento para compilar, implementar, testar e depurar seu software de Ethereum. Ele ajuda os desenvolvedores na criação de contratos inteligentes e dapps localmente antes de implantar na cadeia real. + +Dentro de nosso projeto `hello-world` execute: + +``` +npm install --save-dev hardhat +``` + +Para mais detalhes, confira esta página sobre as [instruções de instalação](https://hardhat.org/getting-started/#overview). + +### Etapa 8: Criar o projeto Hardhat {#step-8-create-hardhat-project} + +Dentro da pasta do nosso projeto `hello-world`, rode: + +``` +npx hardhat +``` + +Você deve então ver uma mensagem de boas-vindas e a opção de selecionar o que quer fazer. Selecione "criar uma hardhat.config.js vazia": + +``` +888 888 888 888 888 +888 888 888 888 888 +888 888 888 888 888 +8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 +888 888 "88b 888P" d88" 888 888 "88b "88b 888 +888 888 .d888888 888 888 888 888 888 .d888888 888 +888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. +888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 + +👷 Welcome to Hardhat v2.0.11 👷‍ + +What do you want to do? … +Create a sample project +❯ Create an empty hardhat.config.js +Quit +``` + +Isto irá gerar um arquivo `hardhat.config.js` no projeto. Usaremos isso mais tarde neste tutorial para especificar a configuração do nosso projeto. + +### Etapa 9: Adicionar as pastas do projeto {#step-9-add-project-folders} + +Para manter a organização do nosso projeto, vamos criar duas novas pastas. No comando de linha, navegue para o diretório raiz do nosso projeto `hello-world` e digite: + +``` +mkdir contracts +mkdir scripts +``` + +- `contracts/` é onde nós vamos manter o arquivo de código do contrato inteligente "hello world" +- `scripts/` é onde nós vamos manter scripts para implantar e interagir com nosso contrato + +### Etapa 10: Escrever nosso contrato {#step-10-write-our-contract} + +Você pode estar se perguntando, quando é que nós vamos escrever código? Está na hora! + +Abra o projeto hello-world no seu editor favorito. Contratos inteligentes são mais comumente escritos em Solidity, o que nós usaremos para escrever o nosso contrato inteligente. + +1. Navegue para a pasta `contracts` e crie um novo arquivo chamado `HelloWorld.sol` +2. Veja abaixo uma amostra de contrato inteligente “Hello World”, que usaremos neste tutorial. Copie o conteúdo abaixo no arquivo `HelloWorld.sol`. + +_Nota: Certifique-se de ler os comentários para entender o que o contrato faz._ + +``` +// Especifica a versão do Solidity usando a versão semântica. +// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +pragma solidity >=0.7.3; + +// Defines a contract named `HelloWorld`. +// Um contrato é uma coleção de funções e dados (seu estado). Uma vez implantado, um contrato reside em um endereço específico na blockchain Ethereum. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +contract HelloWorld { + + //Emitted when update function is called + //Smart contract events are a way for your contract to communicate that something happened on the blockchain to your app front-end, which can be 'listening' for certain events and take action when they happen. + event UpdatedMessages(string oldStr, string newStr); + + // Declares a state variable `message` of type `string`. + // Variáveis de estado são variáveis cujos valores são permanentemente armazenados no armazenamento do contrato. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value. + string public message; + + // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation. + // Os construtores são usados para inicializar os dados do contrato. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + constructor(string memory initMessage) { + + // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable). + message = initMessage; + } + + // A public function that accepts a string argument and updates the `message` storage variable. + function update(string memory newMessage) public { + string memory oldMsg = message; + message = newMessage; + emit UpdatedMessages(oldMsg, newMessage); + } +} +``` + +Este é um contrato inteligente básico que armazena uma mensagem quando da sua criação. Ele pode ser atualizado chamando-se a função `update`. + +### Etapa 11: Vincular as contas MetaMask e Alchemy a seu projeto {#step-11-connect-metamask-alchemy-to-your-project} + +Nós já criamos uma carteira Metamask, uma conta Alchemy e já escrevemos nosso contrato inteligente. Agora é hora de vincularmos os três. + +Toda transação enviada da sua carteira requer uma assinatura, usando sua chave privada única. Para fornecer esta permissão ao nosso programa, podemos armazenar seguramente nossa chave privada em um arquivo de ambiente. Nós armazenaremos também uma chave de API da Alchemy aqui. + +> Para saber mais sobre o envio de transações, confira [este tutorial](https://docs.alchemyapi.io/alchemy/tutorials/sending-transactions-using-web3-and-alchemy) sobre o envio de transações usando web3. + +Primeiro, instale o pacote dotenv na pasta do seu projeto: + +``` +npm install dotenv --save +``` + +Então, crie um arquivo `.env` no diretório raiz do projeto. Adicione sua chave privada MetaMask e URL da API HTTP Alchemy a ele. + +Seu arquivo de ambiente deve ser nomeado `.env` or ele não será reconhecido como arquivo de ambiente. + +Não o nomeie como `process.env` ou `.env-custom` ou qualquer outra coisa. + +- Siga [estas instruções](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) para exportar sua chave privada +- Veja abaixo como obter o URL da API HTTP Alchemy + +![](./get-alchemy-api-key.gif) + +Seu arquivo `.env` ficará assim: + +``` +API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" +PRIVATE_KEY = "your-metamask-private-key" +``` + +Para realmente vinculá-los a nosso código, vamos fazer referência a essas variáveis em nosso arquivo `hardhat.config.js` no passo 13. + +### Etapa 12: Instalar o Ethers.js {#step-12-install-ethersjs} + +Ethers.js é uma biblioteca que facilita a interação e o envio de solicitações ao Ethereum ao incorporar [métodos padrões JSON-RPC](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc) a outros métodos mais amigáveis ao usuário. + +O Hardhat nos permite integrar [plugins](https://hardhat.org/plugins/) para ferramentas adicionais e funcionalidade estendida. Aproveitaremos o [plugin Ethers](https://hardhat.org/plugins/nomiclabs-hardhat-ethers.html) para implantar o contrato. + +No diretório do projeto, digite: + +```bash +npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0" +``` + +### Etapa 13: Atualizar hardhat.config.js {#step-13-update-hardhat.configjs} + +Até aqui, já adicionamos diversas dependências e plugins. Agora precisamos atualizar o `hardhat.config.js` para que nosso projeto reconheça todos eles. + +Atualize seu `hardhat.config.js` para ficar assim: + +```javascript +/** + * @type import('hardhat/config').HardhatUserConfig + */ + +require("dotenv").config() +require("@nomiclabs/hardhat-ethers") + +const { API_URL, PRIVATE_KEY } = process.env + +module.exports = { + solidity: "0.7.3", + defaultNetwork: "goerli", + networks: { + hardhat: {}, + goerli: { + url: API_URL, + accounts: [`0x${PRIVATE_KEY}`], + }, + }, +} +``` + +### Etapa 14: Compilar nosso contrato {#step-14-compile-our-contract} + +Para ter certeza de que tudo está funcionando, vamos compilar nosso contrato. A tarefa `compile` é uma das tarefas integradas do Hardhat. + +Na linha de comando, execute: + +```bash +npx hardhat compile +``` + +Você pode receber o aviso `SPDX license identifier not provided in source file`, mas não há necessidade de se preocupar com isso. Esperemos que tudo mais esteja bem! Se não, você sempre pode enviar uma mensagem no [discord Alchemy](https://discord.gg/u72VCg3). + +### Etapa 15: Escrever nosso script de implantação {#step-15-write-our-deploy-script} + +Agora que nosso contrato está escrito e nosso arquivo de configuração está pronto, é hora de escrever o script de implantação do contrato. + +Navegue até a pasta `scripts/` e crie um novo arquivo chamado `deploy.js`, adicionando o seguinte conteúdo: + +```javascript +async function main() { + const HelloWorld = await ethers.getContractFactory("HelloWorld") + + // Start deployment, returning a promise that resolves to a contract object + const hello_world = await HelloWorld.deploy("Hello World!") + console.log("Contract deployed to address:", hello_world.address) +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error) + process.exit(1) + }) +``` + +A Hardhat fez um trabalho incrível ao explicar o que cada uma dessas linhas de código faz em seu [Tutorial sobre contratos](https://hardhat.org/tutorial/testing-contracts.html#writing-tests). Adotamos aqui as explicações deles. + +```javascript +const HelloWorld = await ethers.getContractFactory("HelloWorld") +``` + +Uma `ContractFactory` em ethers.js é uma abstração usada para implantar novos contratos inteligentes, então, aqui, `HelloWorld` representa uma [fábrica](https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)) para instâncias do nosso contrato Hello World. Quando usar o plugin `hardhat-ethers` `ContractFactory` e `Contract`, as instâncias estão conectadas ao primeiro assinante (proprietário) por padrão. + +```javascript +const hello_world = await HelloWorld.deploy() +``` + +Chamar `deploy()` em uma `ContractFactory`, irá iniciar a implantação, e retornará uma `Promise` que se resolve em um objeto `Contract`. Este é o objeto que tem um método para cada uma de nossas funções de contrato inteligente. + +### Etapa 16: Implantar nosso contrato {#step-16-deploy-our-contract} + +Finalmente estamos prontos para implantar o nosso contrato inteligente! Navegue até a linha de comando e digite: + +```bash +npx hardhat run scripts/deploy.js --network goerli +``` + +Você deverá ver algo assim: + +```bash +Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 +``` + +**Por favor, grave este endereço**. Nós o usaremos mais tarde neste tutorial. + +Se formos ao [etherscan da Goerli](https://goerli.etherscan.io) e procurarmos nosso endereço de contrato, devemos ser capazes de ver que ele foi implantado com sucesso. A transação ficará parecida com isto: + +![](./etherscan-contract.png) + +O endereço `From` deve combinar com o endereço da sua conta MetaMask, e o endereço `To` conterá **Contract Creation**. Se clicarmos na transação, veremos o nosso endereço de contrato no campo `To`. + +![](./etherscan-transaction.png) + +Parabéns! Você acaba de implantar um contrato inteligente em uma rede de teste Ethereum. + +Para entender o que está acontecendo nos bastidores, vamos navegar até a guia Explorer no [painel do Alchemy](https://dashboard.alchemyapi.io/explorer). Se você tem vários aplicativos Alchemy, certifique-se de filtrar por app e selecionar **Hello World**. + +![](./hello-world-explorer.png) + +Aqui você verá um punhado de métodos JSON-RPC que Hardhat/Ethers fizeram em segundo plano para nós quando chamamos a função `.deploy() `. Dois importantes métodos aqui são [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction), que é a requisição para escrever nosso contrato na cadeia Goerli, e [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash) que é uma requisição para ler informações sobre nossa transação, dado o hash. Para saber mais sobre o envio de transações, confira [este tutorial sobre o envio de transações usando web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/). + +## Parte 2: Interaja com o seu Contrato Inteligente {#part-2-interact-with-your-smart-contract} + +Agora que você implantou com sucesso um contrato inteligente na rede Goerli, vamos aprender como interagir com ele. + +### Crie um arquivo interact.js {#create-a-interactjs-file} + +Este é o arquivo onde nós iremos escrever nosso script de interação. Nós usaremos a biblioteca Ether.js que você instalou anteriormente na Parte1. + +Dentro da pasta `scripts/` crie um novo arquivo chamado `interact.js`, adicionando o seguinte código: + +```javascript +// interact.js + +const API_KEY = process.env.API_KEY +const PRIVATE_KEY = process.env.PRIVATE_KEY +const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS +``` + +### Atualize seu arquivo .env {#update-your-env-file} + +Nós usaremos novas variáveis de ambiente, portanto nós precisamos defini-las no arquivo `.env` que [ nós criamos antes](#step-11-connect-metamask-&-alchemy-to-your-project). + +Nós precisaremos adicionar uma definição para a nossa `API_KEY` Alchemy e o `CONTRACT_ADDRESS` onde o nosso contrato inteligente foi implantado. + +Seu arquivo `.env` deverá se parecer com isto: + +```bash +# .env + +API_URL = "https://eth-goerli.alchemyapi.io/v2/" +API_KEY = "" +PRIVATE_KEY = "" +CONTRACT_ADDRESS = "0x" +``` + +### Pegue a ABI do seu contrato {#grab-your-contract-ABI} + +O [ABI (Interface binária da aplicação)](/glossary/#abi) do nosso contrato é a interface para interagir com o nosso contrato inteligente. O Hardhat automaticamente gera uma ABI e a salva no arquivo `HelloWorld.json`. Para usar a ABI, precisaremos analisar o conteúdo adicionando as seguintes linhas de código ao nosso arquivo `interact.js`: + +```javascript +// interact.js +const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json") +``` + +Se quiser ver a ABI, pode imprimi-la no console: + +```javascript +console.log(JSON.stringify(contract.abi)) +``` + +Para ver o seu ABI impresso no console, navegue até seu terminal e execute: + +```bash +npx hardhat run scripts/interact.js +``` + +### Criar uma instância do seu contrato {#create-an-instance-of-your-contract} + +Para interagir com o nosso contrato, precisamos criar uma instância dele em nosso código. Para fazer isso com Ether.js, nós precisaremos trabalhar com três conceitos: + +1. Provedor — um nó fornecedor que lhe dá acesso de leitura e escrita ao blockchain +2. Signatário — representa uma conta Ethereum que pode assinar transações +3. Contrato — um objeto Ether.js representando um contrato específico implantado on-chain + +Usaremos a ABI do contrato da etapa anterior para criar nossa instância do contrato: + +```javascript +// interact.js + +// Provider +const alchemyProvider = new ethers.providers.AlchemyProvider( + (network = "goerli"), + API_KEY +) + +// Signer +const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider) + +// Contract +const helloWorldContract = new ethers.Contract( + CONTRACT_ADDRESS, + contract.abi, + signer +) +``` + +Aprenda mais sobre Provedores, Signatários e Contratos na [documentação ethers.js](https://docs.ethers.io/v5/). + +### Leia a mensagem init {#read-the-init-message} + +Lembra-se de quando implantamos nosso contrato com o `initMessage = "Hello world!"`? Nós vamos agora ler a mensagem armazenada no nosso contrato inteligente e imprimi-la no console. + +Em JavaScript, funções assíncronas são usadas quando interagindo com redes. Para aprender mais sobre funções assíncronas, [leia este artigo](https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff). + +Use o código abaixo para chamar a função `message` no nosso contrato inteligente e ler a mensagem init: + +```javascript +// interact.js + +// ... + +async function main() { + const message = await helloWorldContract.message() + console.log("The message is: " + message) +} +main() +``` + +Depois de rodar o arquivo usando `npx hardhat run scripts/interact.js` no terminal, nós devemos ver esta resposta: + +``` +The message is: Hello world! +``` + +Parabéns! Você acabou de ler com sucesso dados de contrato inteligente do blockchain Ethereum, continue assim! + +### Atualize a mensagem {#update-the-message} + +Ao invés de só ler a mensagem, nós podemos também atualizar a mensagem salva no nosso contrato inteligente usando a função `update`! Muito bacana, não? + +Para atualizar a mensagem, nós podemos chamar diretamente a função `update` no nosso objeto Contract instanciado: + +```javascript +// interact.js + +// ... + +async function main() { + const message = await helloWorldContract.message() + console.log("The message is: " + message) + + console.log("Updating the message...") + const tx = await helloWorldContract.update("This is the new message.") + await tx.wait() +} +main() +``` + +Note que na linha 11, nós fazemos uma chamada para `.wait()` no objeto da transação retornada. Isso garante que nosso script espere pela transação ser minerada no blockchain antes de sair da função. Se a chamada `.wait()` não estiver incluída, o script pode não ver o valor da `message` atualizada no contrato. + +### Leia a nova mensagem {#read-the-new-message} + +Você deve ser capaz de repetir o [passo anterior](#read-the-init-message) para ler o valor atualizado da `message`. Pegue um momento e veja se você pode fazer as mudanças necessárias para imprimir o novo valor! + +Se você precisar de uma dica, aqui está o que o seu arquivo `interact.js` deve se parecer neste ponto: + +```javascript +// interact.js + +const API_KEY = process.env.API_KEY +const PRIVATE_KEY = process.env.PRIVATE_KEY +const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS + +const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json") + +// provider - Alchemy +const alchemyProvider = new ethers.providers.AlchemyProvider( + (network = "goerli"), + API_KEY +) + +// signer - you +const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider) + +// contract instance +const helloWorldContract = new ethers.Contract( + CONTRACT_ADDRESS, + contract.abi, + signer +) + +async function main() { + const message = await helloWorldContract.message() + console.log("The message is: " + message) + + console.log("Updating the message...") + const tx = await helloWorldContract.update("this is the new message") + await tx.wait() + + const newMessage = await helloWorldContract.message() + console.log("The new message is: " + newMessage) +} + +main() +``` + +Agora apenas rode o script e você deve ser capaz de ver a mensagem antiga, o estado atualizado, e a nova mensagem impressa no seu terminal! + +`npx hardhat run scripts/interact.js --network goerli` + +``` +The message is: Hello World! +Updating the message... +The new message is: This is the new message. +``` + +Enquanto estiver rodando este script, você pode perceber que o passo `Updating the message...` leva um tempo para carregar antes da nova mensagem carregar. Isto é por causa do processo de mineração; se você é curioso sobre rastrear transações enquanto elas estão sendo mineradas, visite o [Alchemy mempool](https://dashboard.alchemyapi.io/mempool) para ver o estado da transação. Se a transação for derrubada, também é útil checar o [Goerli Etherscan](https://goerli.etherscan.io) e procurar pelo hash da sua transação. + +## Parte 3: Publique seu Contrato Inteligente no Etherscan {#part-3-publish-your-smart-contract-to-etherscan} + +Você fez todo o trabalho duro dar vida ao seu contrato inteligente; agora é hora de compartilhá-lo com o mundo! + +Verificando seu contrato inteligente no Etherscan, qualquer um pode ver seu código-fonte e interagir com o seu contrato inteligente. Vamos começar! + +### Passo 1: Gere a Chave API na sua conta Etherscan {#step-1-generate-an-api-key-on-your-etherscan-account} + +Uma Chave API Etherscan é necessária para verificar que você possui o contrato inteligente que você está tentando publicar. + +Se você não tem uma conta Etherscan ainda, [se inscreva para uma conta](https://etherscan.io/register). + +Uma vez conectado, encontre seu nome de usuário na barra de navegação, passe o mouse em cima dele, e selecione o botão **My profile**. + +Na página do seu perfil, você deve ver uma barra de navegação lateral. Da barra de navegação lateral, selecione **API Keys**. Em seguida, pressione o botão "Add" para criar uma nova chave API, nomeie seu app **hello-world**e pressione o botão **Create New API Key**. + +Sua nova chave API deve aparecer na tabela de chaves API. Copie a chave API na sua área de transferência. + +Agora nós precisamos adicionar a chave API Etherscan no seu arquivo `.env`. + +Depois de adicionar isso, seu arquivo `.env` deve se parecer com isso: + +```javascript +API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" +PUBLIC_KEY = "your-public-account-address" +PRIVATE_KEY = "your-private-account-address" +CONTRACT_ADDRESS = "your-contract-address" +ETHERSCAN_API_KEY = "your-etherscan-key" +``` + +### Contratos inteligentes implantados pelo Hardhat {#hardhat-deployed-smart-contracts} + +#### Instale o hardhat-etherscan {#install-hardhat-etherscan} + +Publicar o seu contrato no Etherscan usando Hardhat é uma tarefa direta. Você primeiro precisa instalar o plugin `hardhat-etherscan` para começar. `hardhat-etherscan` verificará automaticamente o código-fonte do contrato inteligente e da ABI no Etherscan. Para adicionar isso, no diretório `hello-world` rode: + +```text +npm install --save-dev @nomiclabs/hardhat-etherscan +``` + +Uma vez instalado, inclua o seguinte comando no topo do seu `hardhat.config.js`, e adicione as opções de configuração Etherscan: + +```javascript +// hardhat.config.js + +require("dotenv").config() +require("@nomiclabs/hardhat-ethers") +require("@nomiclabs/hardhat-etherscan") + +const { API_URL, PRIVATE_KEY, ETHERSCAN_API_KEY } = process.env + +module.exports = { + solidity: "0.7.3", + defaultNetwork: "goerli", + networks: { + hardhat: {}, + goerli: { + url: API_URL, + accounts: [`0x${PRIVATE_KEY}`], + }, + }, + etherscan: { + // Your API key for Etherscan + // Obtain one at https://etherscan.io/ + apiKey: ETHERSCAN_API_KEY, + }, +} +``` + +#### Verifique seu contrato inteligente no Etherscan {#verify-your-smart-contract-on-etherscan} + +Certifique-se que todos os arquivos foram salvos e todas as variáveis `.env` estão corretamente configuradas. + +Rode a tarefa `verify`, passando o endereço do contrato, e a rede onde ele foi implantado: + +```text +npx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS 'Hello World!' +``` + +Certifique-se que `DEPLOYED_CONTRACT_ADDRESS` é o endereço do seu contrato inteligente implantado na rede de teste Goerli. Além disso, o argumento final (`'Hello World!'`) tem de ser o mesmo valor de string usado [durante o passo de implantação na parte 1](#write-our-deploy-script). + +Se tudo der certo, você verá a seguinte mensagem no seu terminal: + +```text +Successfully submitted source code for contract +contracts/HelloWorld.sol:HelloWorld at 0xdeployed-contract-address +for verification on Etherscan. Waiting for verification result... + + +Successfully verified contract HelloWorld on Etherscan. +https://goerli.etherscan.io/address/#contracts +``` + +Parabéns! O código do seu contrato inteligente está no Etherscan! + +### Cheque seu contrato inteligente no Etherscan! {#check-out-your-smart-contract-on-etherscan} + +Quando você navegar para o link fornecido no seu terminal, você deve ser capaz de ver o código do seu contrato inteligente e ABI publicados no Etherscan! + +**Parabéns, você conseguiu, campeão! Agora qualquer um pode chamar ou escrever no seu contrato inteligente! Nós mal conseguimos esperar o que você vai construir em seguida!** + +## Parte 4 - Integrando seu contrato inteligente com o front-end {#part-4-integrating-your-smart-contract-with-the-frontend} + +No fim deste tutorial você saberá como: + +- Conectar uma carteira MetaMask no seu dapp +- Ler dados do seu contrato inteligente usando a API [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) +- Assinar transações Ethereum usando MetaMask + +Para este dapp, estaremos usando [React](https://reactjs.org/) como nosso framework de front-end; entretanto, é importante notar que nós não gastaremos muito tempo explicando seus fundamentos, já que estaremos principalmente focados em trazer funcionalidade Web3 para o nosso projeto. + +Como um pré-requisito, você deve ter um nível iniciante de entendimento de React. Caso contrário, recomendamos concluir o tutorial oficial [Introdução ao React](https://reactjs.org/tutorial/tutorial.html). + +### Clonar os arquivos iniciais {#clone-the-starter-files} + +Primeiro, vá até o [repositório GitHub hello-world-part-four](https://github.com/alchemyplatform/hello-world-part-four-tutorial) para obter os arquivos iniciais para esse projeto e clone o repositório no seu computador local. + +Abra o repositório clonado localmente. Note que ele contém duas pastas: `starter-files` e `completed`. + +- `starter-files`- **nós trabalharemos neste diretório**, nós conectaremos a UI à nossa carteira Ethereum e o contrato inteligente que nós publicamos no Etherscan na [Parte 3](#part-3). +- `completed` contém o tutorial inteiro completado e deve ser somente usado como referência se você estiver empacado. + +Em seguida, abra sua cópia de `starter-files` no seu editor de código favorito, e então navegue na pasta `src`. + +Todo o código que vamos escrever será exibido na pasta `src`. Nós estaremos editando o componente `HelloWorld.js` e os arquivos JavaScript `util/interact.js` para dar ao seu projeto funcionalidade Web3. + +### Cheque os arquivos iniciais {#check-out-the-starter-files} + +Antes de começar a codificar, vamos explorar o que nos é fornecido nos arquivos iniciais. + +#### Tenha seu projeto React em execução {#get-your-react-project-running} + +Vamos começar executando o projeto React em nosso navegador. A beleza do React é que uma vez que nosso projeto esteja sendo executado no nosso navegador, qualquer alteração que salvarmos será atualizada ao vivo em nosso navegador. + +Para fazer com que o projeto funcione, navegue até o diretório raiz da pasta `starter-files`, e execute`npm install` no seu terminal para instalar as dependências do projeto: + +```bash +cd starter-files +npm install +``` + +Uma vez terminada a instalação, execute `npm start` em seu terminal: + +```bash +npm start +``` + +Ao fazê-lo, deve abrir [http://localhost:3000/](http://localhost:3000/) no seu navegador, onde você verá o front-end do nosso projeto. Ele deve consistir em um campo \ (um lugar para atualizar a mensagem armazenada no seu contrato inteligente\), um botão “Conectar Carteira”, e um botão “Atualizar”. + +Se você tentar clicar em qualquer dos botões você notará que eles não funcionam — isso porque ainda precisamos programar a funcionalidade deles. + +#### O componente `HelloWorld.js` {#the-helloworld-js-component} + +Vamos voltar à pasta `src` no nosso editor e abrir o arquivo `HelloWorld.js`. É muito importante que entendamos tudo neste arquivo, pois é o principal componente do React no qual vamos trabalhar. + +No começo deste arquivo você irá notar que nós temos diversas declarações importantes que são necessárias para termos nosso projeto rodando, incluindo a biblioteca React, os hooks useEffect e UseState, alguns itens do `./util/interact.js` (nós os descreveremos em mais detalhes em breve!), e o logo Alchemy. + +```javascript +// HelloWorld.js + +import React from "react" +import { useEffect, useState } from "react" +import { + helloWorldContract, + connectWallet, + updateMessage, + loadCurrentMessage, + getCurrentWalletConnected, +} from "./util/interact.js" + +import alchemylogo from "./alchemylogo.svg" +``` + +Em seguida, temos nossas variáveis de estado que serão atualizadas após eventos específicos. + +```javascript +// HelloWorld.js + +//State variables +const [walletAddress, setWallet] = useState("") +const [status, setStatus] = useState("") +const [message, setMessage] = useState("No connection to the network.") +const [newMessage, setNewMessage] = useState("") +``` + +Veja aqui o que cada uma das variáveis representa: + +- `walletAddress` - uma string que armazena o endereço da carteira do usuário +- `status` uma string que armazena uma mensagem útil que guia o usuário em como interagir com o dapp +- `message` - uma string que armazena a mensagem atual no contrato inteligente +- `newMessage` -uma string que armazena a nova mensagem que será escrita no contrato inteligente + +Depois das variáveis de estado, você verá cinco funções não implementadas: `useEffect` ,`addSmartContractListener`, `addWalletListener` , `connectWalletPressed`, e `onUpdatePressed`. Nós explicaremos o que elas fazem abaixo: + +```javascript +// HelloWorld.js + +//called only once +useEffect(async () => { + //TODO: implement +}, []) + +function addSmartContractListener() { + //TODO: implement +} + +function addWalletListener() { + //TODO: implement +} + +const connectWalletPressed = async () => { + //TODO: implement +} + +const onUpdatePressed = async () => { + //TODO: implement +} +``` + +- [`useEffect`](https://reactjs.org/docs/hooks-effect.html)- isto é um hook React hook que é chamado depois que o seu componente é renderizado. Por ele ter um array vazio `[]` prop passada por ele \(veja linha 4\), ele só será chamado na _primeira_ renderização do componente. Aqui nós vamos carregar a mensagem atual armazenada no nosso contrato inteligente, chamar nosso contrato inteligente e listeners da carteira, e atualizar nos UI para refletir se a carteira já está conectada. +- `addSmartContractListener`- esta função configura um listener que irá aguardar o evento `UpdatedMessages` do nosso contrato HelloWorld e atualizar nossa UI quando a mensagem é alterada em nosso contrato inteligente. +- `addWalletListener`- esta função configura um listener que detecta mudanças no estado da carteira MetaMask do usuário, como quando o usuário desconecta sua carteira ou muda endereços. +- `connectWalletPressed`- esta função será chamada para conectar a carteira MetaMask do usuário no nosso dapp. +- `onUpdatePressed` - essa função será chamada quando o usuário quiser atualizar a mensagem armazenada no contrato inteligente. + +Perto do final desse arquivo, temos a interface de usuário do nosso componente. + +```javascript +// HelloWorld.js + +//the UI of our component +return ( +
      + + + +

      Current Message:

      +

      {message}

      + +

      New Message:

      + +
      + setNewMessage(e.target.value)} + value={newMessage} + /> +

      {status}

      + + +
      +
      +) +``` + +Se você procurar com cuidado no código, você notará quando nós usamos nossas várias variáveis de estado na nossa UI: + +- Nas linhas 6 a 12, se a carteira do usuário estiver conectada \(ou seja. `walletAddress.length > 0`\), mostraremos uma versão truncada da `walletAddress` do usuário no botão com a ID "walletButton;", caso contrário, ele simplesmente dirá "Connect Wallet." +- Na linha 17, nós mostramos a mensagem atual armazenada no contrato inteligente, que é capturada na string `message`. +- Nas linhas 23-26, nós usamos um [componente controlado](https://reactjs.org/docs/forms.html#controlled-components) para atualizar nossa variável de estado `newMessage` quando a entrada no campo texto muda. + +Em adição às nossas variáveis de estado, você também verá que as funções `connectWalletPressed` e `onUpdatePressed` são chamadas quando os botões com IDs `publishButton` e `walletButton` são respectivamente clicados. + +Finalmente, vamos endereçar onde esse componente `HelloWorld.js` será adicionado. + +Se você for ao arquivo `App.js`, que é o componente principal do React, que atua como um contêiner para todos os outros componentes, você verá que o nosso componente `HelloWorld.js` é injetado na linha 7. + +Finalmente, mas não menos importante, vamos checar mais um arquivo fornecido para você, o arquivo `interact.js`. + +#### O arquivo `interact.js` {#the-interact-js-file} + +Como queremos respeitar o paradigma [M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), queremos um arquivo separado que contém todas as nossas funções para gerenciar a lógica, dados e regras do nosso dapp, para então conseguirmos exportar essas funções para o nosso front-end \(nosso componente `HelloWorld.js` component\). + +👆🏽Esta é a exata finalidade do nosso arquivo `interact.js`! + +Navegue para a pasta `util` no seu diretório `src`, e você notará que nós incluimos um arquivo chamado `interact.js` que irá conter todas as nossas interações com o contrato inteligente, funções de carteira, e variáveis. + +```javascript +// interact.js + +//export const helloWorldContract; + +export const loadCurrentMessage = async () => {} + +export const connectWallet = async () => {} + +const getCurrentWalletConnected = async () => {} + +export const updateMessage = async (message) => {} +``` + +Você pode notar no topo do arquivo que nós transformamos o objeto `helloWorldContract` em um comentário. Mais tarde neste tutorial nós vamos descomentar este objeto e instanciar nosso contrato inteligente nesta variável, que irá então exportar no nosso componente `HelloWorld.js`. + +As quatro funções não implementadas depois do nosso objeto `helloWorldContract` fazem o seguinte: + +- `loadCurrentMessage`: esta função manipula a lógica de carregamento da mensagem atual armazenada no contrato inteligente. Ela fará uma chamada _read_ para o contrato inteligente Olá, Mundo usando a [API Web3 da Alchemy](https://github.com/alchemyplatform/alchemy-web3). +- `connectWallet`: essa função conectará a MetaMask do usuário ao nosso dapp. +- `getCurrentWalletConnected` - essa função irá checar se uma conta Ethereum já está conectada no nosso dapp no carregamento da página e atualização da nossa UI devidamente. +- `updateMessage` - esta função atualizará a mensagem armazenada no contrato inteligente. Ela fará uma chamada _write_ para o contrato inteligente Hello World, para que a carteira do usuário MetaMask tenha que assinar uma transação Ethereum para atualizar a mensagem. + +Agora que você entende no que estamos trabalhando, vamos entender como ler do nosso contrato inteligente! + +### Passo 3: Leia do seu Contrato Inteligente {#step-3-read-from-your-smart-contract} + +Para ler do seu contrato inteligente, você irá precisar configurar com sucesso: + +- Uma conexão API com a cadeia Ethereum +- Uma instância carregada para o seu contrato inteligente +- Uma função para chamar para a sua função de contrato inteligente +- Um ouvinte para observar as atualizações quando os dados de contrato inteligente que você está lendo mudem + +Isto pode parecer que são muitos passos, mas não se preocupe! Nós vamos acompanhá-lo como fazer cada um deles passo a passo! :\) + +#### Estabeleça uma conexão API com a cadeia Ethereum {#establish-an-api-connection-to-the-ethereum-chain} + +Você se lembra como na Parte 2 deste tutorial usamos a nossa chave [Alchemy Web3 para ler do nosso contrato inteligente](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract/interacting-with-a-smart-contract#step-1-install-web3-library)? Você também irá precisar de uma chave Alchemy Web3 em seu dapp para ler da cadeia. + +Se você ainda não tem, primeiro instale [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) navegando até o diretório raiz do seu `starter-files` e executando o seguinte em seu terminal: + +```text +yarn add @alch/alchemy-web3 +``` + +[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) é um invólucro em torno do [Web3.js](https://docs.web3js.org/), fornecendo métodos aprimorados da API e outros benefícios cruciais para tornar a sua vida de desenvolvedor da Web3 mais fácil. Ele foi projetado para exigir uma configuração mínima, para que você possa começar a usá-la no seu aplicativo imediatamente! + +Então, instale o pacote [dotenv](https://www.npmjs.com/package/dotenv) no seu diretório do projeto, para termos um lugar seguro para armazenar nossa chave API depois de pegarmos ela. + +```text +npm install dotenv --save +``` + +Para o nosso dapp, **nós usaremos nossa chave API Websockets** ao invés de nossa chave API HTTP, já que nos garante configurar um listener que detecta quando a mensagem, armazenada no contrato inteligente, muda. + +Uma vez que você tem a chave API, crie um arquivo `.env` no seu diretório raiz e adicione sua url Alchemy Websockets a ele. Depois disso, seu arquivo `.env` deve se parecer com isso: + +```javascript +REACT_APP_ALCHEMY_KEY = wss://eth-goerli.ws.alchemyapi.io/v2/ +``` + +Agora estamos prontos para configurar nosso ponto de extremidade Web3 da Alchemy no nosso dapp! Vamos voltar para o nosso `interact.js`, que é aninhado dentro da nossa pasta `util` e adicionar o seguinte código no topo do arquivo: + +```javascript +// interact.js + +require("dotenv").config() +const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(alchemyKey) + +//export const helloWorldContract; +``` + +Acima, nós primeiro importamos a chave Alchemy do nosso arquivo `.env` e então passamos nosso `alchemyKey` para `createAlchemyWeb3` estabelecer nosso endpoint Alchemy Web3. + +Com este endpoint pronto, é hora de carregar nosso contrato inteligente! + +#### Carregando o seu contrato inteligente Hello World {#loading-your-hello-world-smart-contract} + +Para carregar o seu contrato inteligente Hello World, você precisará do seu endereço de contrato e ABI, ambos os quais podem ser encontrados no Etherscan se você completou a [Parte 3 deste tutorial.](/developers/tutorials/hello-world-smart-contract-fullstack/#part-3-publish-your-smart-contract-to-etherscan-part-3-publish-your-smart-contract-to-etherscan) + +#### Como obter a ABI do seu contrato no Etherscan {#how-to-get-your-contract-abi-from-etherscan} + +Se você pulou a Parte 3 deste tutorial, você pode usar o contrato Olá, Mundo com o endereço [0x6f3f635A9762B47954229Ea479b4541eAF402A6A](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code). Sua ABI pode ser encontrada [aqui](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code). + +A ABI de um contrato é necessária para especificar qual função um contrato irá invocar, assim como garantir que a função irá retornar dados no formato que você está esperando. Uma vez que nós copiamos nosso contrato ABI, vamos salvá-lo como um arquivo JSON chamado `contract-abi.json` no seu diretório `src`. + +O seu contract-abi.json deve ser armazenado na sua pasta src. + +Armados com nosso endereço de contrato, ABI, e endpoint Alchemy Web3, nós podemos usar o [método do contrato](https://docs.web3js.org/api/web3-eth-contract/class/Contract) para carregar uma instância do nosso contrato inteligente. Importe a ABI do seu contrato no arquivo `interact.js` e adicione o seu endereço de contrato. + +```javascript +// interact.js + +const contractABI = require("../contract-abi.json") +const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A" +``` + +Nós podemos agora finalmente descomentar nossa variável `helloWorldContract`, e carregar o contrato inteligente usando nosso endpoint AlchemyWeb3: + +```javascript +// interact.js +export const helloWorldContract = new web3.eth.Contract( + contractABI, + contractAddress +) +``` + +Para recapitular, as primeiras 12 linhas do seu `interact.js` deve agora se parecer com isso: + +```javascript +// interact.js + +require("dotenv").config() +const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(alchemyKey) + +const contractABI = require("../contract-abi.json") +const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A" + +export const helloWorldContract = new web3.eth.Contract( + contractABI, + contractAddress +) +``` + +Agora que nós temos nosso contrato carregado, nós podemos implementar nossa função `loadCurrentMessage`! + +#### Implementando `loadCurrentMessage` no nosso arquivo `interact.js` {#implementing-loadCurrentMessage-in-your-interact-js-file} + +Esta função é super simples. Nós vamos fazer uma simples chamada async web3 para ler do nosso contrato. Nossa função irá retornar a mensagem armazenada no contrato inteligente: + +Atualize o `loadCurrentMessage` no seu arquivo `interact.js` para o seguinte: + +```javascript +// interact.js + +export const loadCurrentMessage = async () => { + const message = await helloWorldContract.methods.message().call() + return message +} +``` + +Já que nós queremos exibir este contrato inteligente na nossa UI, vamos atualizar a função `useEffect` no nosso componente `HelloWorld.js` com o seguinte: + +```javascript +// HelloWorld.js + +//called only once +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) +}, []) +``` + +Note que nós somente queremos nosso `loadCurrentMessage` ser chamado uma vez durante a primeira renderização do componente. Logo implementaremos `addSmartContractListener` para atualizar automaticamente a interface do usuário depois que a mensagem no contrato inteligente mudar. + +Antes que nós mergulhemos no nosso listener, vamos checar o que nós temos até aqui! Salve seus arquivos `HelloWorld.js` e `interact.js`, e então vá para [http://localhost:3000/](http://localhost:3000/) + +Você notará que a mensagem atual não diz mais "No connection to the network." Ao invés disso, ela reflete a mensagem armazenada no contrato inteligente. Ótimo! + +#### Sua UI poderia agora refletir a mensagem armazenada no contrato inteligente {#your-UI-should-now-reflect-the-message-stored-in-the-smart-contract} + +Agora falando daquele listener... + +#### Implementar `addSmartContractListener` {#implement-addsmartcontractlistener} + +Se você voltar para pensar no arquivo `HelloWorld.sol` que escrevemos na [Parte 1 desta série de tutoriais](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract#step-10-write-our-contract), você se lembrará que há um evento de contrato inteligente chamado `UpdatedMessages` que é emitido depois da função `update` do nosso contrato inteligente ser invocada \(ver linhas 9 e 27\): + +```javascript +// HelloWorld.sol + +// Specifies the version of Solidity, using semantic versioning. +// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +pragma solidity ^0.7.3; + +// Defines a contract named `HelloWorld`. +// Um contrato é uma coleção de funções e dados (seu estado). Uma vez implantado, um contrato reside em um endereço específico na blockchain Ethereum. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +contract HelloWorld { + + //Emitted when update function is called + //Smart contract events are a way for your contract to communicate that something happened on the blockchain to your app front-end, which can be 'listening' for certain events and take action when they happen. + event UpdatedMessages(string oldStr, string newStr); + + // Declares a state variable `message` of type `string`. + // Variáveis de estado são variáveis cujos valores são permanentemente armazenados no armazenamento do contrato. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value. + string public message; + + // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation. + // Os construtores são usados para inicializar os dados do contrato. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + constructor(string memory initMessage) { + + // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable). + message = initMessage; + } + + // A public function that accepts a string argument and updates the `message` storage variable. + function update(string memory newMessage) public { + string memory oldMsg = message; + message = newMessage; + emit UpdatedMessages(oldMsg, newMessage); + } +} +``` + +Eventos de contratos inteligentes são uma maneira do seu contrato comunicar que alguma coisa aconteceu \(ou seja, houve um _event_\) na blockchain no seu aplicativo de front-end, que pode “escutar” eventos específicos e tomar uma ação quando eles acontecem. + +A função `addSmartContractListener` escutará especificamente o evento `UpdatedMessages` do nosso contrato inteligente Olá, Mundo e atualizar nossa interface do usuário para mostrar a nova mensagem. + +Modifique `addSmartContractListener` da seguinte maneira: + +```javascript +// HelloWorld.js + +function addSmartContractListener() { + helloWorldContract.events.UpdatedMessages({}, (error, data) => { + if (error) { + setStatus("😥 " + error.message) + } else { + setMessage(data.returnValues[1]) + setNewMessage("") + setStatus("🎉 Your message has been updated!") + } + }) +} +``` + +Vamos quebrar em partes o que acontece quando o listener detecta um evento: + +- Se um erro ocorre quando o evento é emitido, ele será refletido na UI via nossa variável de estado `status`. +- Caso contrário, nós usaremos o objeto `data` retornado. O `data.returnValues` é uma array indexada no zero onde o primeiro elemento da array armazena a mensagem anterior e o segundo elemento armazena o atualizado. Ao todo, em um evento bem-sucedido, iremos configurar nossa cadeia de caracteres `message` com a mensagem atualizada, limpar a cadeia de caracteres `newMessage` e atualizar nossa variável de estado `status` para refletir que uma nova mensagem foi publicada no nosso contrato inteligente. + +Finalmente, vamos chamar nosso listener em nossa função `useEffect` para que seja inicializada na primeira renderização do componente `HelloWorld.js`. Tudo junto, sua função `useEffect` deve se parecer com: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() +}, []) +``` + +Agora que nós somos capazes de ler do nosso contrato inteligente, seria ótimo descobrir como escrever nele também! Entretanto, para escrever no nosso dapp, nós precisamos primeiro uma carteira Ethereum conectada nele. + +Então, em seguida vamos configurar nossa carteira Ethereum \(MetaMask\) e então conectá-la ao nosso dapp! + +### Passo 4: Configurar sua carteira Ethereum {#step-4-set-up-your-ethereum-wallet} + +Para escrever qualquer coisa na cadeia Ethereum, usuários devem assinar transações usando as chaves privadas das suas carteiras virtuais. Para este tutorial, usaremos o [MetaMask](https://metamask.io/), uma carteira virtual no navegador usada para gerenciar o seu endereço de conta do Ethereum, pois ele torna esta assinatura de transação superfácil para o usuário final. + +Se você quiser entender mais sobre como as transações no Ethereum funcionam, confira [esta página](/developers/docs/transactions/) na Fundação Ethereum. + +#### Baixar MetaMask {#download-metamask} + +Você pode baixar e criar uma conta MetaMask gratuitamente [neste link](https://metamask.io/download.html). Ao criar uma conta, ou mesmo se você já tiver uma conta, certifique-se de mudar para "Goerli Test Network” na parte superior direita \(para não lidarmos com dinheiro real\). + +#### Etapa: Adicionar Faucet ether {#add-ether-from-a-faucet} + +Para assinar a transação no blockchain Ethereum, nós precisamos de alguns Eth falsos. Para obter Eth você pode ir em[FaucETH](https://fauceth.komputing.org) e entrar seu endereço de conta Goerli, clicar em “Request funds”, e então selecionar “Ethereum Testnet Goerli” no menu, e finalmente clicar no botão "Request funds" novamente. Em seguida, você deve ver Eth em sua conta Metamask! + +#### Cheque seu Saldo {#check-your-balance} + +Para verificar novamente que tem saldo, vamos fazer uma solicitação através da ferramenta [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) fornecida pelo [compositor da Alchemy](https://composer.alchemyapi.io?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Ela mostrará a quantidade de Eth na sua carteira. Depois de inserir o endereço da sua conta da MetaMask e clicar em "Send Request", você verá uma resposta como esta: + +```text +{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"} +``` + +**NOTA:** Este resultado está em wei, não em ETH. Lembre-se de que "Wei" é a menor unidade de ether. A conversão de wei para eth é: 1 eth = 10¹⁸ wei. Então, se convertemos 0xde0b6b3a7640000 para decimal, temos 1\*10¹⁸ wei, que é igual a 1 eth. + +Ufa! Nosso dinheiro falso está todo lá! 🤑 + +### Passo 5: Conecte o MetaMask na sua UI {#step-5-connect-metamask-to-your-UI} + +Agora que nossa carteira MetaMask está configurada, vamos conectar nosso dapp a ela! + +#### Função `connectWallet` {#the-connectWallet-function} + +No nosso arquivo `interact.js`, vamos implementar a função `connectWallet`, a qual podemos então chamar no nosso componente `HelloWorld.js`. + +Vamos modificar `connectWallet` para o seguinte: + +```javascript +// interact.js + +export const connectWallet = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_requestAccounts", + }) + const obj = { + status: "👆🏽 Write a message in the text-field above.", + address: addressArray[0], + } + return obj + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + +

      + {" "} + 🦊 + You must install MetaMask, a virtual Ethereum wallet, in your + browser. + +

      +
      + ), + } + } +} +``` + +Então, o que esse bloco gigante de código faz exatamente? + +Bem, primeiro, ele checar se a `window.ethereum` está habilitada no seu navegador. + +`window.ethereum` é uma API global injetada pela MetaMask e outros provedores de carteira que permitem que sites solicitem contas Ethereum dos usuários. Se aprovado, ele pode ler dados dos blockchains que o usuário está conectado, e sugerir que o usuário assine mensagens e transações. Confira a [documentação da MetaMask](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents) para obter mais informações! + +Se `window.ethereum` _não está_ presente, então isso significa que o MetaMask não está instalado. Isso resulta em um objeto JSON sendo retornado, onde o `endereço` retornado é uma string vazia, e o `status` do objeto JSX repassa que o usuário deve instalar o MetaMask. + +Agora se `window.ethereum` _estiver_ presente, e é aí que as coisas ficam interessantes. + +Usando um laço try/catch, nós vamos tentar conectar ao MetaMask chamando[`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts). Chamando esta função o MetaMask irá abrir no navegador, onde o usuário será solicitado a conectar sua carteira ao seu dapp. + +- Se o usuário escolher conectar, `method: "eth_requestAccounts"` irá retornar uma array que contém todos os endereços de contas de usuário que conectaram ao dapp. No total, nossa função `connectWallet` retornará um objeto JSON que contém o _primeiro_ `address` desta matriz \(ver linha 9\) e uma mensagem `status` que pede que o usuário escreva uma mensagem para o contrato inteligente. +- Se o usuário rejeitar a conexão, então o objeto JSON vai conter uma string vazia para o `address` retornado e uma mensagem de `status` que reflete que o usuário rejeitou a conexão. + +Agora que nós escrevemos esta função `connectWallet`, o próximo passo é chamar ele para o nosso componente `HelloWorld.js`. + +#### Adicione a função `connectWallet` ao seu componente de interface do usuário `HelloWorld.js` {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component} + +Navegue para a função `connectWalletPressed` em `HelloWorld.js`, e atualize-o para o seguinte: + +```javascript +// HelloWorld.js + +const connectWalletPressed = async () => { + const walletResponse = await connectWallet() + setStatus(walletResponse.status) + setWallet(walletResponse.address) +} +``` + +Observe como a maior parte das nossas funcionalidades está abstraída do nosso componente `HelloWorld.js` do arquivo `interact.js`? É assim que respeitamos o paradigma M-V-C! + +Em `connectWalletPressed`, simplesmente fazemos uma chamada de espera (await) para a função `connectWallet`, importada, e usando sua resposta, nós atualizaremos nossas variáveis `status` e `walletAddress` através de seus state hooks. + +Agora, vamos salvar os dois arquivos `HelloWorld.js` e `interact.js` e testar nossa UI até agora. + +Abra seu navegador na página [http://localhost:3000/](http://localhost:3000/) e clique no botão “Connect Wallet” na parte superior direita da página. + +Se você tiver o MetaMask instalado, você será solicitado a conectar sua carteira ao seu dapp. Aceite o convite para se conectar. + +Observe que o botão de carteira agora mostra que o seu endereço está conectado! Ótimo!!🔥 + +Em seguida, tente atualizar a página... isso é estranho. Nosso botão de carteira está nos pedindo para conectar o MetaMask, mesmo que já esteja conectado... + +Entretanto, não tenha medo! Nós podemos endereçar (entendeu?) facilmente isso implementando `getCurrentWalletConnected`, o qual irá checar se um endereço já está conectado no nosso dapp e atualizar nossa UI de acordo! + +#### A função `getCurrentWalletConnected` {#the-getcurrentwalletconnected-function} + +Atualize a sua função `getCurrentWalletConnected` no arquivo `interact.js` como mostrado abaixo: + +```javascript +// interact.js + +export const getCurrentWalletConnected = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_accounts", + }) + if (addressArray.length > 0) { + return { + address: addressArray[0], + status: "👆🏽 Write a message in the text-field above.", + } + } else { + return { + address: "", + status: "🦊 Connect to MetaMask using the top right button.", + } + } + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + +

      + {" "} + 🦊 + You must install MetaMask, a virtual Ethereum wallet, in your + browser. + +

      +
      + ), + } + } +} +``` + +Este código é _muito_ similar à função `connectWallet` que nós acabamos de escrever no passo anterior. + +A diferença principal é que, em vez de chamar o método `eth_requestAccounts`, que abre o MetaMask para o usuário conectar sua carteira, aqui chamamos o método `eth_accounts`, que simplesmente retorna uma matriz que contém os endereços MetaMask atualmente conectados ao nosso dapp. + +Para ver esta função em ação, vamos chamar nossa função `useEffect` do nosso componente `HelloWorld.js`: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) +}, []) +``` + +Note que nós usamos a resposta da nossa chamada a `getCurrentWalletConnected` para atualizar nossa `walletAddress` e nossa variável de estado `status`. + +Agora que você adicionou este código, tente atualizar a janela do navegador. + +Ótimo!!!! O botão deve dizer que você está conectado e mostrar uma visualização do endereço de sua carteira conectada - mesmo depois de atualizar! + +#### Implemente `addWalletListener` {#implement-addwalletlistener} + +O passo final na configuração da nossa carteira dapp é implementar o ouvinte de carteira, para que nossa interface atualize quando o estado mudar, como quando o usuário desconecta ou troca de contas. + +No seu arquivo `HelloWorld.js`, modifique a sua função `addWalletListener` para o seguinte: + +```javascript +// HelloWorld.js + +function addWalletListener() { + if (window.ethereum) { + window.ethereum.on("accountsChanged", (accounts) => { + if (accounts.length > 0) { + setWallet(accounts[0]) + setStatus("👆🏽 Write a message in the text-field above.") + } else { + setWallet("") + setStatus("🦊 Connect to MetaMask using the top right button.") + } + }) + } else { + setStatus( +

      + {" "} + 🦊 + You must install MetaMask, a virtual Ethereum wallet, in your browser. + +

      + ) + } +} +``` + +Eu aposto que você nem mesmo precisou da nossa ajuda para entender o que está acontecendo aqui neste ponto, mas por finalidade de clareza, vamos quebrá-lo em partes: + +- Primeiro, nossa função verifica se o `window.ethereum` está habilitado no seu navegador \(ex. MetaMask instalado\). + - Caso contrário, nós simplesmente configuramos a variável de estado `status` para uma JSX string que solicita o usuário instalar a MetaMask. + - Se estiver habilitado, configuramos o ouvinte `window.ethereum.on("accountsChanged")` na linha 3 que houve mudança de estado na carteira MetaMask, inclusive quando o usuário conecta uma conta adicional ao dapp, troca de conta ou desconecta uma conta. Se houver pelo menos uma conta conectada, a variável de estado `walletAddress` é atualizada como a primeira conta no array `accounts` retornada pelo ouvinte. Caso contrário, `walletAddress` é definida como uma string vazia. + +Por último, mas não menos importante, nós devemos chamá-la em nossa função `useEffect`: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) + + addWalletListener() +}, []) +``` + +E é isso! Concluímos com sucesso a programação de toda a nossa carteira! Agora, a nossa última tarefa: atualizar a mensagem armazenada no nosso contrato inteligente! + +### Passo 6: Implemente a função `updateMessage` {#step-6-implement-the-updateMessage-function} + +Tudo bem, nós chegamos ao trecho caseiro! No `updateMessage` do seu arquivo `interact.js`, façamos o seguinte: + +1. Certifique-se que a mensagem que nós queremos publicar no nosso contrato inteligente é válida +2. Assine nossa transação usando MetaMask +3. Chame esta função do nosso componente de frontend `HelloWorld.js` + +Isso não vai demorar muito; vamos terminar este dapp! + +#### Manipulação de erros de script {#input-error-handling} + +Naturalmente, faz sentido ter alguns tipos de gerencialmente de erros de entrada no início da função. + +Queremos que nossa função retorne rapidamente. Se não houver uma extensão MetaMask instalada, não haverá carteiras conectadas \(ou seja, o `address` transmitido é uma cadeira de caracteres vazia\) ou a `message` será uma cadeira de caracteres vazia. Vamos adicionar o seguinte gerencialmente de erro em `updateMessage`: + +```javascript +// interact.js + +export const updateMessage = async (address, message) => { + if (!window.ethereum || address === null) { + return { + status: + "💡 Connect your MetaMask wallet to update the message on the blockchain.", + } + } + + if (message.trim() === "") { + return { + status: "❌ Your message cannot be an empty string.", + } + } +} +``` + +Agora que ele tem o devido gerenciamento de erro de entrada, é hora de assinar a transação via MetaMask! + +#### Assinando a nossa transação {#signing-our-transaction} + +Se você já está confortável com as transações tradicionais Web3 do Ethereum, o código que vamos escrever em seguida será bastante familiar. Abaixo, nosso código de manipulação de erro de entrada, adicione o seguinte a `updateMessage`: + +```javascript +// interact.js + +//set up transaction parameters +const transactionParameters = { + to: contractAddress, // Required except during contract publications. + from: address, // must match user's active address. + data: helloWorldContract.methods.update(message).encodeABI(), +} + +//sign the transaction +try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + status: ( + + ✅{" "} + + View the status of your transaction on Etherscan! + +
      + ℹ️ Once the transaction is verified by the network, the message will be + updated automatically. +
      + ), + } +} catch (error) { + return { + status: "😥 " + error.message, + } +} +``` + +Vamos quebrar em partes o que está acontecendo. Primeiro, configuramos nossos parâmetros de transações, em que: + +- `to` especificar o endereço do destinatário \(nosso contrato inteligente\) +- `from` especifica o signatário da transação, a variável `address` que transmitimos para a nossa função +- `data` contém a chamada para o método `update` do nosso contrato inteligente Olá, Mundo, recebendo nossa variável de cadeia de caracteres `message` como entrada + +Então, nós fazemos uma chamada await, `window.ethereum.request`, onde nós pedimos ao MetaMask para assinar a transação. Observe que nas linhas 11 e 12, estamos especificando nosso método eth `eth_sendTransaction` e passando os nossos `transactionParameters`. + +Neste ponto, a MetaMask irá abrir no navegador e pedirá que o usuário assine ou rejeite a transação. + +- Se a transação tiver sucesso, a função retornará um objeto JSON no qual a cadeia de caracteres JSX `status` pede ao usuário para verificar o Etherscan para mais informações sobre suas transações. +- Se a transação falha, a função irá retornar um objeto JSON onde a string `status` retransmite a mensagem de erro. + +Tudo junto, nossa função `updateMessage` deve se parecer com isso: + +```javascript +// interact.js + +export const updateMessage = async (address, message) => { + //input error handling + if (!window.ethereum || address === null) { + return { + status: + "💡 Connect your MetaMask wallet to update the message on the blockchain.", + } + } + + if (message.trim() === "") { + return { + status: "❌ Your message cannot be an empty string.", + } + } + + //set up transaction parameters + const transactionParameters = { + to: contractAddress, // Required except during contract publications. + from: address, // must match user's active address. + data: helloWorldContract.methods.update(message).encodeABI(), + } + + //sign the transaction + try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + status: ( + + ✅{" "} + + View the status of your transaction on Etherscan! + +
      + ℹ️ Once the transaction is verified by the network, the message will + be updated automatically. +
      + ), + } + } catch (error) { + return { + status: "😥 " + error.message, + } + } +} +``` + +Por último, mas não menos importante, nós precisamos conectar nossa função `updateMessage` ao componente `HelloWorld.js`. + +#### Conecte `updateMessage` ao front-end `HelloWorld.js` {#connect-updatemessage-to-the-helloworld-js-frontend} + +Nossa função `onUpdatePressed` deve fazer uma chamada await para a função `updateMessage` importada e modificar a variável de estado `status` para refletir se a nossa transação teve sucesso ou falhou: + +```javascript +// HelloWorld.js + +const onUpdatePressed = async () => { + const { status } = await updateMessage(walletAddress, newMessage) + setStatus(status) +} +``` + +É super limpo e simples. E advinhe... SEU DAPP ESTÁ COMPLETO!!! + +Vá em frente e teste com o botão **Update**! + +### Faça o seu próprio dapp customizado {#make-your-own-custom-dapp} + +Ebaaaaa, você chegou até o fim deste tutorial! Para recapitular, você aprendeu como: + +- Conectar a carteira MetaMask no seu projeto dapp +- Ler dados do seu contrato inteligente usando a API [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) +- Assinar transações Ethereum usando MetaMask + +Agora você está totalmente equipado para aplicar suas habilidades deste tutorial para construir seu próprio projeto dapp customizado! Como sempre, se você tiver questões, não hesite em nos contatar para pedir ajuda no[Discord da Alchemy](https://discord.gg/gWuC7zB). 🧙‍♂️ + +Uma vez que você terminou este tutorial, nos diga como foi sua experiência ou se você tem alguma opinião, nos marcando no Twitter [@alchemyplatform](https://twitter.com/AlchemyPlatform)! diff --git a/public/content/translations/pt-br/developers/tutorials/hello-world-smart-contract/index.md b/public/content/translations/pt-br/developers/tutorials/hello-world-smart-contract/index.md index 04864b12d21..2db6baca805 100644 --- a/public/content/translations/pt-br/developers/tutorials/hello-world-smart-contract/index.md +++ b/public/content/translations/pt-br/developers/tutorials/hello-world-smart-contract/index.md @@ -7,16 +7,23 @@ tags: - "hardhat" - "alchemy" - "contratos inteligentes" - - "primeiros passos" - "implementação" skill: beginner lang: pt-br published: 2021-03-31 --- -Se você é novo no desenvolvimento de blockchain e não sabe por onde começar, ou se apenas deseja entender como implementar ou interagir com contratos inteligentes, este guia é para você. Mostraremos a você como criar e implementar um simples contrato inteligente na rede de testes Ropsten usando uma carteira virtual ([MetaMask](https://metamask.io/)), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/) e [Alchemy](https://alchemyapi.io/eth). Não se preocupe caso não entenda ainda o que tudo isso significa. Vamos explicar). +Se você é novo no desenvolvimento de blockchain e não sabe por onde começar, ou se apenas deseja entender como implementar ou interagir com contratos inteligentes, este guia é para você. Vamos criar e implantar um contrato inteligente simples na rede de teste Goerli usando uma carteira virtual [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/) e [Alchemy](https://alchemyapi.io/eth) (não se preocupe se você ainda não entendeu o que isso significa, nós explicaremos). -Na segunda parte deste tutorial, analisaremos como podemos interagir com nosso contrato inteligente uma vez que ele esteja implementado e, já na terceira parte, abordaremos como publicá-lo no Etherscan. +> **Atenção** +> +> Aviso de descontinuidade +> +> Para este guia inteiro, a rede de teste Goerli está sendo usada para criação e implantação de contratos inteligentes. Entretanto, por favor note que a Ethereum Foundation anunciou que a [Goerli será descontinuada em breve](https://www.alchemy.com/blog/goerli-faucet-deprecation). +> +> Nós recomendamos você usar a [Sepolia](https://www.alchemy.com/overviews/sepolia-testnet) e [faucets Sepolia](https://sepoliafaucet.com/) para este tutorial. + +Na [parte 2](https://docs.alchemy.com/docs/interacting-with-a-smart-contract) deste tutorial, veremos como podemos interagir com nosso contrato inteligente, assim que for implantado aqui, e na [parte 3](https://docs.alchemy.com/docs/submitted-your-smart-contract-to-etherscan), abordaremos como publicá-lo no Etherscan. Caso surjam perguntas em qualquer momento, sinta-se à vontade para falar no Discord da [Alchemy](https://discord.gg/gWuC7zB)! @@ -26,29 +33,29 @@ Existem muitas maneiras de fazer solicitações à cadeia de Ethereum. Por simpl ## Passo 2: Crie seu aplicativo (e chave de API) {#step-2} -Assim que você criar uma conta na Alchemy, você pode gerar uma chave de API criando um app. Isso nos permitirá fazer solicitações à rede de testes Ropsten. Se não estiver familiarizado com as redes de teste, confira [esta página](/developers/docs/networks/). +Assim que você criar uma conta na Alchemy, você pode gerar uma chave de API criando um app. Isso nos permitirá fazer solicitações na rede de teste Goerli. Se não estiver familiarizado com as redes de teste, confira [esta página](/developers/docs/networks/). -1. Vá até a página "Create App" no painel da Alchemy, passe o mouse sobre a palavra "Apps" na barra de navegação e clique em "Create App" +1. Navegue até a pagina "Create App" na sua "Dashboard da Alchemy", indo na aba de "Apps" na barra de navegação e clicando em “Create App” ![Criar um aplicativo Hello World](./hello-world-create-app.png) -2. Nomeie seu aplicativo "Hello World", ofereça uma breve descrição, selecione "Staging" para o ambiente (usado para a contabilidade de seu app) e escolha "Ropsten" para sua rede. +2. Nomeie seu aplicativo “Hello World”, ofereça uma breve descrição, selecione “Staging” para o ambiente (usado para seu aplicativo de contabilidade) e escolha “Goerli” para sua rede. ![criar uma visualização do app hello world](./create-app-view-hello-world.png) -3. Clique em "Create App", e é isso e tudo! Seu app deveria aparecer na tabela abaixo. +3. Clique em "Criar app" e pronto! Seu app deve aparecer na tabela abaixo. ## Passo 3: Crie uma conta (endereço) de Ethereum {#step-3} Precisamos de uma conta de Ethereum para enviar e receber transações. Para este tutorial, usaremos uma carteira virtual no navegador, a MetaMask, para gerenciar o endereço da sua conta Ethereum. Mais sobre [transações](/developers/docs/transactions/). -Você pode baixar e criar uma conta MetaMask gratuitamente [neste link](https://metamask.io/download.html). Quando estiver criando uma conta, ou se já tiver uma, certifique-se de mudar para a "Ropsten Test Network", no canto superior direito (para não precisar lidar com dinheiro de verdade). +Você pode baixar e criar uma conta MetaMask gratuitamente [neste link](https://metamask.io/download.html). Quando você estiver criando uma conta, ou se já tiver uma conta, certifique-se de mudar para a “Rede de teste Goerli”, no canto superior direito (para que não estejamos lidando com dinheiro real). ![exemplo metamask ropsten](./metamask-ropsten-example.png) ## Passo 4: Adicione ether de um faucet {#step-4} -Para implementar nosso contrato inteligente na rede de teste, precisaremos de alguns ETHs de imitação. Para obter ETH você pode ir para o [faucet da Ropsten](https://faucet.dimensions.network/), inserir seu endereço de conta Ropsten e clicar em "Send Ropsten ETH". Devido ao tráfego de rede, pode levar algum tempo até receber o seu ETH de imitação. Você deveria ver o ETH na sua conta MetaMask logo depois! +Para implantar nosso contrato inteligente na rede de teste, precisaremos de algum Eth falso. Para obter Eth, você pode acessar a [torneira Goerli](https://goerlifaucet.com/), fazer login na sua conta Alchemy, inserir o endereço da carteira e clicar em "Send Me Eth." Pode levar algum tempo para receber seu Eth falso devido ao tráfego de rede. (Enquanto escrevia isto, levou cerca de 30 minutos) Você deve ver Eth em sua conta Metamask logo depois! ## Passo 5: Verifique seu saldo {#step-5} @@ -58,8 +65,8 @@ Para verificar novamente que temos saldo, vamos fazer uma solicitação através { "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" } ``` -> **OBSERVAÇÃO:** este resultado é em wei não em ETH. Lembre-se de que o wei é a menor unidade do ether. A conversão de wei para ETH é 1 ETH = 1018 wei. Desta maneira, se convertermos 0x2B5E3AF16B1880000 em decimal obteremos 5\*10¹⁸, o que equivale a 5 ETH. -> +> **OBSERVAÇÃO:** este resultado é em wei não em ETH. Lembre-se de que "Wei" é a menor unidade de ether. A conversão de wei para ETH é 1 ETH = 1018 wei. Desta maneira, se convertermos 0x2B5E3AF16B1880000 em decimal obteremos 5\*10¹⁸, o que equivale a 5 ETH. +> > Ufa! Nosso dinheiro de imitação está todo aí . ## Passo 6: Inicialize nosso projeto {#step-6} @@ -106,9 +113,9 @@ About to write to /Users/.../.../.../hello-world/package.json: Aprove o package.json e estaremos prontos para começar! -## Passo 7: Baixe o [Hardhat](https://hardhat.org/getting-started/#overview){#step-7} +## Etapa 7: Faça o download do [Hardhat](https://hardhat.org/getting-started/#overview) {#step-7} -Hardhat é um ambiente de desenvolvimento para compilar, implementar, testar e depurar seu software de Ethereum. Ele ajuda os desenvolvedores na criação de contratos inteligentes e dApps localmente antes de serem implementados na cadeia online. +Hardhat é um ambiente de desenvolvimento para compilar, implementar, testar e depurar seu software de Ethereum. Ele ajuda os desenvolvedores na criação de contratos inteligentes e dapps localmente antes de implantar na cadeia real. Dentro de nosso projeto `hello-world` execute: @@ -199,9 +206,9 @@ contract HelloWorld { Este é um contrato inteligente muito simples, que armazena uma mensagem ao ser criado e pode ser atualizado através da função `update`. -## Passo 11: Vincule MetaMask e Alchemy a seu projeto {#step-11} +## Passo 11: Vincule Metamask e Alchemy a seu projeto {#step-11} -Nós já criamos uma carteira MetaMask, uma conta Alchemy e já escrevemos nosso contrato inteligente. Agora é hora de vincularmos os três. +Nós já criamos uma carteira Metamask, uma conta Alchemy e já escrevemos nosso contrato inteligente. Agora é hora de vincularmos os três. Toda transação enviada da sua carteira virtual requer uma assinatura, usando sua chave privada única. Para fornecer essa permissão ao nosso programa, nós podemos armazenar com segurança nossa chave privada (e a chave Alchemy API) em um arquivo de ambiente. @@ -213,7 +220,7 @@ Primeiro, instale o pacote dotenv na pasta do seu projeto: npm install dotenv --save ``` -Depois, crie um arquivo `.env` no diretório raiz do seu projeto e adicione sua chave MetaMask privada e o URL da API HTTP Alchemy nele. +Depois, crie um arquivo `.env` no diretório raiz do seu projeto e adicione sua chave Metamask privada e o URL da API HTTP Alchemy nele. - Siga [estas instruções](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) para exportar sua chave privada - Veja abaixo como obter o URL da API HTTP Alchemy @@ -225,14 +232,14 @@ Copiar o URL da Alchemy API Seu arquivo `.env` ficará assim: ``` -API_URL = "https://eth-ropsten.alchemyapi.io/v2/your-api-key" +API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" PRIVATE_KEY = "your-metamask-private-key" ``` Para realmente vinculá-los a nosso código, vamos fazer referência a essas variáveis em nosso arquivo `hardhat.config.js` no passo 13. -Don't commit .env! Please make sure never to share or expose your .env file with anyone, as you are compromising your secrets in doing so. If you are using version control, add your .env to a gitignore file. +No faça commit do .env! Por favor, tenha certeza de nunca compartilhar ou expor seu arquivo .env com ninguém, pois estará comprometendo suas partes secretas ao fazê-lo. Se estiver usando um controle de versão, adicione seu .env ao arquivo gitignore ## Passo 12: Instale o Ethers.js {#step-12-install-ethersjs} @@ -266,10 +273,10 @@ const { API_URL, PRIVATE_KEY } = process.env; */ module.exports = { solidity: "0.7.3", - defaultNetwork: "ropsten", + defaultNetwork: "goerli", networks: { hardhat: {}, - ropsten: { + goerli: { url: API_URL, accounts: [`0x${PRIVATE_KEY}`] } @@ -330,7 +337,7 @@ Ao chamar `deploy()` em uma `ContractFactory`, a implantação se iniciará e re Finalmente estamos prontos para implantar o nosso contrato inteligente! Navegue até a linha de comando e digite: ``` -npx hardhat run scripts/deploy.js --network ropsten +npx hardhat run scripts/deploy.js --network goerli ``` Você deverá ver algo assim: @@ -339,11 +346,11 @@ Você deverá ver algo assim: Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 ``` -Se formos para a [etherscan Ropsten](https://ropsten.etherscan.io/) e procurarmos o endereço de nosso contrato, poderemos ver se ele foi implantado com sucesso. A transação ficará parecida com isto: +Se formos ao [etherscan da Goerli](https://goerli.etherscan.io/) e procurarmos nosso endereço de contrato, devemos ser capazes de ver que ele foi implantado com sucesso. A transação ficará parecida com isto: ![contrato etherscan](./etherscan-contract.png) -O endereço `From` deve corresponder ao endereço da sua conta MetaMask, e o endereço "Para" vai dizer "Criação de contrato", mas se clicarmos na transação veremos o endereço do nosso contrato no campo `To`: +O endereço `From` deve corresponder ao endereço da sua conta Metamask, e o endereço "Para" vai dizer "Criação de contrato", mas se clicarmos na transação veremos o endereço do nosso contrato no campo `To`: ![transação etherscan](./etherscan-transaction.png) @@ -351,7 +358,7 @@ Parabéns! Você acaba de implantar um contrato inteligente para a cadeia Ethere Para entender o que está acontecendo nos bastidores, vamos navegar até a guia Explorer no [painel do Alchemy](https://dashboard.alchemyapi.io/explorer). Se você tem vários aplicativos Alchemy, certifique-se de filtrar por app e selecionar “Hello World”. ![explorador hello world](./hello-world-explorer.png) -Aqui você verá um punhado de chamadas JSON-RPC que Hardhat/Ethers fizeram em segundo plano para nós quando chamamos a função `.deploy() `. Duas importantes chamadas aqui são a [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction), que é o pedido para realmente escrever nosso contrato inteligente na cadeia de Ropsten, e a [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash), que é um pedido para ler informações sobre nossa transação, dado o hash (um padrão típico ao enviar transações). Para saber mais sobre o envio de transações, confira este tutorial em [ sobre como enviar transações usando a Web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) +Aqui você verá um punhado de chamadas JSON-RPC que Hardhat/Ethers fizeram em segundo plano para nós quando chamamos a função `.deploy() `. Duas importantes chamadas aqui são [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction), que é o pedido para escrever de fato nosso contrato na cadeia Goerli, e [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash) que é um pedido para ler informações sobre nossa transação dado o hash (um padrão típico em transações). Para saber mais sobre o envio de transações, confira este tutorial em [ sobre como enviar transações usando a Web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) Isso é tudo para a parte 1 deste tutorial. Na parte 2, [interagiremos com nosso contrato inteligente](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#part-2-interact-with-your-smart-contract) atualizando nossa mensagem inicial e, na parte 3, [publicaremos nosso contrato inteligente no Etherscan](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#optional-part-3-publish-your-smart-contract-to-etherscan) para que todos aprendam como interagir com ele. diff --git a/public/content/translations/pt-br/developers/tutorials/how-to-implement-an-erc721-market/index.md b/public/content/translations/pt-br/developers/tutorials/how-to-implement-an-erc721-market/index.md new file mode 100644 index 00000000000..dc2b696978c --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/how-to-implement-an-erc721-market/index.md @@ -0,0 +1,149 @@ +--- +title: Como implementar um mercado ERC-721 +description: Como colocar itens tokenizados para venda em um mercado descentralizado +author: "Alberto Cuesta Cañada" +tags: + - "contratos inteligentes" + - "erc-721" + - "solidez" + - "tokens" +skill: intermediate +lang: pt-br +published: 2020-03-19 +source: Hackernoon +sourceUrl: https://hackernoon.com/how-to-implement-an-erc721-market-1e1a32j9 +--- + +Neste artigo, vou lhe mostrar como programar um Craigslist na blockchain Ethereum. + +Antes de Gumtree, Ebay e Craigslist, classificados eram basicamente painéis de cortiça ou papel. Havia seções de classificados nos corredores da escola, jornais, postes de rua, e vitrines. + +Tudo isso mudou com a internet. O número de pessoas que podiam ver um determinado quadro classificado foi multiplicado por muitas ordens de magnitude. Com isso, os mercados que representam tornaram-se muito mais eficientes e escalaram até à dimensão global. A Ebay é uma empresa gigantesca que rastreia a origem destes quadros de classificações físicas. + +Com a blockchain, esses mercados estão definidos para mudar mais uma vez, deixe-me te mostrar como. + +## Monetização {#monetization} + +O modelo de negócio de um conselho de classificações públicas da blockchain precisará ser diferente do da Ebay e da empresa. + +Primeiro, há [o ângulo de descentralização](/developers/docs/web2-vs-web3/). Plataformas existentes precisam manter seus próprios servidores. Uma plataforma descentralizada é mantida por seus usuários, então o custo de executar a plataforma principal cai para zero para o proprietário da plataforma. + +Em seguida, há o front-end, o site ou a interface que dá acesso à plataforma. Aqui há muitas opções. Os proprietários da plataforma podem restringir o acesso e forçar todos a usar a interface, carregando uma taxa. Os proprietários da plataforma também podem decidir abrir o acesso (Poder para as Pessoas!) e deixar qualquer pessoa construir interfaces na plataforma. Ou os proprietários poderiam decidir qualquer abordagem no meio desses extremos. + +_Os líderes empresariais com mais visão do que eu saberão bem como monetizar isso. Tudo o que entendo é que isto é diferente do status quo e é, provavelmente, lucrativo._ + +Além disso, há o ponto relativo à automação e aos pagamentos. Algumas coisas podem ser [efetivamente tokenizadas](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) e negociadas em um quadro de classificações. Ativos tokenizados são facilmente transferidos em uma blockchain. Métodos de pagamento altamente complexos podem ser facilmente implementados em uma blockchain. + +Sinto uma oportunidade de negócios aqui. Um quadro de classificados sem custos correntes pode ser facilmente implementado, com caminhos de pagamento complexos incluídos em cada transação. Tenho certeza de que alguém vai ter uma ideia sobre em que usar isso. + +Estou feliz construindo. Vamos dar uma olhada no código. + +## Implementação {#implementation} + +Há algum tempo iniciamos um [repositório de código aberto](https://github.com/HQ20/contracts?ref=hackernoon.com) com implementações de exemplos de casos de negócios e outros brindes, dê uma olhada. + +O código para este [Ethereum Classifieds Board](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com) está lá, por favor, use e abuse dele. Apenas esteja ciente de que o código não foi auditado e de que você precisa fazer a sua própria diligência antes de deixar o dinheiro entrar. + +Os fundamentos do conselho não são complexos. Todos os anúncios no board serão apenas uma construção com alguns campos: + +```solidity +struct Trade { + address poster; + uint256 item; + uint256 price; + bytes32 status; // Open, Executed, Cancelled +} +``` + +Portanto, há alguém que publique o anúncio. Item à venda. Um preço para o item. O status da operação que pode ser aberto, executado ou cancelado. + +Todas essas trocas serão mantidas em um mapeamento. Porque tudo no Solidity parece ser um mapeamento. Também porque é conveniente. + +```solidity +mapping(uint256 => Trade) public trades; +``` + +Usando um mapeamento significa apenas que temos que criar um id para cada anúncio antes de publicá-lo, e precisaremos saber a identificação de um anúncio antes de podermos operar sobre ele. Existem várias maneiras de lidar com isto, seja no contrato inteligente ou na parte front-end. Por favor pergunte se você precisa de alguns ponteiros. + +Em seguida, a questão de quais são os itens com que lidamos, e qual é esta moeda que é usada para pagar a transação. + +Para os itens, vamos apenas pedir que eles implementem a interface [ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com), que realmente é apenas uma maneira de representar itens do mundo real em uma blockchain, embora [funcione melhor com os recursos digitais](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com). Vamos especificar o nosso próprio contrato ERC721 no construtor, significa que todos os ativos do nosso quadro de classificados precisam ter sido tokenizados previamente. + +Quanto aos pagamentos, vamos fazer algo semelhante. A maioria dos projetos blockchain definem suas próprias criptomoedas [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com). Outros preferem usar um mainstream como a DAI. Neste quadro de classificações, você só precisa decidir em construção qual será a sua moeda. Fácil. + +```solidity +constructor ( + address _currencyTokenAddress, address _itemTokenAddress +) public { + currencyToken = IERC20(_currencyTokenAddress); + itemToken = IERC721(_itemTokenAddress); + tradeCounter = 0; +} +``` + +Nós estamos chegando lá. Temos anúncios, itens para negociação e uma moeda para pagamentos. Fazer um anúncio significa colocar um item no escopo para mostrar que você o tem e que você não publicou duas vezes, possivelmente em um quadro diferente. + +O código abaixo faz exatamente isso. Coloca o item no escrow, cria o anúncio, faz algum serviço doméstico. + +```solidity +function openTrade(uint256 _item, uint256 _price) + public +{ + itemToken.transferFrom(msg.sender, address(this), _item); + trades[tradeCounter] = Trade({ + poster: msg.sender, + item: _item, + price: _price, + status: "Open" + }); + tradeCounter += 1; + emit TradeStatusChange(tradeCounter - 1, "Open"); +} +``` + +Aceitar a troca significa escolher um anúncio (negociação), pagar o preço, receber o item. O código abaixo recupera uma troca. Verifica se está disponível. Paga o item. Recupera o item. Atualiza o anúncio. + +```solidity +function executeTrade(uint256 _trade) + public +{ + Trade memory trade = trades[_trade]; + require(trade.status == "Open", "Trade is not Open."); + currencyToken.transferFrom(msg.sender, trade.poster, trade.price); + itemToken.transferFrom(address(this), msg.sender, trade.item); + trades[_trade].status = "Executed"; + emit TradeStatusChange(_trade, "Executed"); +} +``` + +Por último, temos uma opção para os vendedores recuarem numa negociação antes que um comprador a aceite. Em alguns modelos, os anúncios estariam vivos por um período de tempo antes de eles expirarem. Fica a sua escolha, dependendo do design do seu mercado. + +O código é muito semelhante ao usado para executar uma negociação, apenas não há nenhuma mudança de moeda e o item volta para o cartaz anunciante. + +```solidity +function cancelTrade(uint256 _trade) + public +{ + Trade memory trade = trades[_trade]; + require( + msg.sender == trade.poster, + "Trade can be cancelled only by poster." + ); + require(trade.status == "Open", "Trade is not Open."); + itemToken.transferFrom(address(this), trade.poster, trade.item); + trades[_trade].status = "Cancelled"; + emit TradeStatusChange(_trade, "Cancelled"); +} +``` + +É isso. Você chegou ao fim da implementação. É bastante surpreendente como alguns conceitos de negócios se tornam compactos quando são expressados em código, e este é um desses casos. Verifique o contrato completo [no nosso repositório](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol). + +## Conclusão {#conclusion} + +As seções de classificados são uma configuração comum de mercado que cresceu em grande escala com a internet, tornando-se um modelo de negócio extremamente popular com alguns vencedores monopolistas. + +Também acontece de as seções de classificados serem uma ferramenta fácil de replicar em um ambiente blockchain, com características muito específicas que possibilitarão um desafio para os gigantes da atualidade. + +Neste artigo, tentei fazer uma ponte entre a realidade comercial de um conselho de administração clássico com a implementação tecnológica. Este conhecimento deve ajudá-lo a criar uma visão e um roteiro para a implementação, se você tiver as habilidades certas. + +Como sempre, se você for construir algo divertido e gostaria de alguns conselhos, por favor [envie-me uma mensagem](https://albertocuesta.es/)! Fico sempre feliz em ajudar. diff --git a/public/content/translations/pt-br/developers/tutorials/how-to-mint-an-nft/index.md b/public/content/translations/pt-br/developers/tutorials/how-to-mint-an-nft/index.md index bbabf05713c..94593c6e630 100644 --- a/public/content/translations/pt-br/developers/tutorials/how-to-mint-an-nft/index.md +++ b/public/content/translations/pt-br/developers/tutorials/how-to-mint-an-nft/index.md @@ -4,7 +4,8 @@ description: Este tutorial descreve como criar um NFT na blockchain Ethereum usa author: "Sumi Mudgil" tags: - "ERC-721" - - "Solidity" + - "alchemy" + - "solidity" - "contratos inteligentes" skill: beginner lang: pt-br @@ -13,7 +14,7 @@ published: 2021-04-22 [Beeple](https://www.nytimes.com/2021/03/11/arts/design/nft-auction-christies-beeple.html): 69 milhões de doláres [3LAU](https://www.forbes.com/sites/abrambrown/2021/03/03/3lau-nft-nonfungible-tokens-justin-blau/?sh=5f72ef64643b): 11 milhões de doláres [Grimes](https://www.theguardian.com/music/2021/mar/02/grimes-sells-digital-art-collection-non-fungible-tokens): 6 milhões de doláres -Estes NFTs foram criados usando a poderosa API da Alchemy. Neste tutorial, vamos te ensinar a fazer o mesmo em < 10 minutos. +All of them minted their NFTs using Alchemy’s powerful API. Neste tutorial, vamos te ensinar a fazer o mesmo em < 10 minutos. "Cunhar um NFT" é o ato de publicar uma instância única do seu token ERC-721 na blockchain. Usando nosso contrato inteligente da [Parte 1 desta série de tutoriais NFT](/developers/tutorials/how-to-write-and-deploy-an-nft/), vamos usar nossas habilidades Web3 e criar um NFT. No final deste tutorial, você será capaz de cunhar tantos NFTs quanto seu coração (e sua carteira) desejar! @@ -110,9 +111,9 @@ Uma vez terminada a edição do arquivo JSON, salve-o e faça o upload para o Pi ## Etapa 5: Criar uma instância de seu contrato {#instance-contract} -Agora, para interagir com o nosso contrato, precisamos criar uma instância dele em nosso código. Para fazer isso, precisaremos do nosso endereço de contrato, obtido na implantação ou no [Etherscan](https://goerli.etherscan.io/), procurando o endereço que você usou para implantar o contrato. +Agora, para interagir com o nosso contrato, precisamos criar uma instância dele em nosso código. Para fazer isso, precisaremos do nosso endereço de contrato, obtido na implantação ou no [Etherscan](https://sepolia.etherscan.io/), procurando o endereço que você usou para implantar o contrato. -![Veja o seu endereço de contrato no Etherscan](./viewContractEtherscan.png) +![Veja o seu endereço de contrato no Etherscan](./view-contract-etherscan.png) No exemplo acima, o endereço do contrato é 0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778. @@ -131,7 +132,7 @@ Agora, para criar e enviar transações para a cadeia Ethereum, usaremos seu end Adicione sua chave pública ao seu arquivo `.env` — se você concluiu a parte 1 do tutorial, nosso arquivo `.env` deve ficar assim: ```js -API_URL = "https://eth-goerli.g.alchemy.com/v2/your-api-key" +API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key" PRIVATE_KEY = "your-private-account-address" PUBLIC_KEY = "your-public-account-address" ``` @@ -314,15 +315,15 @@ mintNFT("ipfs://QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP") Agora, execute `node scripts/mint-nft.js` para implantar seu NFT. Depois de alguns segundos, você deverá ver uma resposta como essa no seu terminal: O hash de sua transação é: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8 - + Verifique o Mempool da Alquemy para ver o estado da sua transação! -Em seguida, acesse a [mempool (área de espera) da Alchemy](https://dashboard.alchemyapi.io/mempool) para ver o estado da sua transação (se pendente, minerada ou recusada pela rede). Se a sua transação foi descartada, também é útil verificar o [Goerli Etherscan](https://goerli.etherscan.io/) e procurar pelo hash da transação. +Em seguida, acesse a [mempool (área de espera) da Alchemy](https://dashboard.alchemyapi.io/mempool) para ver o estado da sua transação (se pendente, minerada ou recusada pela rede). Se a sua transação se perdeu, também é útil verificar no [Sepolia Etherscan](https://sepolia.etherscan.io/) e procurar o hash da transação. -![Veja seu hash de transação NFT no Etherscan](./viewNFTEtherscan.png)_Veja seu hash de transação NFT no Etherscan_ +![Veja seu hash de transação NFT no Etherscan](./view-nft-etherscan.png)_Veja seu hash de transação NFT no Etherscan_ E pronto! Você agora implantou E cunhou um NFT na blockchain Ethereum -Usando o `mint-nft.js`, você pode cunhar quantos NFTs você (e sua carteira) desejar! Apenas certifique-se de transmitir um novo tokenURI descrevendo os metadados do NFT (caso contrário, você acaba criando um monte de identificações idênticas, com IDs diferentes). +Using the `mint-nft.js` you can mint as many NFTs as your heart (and wallet) desires! Apenas certifique-se de transmitir um novo tokenURI descrevendo os metadados do NFT (caso contrário, você acaba criando um monte de identificações idênticas, com IDs diferentes). Provavelmente você gostaria de poder exibir seu NFT na sua carteira — então certifique-se de conferir [Parte 3: Como ver seu NFT na sua carteira](/developers/tutorials/how-to-view-nft-in-metamask/)! diff --git a/public/content/translations/pt-br/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md b/public/content/translations/pt-br/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md new file mode 100644 index 00000000000..5621dda9432 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md @@ -0,0 +1,106 @@ +--- +title: Como simular contratos inteligentes em Solidity para teste +description: Por que você deve aproveitar os seus contratos ao testar +author: Markus Waas +lang: pt-br +tags: + - "solidez" + - "contratos inteligentes" + - "testando" + - "simulando" +skill: intermediate +published: 2020-05-02 +source: soliditydeveloper.com +sourceUrl: https://soliditydeveloper.com/mocking-contracts +--- + +[Mock de objetos ](https://wikipedia.org/wiki/Mock_object) são um padrão de design comum na programação orientada a objetos. Vindo da velha palavra francesa "mocquer" com o significado de "diversão de", evoluiu para a "imitação de algo real", que é na realidade, o que estamos fazendo na programação. Por favor, só se divirta de seus contratos inteligentes se você quiser, mas faça o mock deles sempre que puder. Isso torna sua vida mais fácil. + +## Testes de unidade de contratos com simulações {#unit-testing-contracts-with-mocks} + +Simular um contrato (mocking) significa essencialmente criar uma segunda versão desse contrato que se comporta de maneira muito semelhante ao original, mas de uma maneira que pode ser facilmente controlada pelo desenvolvedor. Muitas vezes, você acaba com contratos complexos nos quais você só quer [fazer testes de unidade de pequenas partes do contrato](/developers/docs/smart-contracts/testing/). O problema é: e se o teste desta pequena parte exigir um estado de contrato muito específico que seja difícil de alcançar? + +Você poderia escrever uma lógica de configuração de testes complexa toda vez que apresentasse o contrato no estado necessário ou você escreveria uma simulação (mock, em inglês). Simular um contrato é fácil com herança. Basta criar um segundo contrato mock que herda do original. Agora você pode substituir funções de seu mock. Vejamos com um exemplo. + +## Exemplo: ERC20 Privado {#example-private-erc20} + +Usamos um exemplo de contrato ERC-20 que tem um tempo privado inicial. O proprietário pode gerenciar usuários privados e apenas esses terão permissão para receber tokens no início. Uma vez que um certo tempo tenha passado, todos poderão utilizar os tokens. Se você estiver curioso, estamos usando o hook (código modificado) [`_beforeTokenTransfer`](https://docs.openzeppelin.com/contracts/3.x/extending-contracts#using-hooks) dos novos contratos OpenZeppelin v3. + +```solidity +pragma solidity ^0.6.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract PrivateERC20 is ERC20, Ownable { + mapping (address => bool) public isPrivateUser; + uint256 private publicAfterTime; + + constructor(uint256 privateERC20timeInSec) ERC20("PrivateERC20", "PRIV") public { + publicAfterTime = now + privateERC20timeInSec; + } + + function addUser(address user) external onlyOwner { + isPrivateUser[user] = true; + } + + function isPublic() public view returns (bool) { + return now >= publicAfterTime; + } + + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { + super._beforeTokenTransfer(from, to, amount); + + require(_validRecipient(to), "PrivateERC20: invalid recipient"); + } + + function _validRecipient(address to) private view returns (bool) { + if (isPublic()) { + return true; + } + + return isPrivateUser[to]; + } +} +``` + +E agora vamos fazer o mock disso. + +```solidity +pragma solidity ^0.6.0; +import "../PrivateERC20.sol"; + +contract PrivateERC20Mock is PrivateERC20 { + bool isPublicConfig; + + constructor() public PrivateERC20(0) {} + + function setIsPublic(bool isPublic) external { + isPublicConfig = isPublic; + } + + function isPublic() public view returns (bool) { + return isPublicConfig; + } +} +``` + +Você receberá uma das seguintes mensagens de erro: + +- `PrivateERC20Mock.sol: TypeError: Overriding function is missing "override" specifier.` +- `PrivateERC20.sol: TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?.` + +Como estamos usando a nova versão 0.6 do Solidity, temos que adicionar a palavra-chave `virtual` para funções que podem ser sobrescritas e substituídas pela função substituta. Então vamos adicioná-los para ambas as funções `isPublic`. + +Agora você pode usar `PrivateERC20Mock` nos seus testes de unidade. Quando você quiser testar o comportamento durante o tempo de uso privado, use `setIsPublic(false)` e, da mesma forma, `setIsPublic(true)` para testar o tempo de uso público. É claro que em nosso exemplo, poderíamos usar simplesmente [auxiliares de tempo](https://docs.openzeppelin.com/test-helpers/0.5/api#increase) para alterar os tempos de acordo também. Mas a ideia de mocking deve estar clara agora e você pode imaginar cenários em que não é tão fácil quanto simplesmente avançar no tempo. + +## Mocking em muitos contratos {#mocking-many-contracts} + +Pode ficar confuso se você tiver que criar outro contrato para cada mock. Se isso incomoda você, dê uma olhada na biblioteca [MockContract](https://github.com/gnosis/mock-contract). Ele permite que você sobrescreva e modifique comportamentos de contratos em tempo real. No entanto, ele só funciona para chamadas mocking para outro contrato, portanto, não funcionaria para o nosso exemplo. + +## Mocking podem ser ainda mais poderosas {#mocking-can-be-even-more-powerful} + +Os poderes de mocking não terminam aí. + +- Adicionando funções: sobrescrever uma função específica é útil, mas apenas acrescentar funções adicionais também poderá ser. Um bom exemplo para tokens é ter apenas uma função adicional `mint` para permitir que qualquer usuário obtenha novos tokens gratuitamente. +- Uso em testnets: ao implantar e testar seus contratos em testnets juntamente com seu Dapp, considere usar uma versão mock. Evite sobrescrever funções, a menos que você realmente precise. Afinal, você quer testar a lógica real. Mas adicionar, por exemplo, uma função de redefinição pode ser útil que simplesmente redefine o estado do contrato para o início, sem necessidade de nova implantação. Obviamente, você não gostaria de ter isso em um contrato na mainnet (rede principal). diff --git a/public/content/translations/pt-br/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md b/public/content/translations/pt-br/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md new file mode 100644 index 00000000000..899dffa2ab9 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md @@ -0,0 +1,693 @@ +--- +title: Como usar o Echidna para testar contratos inteligentes +description: Como usar o Echidna para testar automaticamente contratos inteligentes +author: "Trailofbits" +lang: pt-br +tags: + - "solidez" + - "smart contracts" + - "segurança" + - "testando" + - "fuzzing" +skill: advanced +published: 2020-04-10 +source: Construindo contratos seguros +sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna +--- + +## Instalação {#installation} + +Echidna pode ser instalado através do docker ou usando o binário pré-compilado. + +### Echidna com docker {#echidna-through-docker} + +```bash +docker pull trailofbits/eth-security-toolbox +docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox +``` + +_O último comando roda a eth-security-toolbox em um docker que tem acesso ao seu diretório atual. Você pode alterar os arquivos do seu host e executar as ferramentas nos arquivos através do docker_ + +Dentro do docker, execute : + +```bash +solc-select 0.5.11 +cd /home/training +``` + +### Binário {#binary} + +[https://github.com/crytic/echidna/releases/tag/v1.4.0.0](https://github.com/crytic/echidna/releases/tag/v1.4.0.0) + +## Introdução a fuzzing baseado em propriedade {#introduction-to-property-based-fuzzing} + +Echidna é um fuzzer baseado em propriedades, descrevemos em nossos posts anteriores ([1](https://blog.trailofbits.com/2018/03/09/echidna-a-smart-fuzzer-for-ethereum/), [2](https://blog.trailofbits.com/2018/05/03/state-machine-testing-with-echidna/), [3](https://blog.trailofbits.com/2020/03/30/an-echidna-for-all-seasons/)). + +### Fuzzing {#fuzzing} + +[Fuzzing](https://wikipedia.org/wiki/Fuzzing) é uma técnica bem conhecida na comunidade de segurança. It consists of generating inputs that are more or less random to find bugs in the program. Fuzzers por software tradicional (como [AFL](http://lcamtuf.coredump.cx/afl/) ou [LibFuzzer](https://llvm.org/docs/LibFuzzer.html)) são conhecidos por serem ferramentas eficientes para encontrar bugs. + +Além da geração aleatória de entradas, há muitas técnicas e estratégias para gerar bons inputs, incluindo: + +- Obtenha feedback de cada execução e geração de guias usando-o. Por exemplo, se uma entrada recém-gerada leva à descoberta de um novo caminho, ele pode fazer sentido para gerar novas entradas fechadas a ele. +- Geração da entrada respeitando uma restrição estrutural. Por exemplo, se a sua entrada contiver um cabeçalho com uma soma de verificação, fará sentido deixar o difusor gerar uma entrada validando a soma de verificação. +- Usando entradas conhecidas para gerar novas entradas: se você tem acesso a um grande conjunto de dados de entrada válida, seu difusor pode gerar novas entradas a partir deles, ao invés de começar sua geração do zero. Eles geralmente são chamados de _seeds_. + +### Fuzzing baseado em propriedade {#property-based-fuzzing} + +Echidna pertence a uma família específica de fuzzer: fuzzing baseada em propriedades fortemente inspirada pelo [QuickCheck](https://wikipedia.org/wiki/QuickCheck). Em contraste com o fuzzing clássico que tentará encontrar falhas, Echidna tentará quebrar invariantes definidos pelo usuário. + +Nos contratos inteligentes, invariantes são funções Solidity, que podem representar qualquer estado incorreto ou inválido que o contrato possa alcançar, incluindo: + +- Controle de acesso incorreto: quem ataca tornou-se o proprietário do contrato. +- Máquina de estado incorreta: os tokens podem ser transferidos enquanto o contrato é pausado. +- Aritmética incorreta: o usuário pode passar abaixo do saldo e obter tokens gratuitos ilimitados. + +### Testando uma propriedade com Echidna {#testing-a-property-with-echidna} + +Veremos como testar um contrato inteligente com o Echidna. O alvo é o seguinte contrato inteligente [`exemplo.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol): + +```solidity +contract Token{ + mapping(address => uint) public balances; + function airdrop() public{ + balances[msg.sender] = 1000; + } + function consume() public{ + require(balances[msg.sender]>0); + balances[msg.sender] -= 1; + } + function backdoor() public{ + balances[msg.sender] += 1; + } +} +``` + +Assumiremos que esse token deve ter as seguintes propriedades: + +- Qualquer um pode ter no máximo 1000 tokens +- O token não pode ser transferido (não é um token ERC20) + +### Escrever uma propriedade {#write-a-property} + +Propriedades do Echidna são funções de Solidity. Uma propriedade deve: + +- Ter nenhum argumento +- Retornar `verdadeiro` se for bem sucedido +- Tenha seu nome começando com `echidna` + +Echidna irá: + +- Gera automaticamente transações arbitrárias para testar a propriedade. +- Relata quaisquer transações que levem uma propriedade para retornar `` falso ou lançar um erro. +- Descartar efeito lateral ao chamar uma propriedade (ou seja, se a propriedade altera uma variável de estado, ela é descartada após o teste) + +A propriedade a seguir verifica que o "caller" não possui mais do que 1000 tokens: + +```solidity +function echidna_balance_under_1000() public view returns(bool){ + return balances[msg.sender] <= 1000; +} +``` + +Use herança para separar seu contrato de suas propriedades: + +```solidity +contract TestToken is Token{ + function echidna_balance_under_1000() public view returns(bool){ + return balances[msg.sender] <= 1000; + } + } +``` + +[`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol) implementa a propriedade e herda do token. + +### Iniciar um contrato {#initiate-a-contract} + +Echidna precisa de um [constructor](/developers/docs/smart-contracts/anatomy/#constructor-functions) sem argumento. Se seu contrato precisa de uma inicialização específica, você precisa fazê-lo no construtor. + +Há alguns endereços específicos no Echidna: + +- `0x00a329c0648769A73afAc7F9381E08FB43dBEA72` que chama o constructor. +- `0x10000`, `0x20000`, e `0x00a329C0648769a73afAC7F9381e08fb43DBEA70` que aleatoriamente chama as outras funções. + +Nós não precisamos de nenhuma inicialização específica em nosso exemplo atual, como resultado, nosso construtor está vazio. + +### Executando Echidna {#run-echidna} + +Echidna foi lançado com: + +```bash +echidna-test contract.sol +``` + +Se o contract.sol contém múltiplos contratos, você pode especificar o alvo: + +```bash +echidna-test contract.sol --contract MyContract +``` + +### Resumo: Testando uma propriedade {#summary-testing-a-property} + +O seguinte resumo é a execução de Echidna no nosso exemplo: + +```solidity +contract TestToken is Token{ + constructor() public {} + function echidna_balance_under_1000() public view returns(bool){ + return balances[msg.sender] <= 1000; + } + } +``` + +```bash +echidna-test testtoken.sol --contract TestToken +... + +echidna_balance_under_1000: failed!💥 + Call sequence, shrinking (1205/5000): + airdrop() + backdoor() + +... +``` + +Echidna descobriu que a propriedade é violada se `backdoor` é chamada. + +## Filtrando funções para chamar durante uma campanha de fuzzing {#filtering-functions-to-call-during-a-fuzzing-campaign} + +Veremos como filtrar as funções a serem "fuzzed". O alvo é o seguinte contrato inteligente: + +```solidity +contract C { + bool state1 = false; + bool state2 = false; + bool state3 = false; + bool state4 = false; + + function f(uint x) public { + require(x == 12); + state1 = true; + } + + function g(uint x) public { + require(state1); + require(x == 8); + state2 = true; + } + + function h(uint x) public { + require(state2); + require(x == 42); + state3 = true; + } + + function i() public { + require(state3); + state4 = true; + } + + function reset1() public { + state1 = false; + state2 = false; + state3 = false; + return; + } + + function reset2() public { + state1 = false; + state2 = false; + state3 = false; + return; + } + + function echidna_state4() public returns (bool) { + return (!state4); + } +} +``` + +Este pequeno exemplo força Echidna a encontrar uma determinada sequência de transações para alterar uma variável de estado. Isso é difícil para um fuzzer (é recomendado usar uma ferramenta de execução simbólica como [Manticore](https://github.com/trailofbits/manticore)). Podemos executar o Echidna para verificar isto: + +```bash +echidna-test multi.sol +... +echidna_state4: passed! 🎉 +Seed: -3684648582249875403 +``` + +### Filtrando funções {#filtering-functions} + +Echidna tem problemas para encontrar a sequência correta para testar esse contrato, porque as duas funções de redefinição (`reset1` e `reset2`) definirão todas as variáveis de estado como `false`. No entanto, podemos usar um recurso especial Echidna para ou para a lista negra redefinir a função ou apenas para a lista branca `f`, `g`, `h` e `i` funções. + +Para funções da lista negra, podemos usar esse arquivo de configuração: + +```yaml +filterBlacklist: true +filterFunctions: ["reset1", "reset2"] +``` + +Outra abordagem para as funções de filtro é listar as funções na lista branca. Para fazer isso, podemos usar este arquivo de configuração: + +```yaml +filterBlacklist: false +filterFunctions: ["f", "g", "h", "i"] +``` + +- `filterBlacklist` é `verdadeiro` por padrão. +- A filtragem será executada apenas por nome (sem parâmetros). Se você tiver `f()` e `f(uint256)`, o filtro `"f"` corresponderá a ambas as funções. + +### Executar Echidna {#run-echidna-1} + +Para executar Echidna com um arquivo de configuração `blacklist.yaml`: + +```bash +echidna-test multi.sol --config blacklist.yaml +... +echidna_state4: failed!💥 + Call sequence: + f(12) + g(8) + h(42) + i() +``` + +Echidna vai encontrar a sequência de transações para falsificar a propriedade quase de forma mesquinha. + +### Resumo: Filtrando funções {#summary-filtering-functions} + +Echidna pode ser chamada na lista negra ou na lista branca durante uma campanha de fuzzing: + +```yaml +filterBlacklist: true +filterFunctions: ["f1", "f2", "f3"] +``` + +```bash +echidna-test contract.sol --config config.yaml +... +``` + +Echidna inicia uma campanha de fuzzing em qualquer blacklist `f1`, `f2` e `f3` ou apenas chamando a eles, de acordo com o valor do booleano `filterBlacklist`. + +## Como testar a asserção de Solidity com Echidna {#how-to-test-soliditys-assert-with-echidna} + +Neste breve tutorial, vamos mostrar como usar o Echidna para testar a verificação de asserção em contratos. Vamos supor que tenhamos um contrato como este: + +```solidity +contract Incrementor { + uint private counter = 2**200; + + function inc(uint val) public returns (uint){ + uint tmp = counter; + counter += val; + // tmp <= counter + return (counter - tmp); + } +} +``` + +### Escreva uma asserção {#write-an-assertion} + +Queremos ter certeza de que `tmp` é menor ou igual a `contador` depois de retornar a sua diferença. Nós poderíamos escrever uma propriedade de Echidna, mas precisaremos armazenar o valor de `tmp` em algum lugar. Em vez disso, poderíamos usar uma asserção como esta: + +```solidity +contract Incrementor { + uint private counter = 2**200; + + function inc(uint val) public returns (uint){ + uint tmp = counter; + counter += val; + assert (tmp <= counter); + return (counter - tmp); + } +} +``` + +### Executando Echidna {#run-echidna-2} + +Para habilitar o teste de falha de asserção, crie um arquivo de configuração [Echidna](https://github.com/crytic/echidna/wiki/Config) `config.yaml`: + +```yaml +checkAsserts: true +``` + +Quando executamos este contrato em Echidna, obtemos os resultados esperados: + +```bash +echidna-test assert.sol --config config.yaml +Analyzing contract: assert.sol:Incrementor +assertion in inc: failed!💥 + Call sequence, shrinking (2596/5000): + inc(21711016731996786641919559689128982722488122124807605757398297001483711807488) + inc(7237005577332262213973186563042994240829374041602535252466099000494570602496) + inc(86844066927987146567678238756515930889952488499230423029593188005934847229952) + +Seed: 1806480648350826486 +``` + +Como você pode ver, Echidna relata algumas falhas de afirmação na função `inc`. Adicionar mais de uma asserção por função é possível, mas Echidna não pode dizer qual afirmação falhou. + +### Quando e como usar asserções {#when-and-how-use-assertions} + +As asserções podem ser usadas como alternativas às propriedades explícitas, se as condições a serem verificadas estão diretamente relacionadas com o uso correto de alguma operação `f`. Adicionar asserções após algum código forçará que a verificação ocorra imediatamente após sua execução: + +```solidity +function f(..) public { + // some complex code + ... + assert (condition); + ... +} + +``` + +Pelo contrário, usando uma propriedade Echidna explícita irá executar transações aleatoriamente e não há maneira fácil de aplicar exatamente quando elas serão verificadas. Ainda é possível fazer esta solução alternativa: + +```solidity +function echidna_assert_after_f() public returns (bool) { + f(..); + return(condition); +} +``` + +Entretanto, existem alguns problemas: %{issues}: + +- Ele falha se `f` é declarado como `interno` ou `externo`. +- Não está claro quais argumentos devem ser usados para chamar `f`. +- Se `f` reverter, a propriedade irá falhar. + +Em geral, recomendamos seguir a recomendação de [John Regehr](https://blog.regehr.org/archives/1091) sobre como usar asserções: + +- Não force qualquer efeito colateral durante a verificação de asserção. Por exemplo: `assert(ChangeStateAndReturn() == 1)` +- Não faça asserções óbvias. Por exemplo, `assert(var >= 0)` onde `var` é declarado como `uint`. + +Finalmente, **não use** `require` em vez de `assert`, já que Echidna não será capaz de detectá-lo (mas o contrato será revertido mesmo assim). + +### Resumo: checando a asserção {#summary-assertion-checking} + +O seguinte resumo é a execução de Echidna no nosso exemplo: + +```solidity +contract Incrementor { + uint private counter = 2**200; + + function inc(uint val) public returns (uint){ + uint tmp = counter; + counter += val; + assert (tmp <= counter); + return (counter - tmp); + } +} +``` + +```bash +echidna-test assert.sol --config config.yaml +Analyzing contract: assert.sol:Incrementor +assertion in inc: failed!💥 + Call sequence, shrinking (2596/5000): + inc(21711016731996786641919559689128982722488122124807605757398297001483711807488) + inc(7237005577332262213973186563042994240829374041602535252466099000494570602496) + inc(86844066927987146567678238756515930889952488499230423029593188005934847229952) + +Seed: 1806480648350826486 +``` + +Echidna percebeu que a asserção em `inc` pode falhar se essa função é chamada várias vezes com argumentos grandes. + +## Coletando e modificando um corpus Echidna {#collecting-and-modifying-an-echidna-corpus} + +Veremos como coletar e usar um corpus de transações com Echidna. O alvo é o seguinte contrato inteligente [`exemplo.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/magic.sol): + +```solidity +contract C { + bool value_found = false; + function magic(uint magic_1, uint magic_2, uint magic_3, uint magic_4) public { + require(magic_1 == 42); + require(magic_2 == 129); + require(magic_3 == magic_4+333); + value_found = true; + return; + } + + function echidna_magic_values() public returns (bool) { + return !value_found; + } + +} +``` + +Este pequeno exemplo força Echidna a encontrar uma determinada sequência de transações para alterar uma variável de estado. Isso é difícil para um fuzzer (é recomendado usar uma ferramenta de execução simbólica como [Manticore](https://github.com/trailofbits/manticore)). Podemos executar o Echidna para verificar isto: + +```bash +echidna-test magic.sol +... + +echidna_magic_values: passed! 🎉 + +Seed: 2221503356319272685 +``` + +No entanto, ainda podemos usar o Echidna para coletar corpus na condução desta campanha de fuzzing. + +### Coletando um corpus {#collecting-a-corpus} + +Para habilitar a coleção de corpus, crie um diretório corpus: + +```bash +mkdir corpus-magic +``` + +E um [arquivo de configuração Echidna](https://github.com/crytic/echidna/wiki/Config) `config.yaml`: + +```yaml +coverage: true +corpusDir: "corpus-magic" +``` + +Agora podemos rodar nossa ferramenta e checar o corpus coletado: + +```bash +echidna-test magic.sol --config config.yaml +``` + +Echidna ainda não conseguiu encontrar os valores mágicos corretos, mas podemos olhar para o corpus que ele coletou. Por exemplo, um desses arquivos foi: + +```json +[ + { + "_gas'": "0xffffffff", + "_delay": ["0x13647", "0xccf6"], + "_src": "00a329c0648769a73afac7f9381e08fb43dbea70", + "_dst": "00a329c0648769a73afac7f9381e08fb43dbea72", + "_value": "0x0", + "_call": { + "tag": "SolCall", + "contents": [ + "magic", + [ + { + "contents": [ + 256, + "93723985220345906694500679277863898678726808528711107336895287282192244575836" + ], + "tag": "AbiUInt" + }, + { + "contents": [256, "334"], + "tag": "AbiUInt" + }, + { + "contents": [ + 256, + "68093943901352437066264791224433559271778087297543421781073458233697135179558" + ], + "tag": "AbiUInt" + }, + { + "tag": "AbiUInt", + "contents": [256, "332"] + } + ] + ] + }, + "_gasprice'": "0xa904461f1" + } +] +``` + +Claramente, esse input não causará falha em nossa propriedade. No entanto, no próximo passo, veremos como modificá-lo nesse sentido. + +### Semeando um corpus {#seeding-a-corpus} + +Echidna precisa de ajuda para lidar com a função `mágica`. Vamos copiar e modificar a entrada para usar os parâmetros adequados para ele: + +```bash +cp corpus/2712688662897926208.txt corpus/new.txt +``` + +Nós iremos modificar `new.txt` para chamar `mágica(42,129,333,0)`. Agora, podemos reexecutar o Echidna: + +```bash +echidna-test magic.sol --config config.yaml +... +echidna_magic_values: failed!💥 + Call sequence: + magic(42,129,333,0) + + +Unique instructions: 142 +Unique codehashes: 1 +Seed: -7293830866560616537 + +``` + +Desta vez, constatou que a propriedade é violada imediatamente. + +## Localizando transações com alto consumo de gas {#finding-transactions-with-high-gas-consumption} + +Veremos como encontrar as transações com alto consumo de gas com o Echidna. O alvo é o seguinte contrato inteligente: + +```solidity +contract C { + uint state; + + function expensive(uint8 times) internal { + for(uint8 i=0; i < times; i++) + state = state + i; + } + + function f(uint x, uint y, uint8 times) public { + if (x == 42 && y == 123) + expensive(times); + else + state = 0; + } + + function echidna_test() public returns (bool) { + return true; + } + +} +``` + +Aqui `caro` pode ter um grande consumo de gas. + +Atualmente, Echidna sempre precisa de uma propriedade para testar: aqui `echidna_test` sempre retorna `true`. Podemos executar o Echidna para verificar isto: + +``` +echidna-test gas.sol +... +echidna_test: passed! 🎉 + +Seed: 2320549945714142710 +``` + +### Medição do consumo de gas {#measuring-gas-consumption} + +Para habilitar o consumo de gas com Echidna, crie um arquivo de configuração `config.yaml`: + +```yaml +estimateGas: true +``` + +Neste exemplo, também reduziremos o tamanho da sequência de transações para facilitar a compreensão dos resultados: + +```yaml +seqLen: 2 +estimateGas: true +``` + +### Executando Echidna {#run-echidna-3} + +Assim que tivermos o arquivo de configuração criado, poderemos executar o Echidna assim: + +```bash +echidna-test gas.sol --config config.yaml +... +echidna_test: passed! 🎉 + +f used a maximum of 1333608 gas + Call sequence: + f(42,123,249) Gas price: 0x10d5733f0a Time delay: 0x495e5 Block delay: 0x88b2 + +Unique instructions: 157 +Unique codehashes: 1 +Seed: -325611019680165325 + +``` + +- O gas mostrado é um cálculo fornecido por [HEVM](https://github.com/dapphub/dapptools/tree/master/src/hevm#hevm-). + +### Filtrando Chamadas com Redução de Gas {#filtering-out-gas-reducing-calls} + +O tutorial sobre **funções de filtragem para chamar durante uma campanha de difusão** acima mostra como remover algumas funções de seu teste. +Isso pode ser fundamental para obter uma estimativa de gas precisa. Considere o seguinte exemplo: + +```solidity +contract C { + address [] addrs; + function push(address a) public { + addrs.push(a); + } + function pop() public { + addrs.pop(); + } + function clear() public{ + addrs.length = 0; + } + function check() public{ + for(uint256 i = 0; i < addrs.length; i++) + for(uint256 j = i+1; j < addrs.length; j++) + if (addrs[i] == addrs[j]) + addrs[j] = address(0x0); + } + function echidna_test() public returns (bool) { + return true; + } +} +``` + +Se Echidna pode chamar todas as funções, ele não encontrará facilmente transações com alto custo de gas: + +``` +echidna-test pushpop.sol --config config.yaml +... +pop used a maximum of 10746 gas +... +check used a maximum of 23730 gas +... +clear used a maximum of 35916 gas +... +push used a maximum of 40839 gas +``` + +Isso porque o custo depende do tamanho dos `addrs` e chamadas aleatórias tendem a deixar o array quase vazio. Lista negra `pop` e `limpa`, no entanto, nos dá resultados muito melhores: + +```yaml +filterBlacklist: true +filterFunctions: ["pop", "clear"] +``` + +``` +echidna-test pushpop.sol --config config.yaml +... +push used a maximum of 40839 gas +... +check used a maximum of 1484472 gas +``` + +### Localizando transações com alto consumo de gás {#summary-finding-transactions-with-high-gas-consumption} + +Echidna pode encontrar transações com alto consumo de gás usando a opção de configuração `estimateGas`: + +```yaml +estimateGas: true +``` + +```bash +echidna-test contract.sol --config config.yaml +... +``` + +Echidna irá relatar uma sequência com o consumo máximo de gas para cada função, uma vez terminada a campanha de fuzzing. diff --git a/public/content/translations/pt-br/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md b/public/content/translations/pt-br/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md new file mode 100644 index 00000000000..3382b47b034 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md @@ -0,0 +1,514 @@ +--- +title: Como usar o Manticore para encontrar bugs em contratos inteligentes +description: Como usar o Manticore para encontrar bugs automaticamente em contratos inteligentes +author: Trailofbits +lang: pt-br +tags: + - "solidez" + - "smart contracts" + - "segurança" + - "testando" + - "verificação formal" +skill: advanced +published: 2020-01-13 +source: Construindo contratos seguros +sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore +--- + +O objetivo deste tutorial é mostrar como usar o Manticore para encontrar bugs em contratos inteligentes automaticamente. + +## Instalação {#installation} + +Manticore requer >= python 3.6. Pode ser instalado pelo pip ou usando o docker. + +### Manticore através do Docker {#manticore-through-docker} + +```bash +docker pull trailofbits/eth-security-toolbox +docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox +``` + +_O último comando roda a eth-security-toolbox em um docker que tem acesso ao seu diretório atual. Você pode alterar os arquivos do seu host e executar as ferramentas nos arquivos através do docker_ + +Dentro do docker, execute: + +```bash +solc-select 0.5.11 +cd /home/trufflecon/ +``` + +### Manticore através do pip {#manticore-through-pip} + +```bash +pip3 install --user manticore +``` + +solc 0.5.11 é recomendado. + +### Executando um script {#running-a-script} + +Para executar um script python com python 3: + +```bash +python3 script.py +``` + +## Introdução à execução simbólica dinâmica {#introduction-to-dynamic-symbolic-execution} + +### Execução Simbólica Dinâmica em uma Nutshell {#dynamic-symbolic-execution-in-a-nutshell} + +A execução simbólica dinâmica (DSE) é uma técnica de análise de programa que explora um espaço de estado com um alto grau de consciência semântica. Esta técnica baseia-se na descoberta de "caminhos do programa", representados como fórmulas matemáticas chamadas de `predicados de caminho`. Conceitualmente, esta técnica opera em predicados de caminho em dois passos: + +1. Eles são construídos usando restrições na entrada de dados do programa. +2. Eles são usados para gerar entradas no programa que farão com que os caminhos associados sejam executados. + +Esta abordagem não produz falsos positivos no sentido de que todos os estados identificados do programa podem ser acionados durante a execução concreta. Por exemplo, se a análise encontrar um integer overflow, é certo que será reproduzível. + +### Exemplo de Predicado do Caminho {#path-predicate-example} + +Para se ter uma idéia de como o DSE funciona, considere o seguinte exemplo: + +```solidity +function f(uint a){ + + if (a == 65) { + // Um bug está presente + } + +} +``` + +Como `f()` contém dois caminhos, uma DSE construirá dois caminhos diferentes atribuídos: + +- Caminho 1: `a == 65` +- Caminho 2: `Not (a == 65)` + +Cada caminho atribuido é uma fórmula matemática que pode ser dada a uma chamada [SMT solver](https://wikipedia.org/wiki/Satisfiability_modulo_theories), que tentará resolver a equação. Para o `Caminho 1`, o solver dirá que o caminho pode ser explorado com `a = 65`. Para o `Caminho 2`, o solver pode dar para `a` qualquer valor diferente de 65, por exemplo, `a = 0`. + +### Verificando propriedades {#verifying-properties} + +A Manticore permite um controle total sobre toda a execução de cada caminho. Como resultado, permite que você adicione restrições arbitrárias a quase qualquer coisa. Este controle permite a criação de propriedades no contrato. + +Considere o seguinte exemplo: + +```solidity +function unsafe_add(uint a, uint b) returns(uint c){ + c = a + b; // no overflow protection + return c; +} +``` + +Aqui há apenas um caminho para explorar na função: + +- Caminho 1: `c = a + b` + +Usando o Manticore, você pode verificar se há overflow, e adicionar restrições à previsão do caminho: + +- `c = a + b AND (c < a OR c < b)` + +Se é possível encontrar uma avaliação de `um` e `b` para a qual o caminho predicado acima é viável, significa que encontrou um transbordamento ("overflow"). Por exemplo, o solver pode gerar a entrada `a = 10 , b = MAXUINT256`. + +Se você considerar uma versão fixa: + +```solidity +function safe_add(uint a, uint b) returns(uint c){ + c = a + b; + require(c>=a); + require(c>=b); + return c; +} +``` + +A fórmula associada com verificação de overflow seria: + +- `c = a + b AND (c >= a) AND (c=>b) AND (c < a OR c < b)` + +Esta fórmula não pode ser resolvida; em outras palavras, esta é uma **prova** que em `safe_add`, `c` irá sempre aumentar. + +DSE é assim uma ferramenta poderosa, que pode verificar restrições arbitrárias no seu código. + +## Executando sob Manticore {#running-under-manticore} + +Veremos como explorar um contrato inteligente com a API Manticore. O alvo é o seguinte contrato inteligente [`exemplo.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): + +```solidity +pragma solidity >=0.4.24 <0.6.0; + +contract Simple { + function f(uint a) payable public{ + if (a == 65) { + revert(); + } + } +} +``` + +### Executar uma exploração independente {#run-a-standalone-exploration} + +Você pode executar a Manticore diretamente no contrato inteligente pelo seguinte comando (`projeto` pode ser um Arquivo Solidity, ou um diretório de projeto): + +```bash +$ manticore project +``` + +Você obterá a saída de casos de teste como este (a ordem pode mudar): + +``` +... +... m.c.manticore:INFO: Generated testcase No. 0 - STOP +... m.c.manticore:INFO: Generated testcase No. 1 - REVERT +... m.c.manticore:INFO: Generated testcase No. 2 - RETURN +... m.c.manticore:INFO: Generated testcase No. 3 - REVERT +... m.c.manticore:INFO: Generated testcase No. 4 - STOP +... m.c.manticore:INFO: Generated testcase No. 5 - REVERT +... m.c.manticore:INFO: Generated testcase No. 6 - REVERT +... m.c.manticore:INFO: Results in /home/ethsec/workshops/Automated Smart Contracts Audit - TruffleCon 2018/manticore/examples/mcore_t6vi6ij3 +... +``` + +Sem informações adicionais, Manticore explorará o contrato com novas transações simbólicas até que não explore novos caminhos do contrato. Manticore não executa novas transações após uma falha (por exemplo: após um reversão). + +Manticore irá gerar as informações em um diretório `mcore_*`. Entre outros, você encontrará nesse diretório: + +- `global.summary`: cobertura e avisos do compilador +- `test_XXXXX.summary`: cobertura, última instrução, saldos de conta por caso de teste +- `test_XXXXX.tx`: lista detalhada de transações por caso de teste + +Aqui, Manticore encontrou 7 casos de teste, que correspondem à (a ordem do nome do arquivo pode mudar): + +| | Transação 0 | Transação 1 | Transação 2 | Resultado | +|:--------------------:|:-------------------:|:----------------------:| ---------------------- |:---------:| +| **test_00000000.tx** | Criação de contrato | f(!=65) | f(!=65) | STOP | +| **test_00000001.tx** | Criação de contrato | função de contingência | | REVERT | +| **test_00000002.tx** | Criação de contrato | | | RETURN | +| **test_00000003.tx** | Criação de contrato | f(65) | | REVERT | +| **test_00000004.tx** | Criação de contrato | f(!=65) | | STOP | +| **test_00000005.tx** | Criação de contrato | f(!=65) | f(65) | REVERT | +| **test_00000006.tx** | Criação de contrato | f(!=65) | função de contingência | REVERT | + +_Resumo da exploração f(!=65) denota f chamado com qualquer valor diferente de 65._ + +Como você pode perceber, Manticore gera um caso de teste único para cada transação bem sucedida ou revertida. + +Use a flag `--quick-mode` se você quiser uma exploração rápida de código (ele desativa detectores de bugs, cálculo de gas, ...) + +### Manipule um contrato inteligente através da API {#manipulate-a-smart-contract-through-the-api} + +Esta seção descreve detalhes sobre como manipular um contrato inteligente através da API Manticore Python. Você pode criar um novo arquivo com a extensão python `*. y` e escreva o código necessário adicionando os comandos da API (básicos dos quais serão descritos abaixo) neste arquivo e então execute-o com o comando `$ python3 *. a`. Também você pode executar os comandos abaixo diretamente no console python, para executar o console use o comando `$ python3`. + +### Criando Contas {#creating-accounts} + +A primeira coisa que você deve fazer é iniciar uma nova blockchain com os seguintes comandos: + +```python +from manticore.ethereum import ManticoreEVM +``` + +Uma conta de não-contrato é criada usando [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account): + +```python +user_account = m.create_account(balance=1000) +``` + +Um contrato de Solidity pode ser implantado usando [m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract): + +```solidity +source_code = ''' +pragma solidity >=0.4.24 <0.6.0; +contract Simple { + function f(uint a) payable public{ + if (a == 65) { + revert(); + } + } +} +''' +# Iniciar o contrato +contract_account = m.solidity_create_contract(source_code, owner=user_account) +``` + +#### Resumo {#summary} + +- Você pode criar contas de usuário e contratos com [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account) and [m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract). + +### Executando transações {#executing-transactions} + +Manticore suporta dois tipos de transação: + +- Transação bruta: todas as funções são exploradas +- Transação nomeada: apenas uma função é explorada + +#### Transação bruta {#raw-transaction} + +Uma transação bruta é executada usando [m.transaction](https://manticore.readthedocs.io/en/latest/evm.html?highlight=transaction#manticore.ethereum.ManticoreEVM.transaction): + +```python +m.transaction(caller=user_account, + address=contract_account, + data=data, + value=value) +``` + +O chamador, o endereço, os dados ou o valor da transação pode ser concreto ou simbólico: + +- [m.make_symbollic_value](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_value#manticore.ethereum.ManticoreEVM.make_symbolic_value) cria um valor simbólico. +- [m.make_symbollic_value](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_buffer#manticore.ethereum.ManticoreEVM.make_symbolic_buffer) cria um valor simbólico "byte array". + +Por exemplo: + +```python +symbolic_value = m.make_symbolic_value() +symbolic_data = m.make_symbolic_buffer(320) +m.transaction(caller=user_account, + address=contract_address, + data=symbolic_data, + value=symbolic_value +``` + +Se os dados forem simbólicos, Manticore irá explorar todas as funções do contrato durante a execução da transação. Será útil ver a explicação de Função de Fallback nas [Mãos do CTF Ethernaut](https://blog.trailofbits.com/2017/11/06/hands-on-the-ethernaut-ctf/), artigo para entender como a seleção de função funciona. + +#### Transação nomeada {#named-transaction} + +Funções podem ser executadas através de seu nome. Para executar `f(uint var)` com um valor simbólico, do user_account, e com 0 ether, use: + +```python +symbolic_var = m.make_symbolic_value() +contract_account.f(symbolic_var, caller=user_account, value=0) +``` + +Se `valor` da transação não for especificado, ela é 0 por padrão. + +#### Resumo {#summary-1} + +- Os argumentos de uma transação podem ser concretos ou simbólicos +- Uma transação bruta irá explorar todas as funções +- A função pode ser chamada pelo nome + +### Espaço de trabalho {#workspace} + +`m.workspace` é o diretório usado como diretório de saída para todos os arquivos gerados: + +```python +print("Results are in {}".format(m.workspace)) +``` + +### Terminar a Exploração {#terminate-the-exploration} + +Para parar a exploração, use [m.finalize()](https://manticore.readthedocs.io/en/latest/evm.html?highlight=finalize#manticore.ethereum.ManticoreEVM.finalize). Nenhuma transação adicional deve ser enviada quando este método for chamado e a Manticore gerar casos de teste para cada caminho explorado. + +### Resumo: Executando sob Manticore {#summary-running-under-manticore} + +Juntando todos os passos anteriores, obtemos: + +```python +from manticore.ethereum import ManticoreEVM + +m = ManticoreEVM() + +with open('example.sol') as f: + source_code = f.read() + +user_account = m.create_account(balance=1000) +contract_account = m.solidity_create_contract(source_code, owner=user_account) + +symbolic_var = m.make_symbolic_value() +contract_account.f(symbolic_var) + +print("Results are in {}".format(m.workspace)) +m.finalize() # stop the exploration +``` + +Todo o código acima você pode encontrar no [`exemple_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) + +## Obtendo caminhos {#getting-throwing-paths} + +Agora vamos gerar entradas específicas para os caminhos levantando uma exceção em `f()`. O alvo é ainda o seguinte contrato inteligente [`exemplo.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): + +```solidity +pragma solidity >=0.4.24 <0.6.0; +contract Simple { + function f(uint a) payable public{ + if (a == 65) { + revert(); + } + } +} +``` + +### Usando informações do estado {#using-state-information} + +Cada caminho executado tem seu estado de blockchain. Um estado ou está pronto ou é morto, o que significa que atinge um caminho de THROW ou REVERT: + +- [m.ready_states](https://manticore.readthedocs.io/en/latest/states.html#accessing): a lista de estados que estão prontos (não executaram um REVERT/INVALID) +- [m.killed_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): a lista de estados que estão mortos +- [m.all_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): todos os estados + +```python +for state in m.all_statees: + # faz algo com estado +``` + +Você pode acessar informações de estado. Por exemplo: + +- `state.platform.get_balance(account.address)`: o saldo da conta +- `state.platform.transactions`: a lista de transações +- `state.platform.transactions[-1].return_data`: os dados retornados pela última transação + +Os dados retornados pela última transação são um array, que pode ser convertido para um valor com ABI.deserialize, por exemplo: + +```python +data = state.platform.transactions[0].return_data +data = ABI.deserialize("uint", data) +``` + +### Como gerar caixa de teste {#how-to-generate-testcase} + +Use [m.generate_testcase(state, name)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=generate_testcase#manticore.ethereum.ManticoreEVM.generate_testcase) para gerar a caixa de teste: + +```python +m.generate_testcase(estado, 'BugFound') +``` + +### Resumo {#summary-2} + +- Você pode iterar sobre o estado com m.all_states +- `state.platform.get_balance(account.address)` retorna o saldo da conta +- `state.platform.transactions` retorna a lista de transações +- `Transtion.return_data` são os dados retornados +- `m.generate_testcase(state, name)` gera entradas para o estado + +### Resumo: Obtendo o caminho de lançamento {#summary-getting-throwing-path} + +```python +from manticore.ethereum import ManticoreEVM + +m = ManticoreEVM() + +with open('example.sol') as f: + source_code = f.read() + +user_account = m.create_account(balance=1000) +contract_account = m.solidity_create_contract(source_code, owner=user_account) + +symbolic_var = m.make_symbolic_value() +contract_account.f(symbolic_var) + +## Verificando se a execução termina com um REVERT ou INVALID +for state in m.terminated_states: + last_tx = state.platform.transactions[-1] + if last_tx.result in ['REVERT', 'INVALID']: + print('Throw found {}'.format(m.workspace)) + m.generate_testcase(state, 'ThrowFound') +``` + +Todo o código acima você pode encontrar no [`exemple_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) + +_Note que poderíamos ter gerado um script muito mais simples, como todos os estados retornados por terminated_state REVERT ou INVALID no seu resultado: este exemplo foi destinado apenas para demonstrar como manipular a API._ + +## Adicionar Restrições {#adding-constraints} + +Veremos como restringir a exploração. Vamos fazer a suposição de que a documentação de `f()` que afirma que a função nunca é chamada com `a == 65`, então qualquer erro com `a == 65` não é um bug de verdade. O alvo é o seguinte contrato inteligente [`exemplo.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): + +```solidity +pragma solidity >=0.4.24 <0.6.0; +contract Simple { + function f(uint a) payable public{ + if (a == 65) { + revert(); + } + } +} +``` + +### Operadores {#operators} + +O módulo [Operadores](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py) facilita a manipulação de restrições, entre outras que fornece: + +- Operadores.AND, +- Operadores.OR, +- Operators.UGT (não assinado maior que), +- Operators.UGE (não assinado maior ou igual a), +- Operators.UGT (não assinado menor que), +- Operators.ULE (menor que ou igual a). + +Para importar o módulo use o seguinte: + +```python +from manticore.core.smtlib import Operators +``` + +`Operators.CONCAT` é usado para concatenar uma matriz a um valor. Por exemplo, o return_data de uma transação precisa ser alterado para um valor a ser verificado contra outro valor: + +```python +last_return = Operators.CONCAT(256, *last_return) +``` + +### Restrições {#state-constraint} + +Você pode usar restrições globalmente ou para um estado específico. + +#### Restrição global {#state-constraint} + +Use `m.constrain(constraint)` para adicionar um constraint ("restrição") global. Por exemplo, você pode chamar um contrato de um endereço simbólico e restringir este endereço para serem valores específicos: + +```python +symbolic_address = m.make_symbolic_value() +m.constraint(Operators.OR(symbolic == 0x41, symbolic_address == 0x42)) +m.transaction(caller=user_account, + address=contract_account, + data=m.make_symbolic_buffer(320), + value=0) +``` + +#### Restrição de estado {#state-constraint} + +Use o estado de [. onstrain(restrição)](https://manticore.readthedocs.io/en/latest/states.html?highlight=StateBase#manticore.core.state.StateBase.constrain) para adicionar uma restrição a um estado específico. Ele pode ser usado para restringir o estado após sua exploração para verificar alguma propriedade nele. + +### Verificando a constraint ("restrição") {#checking-constraint} + +Use `solver.check(state.constraints)` para saber se uma restrição ainda é viável. Por exemplo, o seguinte irá restringir o simbolic_valor para ser diferente do 65 e verificar se o estado ainda é viável: + +```python +state.constrain(symbolic_var != 65) +if solver.check(state.constraints): + # estado é viável +``` + +### Resumo: Adicionando constraints ("restrições") {#summary-adding-constraints} + +Adicionando constraints ("restrições") ao código anterior, obtemos: + +```python +from manticore.ethereum import ManticoreEVM +from manticore.core.smtlib.solver import Z3Solver + +solver = Z3Solver.instance() + +m = ManticoreEVM() + +with open("example.sol") as f: + source_code = f.read() + +user_account = m.create_account(balance=1000) +contract_account = m.solidity_create_contract(source_code, owner=user_account) + +symbolic_var = m.make_symbolic_value() +contract_account.f(symbolic_var) + +no_bug_found = True + +## Verificar se a execução termina com um REVERT ou INVALID +for state in m.terminated_states: + last_tx = state.platform.transactions[-1] + if last_tx.result in ['REVERT', 'INVALID']: + # we do not consider the path were a == 65 + condition = symbolic_var != 65 + if m.generate_testcase(state, name="BugFound", only_if=condition): + print(f'Bug found, results are in {m.workspace}') + no_bug_found = False + +if no_bug_found: + print(f'No bug found') +``` + +Todo o código acima você pode encontrar no [`exemple_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) diff --git a/public/content/translations/pt-br/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md b/public/content/translations/pt-br/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md new file mode 100644 index 00000000000..b9ac9dc2118 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md @@ -0,0 +1,238 @@ +--- +title: Como utilizar o Slither para encontrar bugs nos contratos inteligentes +description: Como usar o Slither para encontrar automaticamente bugs em contratos inteligentes +author: Trailofbits +lang: pt-br +tags: + - "solidity" + - "smart contracts" + - "segurança" + - "testando" + - "análise estática" +skill: advanced +published: 2020-06-09 +source: Construindo contratos seguros +sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/slither +--- + +## Como usar o Slither {#how-to-use-slither} + +O objetivo deste tutorial é mostrar como usar o Slither para localizar automaticamente bugs em contratos inteligentes. + +- [Instalação](#installation) +- [Uso da linha de comando](#command-line) +- [Introdução à análise estática](#static-analysis): Breve introdução à análise estática +- [API](#api-basics): Descrição da API Python + +## Instalação {#installation} + +O Slither requer a versão 3.6 do Python ou superior. Pode ser instalado pelo pip ou usando o docker. + +Slither via pip: + +```bash +pip3 install --user slither-analyzer +``` + +Slither através de docker: + +```bash +docker pull trailofbits/eth-security-toolbox +docker run -it -v "$PWD":/home/trufflecon trailofbits/eth-security-toolbox +``` + +_O último comando roda a eth-security-toolbox em um docker que tem acesso ao seu diretório atual. Você pode alterar os arquivos do seu host e executar as ferramentas nos arquivos através do docker_ + +Dentro do docker, execute: + +```bash +solc-select 0.5.11 +cd /home/trufflecon/ +``` + +### Executando um script {#running-a-script} + +Para executar um script python com python 3: + +```bash +python3 script.py +``` + +### Linha de comando {#command-line} + +**Linha de comando versus scripts definidos pelo usuário.** O Slither vem com um conjunto de detectores predefinidos que encontram muitos bugs comuns. Chamar o Slither na linha de comando irá executar todos os detectores. Nenhum conhecimento detalhado da análise estática é necessária: + +```bash +slither project_paths +``` + +Além de detectadores, o Slither possui recursos de revisão de código através de suas [printers](https://github.com/crytic/slither#printers) e [ferramentas](https://github.com/crytic/slither#tools). + +Use [crytic.io](https://github.com/crytic) para obter acesso a detectadores privados e integração GitHub. + +## Análise estática {#static-analysis} + +Os recursos e design do framework estático de análise do Slither foram descritos nos posts de blog ([1](https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/)), [2](https://blog.trailofbits.com/2019/05/27/slither-the-leading-static-analyzer-for-smart-contracts/)) e em um [documento acadêmico](https://github.com/trailofbits/publications/blob/master/papers/wetseb19.pdf). + +A análise estática existe em diferentes "flavors". Você provavelmente percebe que compiladores como [clang](https://clang-analyzer.llvm.org/) e [gcc](https://lwn.net/Articles/806099/) dependem destas técnicas de pesquisa, mas também sustenta ([Infer](https://fbinfer.com/), [CodeClimate](https://codeclimate.com/), [FindBugs](http://findbugs.sourceforge.net/) e ferramentas baseadas em métodos formais como [Frama-C](https://frama-c.com/) e [Polyspace](https://www.mathworks.com/products/polyspace.html). + +Nós não analisaremos exaustivamente técnicas de análise estática e pesquisador aqui. Em vez disso, vamos focar no que é necessário para entender como o Slither funciona para que você possa usá-lo de forma mais eficiente para encontrar bugs e entender códigos. + +- [Representação de código](#code-representation) +- [Análise de código](#analysis) +- [Representação intermediária](#intermediate-representation) + +### Representação de código {#code-representation} + +Em contraste com uma análise dinâmica, que justifica um único caminho de execução, razões de análise estática sobre todos os caminhos ao mesmo tempo. Para isso, ele depende de uma representação diferente do código. As duas mais comuns são a árvore de sintaxe abstrata (AST) e o gráfico de fluxo de controle (CFG). + +### Árvores de sintaxe abstratas (AST) {#abstract-syntax-trees-ast} + +AST é usado toda vez que o compilador analisa o código. É provavelmente a estrutura mais básica sobre a qual se pode efetuar a análise estática. + +Em poucas palavras, a AST é uma árvore estruturada onde, normalmente, cada folha contém uma variável ou uma constante e os nós internos são operações ou operações de fluxo de controle. Considere o seguinte código: + +```solidity +function safeAdd(uint a, uint b) pure internal returns(uint){ + if(a + b <= a){ + revert(); + } + return a + b; +} +``` + +O AST correspondente é mostrado em: + +![AST](./ast.png) + +O Slither usa o AST exportado pelo solc. + +Enquanto for simples construir, o AST é uma estrutura aninhada. Por vezes, esta não é a mais simples de analisar. Por exemplo, para identificar as operações usadas pela expressão `a + b <= a`,, primeiro você deve analisar `<=` e, em seguida, `+`. Uma abordagem comum é usar o chamado padrão de visitantes, que navega pela árvore recursivamente. O Slither contém um visitante genérico em [`ExpressionVisitor`](https://github.com/crytic/slither/blob/master/slither/visitors/expression/expression.py). + +O código a seguir usa `ExpressionVisitor` para detectar se a expressão contém uma adição: + +```python +from slither.visitors.expression.expression import ExpressionVisitor +from slither.core.expressions.binary_operation import BinaryOperationType + +class HasAddition(ExpressionVisitor): + + def result(self): + return self._result + + def _post_binary_operation(self, expression): + if expression.type == BinaryOperationType.ADDITION: + self._result = True + +visitor = HasAddition(expression) # expression is the expression to be tested +print(f'The expression {expression} has a addition: {visitor.result()}') +``` + +### Controlar Gráfico de Fluxos (CFG) {#control-flow-graph-cfg} + +A segunda representação de código mais comum é o gráfico de fluxo de controle (CFG). Como seu nome sugere, é uma representação baseada em gráficos que expõe todos os caminhos de execução. Cada nó contém uma ou várias instruções. Bordas no gráfico representam as operações de fluxo de controle (se/então/outra vez, loop, etc). O nosso exemplo anterior é o do CFG: + +![CFG](./cfg.png) + +O CFG é a representação que está por cima da qual se constrói a maioria das análises. + +Existem muitas outras representações de código. Cada representação tem vantagens e desvantagens de acordo com a análise que você deseja realizar. + +### Análise {#analysis} + +O tipo mais simples de análises que você pode realizar com o Slither são análises sintáticas. + +### Análises de sintaxe {#syntax-analysis} + +O Slither pode navegar através dos diferentes componentes do código e sua representação para encontrar inconsistências e falhas usando uma abordagem semelhante a padrões de correspondência. + +Por exemplo, os seguintes detectores procuram por problemas relacionados à sintaxe: + +- [State variable shadowing](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing): itera sobre todas as variáveis de estado e verifica se tem alguma variável "shadow" de um contrato herdado ([state.py#L51-L62](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/shadowing/state.py#L51-L62)) + +- [Interface ERC20 incorreta](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface): procurar por assinaturas de função ERC20 incorretas ([incorrect_erc20_interface.py#L34-L55](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/erc/incorrect_erc20_interface.py#L34-L55)) + +### Análise semântica {#semantic-analysis} + +Em contraste com a análise de sintaxe, uma análise semântica vai aprofundar e analisar o "significado" do código. Esta família inclui vários tipos de análises. Conduzem a resultados mais poderosos e úteis, mas são também mais complexos de escrever. + +Análises semânticas são usadas para detecções de vulnerabilidades mais avançadas. + +#### Análise de dependência de dados {#fixed-point-computation} + +Uma variável `variable_a` diz ser dependente de dados `variable_b` se houver um caminho para o qual o valor de `variable_a` seja influenciado pela `variable_b`. + +No código a seguir, `variable_a` depende de `variable_b`: + +```solidity +// ... +variable_a = variable_b + 1; +``` + +O Slither vem com capacidades embutidas de [dependência de dados,](https://github.com/crytic/slither/wiki/data-dependency) graças à sua representação intermediária (discutida em uma seção posterior). + +Um exemplo de uso de dependência de dados pode ser encontrado em ["dangerous strict equality detector"](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities). Aqui o Slither procurará por uma comparação rigorosa de igualdade com um valor perigoso ([incorrect_strict_equality. y#L86-L87](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L86-L87)), e informará o usuário que deve usar `>=` ou `<=` ao invés de `==`para evitar um invasor para prender o contrato. Entre outros, o detector considerará como perigoso o valor de retorno de uma chamada para o `balanceOf(endereço)` ([incorrect_strict_equality. y#L63-L64](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L63-L64)), e usará o mecanismo de dependência de dados para rastrear seu uso. + +#### Cálculo de ponto fixo {#fixed-point-computation} + +Se a sua análise navegar através do CFG e seguir as bordas, é provável que você veja os nós já visitados. Por exemplo, se um loop é apresentado como mostrado abaixo: + +```solidity +for(uint i; i < range; ++){ + variable_a += 1 +} +``` + +A sua análise terá de saber quando parar. Existem duas estratégias principais aqui: (1) iterar em cada nó um número finito de vezes, (2) calcular um chamado _fixpoint_. Um ponto de acesso basicamente significa que a análise deste nó não fornece nenhuma informação significativa. + +Um exemplo de fixpoint usado pode ser encontrado nos detectadores de reentrância: Slither explora os nós, e procurar por chamadas externas, escrever e ler para armazenar. Uma vez que chegou a um ponto de correção ("fixpoint") ([reentrancy.py#L125-L131](https://github.com/crytic/slither/blob/master/slither/detectors/reentrancy/reentrancy.py#L125-L131)), interrompe a exploração e analisa os resultados para ver se uma reentrância está presente, através de diferentes padrões de reentrada ([reentrancy_benign. y](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_benign.py), [reentrancy_read_before_write.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_read_before_write.py), [reentrancy_eth.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_eth.py)). + +Escrever análises usando um cálculo de ponto fixo eficiente requer um bom entendimento de como a análise propaga sua informação. + +### Representação intermediária {#intermediate-representation} + +Uma representação intermediária (IR) é uma linguagem que deve ser mais acessível à análise estática do que a original. Slither traduz Solidity para seu próprio IR: [SlithIR](https://github.com/crytic/slither/wiki/SlithIR). + +Compreender o SlithIR não é necessário se você quiser apenas escrever verificações básicas. No entanto, será útil se você planejar escrever análises semânticas avançadas. As [SlithIR](https://github.com/crytic/slither/wiki/Printer-documentation#slithir) e [SSA](https://github.com/crytic/slither/wiki/Printer-documentation#slithir-ssa)printers irão ajudá-lo a entender como o código é traduzido. + +## API Básica {#api-basics} + +Slither tem uma API que permite explorar os atributos básicos do contrato e suas funções. + +Carregando um codebase: + +```python +from slither import Slither +slither = Slither('/path/to/project') + +``` + +### Explorando contratos e funções {#exploring-contracts-and-functions} + +Um objeto `Slither` contém: + +- contracts`contracts (list(Contract)`: lista de contratos +- `contracts_derived (list(Contract)`: lista de contratos que não são herdados por outro contrato (subconjunto de contratos) +- `get_contract_from_name (str)`: Retorna um contrato a partir de seu nome + +Um objeto `Slither` contém: + +- `name (str)`: Nome do contrato +- `functions (list(Function))`: Lista de funções +- `modifiers (list(Modifier))`: Lista de funções +- `all_functions_called (list(Função/Modificador))`: Lista de todas as funções internas acessíveis pelo contrato +- `herança (lista(contrato))`: Lista de contratos herdados +- `get_function_from_signature (str)`: Retorna uma função a partir de sua assinatura +- `get_function_from_signature (str)`: Retorna uma função a partir de sua assinatura +- `get_contract_from_name (str)`: Retorna um contrato a partir de seu nome + +Um objeto `Function` ou `Modifier` têm: + +- `name (str)`: Nome da função +- `contract (contract)`: o contrato onde a função é declarada +- `nodes (list(Node))`: Lista dos nós que compõem o CFG da função/modificador +- `entry_point (Node)`: Ponto de entrada do CFG +- `variables_read (list(variável))`: Lista de variáveis lidas +- `variables_written (list(variável))`: Lista de variáveis escritas +- `state_variables_read (list(StateVariable))`: Lista de variáveis de estado lidas (subconjunto de variáveis lidas) +- `state_variables_written (list(StateVariable))`: Lista de variáveis de estado escritas (subconjunto de variáveis escritas) diff --git a/public/content/translations/pt-br/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md b/public/content/translations/pt-br/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md new file mode 100644 index 00000000000..2dae6657637 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md @@ -0,0 +1,84 @@ +--- +title: Como configurar Tellor como seu Oráculo +description: Um guia para começar a integrar o oráculo Tellor ao seu protocolo +author: "Tellor" +lang: pt-br +tags: + - "solidity" + - "contratos inteligentes" + - "oráculos" +skill: intermediate +published: 2021-06-29 +source: Documentação Tellor +sourceUrl: https://docs.tellor.io/tellor/ +--- + +Pop Quiz: Seu protocolo está quase pronto, mas precisa de um oráculo para obter acesso aos dados off-chain... O que você faz? + +## (Soft) Pré-requisitos {#soft-prerequisites} + +Esse texto tem como objetivo tornar o acesso a um conjunto de dados através do uso de um oráculo o mais simples e direto possível. Dito isso, estamos assumindo o seguinte sobre seu nível de habilidade de codificação para focar no aspecto do oráculo. + +Suposições: + +- você pode navegar em um terminal +- você tem o npm instalado +- você sabe como usar o npm para gerenciar dependências + +Tellor é um oráculo vivo e de código aberto pronto para implementação. Este guia para iniciantes está aqui para mostrar a facilidade com que se pode começar a trabalhar com Tellor, fornecendo ao seu projeto um oráculo totalmente descentralizado e resistente à censura. + +## Visão geral {#overview} + +Tellor é um sistema de oráculo onde as partes podem solicitar o valor de um ponto de dados off-chain (por exemplo, BTC/USD) e os repórteres (nós ou participantes) competem para adicionar esse valor a um banco de dados on-chain, acessível por todos os contratos inteligentes do Ethereum. As entradas para este banco de dados são asseguradas por uma rede de repórteres participantes. Tellor utiliza mecanismos de incentivo cripto-econômico, recompensando envios de dados honestos por repórteres e punindo maus atores por meio da emissão do token Tellor, Tributos (TRB) e um mecanismo de disputa. + +Neste tutorial, nós iremos ver: + +- Configurar o kit de ferramentas inicial, que você precisará para começar a trabalhar. +- Percorra por um exemplo simples. +- Listar os endereços de teste das redes as quais você pode testar o Tellor atualmente. + +## UsingTellor {#usingtellor} + +A primeira coisa que você vai querer fazer é instalar as ferramentas básicas necessárias para usar o Tellor como seu oráculo. Use [este pacote](https://github.com/tellor-io/usingtellor) para instalar os contratos de usuário do Tellor: + +`npm install usingtellor` + +Uma vez instalado, isso permitirá que seus contratos herdem as funções do contrato 'UsingTellor'. + +Excelente! Agora que você tem as ferramentas prontas, vamos passar por um simples exercício onde recuperamos o preço do bitcoin: + +### Exemplo BTC/USD {#btcusd-example} + +Herde o contrato UsingTellor, passando o endereço do Tellor como um argumento do construtor: + +Aqui está um exemplo: + +```solidity +import "usingtellor/contracts/UsingTellor.sol"; + +contract PriceContract is UsingTellor { + uint256 public btcPrice; + + //This Contract now has access to all functions in UsingTellor + +constructor(address payable _tellorAddress) UsingTellor(_tellorAddress) public {} + +function setBtcPrice() public { + bytes memory _b = abi.encode("SpotPrice",abi.encode("btc","usd")); + bytes32 _queryId = keccak256(_b); + + uint256 _timestamp; + bytes _value; + + (_value, _timestamp) = getDataBefore(_queryId, block.timestamp - 15 minutes); + + btcPrice = abi.decode(_value,(uint256)); + } +} +``` + +Para uma lista completa de endereços de contrato, consulte [aqui](https://docs.tellor.io/tellor/the-basics/contracts-reference). + +Para facilidade de uso, o repositório UsingTellor vem com uma versão do contrato [Tellor Playground](https://github.com/tellor-io/TellorPlayground) para facilitar a integração. Consulte [aqui](https://github.com/tellor-io/sampleUsingTellor#tellor-playground) para obter uma lista de funções úteis. + +Para uma implementação mais robusta do oráculo Tellor, confira a lista completa de funções, disponíveis [aqui](https://github.com/tellor-io/usingtellor/blob/master/README.md). diff --git a/public/content/translations/pt-br/developers/tutorials/how-to-view-nft-in-metamask/index.md b/public/content/translations/pt-br/developers/tutorials/how-to-view-nft-in-metamask/index.md index c5a4eaf33c3..3171780741b 100644 --- a/public/content/translations/pt-br/developers/tutorials/how-to-view-nft-in-metamask/index.md +++ b/public/content/translations/pt-br/developers/tutorials/how-to-view-nft-in-metamask/index.md @@ -1,12 +1,12 @@ --- title: Como ver seu NFT na sua carteira (Parte 3/3 da série de tutorial sobre NFT) -description: Este tutorial descreve como visualizar um NFT existente no MetaMask! +description: This tutorial describes how to view an existing NFT on MetaMask! author: "Sumi Mudgil" tags: - "ERC-721" - "Alchemy" - "Solidity" -skill: beginner +skill: intermediate lang: pt-br published: 2021-04-22 --- @@ -17,15 +17,15 @@ Parabéns! Você chegou à parte mais curta e simples da nossa série de tutoria Como pré-requisito, você já deve ter MetaMask instalado no celular e deve incluir a conta para a qual você cunhou seu NFT. Você pode obter o aplicativo gratuitamente no [iOS](https://apps.apple.com/us/app/metamask-blockchain-wallet/id1438144202) ou [Android](https://play.google.com/store/apps/details?id=io.metamask&hl=en_US&gl=US). -## Passo 1: Definir a sua rede como Goerli {#set-network-to-goerli} +## Passo 1: Defina sua rede para Sepolia {#set-network-to-sepolia} -No topo do aplicativo, pressione o botão "Wallet". Em seguida, você será solicitado a selecionar uma rede. Como o nosso NFT foi cunhado na rede Goerli, selecione Goerli como a sua rede. +No topo do aplicativo, pressione o botão "Wallet". Em seguida, você será solicitado a selecionar uma rede. Como nosso NFT foi cunhado na rede Sepolia, você deverá selecionar Sepolia como sua rede. -![Como definir a Goerli como sua rede na MetaMask Mobile](./goerliMetamask.gif) +![Como definir Sepolia como sua rede no MetaMask Mobile](./goerliMetamask.gif) ## Passo 2: Adicionar o seu colecionável ao MetaMask {#add-nft-to-metamask} -Assim que você estiver na rede Goerli, selecione a guia "Colecionáveis" na direita e adicione o endereço do contrato inteligente do NFT e o ID do token ERC-721 correspondente, que você deve encontrar no Etherscan com base no hash de transação do seu NFT, como visto na Parte II do nosso tutorial. +Quando estiver na rede Sepolia, selecione a guia “Colecionáveis” à direita e adicione o endereço do contrato inteligente NFT e o ID do token ERC-721 do seu NFT - o qual você poderá encontrar no Etherscan com base no hash da transação do seu NFT implantado na Parte II do nosso tutorial. ![Como encontrar seu hash de transação e o ID do token ERC-721](./findNFTEtherscan.png) diff --git a/public/content/translations/pt-br/developers/tutorials/how-to-write-and-deploy-an-nft/index.md b/public/content/translations/pt-br/developers/tutorials/how-to-write-and-deploy-an-nft/index.md index f2727475e78..1419b4d33c0 100644 --- a/public/content/translations/pt-br/developers/tutorials/how-to-write-and-deploy-an-nft/index.md +++ b/public/content/translations/pt-br/developers/tutorials/how-to-write-and-deploy-an-nft/index.md @@ -7,7 +7,7 @@ tags: - "Alchemy" - "Solidity" - "contratos inteligentes" -skill: beginner +skill: intermediate lang: pt-br published: 2021-04-22 --- @@ -16,7 +16,7 @@ Com os NFTs trazendo a blockchain aos olhos do público, agora é uma excelente A Alchemy tem muito orgulho por estar no espaço NFT com os maiores nomes incluindo Makersplace (recentemente atingiu a marca de 69 milhões de doláres em vendas de artes digitais), Dapper Labs (criadores do NBA Top Shot e Crypto Kitties), OpenSea (o maior mercado de NFT do mundo), Zora, Super Rare, NFTfi, Foundation, Enjin, Origin Protocol, Immutable e muito mais. -Neste tutorial, veremos como criar e implantar um contrato inteligente ERC-721 na rede de teste Goerli usando [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/), [Pinata](https://pinata.cloud/) e [Alchemy](https://alchemy.com/signup/eth) (não se preocupe se você não entender o que isso significa — vamos explicar!). +Neste tutorial, nós vamos criar e implantar um contrato inteligente ERC-721 na rede de teste Sepolia usando [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/), [Pinata](https://pinata.cloud/) e [Alquimia](https://alchemy.com/signup/eth) (não se preocupe caso não entender o que tudo isso significa — explicaremos tudo!). Na parte 2 deste tutorial, veremos como podemos usar nosso contrato inteligente para gerar NFT, e na Parte 3, explicaremos como ver seu NFT no MetaMask. @@ -30,15 +30,15 @@ Neste tutorial, também aproveitaremos as ferramentas de desenvolvedor da Alchem ## Etapa 2: Criar seu aplicativo (e chave de API) {#make-api-key} -Assim que criar uma conta na Alchemy, você pode gerar uma chave de API criando um "app". Isso nos permitirá fazer solicitações na rede de teste Goerli. Confira [este guia](https://docs.alchemyapi.io/guides/choosing-a-network) se você está curioso para aprender mais sobre as redes de teste. +Assim que criar uma conta na Alchemy, você pode gerar uma chave de API criando um "app". Isso nos permitirá fazer solicitações à rede de teste Sepolia. Confira [este guia](https://docs.alchemyapi.io/guides/choosing-a-network) se você está curioso para aprender mais sobre as redes de teste. 1. Vá até a página "Create App" no painel da Alchemy, passe o mouse sobre a palavra "Apps" na barra de navegação e clique em "Create App" ![Crie seu aplicativo](./create-your-app.png) -2. Nomeie seu aplicativo (escolhemos “Meu primeiro NFT!”), faça uma breve descrição dele, selecione “Ethereum” para a cadeia e escolha “Goerli” para sua rede. Desde a fusão, as outras redes de teste foram descontinuadas. +2. Nomeie seu app (nós escolhemos “Meu primeiro NFT!”), ofereça uma breve descrição, selecione “Ethereum” para a rede e escolha “Sepolia” para sua rede. Desde a fusão, as outras redes de teste foram descontinuadas. -![Configure e publique seu aplicativo](./configure-and-publish-your-app.png) +![Configure e publique seu aplicativo](./alchemy-explorer-sepolia.png) 3. Clique em "Create App", e é isso e tudo! Seu app deveria aparecer na tabela abaixo. @@ -46,13 +46,13 @@ Assim que criar uma conta na Alchemy, você pode gerar uma chave de API criando Precisamos de uma conta Ethereum para enviar e receber transações. Para este tutorial, usaremos uma carteira virtual no navegador, a MetaMask, para gerenciar o endereço da sua conta Ethereum. Se você quiser entender mais sobre como as transações no Ethereum funcionam, confira [esta página](/developers/docs/transactions/) na Fundação Ethereum. -Você pode baixar e criar uma conta MetaMask gratuitamente [neste link](https://metamask.io/download.html). Quando você estiver criando uma conta, ou se já tiver uma conta, certifique-se de mudar para a “Rede de teste Goerli”, no canto superior direito (para que não estejamos lidando com dinheiro real). +Você pode baixar e criar uma conta MetaMask gratuitamente [neste link](https://metamask.io/download.html). Quando você estiver criando uma conta, ou se você já tiver uma, certifique-se de mudar para a “Sepolia Test Network” no canto superior direito (para que não lidemos com dinheiro real). -![Defina Goerli como sua rede](./metamask-goerli.png) +![Defina Sepolia como sua rede](./metamask-goerli.png) ## Etapa 4: Adicionar ether de um faucet {#step-4-add-ether-from-a-faucet} -Para implementar nosso contrato inteligente na rede de teste, precisaremos de alguns ETHs de imitação. Para obter ETH, você pode acessar [Goerli Faucet](https://goerlifaucet.com/) hospedado pela Alchemy, fazer login e inserir o endereço da sua conta, clicar em "Send Me ETH". Você deveria ver o ETH na sua conta MetaMask logo depois! +Para implementar nosso contrato inteligente na rede de teste, precisaremos de alguns ETHs de imitação. Para obter ETH, você pode acessar a [Torneira da Sepolia](https://sepoliafaucet.com/) hospedada pela Alchemy, fazer login, inserir o endereço da sua conta e clicar em "Enviar-me ETH". Você deveria ver o ETH na sua conta MetaMask logo depois! ## Etapa 5: Verificar seu saldo {#check-balance} @@ -87,7 +87,7 @@ Não importa realmente como você responde às questões de instalação; aqui e author: license: (ISC) About to write to /Users/thesuperb1/Desktop/my-nft/package.json: - + { "name": "my-nft", "version": "1.0.0", @@ -234,14 +234,12 @@ Então crie um arquivo `.env` no diretório raiz do nosso projeto e adicione sua Seu arquivo `.env` ficará assim: - API_URL="https://eth-goerli.g.alchemy.com/v2/your-api-key" + API_URL="https://eth-sepolia.g.alchemy.com/v2/your-api-key" PRIVATE_KEY="your-metamask-private-key" Para realmente conectá-las ao nosso código, referenciaremos essas variáveis em nosso arquivo hardhat.config.js na etapa 13. - -No faça commit do .env! Por favor, tenha certeza de nunca compartilhar ou expor seu arquivo .env com ninguém, pois estará comprometendo suas partes secretas ao fazê-lo. Se estiver usando um controle de versão, adicione seu .env ao arquivo gitignore. - + ## Etapa 12: Instalar o Ethers.js {#install-ethers} @@ -249,7 +247,7 @@ Ethers.js é uma biblioteca que facilita a interação e o envio de solicitaçõ Hardhat torna muito fácil a integração de [plugins](https://hardhat.org/plugins/), para ferramentas adicionais e funcionalidades extendidas. Aproveitaremos o [plugin Ethers](https://hardhat.org/plugins/nomiclabs-hardhat-ethers.html) para implantação de contratos. ([Ethers.js](https://github.com/ethers-io/ethers.js/) tem alguns métodos de implantação de contratos bastante claros). -No diretório do seu projeto, digite: +No diretório do projeto, digite: npm install --save-dev @nomiclabs/hardhat-ethers ethers@^5.0.0 @@ -269,10 +267,10 @@ Atualize seu hardhat.config.js para ficar assim: const { API_URL, PRIVATE_KEY } = process.env; module.exports = { solidity: "0.8.1", - defaultNetwork: "goerli", + defaultNetwork: "sepolia", networks: { hardhat: {}, - goerli: { + sepolia: { url: API_URL, accounts: [`0x${PRIVATE_KEY}`] } @@ -287,7 +285,7 @@ Na linha de comando, execute: npx hardhat compile -Você pode receber o aviso "SPDX license identifier not provided in source file", mas não há necessidade de se preocupar com isso. Esperamos que tudo mais esteja bem! Se não, você sempre pode enviar uma mensagem no [discord Alchemy](https://discord.gg/u72VCg3). +Você pode receber o aviso do identificador de licença SPDX não fornecido no arquivo fonte, mas não há necessidade de se preocupar com isso. Esperemos que tudo mais esteja bem! Se não, você sempre pode enviar uma mensagem no [discord Alchemy](https://discord.gg/u72VCg3). ## Etapa 15: Escrever nosso script de implantação {#write-deploy} @@ -317,7 +315,7 @@ A Hardhat fez um trabalho incrível ao explicar o que cada uma dessas linhas de const MyNFT = await ethers.getContractFactory("MyNFT"); -Uma ContractFactory em ethers.js é uma abstração usada para implantar novos contratos inteligentes, então, MyNFT aqui representa uma fábrica para instâncias do nosso contrato NFT. Ao usar o plug-in hardhat-ethers, as instâncias ContractFactory e Contract são conectadas ao primeiro signatário por padrão. +Uma ContractFactory em ethers.js é uma abstração usada para implantar novos contratos inteligentes, então a MyNFT aqui representa uma fábrica para instâncias do nosso contrato NFT. Ao usar o plug-in hardhat-ethers, as instâncias ContractFactory e Contract são conectadas ao primeiro signatário por padrão. const myNFT = await MyNFT.deploy(); @@ -327,26 +325,26 @@ Ao chamar deploy() em uma ContractFactory, a implantação se iniciará e retorn Finalmente estamos prontos para implantar o nosso contrato inteligente! Navegue de volta para a raiz do diretório do seu projeto e, na linha de comando, execute: - npx hardhat --network goerli run scripts/deploy.js + npx hardhat --network sepo lia run scripts/deploy.js Você deverá ver algo assim: Contrato implantado no endereço: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650 -Se nós formos ao [Goerli etherscan](https://goerli.etherscan.io/) e procurarmos pelo endereço do nosso contrato, conseguiremos ver que ele foi implantado com sucesso. Se você não conseguir ver o endereço imediatamente, aguarde um momento, pois pode demorar algum tempo. A transação ficará parecida com isto: +Se nós formos ao [Sepolia etherscan](https://sepolia.etherscan.io/) e procurarmos o endereço do nosso contrato, poderemos ver que ele foi implantado com sucesso. Se você não puder ver o endereço imediatamente, por favor, aguarde um momento, pois pode levar algum tempo. A transação ficará parecida com isto: -![Veja o seu endereço de transação no Etherscan](./etherscan-goerli-contract-creation.png) +![Veja o seu endereço de transação no Etherscan](./etherscan-sepoila-contract-creation.png) O endereço do remetente (From) deve corresponder ao seu endereço da conta MetaMask e o endereço do destinatário (To) deve dizer "Contract Creation". Se clicarmos na transação, veremos o nosso endereço de contrato no campo "To": -![Veja o seu endereço de contrato no Etherscan](./etherscan-goerli-tx-details.png) +![Veja o seu endereço de contrato no Etherscan](./etherscan-sepolia-tx-details.png) Sim! Você acabou de implantar seu contrato inteligente NFT na cadeia Ethereum (testnet)! -Para entender o que está acontecendo nos bastidores, vamos navegar até a guia Explorer no [painel do Alchemy](https://dashboard.alchemyapi.io/explorer). Se você tem vários aplicativos Alchemy, certifique-se de filtrar por app e selecionar "MyNFT". +Para entender o que está acontecendo nos bastidores, vamos navegar até a guia Explorer no [painel do Alchemy](https://dashboard.alchemyapi.io/explorer). Se você tem vários aplicativos Alchemy certifique-se de filtrar por app e selecionar "MyNFT". ![Exibir chamadas feitas "em segundo plano" com o Explorer Dashboard do Alquimia](./alchemy-explorer-goerli.png) -Aqui você verá um punhado de chamadas JSON-RPC que Hardhat/Ethers fizeram em segundo plano para nós quando chamamos a função .deploy() . Duas chamadas importantes aqui são [eth_sendRawTransaction](/developers/docs/apis/json-rpc/#eth_sendrawtransaction), que é o pedido para realmente escrever nosso contrato inteligente na cadeia Goerli e [eth_getTransactionByHash](/developers/docs/apis/json-rpc/#eth_gettransactionbyhash) que é um pedido para ler informações sobre nossa transação, conforme o hash (um padrão típico ao enviar transações). Para saber mais sobre o envio de transações, confira [este tutorial](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) sobre como enviar transações usando a Web3. +Aqui você verá um punhado de chamadas JSON-RPC que Hardhat/Ethers fizeram em segundo plano para nós quando chamamos a função .deploy() . Dois importantes pontos a destacar aqui são [eth_sendRawTransaction](/developers/docs/apis/json-rpc/#eth_sendrawtransaction), que é a solicitação para realmente escrever nosso contrato inteligente na cadeia Sepolia, e [eth_getTransactionByHash](/developers/docs/apis/json-rpc/#eth_gettransactionbyhash), que é uma solicitação para ler informações sobre nossa transação dado o hash (um padrão típico ao enviar transações). Para saber mais sobre o envio de transações, confira [este tutorial](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) sobre como enviar transações usando a web3. Isso é tudo para a Parte 1 deste tutorial. Na [Parte 2, interagiremos com o nosso contrato inteligente cunhando um NFT](/developers/tutorials/how-to-mint-an-nft/), e na [Parte 3, mostraremos como ver o seu NFT na sua carteira Ethereum](/developers/tutorials/how-to-view-nft-in-metamask/)! diff --git a/public/content/translations/pt-br/developers/tutorials/interact-with-other-contracts-from-solidity/index.md b/public/content/translations/pt-br/developers/tutorials/interact-with-other-contracts-from-solidity/index.md new file mode 100644 index 00000000000..53c8a1a6b79 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/interact-with-other-contracts-from-solidity/index.md @@ -0,0 +1,177 @@ +--- +title: Interaja com outros contratos de Solidity +description: Como implantar um contrato inteligente a partir de um contrato existente e interagir com ele +author: "jdourlens" +tags: + - "contratos Inteligentes" + - "solidity" + - "remix" + - "implementação" + - "componibilidade" +skill: advanced +lang: pt-br +published: 2020-04-05 +source: EthereumDev +sourceUrl: https://ethereumdev.io/interact-with-other-contracts-from-solidity/ +address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" +--- + +Nos tutoriais anteriores, aprendemos muito [como publicar seu primeiro contrato inteligente](/developers/tutorials/deploying-your-first-smart-contract/) e adicionar alguns recursos a ele, como [controlar o acesso com modificadores](https://ethereumdev.io/organize-your-code-and-control-access-to-your-smart-contract-with-modifiers/) ou [manipulação de erros no Solidity](https://ethereumdev.io/handle-errors-in-solidity-with-require-and-revert/). Neste tutorial, aprenderemos como implantar um contrato inteligente a partir de um contrato existente e interagir com ele. + +Faremos um contrato que permite a qualquer pessoa ter seu próprio contrato inteligente`Counter`, criando uma fábrica para ele. Seu nome será `CounterFactory`. De início, aqui está o código do nosso primeiro contrato inteligente `Counter`: + +```solidity +pragma solidity 0.5.17; + +contract Counter { + + uint256 private _count; + address private _owner; + address private _factory; + + + modifier onlyOwner(address caller) { + require(caller == _owner, "You're not the owner of the contract"); + _; + } + + modifier onlyFactory() { + require(msg.sender == _factory, "You need to use the factory"); + _; + } + + constructor(address owner) public { + _owner = owner; + _factory = msg.sender; + } + + function getCount() public view returns (uint256) { + return _count; + } + + function increment(address caller) public onlyFactory onlyOwner(caller) { + _count++; + } + +} +``` + +Note que modificamos ligeiramente o código do contrato para manter um controle do endereço da fábrica e do endereço do proprietário. Quando você chamar um código de contrato de outro contrato, o msg.sender irá consultar o endereço da nossa fábrica de contratos. Este é **um ponto muito importante para entender** como usar um contrato para interagir com outros contratos é uma prática comum. Você deve, portanto, cuidar de quem é o remetente em casos complexos. + +Para isso também adicionamos um modificador de `onlyFactory` que certifica-se de que a função de mudança de estado só pode ser chamada pela fábrica que passará o chamador original como um parâmetro. + +Dentro de nossa nova `CounterFactory` que gerenciará todos os outros Counters, adicionaremos um mapeamento que associará o proprietário ao endereço de seu contrato: + +```solidity +mapping(address => Counter) _counters; +``` + +Na Ethereum, o mapeamento é equivalente a objetos em Javascript. Eles permitem mapear uma chave do tipo A para um valor do tipo B. Neste caso, mapeamos o endereço de um proprietário com a instância de seu Counter. + +Instanciar um novo Counter para alguém ficará assim: + +```solidity + function createCounter() public { + require (_counters[msg.sender] == Counter(0)); + _counters[msg.sender] = new Counter(msg.sender); + } +``` + +Primeiro, verificamos se a pessoa já possui um Counter. Se ele não tem um Counter, instanciamos um novo Counter, passando seu endereço para o construtor `Counter` e atribuímos a instância recém-criada para o mapeamento. + +Para obter a contagem de um Counter específico, fica assim: + +```solidity +function getCount(address account) public view returns (uint256) { + require (_counters[account] != Counter(0)); + return (_counters[account].getCount()); +} + +function getMyCount() public view returns (uint256) { + return (getCount(msg.sender)); +} +``` + +A primeira função verifica se o contrato do Counter existe para um determinado endereço e, em seguida, chama o método `getCount` a partir da instância. A segunda função: `getMyCount` é apenas um breve fim para passar a função msg.sender diretamente para a função `getCount`. + +A função `increment` é bastante parecida, mas passa o remetente da transação original para o contrato `Counter`: + +```solidity +function increment() public { + require (_counters[msg.sender] != Counter(0)); + Counter(_counters[msg.sender]).increment(msg.sender); + } +``` + +Observe que, se for chamado várias vezes, nosso contador poderá ser vítima de um transbordamento ("overflow"). Você deve usar a [biblioteca SafeMath](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/) tanto quanto possível para se proteger deste possível caso. + +Para implantar nosso contrato, você precisará fornecer tanto o código da `CounterFactory` quanto o `Counter`. Ao implantar, por exemplo, em Remix, você precisará selecionar a CounterFactory. + +Aqui está o código completo: + +```solidity +pragma solidity 0.5.17; + +contract Counter { + + uint256 private _count; + address private _owner; + address private _factory; + + + modifier onlyOwner(address caller) { + require(caller == _owner, "You're not the owner of the contract"); + _; + } + + modifier onlyFactory() { + require(msg.sender == _factory, "You need to use the factory"); + _; + } + + constructor(address owner) public { + _owner = owner; + _factory = msg.sender; + } + + function getCount() public view returns (uint256) { + return _count; + } + + function increment(address caller) public onlyFactory onlyOwner(caller) { + _count++; + } + +} + +contract CounterFactory { + + mapping(address => Counter) _counters; + + function createCounter() public { + require (_counters[msg.sender] == Counter(0)); + _counters[msg.sender] = new Counter(msg.sender); + } + + function increment() public { + require (_counters[msg.sender] != Counter(0)); + Counter(_counters[msg.sender]).increment(msg.sender); + } + + function getCount(address account) public view returns (uint256) { + require (_counters[account] != Counter(0)); + return (_counters[account].getCount()); + } + + function getMyCount() public view returns (uint256) { + return (getCount(msg.sender)); + } + +} +``` + +Depois de compilar, na seção de implante de Remix, você selecionará a fábrica a ser implantada: + +![Selecionando a fábrica a ser implantada no Remix](./counterfactory-deploy.png) + +Então você pode brincar com sua fábrica de contrato e verificar a mudança de valor. Se você prefere chamar o contrato inteligente a partir de um endereço diferente, altere o endereço na Conta selecionada do Remix. diff --git a/public/content/translations/pt-br/developers/tutorials/kickstart-your-dapp-frontend-development-wth-create-eth-app/index.md b/public/content/translations/pt-br/developers/tutorials/kickstart-your-dapp-frontend-development-wth-create-eth-app/index.md new file mode 100644 index 00000000000..d96aa4a5e30 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/kickstart-your-dapp-frontend-development-wth-create-eth-app/index.md @@ -0,0 +1,110 @@ +--- +title: Comece a desenvolver o front-end do seu dapp usando create-eth-app +description: Uma visão geral de como criar um aplicativo eth-app e seus recursos +author: "Markus Waas" +tags: + - "create-eth-app" + - "front-end" + - "javascript" + - "ethers.js" + - "o grafo" + - "defi" +skill: intermediate +lang: pt-br +published: 2020-04-27 +source: soliditydeveloper.com +sourceUrl: https://soliditydeveloper.com/create-eth-app +--- + +Da última vez, olhamos [para a grande imagem de Solidity](https://soliditydeveloper.com/solidity-overview-2020) e já mencionamos o app [create-eth-](https://github.com/PaulRBerg/create-eth-app). Agora você vai descobrir como usá-lo, quais recursos são integrados e ideias adicionais sobre como expandir sobre isso. Iniciado por Paul Razvan Berg, o fundador do [Sablier](http://sablier.com/), este aplicativo irá iniciar seu desenvolvimento de frontend e vem com várias integrações opcionais para escolher. + +## Instalação {#installation} + +A instalação requer Yarn 0.25 ou versão superior (`npm install yarn --global`). Ela é muito simples de executar: + +```bash +yarn create eth-app my-eth-app +cd my-eth-app +yarn react-app:start +``` + +Está usando [create-react-app](https://github.com/facebook/create-react-app) debaixo do "hood". Para ver sua aplicação, abra `http://localhost:3000/`. Quando você estiver pronto para implantar em produção, crie um pacote minificado com o build Yarn. Uma maneira fácil de hospedar isso seria [Netlify](https://www.netlify.com/). Você pode criar um repositório GitHub, adicioná-lo ao Netlify, configurar o comando build e pronto! Seu aplicativo será hospedado e utilizável para todos. E tudo isso gratuitamente. + +## Funcionalidades {#features} + +### React & create-react-app {#react--create-react-app} + +Primeiro de tudo o coração da aplicação: React e todas as funcionalidades adicionais que vêm com o _create-react-app_. Usar apenas essa é uma ótima opção se você não quiser integrar a Ethereum. O [React](https://reactjs.org/) torna a construção de interfaces de usuário interativas muito fácil. Ele pode não ser tão simples para iniciantes como o [Vue](https://vuejs.org/), mas ainda é o mais usado, tem mais recursos e, sobretudo, conta com milhares de opções de bibliotecas adicionais. O _create-react-app_ torna muito fácil começar com ele também e inclui: + +- React, JSX, ES6, TypeScript, Sintaxe Flow. +- Idioma extra além do ES6 como o operador de propagação de objetos. +- CSS prefixados automaticamente, para que você não precise de -webkit- ou outros prefixos. +- Um rápido corretor de teste de unidade interativa com suporte embutido para relatórios de cobertura. +- Um servidor de desenvolvimento dinâmico que avisa sobre erros comuns. +- Um script de compilação para empacotar JS, CSS e imagens para produção, com hashes e sourcemaps. + +O _create-eth-app_ em particular está usando novos [efeitos de hooks](https://reactjs.org/docs/hooks-effect.html). Um método para escrever componentes ditos funcionais, poderosos, mas muito pequenos. Veja a seção abaixo sobre Apollo sobre como eles são usados no _create-eth-app_. + +### Yarn workspaces {#yarn-workspaces} + +[Yarn Workspace](https://classic.yarnpkg.com/en/docs/workspaces/) permite que você tenha vários pacotes, mas ser capaz de gerenciar tudo a partir da pasta raiz e instalar as dependências de uma só vez usando `yarn install`. Isso faz sentido especialmente para pacotes adicionais menores, como o gerenciamento de endereços de contratos inteligentes / ABI (a informação sobre onde você implementou quais contratos inteligentes e como se comunicar com eles) ou a integração de grafos, ambos parte do `create-eth-app`. + +### ethers.js {#ethersjs} + +Enquanto o [Web3](https://docs.web3js.org/) ainda é mais usado, [ethers. s](https://docs.ethers.io/) tem recebido muito mais tração como uma alternativa no último ano e é integrada no _create-eth-app_. Você pode trabalhar com este, alterá-lo para Web3 ou considerar a possibilidade de atualizar para [ethers.js v5](https://docs-beta.ethers.io/) que já quase saiu da versão beta. + +### The Graph {#the-graph} + +[GraphQL](https://graphql.org/) é uma forma alternativa de manipular dados em comparação com uma [Restful API](https://restfulapi.net/). Eles têm várias vantagens sobre o Restful Apis, especialmente para dados descentralizados da blockchain. Se você estiver interessado no raciocínio por trás disso, dê uma olhada no [GraphQL Will Power the Decentralized Web](https://medium.com/graphprotocol/graphql-will-power-the-decentralized-web-d7443a69c69a). + +Geralmente, você obteria dados diretamente do seu contrato inteligente. Gostaria de saber o horário da última transação? Basta chamar `MyContract.methods.latestTradeTime().call()` que busca os dados de um nó Ethereum em seu dapp. Mas e se você precisar de centenas de pontos de dados diferentes? Isso resultaria em centenas de buscas de dados para o nó, cada vez exigindo um [RTT](https://wikipedia.org/wiki/Round-trip_delay_time) tornando seu dapp lento e ineficiente. Uma solução alternativa pode ser uma função de busca de chamadas dentro do seu contrato que retorna vários dados de uma só vez. Mas nem sempre é o ideal. + +E então talvez também estejam interessados em dados históricos. Você quer saber não apenas a última troca, mas também os tempos para todas as negociações que você já fez. Use o _create-eth-app_ pacote de subgráfico, leia a [documentação](https://thegraph.com/docs/define-a-subgraph) e adapte-a aos seus próprios contratos. Se você estiver procurando contratos inteligentes populares, pode até ser que já exista um subgrafo. Confira o [explorador de subgrafos](https://thegraph.com/explorer/). + +Ao obter um subgrafo, você pode escrever uma consulta simples em seu dapp para recuperar todos os dados importantes da blockchain, incluindo os históricos de que você precisa — basta uma única busca. + +### Apollo {#apollo} + +Graças à integração do [Apollo Boost](https://www.apollographql.com/docs/react/get-started/), você pode integrar facilmente o grafo em seu aplicativo React. Especialmente ao usar [React hooks e Apollo](https://www.apollographql.com/blog/apollo-client-now-with-react-hooks-676d116eeae2), buscar dados é tão simples como escrever uma única consulta GraphQl em seu componente: + +```js +const { loading, error, data } = useQuery(myGraphQlQuery) + +React.useEffect(() => { + if (!loading && !error && data) { + console.log({ data }) + } +}, [loading, error, data]) +``` + +## Modelos {#templates} + +No topo, você pode escolher entre vários modelos diferentes. Até agora você pode usar uma integração de Aave, composto, UniSwap ou saborosa. Todos eles adicionam importantes endereços de contrato inteligente de serviço, juntamente com integrações pré-fabricadas de subgráficos. Apenas adicione o template ao comando de criação como `yarn create eth-app my-eth-app --with-template aave`. + +### Aave {#aave} + +[Aave](https://aave.com/) é um mercado descentralizado de empréstimos de dinheiro. Os depositantes fornecem liquidez ao mercado para ganhar uma renda passiva, enquanto os tomadores podem fazer um empréstimo usando garantias. Uma característica única da Aave são os [empréstimos rápidos](https://docs.aave.com/developers/guides/flash-loans) que permitem que você empreste dinheiro sem nenhuma garantia, contanto que você devolva o empréstimo dentro de uma transação. Isso pode ser útil, por exemplo, para você obter dinheiro extra em uma operação de arbitragem. + +Os tokens negociados que ganham seus interesses são chamados de _aTokens_. + +Quando você optar por integrar o Aave ao _create-eth-app_, você terá uma [integração subgraph](https://docs.aave.com/developers/getting-started/using-graphql). O Aave usa The Graph e já fornece vários subgrafos prontos para uso no [Ropsten](https://thegraph.com/explorer/subgraph/aave/protocol-ropsten) e na [Rede principal](https://thegraph.com/explorer/subgraph/aave/protocol), em formato [bruto](https://thegraph.com/explorer/subgraph/aave/protocol-raw) ou [formatado](https://thegraph.com/explorer/subgraph/aave/protocol). + +![Meme de Empréstimo Aave – "Yeahhh, se eu conseguisse manter meu empréstimo rápido por mais de 1 transação, isso seria ótimo"](./flashloan-meme.png) + +### Compound {#compound} + +[Compound](https://compound.finance/) é similar a Aave. A integração já inclui o novo [Compound v2 Subgraph](https://medium.com/graphprotocol/https-medium-com-graphprotocol-compound-v2-subgraph-highlight-a5f38f094195). Aqui, os tokens que obtêm lucro são surpreendentemente chamados de _cTokens_. + +### Uniswap {#uniswap} + +[Uniswap](https://uniswap.exchange/) é uma exchange descentralizada (DEX). Provedores de liquidez podem ganhar taxas fornecendo os tokens necessários ou serviços para ambos os lados de uma negociação. Ela é amplamente utilizada e, portanto, possui uma das mais altas taxas de liquidez para uma grande variedade de tokens. Você pode integrá-lo facilmente ao seu dapp para, por exemplo, permitir que os usuários troquem seu ETH por DAI. + +Infelizmente, no momento em que escrevemos a integração é apenas para o Uniswap v1 e não para o [recém-lançado v2](https://uniswap.org/blog/uniswap-v2/). + +### Sablier {#sablier} + +O [Sablier](https://sablier.com/) permite que os usuários efetuem pagamentos continuamente. Em vez de um único dia de pagamento, você na verdade recebe o seu dinheiro constantemente sem mais administração após a configuração inicial. A integração inclui seu [próprio subgráfico](https://thegraph.com/explorer/subgraph/sablierhq/sablier). + +## O que vem a seguir? {#whats-next} + +Se você tiver perguntas sobre o _create-eth-app_, acesse o [servidor da comunidade Sablier](https://discord.gg/bsS8T47), onde você pode entrar em contato com os autores do _create-eth-app_. Como alguns primeiros passos que você pode querer integrar uma estrutura UI como [Material UI](https://material-ui.com/), escrever consultas GraphQL para os dados que você realmente precisa e configurar a implantação. diff --git a/public/content/translations/pt-br/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md b/public/content/translations/pt-br/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md new file mode 100644 index 00000000000..0457b9e3218 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md @@ -0,0 +1,272 @@ +--- +title: Aprenda Tópicos fundamentais de Ethereum com SQL +description: Este tutorial ajuda os leitores a entender os conceitos fundamentais de Ethereum, incluindo transações, blocos e gas, consultando dados on-chain com linguagem de consulta estruturada (SQL). +author: "Paul Apivat" +tags: + - "SQL" + - "Querying" + - "Transações" +skill: intermediate +lang: pt-br +published: 2021-05-11 +source: paulapivat.com +sourceUrl: https://paulapivat.com/post/query_ethereum/ +--- + +Muitos tutorias da Ethereum são direcionadas para desenvolvedores, mas há uma falta de recursos educacionais para analistas de dados ou pessoas que desejam ver dados on-chain sem executar um cliente ou um nó. + +Esse tutorial ajuda os leitores a entenderem os conceitos fundamentais da Ethereum, incluindo transações, blocos e gás, consultando dados on-chain com a linguagem SQL por meio de uma interface fornecida por [Dune Analytics](https://dune.xyz/home). + +Dados on-chain podem nos ajudar a compreender a rede Ethereum como uma economia para capacidade computacional, e deve servir como base para entender os desafios enfrentados pela Ethereum hoje (por exemplo, o aumento dos preços do gas) e, o mais importante, discussões sobre soluções de escalabilidade. + +### Transações {#transactions} + +A jornada do usuário no Ethereum começa com a inicialização de uma conta controlada ou uma entidade com saldo ETH. Há duas categorias de contas: controlada pelo usuário ou um contrato inteligente (veja em: [ethereum.org](/developers/docs/accounts/)). + +Qualquer conta pode ser visualizada em um explorador de bloco como a [Etherscan](https://etherscan.io/). Exploradores de bloco são um portal para os dados da Ethereum. Eles exibem, em tempo real, dados em blocos, transações, mineiradores, contas, e outras atividades on-chain (veja [aqui](/developers/docs/data-and-analytics/block-explorers/)). + +No entanto, um usuário pode desejar consultar um dado diretamente para reconciliar as informações fornecidas por exploradores de bloco externos. O [Dune Analytics](https://duneanalytics.com/) fornece esse recurso para qualquer pessoa com algum conhecimento em SQL. + +Como referência, a conta de contrato inteligente da Fundação Ethereum (EF) pode ser visualizada na [Etherscan](https://etherscan.io/address/0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae). + +Uma coisa a ser observada é que todas as contas, incluindo as EF's, têm um endereço público que pode ser utilizado para enviar e receber transações. + +O saldo da conta na Etherscan inclui transações regulare e transações internas. As transações internas, apesar do nome, não são _realmente_ transações que alteram o estado da cadeia. Elas são transferências de valores iniciadas pela execução de um contrato ([fonte](https://ethereum.stackexchange.com/questions/3417/how-to-get-contract-internal-transactions)). Visto que as transações internas não têm assinatura, elas **não** são incluídas na blockchain e não podem ser consultadas com o Dune Analytics. + +Portanto, este tutorial irá focar em transações regulares. Isso pode ser consultado como: + +```sql +WITH temp_table AS ( +SELECT + hash, + block_number, + block_time, + "from", + "to", + value / 1e18 AS ether, + gas_used, + gas_price / 1e9 AS gas_price_gwei +FROM ethereum."transactions" +WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' +ORDER BY block_time DESC +) +SELECT + hash, + block_number, + block_time, + "from", + "to", + ether, + (gas_used * gas_price_gwei) / 1e9 AS txn_fee +FROM temp_table +``` + +Isso irá gerar as mesmas informações fornecidas na página de transações do Etherscan. Para você comparar, aqui estão duas fontes: + +#### Etherscan {#etherscan} + +![](./etherscan_view.png) + +[Visualizar página de contratos de EF's no Etherscan.](https://etherscan.io/address/0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe) + +#### Dune Analytics {#dune-analytics} + +![](./dune_view.png) + +Você pode encontrar o painel [aqui](https://duneanalytics.com/paulapivat/Learn-Ethereum). Clique na tabela para visualizar a consulta (veja também acima). + +### Decompondo Transações {#breaking_down_transactions} + +Uma transação enviada inclui várias informações, incluindo ([fonte](/developers/docs/transactions/)): + +- **Destinatário**: O endereço de recebimento (chamado como "para") +- **Assinatura**: Enquanto as chaves privadas de um remetente assinam uma transação, o que podemos consultar com o SQL é o endereço público de um remetente ("de"). +- **Valor**: Esta é a quantidade de ETH transferido (veja a coluna `ether`). +- **Dados**: Estes são dados arbitrários misturados (veja a coluna `dados`). +- **gasLimit**: a quantidade máxima de gas que pode ser consumida pela transação. As unidades de gas representam etapas computacionais +- **maxPriorityFeePerGas**: a quantidade máxima de gas a ser incluída como dica para o minerador +- **maxFeePerGas** - a quantidade máxima de gas disposta a ser paga pela transação (incluindo baseFeePerGas e maxPriorityFeePerGas) + +Podemos consultar essas informações específicas sobre transações no endereço público da Fundação Ethereum: + +```sql +SELECT + "to", + "from", + value / 1e18 AS ether, + data, + gas_limit, + gas_price / 1e9 AS gas_price_gwei, + gas_used, + ROUND(((gas_used / gas_limit) * 100),2) AS gas_used_pct +FROM ethereum."transactions" +WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' +ORDER BY block_time DESC +``` + +### Blocos {#blocks} + +Cada transação irá alterar o estado da máquina virtual da Ethereum ([EVM](/developers/docs/evm/)) ([fonte](/developers/docs/transactions/)). As transações são transmitidas à rede para serem verificadas e incluídas em um bloco. Cada transação está associada a um número de bloco. Para ver os dados, nós podemos consultar um número de bloco específico: 12396854 (o bloco mais recente entre as transações da Fundação Ethereum a partir desta escrita, 11/05/21). + +Além disso, quando consultarmos os próximos dois blocos, podemos observar que cada bloco contém o hash do bloco anterior (i.., hash pai), ilustrando como a blockchain é formada. + +Cada bloco contém uma referência ao bloco pai. Isso é mostrado abaixo entre as colunas `hash` e `parent_hash` (fonte[](/developers/docs/blocks/)): + +![parent_hash](./parent_hash.png) + +Aqui está a [consulta](https://duneanalytics.com/queries/44856/88292) no Dune Analytics: + +```sql +SELECT + time, + number, + hash, + parent_hash, + nonce +FROM ethereum."blocks" +WHERE "number" = 12396854 OR "number" = 12396855 OR "number" = 12396856 +LIMIT 10 +``` + +Podemos examinar um bloco consultando o horário, o número de bloco, a dificuldade (quantidade de computação necessária), o hash, o hash pai e a nonce. + +A única coisa que esta consulta não cobre é a _lista de transações_ que requer uma consulta separada abaixo e _raiz do estado_. Um nó completo ou de arquivamento irá armazenar todas as transações e transições de estado, permitindo que os clientes consultem o estado da cadeia a qualquer momento. Como isso requer um grande espaço de armazenamento, nós podemos separar os dados em cadeia dos dados de estado: + +- Dados em cadeia (lista de blocos, transações) +- Dados de estado (resultado da transição de estado de cada transação) + +A raiz de estado cai na última e são _ dados implícitos_ (não armazenados na cadeia), enquanto os dados em cadeia são explícitos e armazenados na própria cadeia ([fonte](https://ethereum.stackexchange.com/questions/359/where-is-the-state-data-stored)). + +Para este tutorial, estaremos focando em dados on-chain que _podem_ ser consultados com SQL via Dune Analytics. + +Como mencionado acima, cada bloco contém uma lista de transações, podemos consultar isso filtrando por um bloco específico. Vamos tentar o bloco mais recente, 12396854: + +```sql +SELECT * FROM ethereum."transactions" +WHERE block_number = 12396854 +ORDER BY block_time DESC` +``` + +Segue o SQL output no Dune: + +![](./list_of_txn.png) + +Este único bloco sendo adicionado à cadeia altera o estado da máquina virtual Ethereum ([EVM](/developers/docs/evm/)). Dezenas, às vezes centenas, de transações são verificadas de uma só vez. Neste caso específico, foram incluídas 222 transações. + +Para ver quantas foram realmente bem-sucedidas, nós adicionaríamos outro filtro para contar transações bem-sucedidas: + +```sql +WITH temp_table AS ( + SELECT * FROM ethereum."transactions" + WHERE block_number = 12396854 AND success = true + ORDER BY block_time DESC +) +SELECT + COUNT(success) AS num_successful_txn +FROM temp_table +``` + +Para o bloco 12396854, do total de 222 transações, 204 foram verificadas com sucesso: + +![](./successful_txn.png) + +As solicitações de transações ocorrem dezenas de vezes por segundo, mas os blocos são confirmados aproximadamente uma vez a cada 15 segundos ([source](/developers/docs/blocks/)). + +Para ver que há um bloco produzido aproximadamente a cada 15 segundos, poderíamos pegar o número de segundos em um dia (86400) por 15, para obter um número médio estimado de blocos por dia (~ 5760). + +O gráfico de blocos Ethereum produzidos por dia (2016 - presente) é: + +![](./daily_blocks.png) + +O número médio de blocos produzidos diariamente durante esse período de tempo é de aproximadamente ~5.874: + +![](./avg_daily_blocks.png) + +As consultas são: + +```sql +# query to visualize number of blocks produced daily since 2016 + +SELECT + DATE_TRUNC('day', time) AS dt, + COUNT(*) AS block_count +FROM ethereum."blocks" +GROUP BY dt +OFFSET 1 + +# average number of blocks produced per day + +WITH temp_table AS ( +SELECT + DATE_TRUNC('day', time) AS dt, + COUNT(*) AS block_count +FROM ethereum."blocks" +GROUP BY dt +OFFSET 1 +) +SELECT + AVG(block_count) AS avg_block_count +FROM temp_table +``` + +O número médio de blocos produzidos por dia desde 2016 está um pouco acima desse número em 5.874. Alternativamente, dividindo 86400 segundos por 5874 blocos médios resultam em 14,7 segundos ou aproximadamente um bloco a cada 15 segundos. + +### Gás {#gas} + +Blocos são limitados em tamanho. O tamanho máximo do bloco é dinâmico e varia de acordo com a demanda de rede entre 12.500.000 e 25.000.000 unidades. Limites são necessários para evitar que, blocos de tamanho arbitrariamente grandes coloquem tensão em nós completos, em termos de espaço em disco e requisitos de velocidade ([source](/developers/docs/blocks/)). + +Uma maneira de conceitualizar o limite de gas do bloco é pensar nele como o **suprimento** de espaço de bloco disponível para as transações em lote. O limite de gas do bloco pode ser consultado e visualizado a partir de 2016 até o presente dia: + +![](./avg_gas_limit.png) + +```sql +SELECT + DATE_TRUNC('day', time) AS dt, + AVG(gas_limit) AS avg_block_gas_limit +FROM ethereum."blocks" +GROUP BY dt +OFFSET 1 +``` + +Depois, há o gas real usado diariamente para pagar pela computação realizada na cadeia Ethereum (ou seja, enviar transações, chamar um contrato inteligente, cunhar um NFT). Esta é a **demanda** por espaço de bloco disponível no Ethereum: + +![](./daily_gas_used.png) + +```sql +SELECT + DATE_TRUNC('day', time) AS dt, + AVG(gas_used) AS avg_block_gas_used +FROM ethereum."blocks" +GROUP BY dt +OFFSET 1 +``` + +Também podemos justapor esses dois gráficos para ver como a **demanda e oferta** se alinham: + +![gas_demand_supply](./gas_demand_supply.png) + +Portanto, podemos entender os preços do gas em função da demanda por espaço no bloco Ethereum, dada a oferta disponível. + +Finalmente, podemos querer consultar os preços médios diários do gas para a cadeia Ethereum, no entanto, fazê-lo resultará em um tempo de consulta especialmente longo, então, filtraremos a nossa consulta pela quantidade média de gas paga por transação pela Fundação Ethereum. + +![](./ef_daily_gas.png) + +Podemos ver os preços do gas pagos por todas as transações feitas para o endereço da Ethereum Foundation ao longo dos anos. Aqui está a consulta: + +```sql +SELECT + block_time, + gas_price / 1e9 AS gas_price_gwei, + value / 1e18 AS eth_sent +FROM ethereum."transactions" +WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' +ORDER BY block_time DESC +``` + +### Resumo {#summary} + +Com este tutorial, entendemos os conceitos fundamentais do Ethereum e como a blockchain do Ethereum funciona consultando e obtendo uma ideia dos dados on-chain. + +O painel que contém todo o código usado neste tutorial pode ser encontrado [aqui](https://duneanalytics.com/paulapivat/Learn-Ethereum). + +Para mais uso de dados para explorar a web3 [siga-me no Twitter](https://twitter.com/paulapivat). diff --git a/public/content/translations/pt-br/developers/tutorials/logging-events-smart-contracts/index.md b/public/content/translations/pt-br/developers/tutorials/logging-events-smart-contracts/index.md new file mode 100644 index 00000000000..d74031cc9e8 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/logging-events-smart-contracts/index.md @@ -0,0 +1,66 @@ +--- +title: Registrando dados de contratos inteligentes com eventos +description: Uma introdução aos eventos de contrato inteligentes e como você pode usá-los para registrar os dados +author: "jdourlens" +tags: + - "contratos inteligentes" + - "remix" + - "solidity" + - "eventos" +skill: intermediate +lang: pt-br +published: 2020-04-03 +source: EthereumDev +sourceUrl: https://ethereumdev.io/logging-data-with-events/ +address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" +--- + +No Solidity, [eventos](/developers/docs/smart-contracts/anatomy/#events-and-logs) são sinais enviados que os contratos inteligentes podem disparar. Dapps, ou qualquer coisa conectada à API Ethereum JSON-RPC, podem reconhecer esses eventos e agir em conformidade. Um evento também pode ser indexado para que o histórico de eventos seja pesquisável posteriormente. + +## Eventos {#events} + +O evento mais comum na blockchain Ethereum no momento da redação deste artigo é o evento Transfer, que é emitido por tokens ERC20 quando alguém transfere tokens. + +```solidity +event Transfer(address indexed from, address indexed to, uint256 value); +``` + +A assinatura do evento é declarada dentro do código do contrato e pode ser emitida com a palavra-chave de emissão. Por exemplo, os registros de eventos de transferência que enviaram a transferência (_from_), para quem foram transferidos (_to_) e quantos tokens foram transferidos (_value_). + +Se voltarmos ao nosso contrato inteligente Contador e decidirmos registrar toda vez que o valor for alterado. Como este contrato não é para ser usado, mas serve como uma base para a construção de outro contrato, estendendo-o: é chamado de contrato abstrato. No caso de nosso exemplo de contador, ele ficaria assim: + +```solidity +pragma solidity 0.5.17; + +contract Counter { + + event ValueChanged(uint oldValue, uint256 newValue); + + // Private variable of type unsigned int to keep the number of counts + uint256 private count = 0; + + // Function that increments our counter + function increment() public { + count += 1; + emit ValueChanged(count - 1, count); + } + + // Getter to get the count value + function getCount() public view returns (uint256) { + return count; + } + +} +``` + +Observe que: + +- **Linha 5**: declaramos nosso evento e o que ele contém, o valor antigo e o novo valor. + +- **Linha 13**: Quando incrementamos nossa variável de contagem, emitimos o evento. + +Se implementarmos o contrato e chamarmos a função de incremento, veremos que o Remix será exibido automaticamente se você clicar na nova transação dentro de um array de logs nomeados. + +![Captura de tela Remix](./remix-screenshot.png) + +Os logs são muito úteis para depurar seus contratos inteligentes, mas também são importantes se você criar aplicativos usados por diferentes pessoas e tornar mais fácil fazer análises para rastrear e entender como seu contrato inteligente é usado. Os registros gerados pelas transações são exibidos em exploradores de blocos populares e você também pode, por exemplo, usá-los para criar 'scripts' fora da cadeia para ver eventos específicos e agir quando eles ocorrerem. diff --git a/public/content/translations/pt-br/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md b/public/content/translations/pt-br/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md new file mode 100644 index 00000000000..f0a29036ae2 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md @@ -0,0 +1,241 @@ +--- +title: Provas de Merkle para integridade de dados offline +description: Assegurar a integridade dos dados na cadeia para os dados armazenados, sobretudo, fora da cadeia +author: Ori Pomerantz +tags: + - "armazenamento" +skill: advanced +lang: pt-br +published: 2021-12-30 +--- + +## Introdução {#introduction} + +Idealmente, gostaríamos de guardar tudo no armazenamento do Ethereum, que é armazenado em milhares de computadores e conta com uma disponibilidade extremamente alta (os dados não podem ser censurados) e integridade (os dados não podem ser modificados de forma não autorizada), sabendo que armazenar uma palavra de 32 bytes normalmente custa 20.000 gás. No momento em que estou escrevendo isto, o custo é equivalente a $6,60. A 21 centavos por byte, isso é bastante caro para muitas utilizações. + +Para resolver esse problema, o ecossistema do Ethereum desenvolveu [muitas formas alternativas de armazenar dados de forma descentralizada](/developers/docs/storage/). Geralmente, elas envolvem um equilíbrio entre a disponibilidade e o preço. No entanto, a integridade é geralmente assegurada. + +Neste artigo, você aprenderá **como** garantir a integridade dos dados sem armazenar os dados na blockchain, usando [ provas de Merkle](https://computersciencewiki.org/index.php/Merkle_proof). + +## Como isso funciona? {#how-does-it-work} + +Em teoria, poderíamos apenas armazenar o hash dos dados na cadeia e enviar todos os dados em transações que precisam deles. No entanto, isso ainda é demasiado caro. Um byte de dados para uma transação custa cerca de 16 gás, atualmente cerca de meio centavo ou cerca de $5 por kilobyte. A $5.000 por megabyte, isso ainda é muito caro para várias utilizações, mesmo sem o custo adicional de hashing de dados. + +A solução é fazer hash repetidamente de diferentes subconjuntos dos dados. Para os dados que você não precisa enviar, você pode apenas enviar um hash. Você pode fazer isso usando uma árvore de Merkle, uma estrutura de dados de árvore em que cada nó é um hash dos nós abaixo: + +![Árvores de Merkle](tree.png) + +O hash raiz é a única parte que precisa ser armazenada na cadeia. Para comprovar um determinado valor, forneça todos os hashes que precisam ser combinados com ele para obter a raiz. Por exemplo, para provar `C` você fornece `D`, `(H-B)`, e `H(E-H)`. + +![Prova do valor de C](proof-c.png) + +## Implementação {#implementation} + +[O código de exemplo é fornecido aqui](https://github.com/qbzzt/merkle-proofs-for-offline-data-integrity). + +### Código fora da cadeia {#off-chain-code} + +Neste artigo, usamos JavaScript para os cálculos fora da cadeia. A maioria dos aplicativos descentralizados tem seu componente off-chain em JavaScript. + +#### Criando a raiz Merkle {#creating-the-merkle-root} + +Primeiro, precisamos fornecer a raiz Merkle à cadeia. + +```javascript +const ethers = require("ethers") +``` + +[Usamos a função hash do pacote ethers](https://docs.ethers.io/v5/api/utils/hashing/#utils-keccak256). + +```javascript +// The raw data whose integrity we have to verify. The first two bytes a +// are a user identifier, and the last two bytes the amount of tokens the +// user owns at present. +const dataArray = [ + 0x0bad0010, 0x60a70020, 0xbeef0030, 0xdead0040, 0xca110050, 0x0e660060, + 0xface0070, 0xbad00080, 0x060d0091, +] +``` + +Codificar cada entrada em um único inteiro de 256 bits resulta em um código menos legível que o JSON, por exemplo. No entanto, isso significa um processamento significativamente menor para recuperar os dados contidos no contrato, portanto, custos de gás muito menores. [Você pode ler o JSON na cadeia](https://github.com/chrisdotn/jsmnSol), porém, isso é uma má ideia e evite fazer isso se puder. + +```javascript +// The array of hash values, as BigInts +const hashArray = dataArray +``` + +Nesse caso, para começar, nossos dados têm um valor 256 bits. Portanto, não é necessário qualquer tipo de processamento. Se usarmos uma estrutura de dados mais complicada, como cadeias de caracteres, precisamos ter certeza de que fazemos primeiro o hash dos dados para obter uma matriz de hashes. Observe que isso também é devido ao fato de não nos importarmos se usuários conhecem as informações de outros usuários. Caso contrário, teríamos tido que fazer um hash, para que o usuário 1 não saiba o valor para o usuário 0, ao usuário 2 que não saberá o valor para o usuário 3, etc. + +```javascript +// Convert between the string the hash function expects and the +// BigInt we use everywhere else. +const hash = (x) => + BigInt(ethers.utils.keccak256("0x" + x.toString(16).padStart(64, 0))) +``` + +A função hash de ethers espera obter uma cadeia de caracteres em JavaScript com um número hexadecimal, como `0x60A7`, e responde com outra cadeia de caracteres com a mesma estrutura. No entanto, para o resto do código, é mais fácil usar `BigInt`, então convertemos em uma cadeia de caracteres hexadecimal e de volta novamente. + +```javascript +// Symmetrical hash of a pair so we won't care if the order is reversed. +const pairHash = (a, b) => hash(hash(a) ^ hash(b)) +``` + +Essa função é simétrica (hash de um [xor](https://en.wikipedia.org/wiki/Exclusive_or) b). Isto significa que quando verificamos a prova de Merkle, não precisamos nos preocupar se devemos colocar o valor da prova antes ou depois do valor calculado. A verificação da prova de Merkle é feita na cadeia, portanto, quanto menos precisarmos fazer lá, melhor. + +Atenção: A criptografia é mais difícil do que parece. A versão inicial deste artigo tinha a função hash `hash(a^b)`. Essa foi uma **má** ideia, porque significava que se você conhecesse os valores legítimos de `a` e de `b`, você poderia usar `b' = a^b^a'` para provar qualquer valor `a'` desejado. Com essa função, você teria que calcular `b'`, de forma que `hash(a') ^ hash(b')` fosse igual a um valor conhecido (o próximo branch a caminho da raiz), o que é muito mais difícil. + +```javascript +// The value to denote that a certain branch is empty, doesn't +// have a value +const empty = 0n +``` + +Quando o número de valores não é uma potência inteira de dois, precisamos lidar com branches vazios. O programa faz isso colocando zero como espaço reservado. + +![Árvore de Merkle com branches faltando](merkle-empty-hash.png) + +```javascript +// Calculate one level up the tree of a hash array by taking the hash of +// each pair in sequence +const oneLevelUp = (inputArray) => { + var result = [] + var inp = [...inputArray] // To avoid over writing the input // Add an empty value if necessary (we need all the leaves to be // paired) + + if (inp.length % 2 === 1) inp.push(empty) + + for (var i = 0; i < inp.length; i += 2) + result.push(pairHash(inp[i], inp[i + 1])) + + return result +} // oneLevelUp +``` + +Esta função “escala” um nível na árvore de Merkle, fazendo hash dos pares de valores na camada atual. Observe que esta não é a implementação mais eficiente. Poderíamos ter evitado copiar a entrada e apenas adicionar `hashEmpty` quando apropriado no loop, mas este código é otimizado para melhorar a legibilidade. + +```javascript +const getMerkleRoot = (inputArray) => { + var result + + result = [...inputArray] // Climb up the tree until there is only one value, that is the // root. // // If a layer has an odd number of entries the // code in oneLevelUp adds an empty value, so if we have, for example, // 10 leaves we'll have 5 branches in the second layer, 3 // branches in the third, 2 in the fourth and the root is the fifth + + while (result.length > 1) result = oneLevelUp(result) + + return result[0] +} +``` + +Para obter a raiz, suba até que haja apenas um valor restante. + +#### Criando uma prova de Merkle {#creating-a-merkle-proof} + +Uma prova de Merkle é o conjunto de valores a fazer hash junto com o valor que está sendo provado para recuperar a raiz de Merkle. O valor a provar está frequentemente disponível a partir de outros dados, então eu prefiro fornecê-lo separadamente do que como parte do código. + +```javascript +// A merkle proof consists of the value of the list of entries to +// hash with. Because we use a symmetrical hash function, we don't +// need the item's location to verify the proof, only to create it +const getMerkleProof = (inputArray, n) => { +    var result = [], currentLayer = [...inputArray], currentN = n + +    // Until we reach the top +    while (currentLayer.length > 1) { +        // No odd length layers +        if (currentLayer.length % 2) +            currentLayer.push(empty) + +        result.push(currentN % 2 +               // If currentN is odd, add with the value before it to the proof +            ? currentLayer[currentN-1] +               // If it is even, add the value after it +            : currentLayer[currentN+1]) + +``` + +Fazemos o hash `(v[0],v[1])`, `(v[2],v[3])`, etc. Portanto, para valores pares, precisamos do próximo e, para valores ímpares, precisamos do anterior. + +```javascript +        // Move to the next layer up +        currentN = Math.floor(currentN/2) +        currentLayer = oneLevelUp(currentLayer) +    }   // while currentLayer.length > 1 + +    return result +}   // getMerkleProof +``` + +### Código on-chain {#on-chain-code} + +Por fim, temos o código que verifica a prova. O código on-chain é escrito em [Solidity](https://docs.soliditylang.org/en/v0.8.11/). A otimização é aqui muito mais importante, porque o gás é relativamente caro. + +```solidity +//SPDX-License-Identifier: Public Domain +pragma solidity ^0.8.0; + +import "hardhat/console.sol"; +``` + +Escrevi isso usando o [ambiente de desenvolvimento de hardware](https://hardhat.org/), que nos permite ter [saída do console do Solidity](https://hardhat.org/tutorial/debugging-with-hardhat-network.html) em desenvolvimento. + +```solidity + +contract MerkleProof { +    uint merkleRoot; + +    function getRoot() public view returns (uint) { +      return merkleRoot; +    } + +    // Extremely insecure, in production code access to +    // this function MUST BE strictly limited, probably to an +    // owner +    function setRoot(uint _merkleRoot) external { +      merkleRoot = _merkleRoot; +    }   // setRoot +``` + +Configure e obtenha funções para a raiz de Merkle. Deixar que todo mundo atualize a raiz de Merkle é uma _ideia extremamente má_ em um sistema de produção. Aqui, faço isso por uma questão de simplicidade no código de exemplo. **Não faça isso em um sistema no qual a integridade de dados realmente importa**. + +```solidity +    function hash(uint _a) internal pure returns(uint) { +      return uint(keccak256(abi.encode(_a))); +    } + +    function pairHash(uint _a, uint _b) internal pure returns(uint) { +      return hash(hash(_a) ^ hash(_b)); +    } +``` + +Essa função gera um par de hashes. Ela é simplesmente a tradução do Solidity do código em JavaScript para `hash` e `pairHash`. + +**Observação:** Este é outro caso de otimização para facilidade de leitura. Baseado em [a definição da função](https://www.tutorialspoint.com/solidity/solidity_cryptographic_functions.htm), é possível armazenar os dados como um valor de [`bytes32`](https://docs.soliditylang.org/en/v0.5.3/types.html#fixed-size-byte-arrays) e evitar as conversões. + +```solidity +    // Verify a Merkle proof +    function verifyProof(uint _value, uint[] calldata _proof) +        public view returns (bool) { +      uint temp = _value; +      uint i; + +      for(i=0; i<_proof.length; i++) { +        temp = pairHash(temp, _proof[i]); +      } + +      return temp == merkleRoot; +    } + +}  // MarkleProof +``` + +Na notação matemática, a verificação pela prova de Merkle tem esta aparência: `H(proof_n, H(proof_n-1, H(proof_n-2, ... H(prova_1, H(prova_0, valor)...)))`. Este código implementa-o. + +## Provas de Merkle e rollups não se misturam {#merkle-proofs-and-rollups} + +As provas de Merkle não funcionam bem com [rollups](/developers/docs/scaling/#rollups). O motivo é que os rollups escrevem todos os dados da transação no L1, mas são processadas no L2. O custo para enviar uma prova de Merkle com uma média de transação a 638 gás por camada (atualmente, um byte nos dados de chamadas custa 16 gás se não for zero, e 4 se for zero). Se temos 1024 palavras de dados, uma prova de Merkle requer dez camadas, ou um total de 6380 gás. + +Procurando um exemplo no [Optimism](https://public-grafana.optimism.io/d/9hkhMxn7z/public-dashboard?orgId=1&refresh=5m), escrever custos de gás L1 custa cerca de 100 gwei e escrever custos de gás L2 custa 0,001 gwei (esse é o preço normal, que pode aumentar com o congestionamento). Portanto, pelo custo de um gás L1 podemos gastar cem mil gás no processamento L2. Supondo que não sobrescrevamos o armazenamento, isso significa que podemos escrever cerca de cinco palavras para armazenamento na L2 pelo preço de um gás L1. Para uma única prova de Merkle, podemos escrever todas as 1024 palavras para armazenamento (assumindo que elas podem ser calculadas em cadeia para começar, em vez de serem fornecidos em uma transação) e ainda restam a maior parte do gás. + +## Conclusão {#conclusion} + +Na vida real, você pode nunca implementar Merkle por conta própria. Existem bibliotecas conhecidas e auditadas que você pode usar e, de um modo geral, é melhor não implementar primitivos criptográficos por conta própria. Mas espero que agora você compreenda melhor as provas de Merkle e que possa decidir quando é que vale a pena utilizar. + +Observe que, enquanto as provas de Merkle preservam a _integridade_, elas não preservam a disponibilidade __. Saber que mais ninguém pode tomar seus ativos é uma pequena consolação se o armazenamento de dados decidir impedir o acesso e você não pode construir uma Merkle para acessá-los também. Portanto, as árvores de Merkle são melhor usadas com algum tipo de armazenamento descentralizado, como IPFS. diff --git a/public/content/translations/pt-br/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md b/public/content/translations/pt-br/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md new file mode 100644 index 00000000000..8d7bc371bd1 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md @@ -0,0 +1,147 @@ +--- +title: Monitorando o Geth com InfluxDB e Grafana +description: +author: "Mário Havel" +tags: + - "clientes" + - "nós" +skill: intermediate +lang: pt-br +published: 2021-01-13 +--- + +Esse tutorial ajudará você a configurar o monitoramento do seu Geth para você poder entender melhor o seu desempenho e identificar possíveis problemas. + +## Pré-Requisitos {#prerequisites} + +- Você já deveria estar executando uma instância de Geth. +- A maioria dos passos e exemplos são para o ambiente Linux, o conhecimento básico sobre terminais será útil. +- Confira este vídeo da visão geral da suíte de métricas do Geth: [Monitoring an Ethereum infrastructure by Péter Szilágyi](https://www.youtube.com/watch?v=cOBab8IJMYI). + +## Stack de monitoramento {#monitoring-stack} + +Um cliente Ethereum coleta muitos dados que podem ser lidos na forma de uma base de dados cronológica. Para facilitar o monitoramento, você pode inserir isso em um software de visualização de dados. Existem múltiplas opções disponíveis: + +- [Prometheus](https://prometheus.io/) (modelo pull) +- [InfluxDB](https://www.influxdata.com/get-influxdb/) (modelo push) +- [Telegraf](https://www.influxdata.com/get-influxdb/) +- [Grafana](https://www.grafana.com/) +- [Datadog](https://www.datadoghq.com/) +- [Chronograf](https://www.influxdata.com/time-series-platform/chronograf/) + +Também há o [Geth Prometheus Exporter](https://github.com/hunterlong/gethexporter), uma opção pré-configurada com InfluxDB e Grafana. Você pode configurá-lo facilmente usando docker e [Ethbian OS](https://ethbian.org/index.html) para RPi 4. + +Neste tutorial, nós configuramos seu cliente Geth para enviar dados para o InfluxDB para criar um banco de dados e o Grafana para criar um gráfico de visualização dos dados. Fazer isso manualmente ajudará você a entender melhor o processo, alterá-lo e fazer deploy em diferentes ambientes. + +## Configurando o InfluxDB {#setting-up-influxdb} + +Primeiro, vamos baixar e instalar o InfluxDB. Várias opções de download podem ser encontradas na [página de release do Influxdata](https://portal.influxdata.com/downloads/). Escolha o que mais se adequa ao seu ambiente. Você também pode instalá-lo a partir de um [repositório](https://repos.influxdata.com/). Por exemplo, em uma distribuição baseada em Debian: + +``` +curl -tlsv1.3 --proto =https -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add +source /etc/lsb-release +echo "deb https://repos.influxdata.com/${DISTRIB_ID,,} ${DISTRIB_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/influxdb.list +sudo apt update +sudo apt install influxdb -y +sudo systemctl enable influxdb +sudo systemctl start influxdb +sudo apt install influxdb-client +``` + +Após instalar o InfluxDB com sucesso, certifique-se de que ele está sendo executado em segundo plano. Por padrão, ele é acessível em `localhost:8086`. Antes de usar o cliente `influx` você tem que criar um novo usuário com privilégios de administrador. Este usuário servirá para gerenciamento de alto nível, criando bancos de dados e usuários. + +``` +curl -XPOST "http://localhost:8086/query" --data-urlencode "q=CREATE USER username WITH PASSWORD 'password' WITH ALL PRIVILEGES" +``` + +Agora você pode usar o cliente influx para entrar no [shell do InfluxDB](https://docs.influxdata.com/influxdb/v1.8/tools/shell/) com este usuário. + +``` +influx -username 'username' -password 'password' +``` + +Comunificando diretamente com o InfluxDB em seu shell, você pode criar banco de dados e usuário para métricas do geth. + +``` +create database geth +create user geth with password choosepassword +``` + +Verifique as entradas criadas com: + +``` +show databases +show users +``` + +Saia do Shell InfluxDB. + +``` +exit +``` + +O InfluxDB está rodando e configurado para armazenar métricas do Geth. + +## Preparando o Geth {#preparing-geth} + +Depois de configurar o banco de dados, precisamos habilitar a coleção de métricas no Geth. Preste atenção em `METRICS AND STATS OPTIONS` com `geth --help`. Várias opções podem ser encontradas lá, neste caso queremos que o Geth envie dados para o InfluxDB. A configuração básica especifica o endpoint onde o InfluxDB é acessível e a autenticação para o banco de dados. + +``` +geth --metrics --metrics.influxdb --metrics.influxdb.endpoint "http://0.0.0.0:8086" --metrics.influxdb.username "geth" --metrics.influxdb.password "chosenpassword" +``` + +Estas flags podem ser anexadas a um comando que inicie o cliente ou salvas no arquivo de configuração. + +Você pode verificar que o Geth está fazendo push de dados com sucesso, por exemplo, listando as métricas no banco de dados. Saia do shell do InfluxDB: + +``` +use geth +show measurements +``` + +## Configurando o Grafana {#setting-up-grafana} + +O próximo passo é instalar o Grafana que interpretará os dados graficamente. Siga o processo de instalação do seu ambiente na documentação do Grafana. Certifique-se de instalar a versão OSS se você não quiser o contrário. Etapas de instalação de exemplo para distribuições Debian usando o repositório: + +``` +curl -tlsv1.3 --proto =https -sL https://packages.grafana.com/gpg.key | sudo apt-key add - +echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list +sudo apt update +sudo apt install grafana +sudo systemctl enable grafana-server +sudo systemctl start grafana-server +``` + +Quando você estiver rodando o Grafana, ele deve ser acessível em `localhost:3000`. Use seu navegador preferido para acessar esta URL e, em seguida, faça login com as credenciais padrão (usuário: `admin` e senha: `admin`). Quando solicitado, altere a senha padrão e salve. + +![](./grafana1.png) + +Você vai ser redirecionado para a página principal do Grafana. Primeiro, configure seu source data. Clique no ícone de configuração na barra esquerda e selecione "Data sources". + +![](./grafana2.png) + +Ainda não existem data sources criados, clique em "Add data source" para definir um. + +![](./grafana3.png) + +Para esta configuração, selecione "InfluxDB" e prossiga. + +![](./grafana4.png) + +A configuração do data source é bem simples se você estiver rodando ferramentas na mesma máquina. Você precisa configurar o endereço e os detalhes do InfluxDB para acessar o banco de dados. Consulte a imagem abaixo. + +![](./grafana5.png) + +Se tudo estiver completo e o InfluxDB estiver acessível, clique em "Save and test" e aguarde a confirmação aparecer. + +![](./grafana6.png) + +O Grafana está agora configurado para ler dados do InfluxDB. Agora você precisa criar um painel que o interprete e o exiba. As propriedades dos Dashboards são codificadas em arquivos JSON que podem ser criados por qualquer um e podem ser facilmente importados. Na barra esquerda, clique em "Create and Import". + +![](./grafana7.png) + +Para um dashboard de monitoramento do Geth, copie o ID [deste dashboard](https://grafana.com/grafana/dashboards/13877/) e cole-o em "Import page" no Grafana. Depois de salvar o dashboard, ele deve ficar assim: + +![](./grafana8.png) + +Você pode modificar seus dashboards. Cada dashboard pode ser editado, movido, removido ou adicionado. Você pode alterar suas configurações. É com você! Para saber mais sobre como os dashboards funcionam, consulte a [documentação do Grafana](https://grafana.com/docs/grafana/latest/dashboards/). Você também pode estar interessado sobre [Notificações / Alertas](https://grafana.com/docs/grafana/latest/alerting/). Isso permite configurar notificações de alerta para quando as métricas alcançarem certos valores. Vários canais de comunicação são suportados. diff --git a/public/content/translations/pt-br/developers/tutorials/nft-minter/index.md b/public/content/translations/pt-br/developers/tutorials/nft-minter/index.md new file mode 100644 index 00000000000..b5ef01302fc --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/nft-minter/index.md @@ -0,0 +1,874 @@ +--- +title: Tutorial de criação de uma NFT +description: Neste tutorial, você irá construir um minter NFT e, também, aprender a como criar um full stack dapp conectando seu contrato inteligente a um React frontend usando MetaMask e ferramentas Web3. +author: "smudgil" +tags: + - "solidity" + - "NFT" + - "alchemy" + - "contratos inteligentes" + - "front-end" + - "Pinata" +skill: intermediate +lang: pt-br +published: 2021-10-06 +--- + +Um dos maiores desafios para desenvolvedores vindos de um background Web2 é descobrir como conectar seu contrato inteligente a um projeto frontend e interagir com ele. + +Ao criar um minter NFT — uma simples UI onde você pode inserir um link para seu ativo digital, um título e uma descrição — você aprenderá a: + +- Conectar ao MetaMask através do seu projeto frontend +- Chamar métodos de contrato inteligentes no seu frontend +- Assine transações usando MetaMask + +Neste tutorial, usaremos o [React](https://reactjs.org/) como nossa estrutura de frontend. Como este tutorial está focado principalmente no desenvolvimento da Web3, nós não passaremos muito tempo detalhando os fundamentos do React. Em vez disso, nós focaremos em trazer funcionalidade para o nosso projeto. + +Como pré-requisito, você deve ter uma compreensão mínima do React – saber como funcionam componentes, props, useState/useEffect e chamadas de funções básicas. Se você nunca ouviu falar de nenhum desses termos antes, você pode querer conferir este [Intro to React tutorial](https://reactjs.org/tutorial/tutorial.html). Para os que apreciam mais visualidade, é altamente recomendável esta excelente série de vídeos [Full Modern React Tutorial](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gZD-TvwTutorialfod2gaISzfRiP9d) por Net Ninja. + +E se você ainda não fez, você definitivamente precisará criar uma conta Alchemy para concluir este tutorial, bem como construir qualquer coisa no blockchain. Inscreva-se para uma conta gratuita [aqui](https://alchemy.com/). + +Sem mais delongas, vamos começar! + +## Criando NFTs 101 {#making-nfts-101} + +Antes de começarmos a olhar para qualquer código, é importante entender como funciona fazer uma NFT. Envolve duas etapas: + +### Publicar um contrato inteligente da NFT no blockchain Ethereum {#publish-nft} + +A maior diferença entre os dois padrões de contrato inteligente NFT é que o ERC-1155 é um padrão multi-token e inclui a funcionalidade de lote, enquanto o ERC-721 é um padrão de token único, portanto, suporta apenas a transferência de um token por vez. + +### Chamar a função mint {#minting-function} + +Normalmente, esta função mint requer que você passe duas variáveis como parâmetros, primeiro o destinatário `recipient`, que especifica o endereço que receberá a sua NFT recém-mintada, e segundo o `tokenURI` da NFT, uma string que indica a um documento JSON que descreve os metadados da NFT. + +Os metadados de uma NFT são o que realmente a torna realidade, permitindo que tenha propriedades configuráveis, como um nome, descrição, imagem (ou diferentes ativos digitais), e outros atributos. Aqui está [um exemplo de um tokenURI](https://gateway.pinata.cloud/ipfs/QmSvBcb4tjdFpajGJhbFAWeK3JAxCdNQLQtr6ZdiSi42V2), que contém os metadados de uma NFT. + +Neste tutorial, vamos nos concentrar na parte 2, chamando a função mint de contrato inteligente de uma NFT existente usando nossa interface do React. + +[Aqui está um link](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE) para o contrato inteligente NFT ERC-721 que vamos chamar neste tutorial. Se você gostaria de saber como o fizemos, é altamente recomendável que você veja nosso outro tutorial, ["Como criar uma NFT"](https://docs.alchemyapi.io/alchemy/tutorials/how-to-create-an-nft). + +Legal, agora que entendemos como fazer uma NFT funcionar, vamos clonar nossos arquivos iniciais! + +## Clonar os arquivos iniciais {#clone-the-starter-files} + +Primeiro, vá para o [repositório GitHub do nft-minter-tutorial](https://github.com/alchemyplatform/nft-minter-tutorial) para obter os arquivos iniciais para este projeto. Clone este repositório para o seu ambiente local.= + +Quando você abrir este repositório clonado `nft-minter-tutorial`, irá notar que ele contém duas pastas: `minter-starter-files` e `nft-minter`. + +- `minter-starter-files` contém os arquivos iniciais (essencialmente a interface do React) para este projeto. Neste tutorial, **trabalharemos nesse diretório**, enquanto você aprende a dar vida a sua interface do usuário, conectando-a à sua carteira Ethereum e a um contrato inteligente de NFT. +- `nft-minter` contém o tutorial completo e serve para você como uma **referência** **se você ficar preso.** + +Em seguida, abra sua cópia de `minter-starter-files` no seu editor de código e navegue para a pasta `src`. + +Todo o código que vamos escrever será exibido na pasta `src`. Vamos editar o componente `Minter.js` e escrever arquivos javascript adicionais para dar funcionalidades Web3 ao nosso projeto. + +## Passo 2: Confira nossos arquivos iniciais {#step-2-check-out-our-starter-files} + +Antes de começarmos a codificar, é importante verificar o que já está fornecido para nós nos arquivos iniciais. + +### Tenha seu projeto React em execução {#get-your-react-project-running} + +Vamos começar executando o projeto React em nosso navegador. A beleza do React é que uma vez que nosso projeto esteja sendo executado no nosso navegador, qualquer alteração que salvarmos será atualizada ao vivo em nosso navegador. + +Para fazer com que o projeto funcione, navegue até o diretório raiz da pasta `minter-starter-files`, e execute`npm install` no seu terminal para instalar as dependências do projeto: + +```bash +cd minter-starter-files +npm install +``` + +Uma vez terminada a instalação, execute `npm start` em seu terminal: + +```bash +npm start +``` + +Feito isso, você deve abrir http://localhost:3000/ no seu navegador, onde você verá o frontend do nosso projeto. Ele deve consistir de 3 campos: um local para inserir um link para o ativo do seu NFT, digite o nome da sua NFT e forneça uma descrição. + +Se você tentar clicar nos botões "Connectar Wallet" ou "Mint NFT", você notará que eles não funcionam — isso porque ainda precisamos programar a funcionalidade deles! :\) + +### O componente Minter.js {#minter-js} + +**NOTA:** Certifique-se de estar na pasta `minter-starter-files` e não na pasta `nft-minter`! + +Vamos voltar à pasta `src` no nosso editor e abrir o arquivo `Minter.js`. É muito importante que entendamos tudo neste arquivo, pois é o principal componente do React no qual vamos trabalhar. + +No topo do nosso arquivo, temos nossas variáveis de estado que serão atualizadas após eventos específicos. + +```javascript +//State variables +const [walletAddress, setWallet] = useState("") +const [status, setStatus] = useState("") +const [name, setName] = useState("") +const [description, setDescription] = useState("") +const [url, setURL] = useState("") +``` + +Nunca ouviu falar de variáveis de estado do React ou State Hooks? Confira [está](https://reactjs.org/docs/hooks-state.html) documentação. + +Veja aqui o que cada uma das variáveis representa: + +- `walletAddress` - uma string que armazena o endereço da carteira do usuário +- `status` - uma string que contém uma mensagem a ser exibida na parte inferior da interface do usuário +- `name` - uma string que armazena o nome da NFT +- `descrição` - uma string que armazena a descrição da NFT +- `url` - uma string que é um link para o ativo digital da NFT + +Após as variáveis de estado, você verá três funções não implementadas: `useEffect`, `connectWalletPressed`, e `onMintPressed`. Você irá notar que todas essas funções são `async`, isso é porque iremos fazer chamadas assíncronas da API nelas! Os nomes delas são relacionadas com sua funcionalidade: + +```javascript +useEffect(async () => { + //TODO: implement +}, []) + +const connectWalletPressed = async () => { + //TODO: implement +} + +const onMintPressed = async () => { + //TODO: implement +} +``` + +- [`useEffect`](https://reactjs.org/docs/hooks-effect.html) - este é um React Hook que é chamado depois que seu componente é renderizado. Porque ele tem uma array vazia `[]` "prop" passada para ela (veja a linha 3), ela só será chamada na _primeira_ renderização do componente. Aqui vamos chamar nosso ouvinte de carteira e outra função de carteira para atualizar nossa interface de usuário para refletir se uma carteira já está conectada. +- `connectWalletPressed` - esta função será chamada para conectar a carteira MetaMask do usuário ao nosso dapp. +- `onMintPressed` - esta função será chamada para mintar a NFT do usuário. + +Perto do final desse arquivo, temos a interface de usuário do nosso componente. Se você escanear este código com cuidado, notará que atualizamos nossa `url`, `name`, e `description` variáveis de estado quando a entrada em seus campos de texto correspondentes muda. + +Você também verá que `connectWalletPressed` e `onMintPressed` são chamadas quando os botões com IDs `mintButton` e `walletButton` são clicados respectivamente. + +```javascript +//the UI of our component +return ( +
      + + +

      +

      🧙‍♂️ Alchemy NFT Minter

      +

      + Simply add your asset's link, name, and description, then press "Mint." +

      +
      +

      🖼 Link to asset:

      + setURL(event.target.value)} + /> +

      🤔 Name:

      + setName(event.target.value)} + /> +

      ✍️ Description:

      + setDescription(event.target.value)} + /> +
      + +

      {status}

      +
      +) +``` + +Finalmente, vamos endereçar onde esse componente Minter será adicionado. + +Se você for ao arquivo `App.js`, que é o componente principal do React que atua como um contêiner para todos os outros componentes, você verá que nosso componente Minter é injetado na linha 7. + +**Neste tutorial, vamos apenas editar o arquivo `Minter.js` e adicionar arquivos em nossa pasta `src`.** + +Agora que entendemos com o que estamos trabalhando, vamos configurar a nossa carteira Ethereum! + +## Configure sua carteira Ethereum {#set-up-your-ethereum-wallet} + +Para que os usuários possam interagir com o seu contrato inteligente, eles precisarão conectar a sua carteira Ethereum ao seu dapp. + +### Baixar MetaMask {#download-metamask} + +Para este tutorial, usaremos uma carteira virtual no navegador, a MetaMask, para gerenciar o endereço da sua conta Ethereum. Se você quiser entender mais sobre como as transações no Ethereum funcionam, confira [esta página](/developers/docs/transactions/) na Fundação Ethereum. + +Você pode baixar e criar uma conta MetaMask gratuitamente [neste link](https://metamask.io/download.html). Quando estiver criando uma conta, ou se já tiver uma, certifique-se de mudar para a "Ropsten Test Network", no canto superior direito (para não precisar lidar com dinheiro de verdade\). + +### Etapa: Adicionar Faucet ether {#add-ether-from-faucet} + +Para mintar as nossas NFT (ou assinar quaisquer transações no blockchain Ethereum), precisaremos de alguns Eth falsos. Para obter Eth você pode ir para o [faucet da Ropsten](https://faucet.ropsten.be/), inserir seu endereço de conta Ropsten e clicar em "Send Ropsten Eth." Em seguida, você deve ver Eth em sua conta Metamask! + +### Conferir o seu saldo {#check-your-balance} + +Para verificar novamente que tem saldo, vamos fazer uma solicitação através da ferramenta [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) fornecida pelo [compositor da Alchemy](https://composer.alchemyapi.io?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Ela mostrará a quantidade de Eth na sua carteira. Depois de inserir o endereço da sua conta da MetaMask e clicar em "Send Request", você verá uma resposta como esta: + +```text +{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"} +``` + +**NOTA:** Este resultado está em wei, não em ETH. Lembre-se de que "Wei" é a menor unidade de ether. A conversão de wei para eth é: 1 eth = 10¹⁸ wei. Então, se convertemos 0xde0b6b3a7640000 para decimal, temos 1\*10¹⁸ wei, que é igual a 1 eth. + +Ufa! Nosso dinheiro falso está todo lá! + +## Conecte o MetaMask à sua interface {#connect-metamask-to-your-UI} + +Agora que nossa carteira MetaMask está configurada, vamos conectar nosso dapp a ela! + +Como queremos prescrever conforme o paradigma [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), vamos criar um arquivo separado que contém nossas funções para gerenciar a lógica, dados e regras de nosso dapp, e então passar essas funções para nosso frontend (nosso componente Minter.js). + +### Função `connectWallet` {#connect-wallet-function} + +Para fazer isso, vamos criar uma nova pasta chamada `utils` em seu diretório `src` e adicionar um arquivo chamado `interact.js` dentro dele, que conterá todas as funções de nossa carteira e da interação com o contrato inteligente. + +No nosso arquivo `interact.js`, vamos escrever uma função `connectWallet`, que então importar e chamará nosso componente `Minter.js`. + +No seu arquivo`interact.js`, adicione o seguinte + +```javascript +export const connectWallet = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_requestAccounts", + }) + const obj = { + status: "👆🏽 Write a message in the text-field above.", + address: addressArray[0], + } + return obj + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + +

      + {" "} + 🦊 + You must install MetaMask, a virtual Ethereum wallet, in your + browser. + +

      +
      + ), + } + } +} +``` + +Vamos dividir o que este código faz: + +Primeiro, nossa função verifica se o `window.ethereum` está habilitado no seu navegador. + +`window.ethereum` é uma API global injetada pela MetaMask e outros provedores de carteira que permitem que sites solicitem contas Ethereum dos usuários. Se aprovada, ela pode ler dados das blockchains ao qual o usuário está conectado e sugerir que o usuário assine mensagens e transações. Confira a [documentação da MetaMask](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents) para obter mais informações! + +Se `window.ethereum` _não está_ presente, então isso significa que o MetaMask não está instalado. Isso resulta em um objeto JSON sendo retornado, onde o `endereço` retornado é uma string vazia, e o `status` do objeto JSX repassa que o usuário deve instalar o MetaMask. + +**A maioria das funções que escrevermos retornarão objetos JSON que podemos usar para atualizar nossas variáveis de estado e interface de usuário.** + +Agora se `window.ethereum` _estiver_ presente, e é aí que as coisas ficam interessantes. + +Usando um loop de try/catch, tentaremos nos conectar a MetaMask chamando`[window.ethereum.request({ method: "eth_requestAccounts" });](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts)`. Chamando esta função o MetaMask irá abrir no navegador, onde o usuário será solicitado a conectar sua carteira ao seu dapp. + +- Se o usuário escolher conectar-se, `método: "eth_requestAccounts"` retornará um array que contém todos os endereços de conta do usuário que estão conectados ao dapp. No total, nossa função `connectWallet` retornará um objeto JSON que contém o _primeiro_ `address` desta matriz \(ver linha 9\) e uma mensagem `status` que pede que o usuário escreva uma mensagem para o contrato inteligente. +- Se o usuário rejeitar a conexão, então o objeto JSON vai conter uma string vazia para o `address` retornado e uma mensagem de `status` que reflete que o usuário rejeitou a conexão. + +### Adicionar função connectWallet ao seu componente UI Minter.js {#add-connect-wallet} + +Agora que escrevemos esta função `connectWallet`, vamos conectá-la ao nosso componente `Minter.js.`. + +Primeiro, teremos que importar nossa função para o arquivo `Minter.js` adicionando `import { connectWallet } from "./utils/interact.js";` para o topo do arquivo `Minter.js`. Suas primeiras 11 linhas de `Minter.js` agora devem se parecer com isto: + +```javascript +import { useEffect, useState } from "react"; +import { connectWallet } from "./utils/interact.js"; + +const Minter = (props) => { + + //State variables + const [walletAddress, setWallet] = useState(""); + const [status, setStatus] = useState(""); + const [name, setName] = useState(""); + const [description, setDescription] = useState(""); + const [url, setURL] = useState(""); +``` + +Então, dentro da nossa função `connectWalletPressed`, vamos chamar nossa função importada `connectWallet`, assim: + +```javascript +const connectWalletPressed = async () => { + const walletResponse = await connectWallet() + setStatus(walletResponse.status) + setWallet(walletResponse.address) +} +``` + +Observe como a maior parte das nossas funcionalidades está abstraída do nosso componente `Minter.js` do arquivo `interact.js`? É assim que respeitamos o paradigma M-V-C! + +Em `connectWalletPressed`, simplesmente fazemos uma chamada de espera (await) para a função `connectWallet`, importada, e usando sua resposta, nós atualizaremos nossas variáveis `status` e `walletAddress` através de seus state hooks. + +Agora, vamos salvar os dois arquivos `Minter.js` e `interact.js` e testar nossa UI até agora. + +Abra seu navegador em localhost:3000, e pressione o botão "Conectar Carteira" no canto superior direito da página. + +Se você tiver o MetaMask instalado, você será solicitado a conectar sua carteira ao seu dapp. Aceite o convite para se conectar. + +Você verá que o botão da carteira agora reflete que seu endereço está conectado. + +Em seguida, tente atualizar a página... isso é estranho. Nosso botão de carteira está nos pedindo para conectar o MetaMask, mesmo que já esteja conectado... + +Mas não se preocupe! Nós podemos facilmente corrigir isso implementando uma função chamada `getCurrentWalletConnected`, que irá verificar se um endereço já está conectado ao nosso dapp e atualizará nossa interface do usuário adequadamente! + +### Função getCurrentWalletConnected {#get-current-wallet} + +Em seu arquivo `interact.js`, adicione a função`getCurrentWalletConnected`: + +```javascript +export const getCurrentWalletConnected = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_accounts", + }) + if (addressArray.length > 0) { + return { + address: addressArray[0], + status: "👆🏽 Write a message in the text-field above.", + } + } else { + return { + address: "", + status: "🦊 Connect to MetaMask using the top right button.", + } + } + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + +

      + {" "} + 🦊 + You must install MetaMask, a virtual Ethereum wallet, in your + browser. + +

      +
      + ), + } + } +} +``` + +Este código é _muito_ semelhante à função `connectWallet` que acabamos de escrever. + +A diferença principal é que, em vez de chamar o método `eth_requestAccounts`, que abre o MetaMask para o usuário conectar sua carteira, aqui chamamos o método `eth_accounts`, que simplesmente retorna uma matriz que contém os endereços MetaMask atualmente conectados ao nosso dapp. + +Para ver essa função em ação, vamos chamá-la na função `useEffect` do nosso componente `Minter.js`. + +Como fizemos para `connectWallet`, devemos importar essa função do nosso arquivo `interact.js` para o `Minter.js`, assim: + +```javascript +import { useEffect, useState } from "react" +import { + connectWallet, + getCurrentWalletConnected, //import here +} from "./utils/interact.js" +``` + +Agora, simplesmente a chamamos em nossa função `useEffect`: + +```javascript +useEffect(async () => { + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) +}, []) +``` + +Note que nós usamos a resposta da nossa chamada a `getCurrentWalletConnected` para atualizar nossa `walletAddress` e nossa variável de estado `status`. + +Depois de adicionar este código, tente atualizar a janela do navegador. O botão deve dizer que você está conectado e mostrar uma visualização do endereço de sua carteira conectada - mesmo depois de atualizar! + +### Implementar addWalletListener {#implement-add-wallet-listener} + +O passo final na configuração da nossa carteira dapp é implementar o ouvinte de carteira, para que nossa interface atualize quando o estado mudar, como quando o usuário desconecta ou troca de contas. + +No seu arquivo `Minter.js`, adicione a função `addWalletListener` que se parece com o seguinte: + +```javascript +function addWalletListener() { + if (window.ethereum) { + window.ethereum.on("accountsChanged", (accounts) => { + if (accounts.length > 0) { + setWallet(accounts[0]) + setStatus("👆🏽 Write a message in the text-field above.") + } else { + setWallet("") + setStatus("🦊 Connect to MetaMask using the top right button.") + } + }) + } else { + setStatus( +

      + {" "} + 🦊 + You must install MetaMask, a virtual Ethereum wallet, in your browser. + +

      + ) + } +} +``` + +Vamos dividir rapidamente o que está acontecendo aqui: + +- Primeiro, nossa função verifica se o `window.ethereum` está habilitado no seu navegador \(ex. MetaMask instalado\). + - Caso contrário, nós simplesmente configuramos a variável de estado `status` para uma JSX string que solicita o usuário instalar a MetaMask. + - Se estiver habilitado, configuramos o ouvinte `window.ethereum.on("accountsChanged")` na linha 3 que houve mudança de estado na carteira MetaMask, inclusive quando o usuário conecta uma conta adicional ao dapp, troca de conta ou desconecta uma conta. Se houver pelo menos uma conta conectada, a variável de estado `walletAddress` é atualizada como a primeira conta no array `accounts` retornada pelo ouvinte. Caso contrário, `walletAddress` é definida como uma string vazia. + +Finalmente, nós devemos chamá-la em nossa função `useEffect`: + +```javascript +useEffect(async () => { + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) + + addWalletListener() +}, []) +``` + +E Voila! Concluímos a programação de toda a funcionalidade da nossa carteira! Agora que a nossa carteira está pronta, vamos descobrir como mintar nossa NFT! + +## Metadados NFT 101 {#nft-metadata-101} + +Lembra dos metadados da NFT que acabamos de falar no Passo 0 deste tutorial - ele dá vida a uma NFT, permitindo que tenha propriedades, como um ativo digital, nome, descrição e outros atributos. + +Vamos precisar configurar esse metadado como um objeto JSON e amarzena-lo, para que possamos passa-lo como parâmetro `tokenURI` quando chamarmos a função `mintNFT` do nosso contrato inteligente. + +No campo texto "Link to Asset", "Name", "Description" inclui as diferentes propriedades dos metadados de nosso NFT. Nós vamos formatar estes metadados como um objeto JSON, mas há algumas opções para onde podemos armazenar este objeto JSON: + +- Poderíamos armazená-lo no blockchain Ethereum; no entanto, fazê-lo seria muito caro. +- Nós poderíamos armazená-lo em um servidor centralizado, como AWS ou Firebase. Mas isso iria contra nossa ética de descentralização. +- Poderíamos usar o IPFS, um protocolo descentralizado e uma rede peer-to-peer para armazenar e compartilhar dados em um sistema de arquivos distribuído. Como este protocolo é descentralizado e gratuito, essa é a melhor opção! + +Para armazenar nossos metadados no IPFS, vamos usar [Pinata](https://pinata.cloud/), uma conveniente API IPFS e um conjunto de ferramentas. Na próxima etapa, vamos explicar exatamente como fazer isso! + +## Use o Pinata para fixar seus metadados no IPFS {#use-pinata-to-pin-your-metadata-to-IPFS} + +Se você não tem uma conta no [Pinata](https://pinata.cloud/), cadastre-se [aqui](https://pinata.cloud/) gratuitamente e conclua as etapas de confirmação do seu e-mail e conta. + +### Crie sua chave API do Pinata {#create-pinata-api-key} + +Navegue para a página[https://pinata.cloud/keys](https://pinata.cloud/keys), então selecione o botão "New Key" no topo da página, defina o Admin widget como ativado, e nomeie sua chave. + +Será mostrado a você um pop-up com as informações da sua API. Certifique-se de colocar isto num lugar seguro. + +Agora que a nossa chave está configurada, vamos adicioná-la ao nosso projeto para que possamos usá-la. + +### Criar o arquivo .env {#create-a-env} + +Podemos armazenar com segurança nossa chave e segredo do Pinata em um arquivo de ambiente. Vamos instalar o [pacote dotenv](https://www.npmjs.com/package/dotenv) no diretório do seu projeto. + +Abra uma nova aba no seu terminal \(separado do terminal executando o local host\) e certifique-se de estar na pasta `minter-starter-files`, então execute o seguinte comando no seu terminal: + +```text +npm install dotenv --save +``` + +Em seguida, crie um arquivo `.env` no diretório raiz dos seus `minter-starter-files` inserindo o seguinte na sua linha de comando: + +```javascript +vim.env +``` + +Isto abrirá seu arquivo `.env` no formato vim \(um editor de texto\). Para salvar, aperte "esc" + ":" + "q" no seu teclado nesta ordem. + +Em seguida, no VSCode, navegue até o seu arquivo `.env` e adicione sua chave de API Pinata e sua API secreta, assim: + +```text +REACT_APP_PINATA_KEY = +REACT_APP_PINATA_SECRET = +``` + +Salve o arquivo e então você estará pronto para começar a escrever a função de enviar seus metadados JSON para IPFS! + +### Implementar pinJSONToIPFS {#pin-json-to-ipfs} + +Felizmente para nós, a Pinata tem uma API [especificamente para carregar dados JSON para o IPFS](https://pinata.cloud/documentation#PinJSONToIPFS) e um JavaScript conveniente com axios de exemplo que podemos usar, com algumas pequenas modificações. + +Na sua pasta `utils`, vamos criar outro arquivo chamado `pinata.js` e então importar nossa chave Pinata do arquivo .env assim: + +```javascript +require("dotenv").config() +const key = process.env.REACT_APP_PINATA_KEY +const secret = process.env.REACT_APP_PINATA_SECRET +``` + +Em seguida, cole o código adicional abaixo no seu arquivo `pinata.js`. Não se preocupe, nós iremos clarificar o que tudo isso significa! + +```javascript +require("dotenv").config() +const key = process.env.REACT_APP_PINATA_KEY +const secret = process.env.REACT_APP_PINATA_SECRET + +const axios = require("axios") + +export const pinJSONToIPFS = async (JSONBody) => { + const url = `https://api.pinata.cloud/pinning/pinJSONToIPFS` + //making axios POST request to Pinata ⬇️ + return axios + .post(url, JSONBody, { + headers: { + pinata_api_key: key, + pinata_secret_api_key: secret, + }, + }) + .then(function (response) { + return { + success: true, + pinataUrl: + "https://gateway.pinata.cloud/ipfs/" + response.data.IpfsHash, + } + }) + .catch(function (error) { + console.log(error) + return { + success: false, + message: error.message, + } + }) +} +``` + +Então, o que esse código faz exatamente? + +Primeiro, importa [axios](https://www.npmjs.com/package/axios), a um cliente HTTP baseado em promessas para o navegador e node.js, que utilizaremos para fazer um pedido a Pinata. + +Em seguida, temos nossa função assíncrona `pinJSONToIPFS`, que recebe um `JSONBody` como sua entrada e a chave e senha do API Pinata em seu cabeçalho, tudo para fazer uma solicitação POST para sua API `pinJSONToIPFS`. + +- Se esta solicitação POST for bem sucedida, então nossa função retorna um objeto JSON com o valor booleano `sucess` como verdadeiro e a `pinataUrl` onde nossos metadados foram fixados. Nós usaremos a `pinataUrl` retornada, como entrada na `tokenURI` para a função mint do nosso contrato inteligente. +- Se esta solicitação POST falhar, então, nossa função retorna um objeto JSON com o booleano `success` como falso e uma `message` que transmite nosso erro. + +Assim como na nossa função `connectWallet`retorna tipos, estamos retornando objetos JSON para que possamos usar seus parâmetros para atualizar nossas variáveis de estado e nossa interface de usuário. + +## Carregar seu contrato inteligente {#load-your-smart-contract} + +Agora que temos uma maneira de enviar nossos metadados NFT para IPFS através de nossa função de `pinJSONToIPFS`, vamos precisar de uma forma de carregar uma instância do nosso contrato inteligente para que possamos chamar a função `mintNFT`. + +Como mencionado anteriormente, neste tutorial usaremos [este é um contrato inteligente NFT existente](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE); no entanto, se você quer aprender como o fizemos ou como fazer um você mesmo, é altamente recomendável que você confira nosso outro tutorial, ["Como criar uma NFT.](https://docs.alchemyapi.io/alchemy/tutorials/how-to-create-an-nft). + +### O contrato ABI {#contract-abi} + +Se você examinar de perto nossos arquivos, você notará que no nosso diretório `src`, há um arquivo `contract-abi.json`. Um ABI é necessário para especificar qual função um contrato irá invocar, como também garantir que a função retornará dados no formato que você espera. + +Também precisaremos de uma chave API Alchemy e da API Alchemy Web3 para conectar ao blockchain Ethereum e carregar o nosso contrato inteligente. + +### Crie a sua chave API Alchemy {#create-alchemy-api} + +Se ainda não tiver uma conta na Alchemy, você pode se cadastrar gratuitamente [neste link](https://alchemy.com/?a=eth-org-nft-minter) + +Assim que criar uma conta na Alchemy, você pode gerar uma chave de API criando um "app". Isso nos permitirá fazer solicitações à rede de testes Ropsten. + +Navegue até a pagina "Create App" no seu "Dashboard da Alchemy", passe o cursor sob "Apps" na barra de navegação e clique em “Create App”. + +Nomeie seu aplicativo; nós escolhemos "Minha primeira NFT!", faça uma breve descrição, selecione "Staging" para o ambiente (usado para a contabilidade do seu ‘app’) e escolha "Ropsten" para sua rede. + +Clique em "Create App", e é isso e tudo! Seu app deveria aparecer na tabela abaixo. + +Incrível agora que criamos a nossa URL de API Alchemy HTTP, copie-a para a sua área de transferência... + +…e então vamos adicioná-lo ao nosso arquivo `.env`. Ao todo, seu arquivo .env deve se parecer com isto: + +```text +REACT_APP_PINATA_KEY = +REACT_APP_PINATA_SECRET = +REACT_APP_ALCHEMY_KEY = https://eth-ropsten.alchemyapi.io/v2/ +``` + +Agora que temos nosso contrato ABI e nossa chave API do Alchemy, estamos prontos para carregar o nosso contrato inteligente usando [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3). + +### Configure seu Alchemy Web3 endpoint e contrato {#setup-alchemy-endpoint} + +Primeiro, se você ainda não tiver, você precisará instalar [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) navegando até o diretório home: `nft-minter-tutorial` no terminal: + +```text +cd .. +yarn add @alch/alchemy-web3 +``` + +Em seguida, voltaremos para o nosso arquivo `interact.js`. No topo do arquivo, adicione o seguinte código para importar a chave de Alchemy do seu arquivo .env e configure seu Alchemy Web3 endpoint: + +```javascript +require("dotenv").config() +const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(alchemyKey) +``` + +[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) é um invólucro em torno do [Web3.js](https://docs.web3js.org/), fornecendo métodos aprimorados da API e outros benefícios cruciais para tornar a sua vida de desenvolvedor da Web3 mais fácil. Ele foi projetado para exigir uma configuração mínima, para que você possa começar a usá-la no seu aplicativo imediatamente! + +Em seguida, vamos adicionar nosso contrato ABI e endereço do contrato ao nosso arquivo. + +```javascript +require("dotenv").config() +const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(alchemyKey) + +const contractABI = require("../contract-abi.json") +const contractAddress = "0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE" +``` + +Assim que tivermos ambas as coisas, estaremos prontos para começar a codificar a nossa função "mint"! + +## Implementar a função mintNFT {#implement-the-mintnft-function} + +Dentro do seu arquivo `interact.js`, vamos definir nossa função, `mintNFT`, que deliberadamente vai criar nossa NFT. + +Porque vamos fazer numerosas chamadas assíncronas \(para o Pinata fixar nossos metadados para IPFS, Alchemy Web3 para carregar o nosso contrato inteligente, e MetaMask para assinar nossas transações\), nossa função também será assíncrona. + +As três entradas para nossa função serão a `url` do nosso ativo digital, `name`e `description`. Adicione a seguinte assinatura da função abaixo da função `connectWallet`: + +```javascript +export const mintNFT = async (url, name, description) => {} +``` + +### Manipulação de erros de script {#input-error-handling} + +Naturalmente, faz sentido ter algum tipo de tratamento de erro de entrada no início da função, então vamos sair desta função se nossos parâmetros de entrada não estiverem corretos. Dentro da nossa função, vamos adicionar o seguinte código: + +```javascript +export const mintNFT = async (url, name, description) => { + //error handling + if (url.trim() == "" || name.trim() == "" || description.trim() == "") { + return { + success: false, + status: "❗Please make sure all fields are completed before minting.", + } + } +} +``` + +Essencialmente, se algum dos parâmetros de entrada for uma string vazia, então retornamos um objeto JSON onde o valor booleano `success` é falso, e a string `status` repassa que todos os campos na nossa UI precisam estar completos. + +### Carregar os metadados para o IPFS {#upload-metadata-to-ipfs} + +Assim que soubermos que nossos metadados estão formatados corretamente, o próximo passo é envolvê-lo em um objeto JSON e enviá-lo para IPFS através do `pinJSONToIPFS` que escrevemos! + +Para fazer isso, precisamos primeiro importar a função `pinJSONToIPFS` para nosso arquivo `interact.js`. No topo do `interact.js`, vamos adicionar: + +```javascript +import { pinJSONToIPFS } from "./pinata.js" +``` + +Lembre-se que `pinJSONToIPFS` recebe um corpo JSON. Então, antes de fazer a chamada, precisaremos formatar a nossa `url`, `name`e `description` parâmetros em um objeto JSON. + +Vamos atualizar nosso código para criar um objeto JSON chamado `metadada` e então fazer uma chamada para `pinJSONToIPFS` com este parâmetro `metadada`: + +```javascript +export const mintNFT = async (url, name, description) => { + //error handling + if (url.trim() == "" || name.trim() == "" || description.trim() == "") { + return { + success: false, + status: "❗Please make sure all fields are completed before minting.", + } + } + + //make metadata + const metadata = new Object() + metadata.name = name + metadata.image = url + metadata.description = description + + //make pinata call + const pinataResponse = await pinJSONToIPFS(metadata) + if (!pinataResponse.success) { + return { + success: false, + status: "😢 Something went wrong while uploading your tokenURI.", + } + } + const tokenURI = pinataResponse.pinataUrl +} +``` + +Note, nós armazenamos a resposta de nossa chamada para `pinJSONToIPFS(metadada)` no objeto `pinataResponse`. Então, analisamos esse objeto para quaisquer erros. + +Se houver um erro, nós retornamos um objeto JSON onde o `sucess` booleano é falso e nossa string `status` relata que nossa chamada falhou. Caso contrário, nós extraímos a `pinataURL` da `pinataResponse` e armazenamos como nossa variável `tokenURI`. + +Agora é hora de carregar o nosso contrato inteligente usando a API da Alchemy Web3 que inicializamos no topo do nosso arquivo. Adicione a seguinte linha de código na parte inferior da função `mintNFT` para definir o contrato na `window.contract` variável global: + +```javascript +window.contract = await new web3.eth.Contract(contractABI, contractAddress) +``` + +A última coisa a adicionar em nossa função `mintNFT` é a nossa transação Ethereum: + +```javascript +//set up your Ethereum transaction +const transactionParameters = { + to: contractAddress, // Required except during contract publications. + from: window.ethereum.selectedAddress, // must match user's active address. + data: window.contract.methods + .mintNFT(window.ethereum.selectedAddress, tokenURI) + .encodeABI(), //make call to NFT smart contract +} + +//sign the transaction via MetaMask +try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + success: true, + status: + "✅ Check out your transaction on Etherscan: https://ropsten.etherscan.io/tx/" + + txHash, + } +} catch (error) { + return { + success: false, + status: "😥 Something went wrong: " + error.message, + } +} +``` + +Se você já está familiarizado com as transações na Ethereum, perceberá que a estrutura é bem parecida com a que você já viu. + +- Primeiro, nós configuramos nossos parâmetros de transações. + - `to` especificar o endereço do destinatário \(nosso contrato inteligente\) + - `from` especifica o signatário da transação \(o endereço conectado ao MetaMask: `window.ethereum.selectedAddress`\) + - `data` contém a chamada para nosso contrato inteligente do método `mintNFT`, que recebe nossa `tokenURI` e o endereço da carteira do usuário, `window.ethereum.selectedAddress` como entradas +- Então, faremos uma chamada para, `window.ethereum.request,` onde pedimos ao MetaMask para assinar a transação. Note que nessa solicitação, estamos especificando nosso método eth \(eth_SentTransaction\) e passando em nossos `transactionParameters`. Neste ponto, a MetaMask irá abrir no navegador e pedirá que o usuário assine ou rejeite a transação. + - Se a transação for bem-sucedida, a função retornará um objeto JSON onde o booleano `success` é definido como verdadeiro e a string `status` pede que o usuário verifique o Etherscan para obter mais informações sobre sua transação. + - Se a transação falhar, a função retornará um objeto JSON onde o booleano `success` é definido como falso, `status` string retransmite a mensagem de erro. + +Ao todo, nossa função `mintNFT` deve-se parecer com isto: + +```javascript +export const mintNFT = async (url, name, description) => { + //error handling + if (url.trim() == "" || name.trim() == "" || description.trim() == "") { + return { + success: false, + status: "❗Please make sure all fields are completed before minting.", + } + } + + //make metadata + const metadata = new Object() + metadata.name = name + metadata.image = url + metadata.description = description + + //pinata pin request + const pinataResponse = await pinJSONToIPFS(metadata) + if (!pinataResponse.success) { + return { + success: false, + status: "😢 Something went wrong while uploading your tokenURI.", + } + } + const tokenURI = pinataResponse.pinataUrl + + //load smart contract + window.contract = await new web3.eth.Contract(contractABI, contractAddress) //loadContract(); + + //set up your Ethereum transaction + const transactionParameters = { + to: contractAddress, // Required except during contract publications. + from: window.ethereum.selectedAddress, // must match user's active address. + data: window.contract.methods + .mintNFT(window.ethereum.selectedAddress, tokenURI) + .encodeABI(), //make call to NFT smart contract + } + + //sign transaction via MetaMask + try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + success: true, + status: + "✅ Check out your transaction on Etherscan: https://ropsten.etherscan.io/tx/" + + txHash, + } + } catch (error) { + return { + success: false, + status: "😥 Something went wrong: " + error.message, + } + } +} +``` + +Essa é uma função gigante! Agora, só precisamos conectar nossa função `mintNFT` com nosso componente `Minter.js`... + +## Conectando mintNFT ao nosso frontend Minter.js {#connect-our-frontend} + +Abra o seu arquivo `Minter.js` e atualize `import { connectWallet, getCurrentWalletConnected } from "./utils/interact.js";` a linha em cima deve ser: + +```javascript +import { + connectWallet, + getCurrentWalletConnected, + mintNFT, +} from "./utils/interact.js" +``` + +Finalmente, implemente a função `onMintPressed` para fazer a chamada(await call) para a função `mintNFT`importada e atualize a variável de estado `status` para refletir se nossa transação foi bem-sucedida ou falhou: + +```javascript +const onMintPressed = async () => { + const { status } = await mintNFT(url, name, description) + setStatus(status) +} +``` + +## Implante seu NFT a um site ao vivo {#deploy-your-NFT} + +Pronto para deixar seu projeto ao vivo para que usuários interajam? Confira [este tutorial](https://docs.alchemy.com/alchemy/tutorials/nft-minter/how-do-i-deploy-nfts-online) para implantar seu Minter em um site ao vivo. + +Um último passo... + +## Leve o mundo blockchain numa enxurrada {#take-the-blockchain-world-by-storm} + +Só uma brincadeira, você chegou ao fim do tutorial! + +Para recapitular, construindo um minter NFT, você aprendeu com sucesso como: + +- Conectar ao MetaMask através do seu projeto frontend +- Chamar métodos de contrato inteligentes no seu frontend +- Assine transações usando MetaMask + +Provavelmente você gostaria de poder exibir seu NFT na sua carteira — então certifique-se de conferir [ a parte Como ver seu NFT na sua carteira](https://docs.alchemyapi.io/alchemy/tutorials/how-to-write-and-deploy-a-nft-smart-contract/how-to-view-your-nft-in-your-wallet)! + +E, como sempre, se você tiver alguma dúvida, estamos aqui para ajudar no [Alchemy Discord](https://discord.gg/gWuC7zB). Mal podemos esperar para ver como você aplicará os conceitos deste tutorial em seus projetos futuros! diff --git a/public/content/translations/pt-br/developers/tutorials/optimism-std-bridge-annotated-code/index.md b/public/content/translations/pt-br/developers/tutorials/optimism-std-bridge-annotated-code/index.md new file mode 100644 index 00000000000..4eb6f676681 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/optimism-std-bridge-annotated-code/index.md @@ -0,0 +1,1277 @@ +--- +title: "Passo a passo do contrato de ponte padrão da Optimism" +description: Como funciona a ponte padrão para a Optimism? Porque funciona desta maneira? +author: Ori Pomerantz +tags: + - "solidity" + - "ponte" + - "camada 2" +skill: intermediate +published: 2022-03-30 +lang: pt-br +--- + +[Optimism](https://www.optimism.io/) é uma [ Optimistic Rollup](/developers/docs/scaling/optimistic-rollups/). Optimistic rollups podem processar transações por um preço muito inferior ao Ethereum Mainnet (também conhecido como layer 1 ou L1) porque as transações são processadas apenas por alguns nós, em vez de cada nó na rede. Ao mesmo tempo, os dados são todos escritos em L1, de modo que tudo pode ser provado e reconstruído com todas as garantias de integridade e disponibilidade da rede principal. + +Para usar ativos L1 na Optimism (ou qualquer outra L2), os ativos precisam ser [enviados pela ponte](/bridges/#prerequisites). Uma maneira de conseguir isso é os usuários bloquearem ativos (ETH e [tokens ERC-20](/developers/docs/standards/tokens/erc-20/) são os mais comuns) na L1, e receber ativos equivalentes para usar na L2. Por fim, quem for que acabe com eles, talvez queira enviá-los de volta para a L1. Ao fazer isso, os ativos são queimados na L2 e, em seguida, liberados para o usuário na L1. + +É assim que a [ponte padrão Optimism](https://community.optimism.io/docs/developers/bridge/standard-bridge) funciona. Neste artigo, passamos pelo código-fonte para essa ponte para ver como ele funciona e estudá-lo como um exemplo de código Solidity bem escrito. + +## Fluxo de controle {#control-flows} + +A ponte tem dois fluxos principais: + +- Depósito (de L1 a L2) +- Saque de (L2 para L1) + +### Fluxo de depósitos {#deposit-flow} + +#### Camada 1 {#deposit-flow-layer-1} + +1. Se depositar um ERC-20, o depositante dá à ponte uma permissão para gastar o valor que está sendo depositado +2. O depositor chama a ponte L1(`depositERC20`, `depositERC20To`, `depositETH`, ou `depositETHTo`) +3. A ponte L1 toma posse do ativo que está na ponte + - ETH: O ativo é transferido pelo depositante como parte da chamada + - ERC-20: O ativo é transferido pela ponte para si mesmo usando a permissão fornecida pelo depositante +4. A ponte L1 usa o mecanismo de mensagem entre domínios para chamar `finalizeDeposit` na ponte L2 + +#### Camada 2 {#deposit-flow-layer-2} + +5. A ponte L2 verifica que a chamada do `finalizeDeposit` é legítima: + - Se veio do contrato de mensagem entre domínios + - Era originalmente da ponte em L1 +6. A ponte L2 checa se o contrato do token ERC-20 na L2 é o correto: + - O contrato L2 reporta que sua contraparte L1 é a mesma de onde vieram os tokens da L1 + - O contrato L2 reporta que suporta a interface correta ([usando ERC-165](https://eips.ethereum.org/EIPS/eip-165)). +7. Se o contrato L2 é o correto, chame-o para cunhar o número apropriado de tokens para o endereço apropriado. Se não, comece o processo de retirada para permitir o usuário reclamar os tokens no L1. + +### Fluxo de retirada {#withdrawal-flow} + +#### Camada 2 {#withdrawl-flow-layer-2} + +1. O sacador chama a ponte L2 (`withdraw` ou `withdrawTo`) +2. A ponte L2 queima o número apropriado de tokens pertencentes a `msg.sender` +3. A ponte L2 usa o mecanismo de mensagens entre domínios para chamar `finalizeETHWithdrawal` ou `finalizeERC20Withdrawal` na ponte L1 + +#### Camada 1 {#withdrawl-flow-layer-1} + +4. A ponte L1 verifica a chamada a `finalizeETHWithdrawal` ou `finalizeERC20Withdrawal` é legitima: + - Veio de um mecanismo de mensagens entre domínios + - Foi originada da ponte no L2 +5. A ponte L1 transfere o ativo apropriado (ETH ou ERC-20) para o endereço apropriado + +## Código Camada 1 {#layer-1-code} + +Este é o código que roda na L1, a Rede Principal do Ethereum. + +### IL1ERC20Bridge {#IL1ERC20Bridge} + +[Esta interface é definida aqui](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1ERC20Bridge.sol). Ela inclui funções e definições exigidas para realizar a ponte de tokens ERC-20. + +```solidity +// SPDX-License-Identifier: MIT +``` + +[Maioria do código da Optimism é lançada sob a licença MIT](https://help.optimism.io/hc/en-us/articles/4411908707995-What-software-license-does-Optimism-use-). + +```solidity +pragma solidity >0.5.0 <0.9.0; +``` + +Neste momento, a última versão do Solidity é 0.8.12. Até versão 0.9.0 ser lançada, nós não sabemos se este código é compatível com ele ou não. + +```solidity +/** + * @title IL1ERC20Bridge + */ +interface IL1ERC20Bridge { + /********** + * Events * + **********/ + + event ERC20DepositInitiated( +``` + +Na terminologia de ponte Optimism _deposit_ significa transferência de L2 para L2, e _withdrawal_ significa uma transferência de L2 para L1. + +```solidity + address indexed _l1Token, + address indexed _l2Token, +``` + +Na maioria dos casos o endereço de um ERC-20 na L1 não é o mesmo endereço do equivalente ERC-20 na L2. [Você pode ver a lista de endereços de tokens aqui](https://static.optimism.io/optimism.tokenlist.json). O endereço com `chainId` 1 está na L1 (Mainnet) e o endereço com `chainId` 10 está na L2 (Optimism). Os outros dois valores `chainId` são para a rede de testes Kovan (42) e a rede de testes Optimistic Kovan (69). + +```solidity + address indexed _from, + address _to, + uint256 _amount, + bytes _data + ); +``` + +É possível adicionar notas para transferências, caso no qual elas são adicionadas para os eventos que as reportam. + +```solidity + event ERC20WithdrawalFinalized( + address indexed _l1Token, + address indexed _l2Token, + address indexed _from, + address _to, + uint256 _amount, + bytes _data + ); +``` + +O mesmo contrato de ponte manipula transferências em ambas as direções. No caso da ponte L1, isto significa inicialização de depósitos e finalização de retiradas. + +```solidity + + /******************** + * Public Functions * + ********************/ + + /** + * @dev get the address of the corresponding L2 bridge contract. + * @return Address of the corresponding L2 bridge contract. + */ + function l2TokenBridge() external returns (address); +``` + +Esta função não é realmente necessária, porque na L2 ela é um contrato pré-implantado, então ela está sempre no endereço `0x4200000000000000000000000000000000000010`. Ela está aqui por simetria com a ponte L2, porque o endereço da ponte L1 _não_ é trivial de saber. + +```solidity + /** + * @dev deposit an amount of the ERC20 to the caller's balance on L2. + * @param _l1Token Address of the L1 ERC20 we are depositing + * @param _l2Token Address of the L1 respective L2 ERC20 + * @param _amount Amount of the ERC20 to deposit + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function depositERC20( + address _l1Token, + address _l2Token, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) external; +``` + +O parâmetro `_l2Gas` é a quantidade de gas L2 que a transação tem permissão de gastar. [Até um certo (alto) limite, isto é grátis](https://community.optimism.io/docs/developers/bridge/messaging/#for-l1-%E2%87%92-l2-transactions-2), portanto a menos que o contrato ERC-20 faça algo realmente estranho quando cunhando, isto não deveria ser um problema. Esta função cuida do cenário comum, onde um usuário faz a ponte dos ativos para o mesmo endereço em uma blockchain diferente. + +```solidity + /** + * @dev deposit an amount of ERC20 to a recipient's balance on L2. + * @param _l1Token Address of the L1 ERC20 we are depositing + * @param _l2Token Address of the L1 respective L2 ERC20 + * @param _to L2 address to credit the withdrawal to. + * @param _amount Amount of the ERC20 to deposit. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function depositERC20To( + address _l1Token, + address _l2Token, + address _to, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) external; +``` + +Esta função é quase idêntica a `depositERC20`, mas ela deixa você enviar o ERC-20 para diferentes endereços. + +```solidity + /************************* + * Cross-chain Functions * + *************************/ + + /** + * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the + * L1 ERC20 token. + * This call will fail if the initialized withdrawal from L2 has not been finalized. + * + * @param _l1Token Address of L1 token to finalizeWithdrawal for. + * @param _l2Token Address of L2 token where withdrawal was initiated. + * @param _from L2 address initiating the transfer. + * @param _to L1 address to credit the withdrawal to. + * @param _amount Amount of the ERC20 to deposit. + * @param _data Data provided by the sender on L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function finalizeERC20Withdrawal( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external; +} +``` + +Saques (e outras mensagens de L2 para L1) na Optimism é um processo em duas etapas: + +1. Uma transação inicial no L2. +2. Uma transação de finalização ou de reclamação na L1. Esta transação precisa acontecer depois do [período de desafio de falha](https://community.optimism.io/docs/how-optimism-works/#fault-proofs) para a transação L2 terminar. + +### IL1StandardBridge {#il1standardbridge} + +[Esta interface é definida aqui](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1StandardBridge.sol). Este arquivo contém definições de evento e função para ETH. Estas definições são muito similares com aquelas definidas em `IL1ERC20Bridge` acima para ERC-20. + +A ponte interface é dividida entre dois arquivos, porque alguns tokens ERC-20 requerem processamento customizado e não podem ser manipulados pela ponte padrão. Dessa maneira a ponte customizada que manipula este token pode implementar `IL1ERC20Bridge` e não ter que também fazer a ponte ETH. + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +import "./IL1ERC20Bridge.sol"; + +/** + * @title IL1StandardBridge + */ +interface IL1StandardBridge is IL1ERC20Bridge { + /********** + * Events * + **********/ + event ETHDepositInitiated( + address indexed _from, + address indexed _to, + uint256 _amount, + bytes _data + ); +``` + +Este evento é praticamente idêntico à versão ERC-20 (`ERC20DepositInitiated`), exceto por não ter os endereços de token L1 e L2. O mesmo é verdade para outros eventos e funções. + +```solidity + event ETHWithdrawalFinalized( + . + . + . + ); + + /******************** + * Public Functions * + ********************/ + + /** + * @dev Deposit an amount of the ETH to the caller's balance on L2. + . + . + . + */ + function depositETH(uint32 _l2Gas, bytes calldata _data) external payable; + + /** + * @dev Deposit an amount of ETH to a recipient's balance on L2. + . + . + . + */ + function depositETHTo( + address _to, + uint32 _l2Gas, + bytes calldata _data + ) external payable; + + /************************* + * Cross-chain Functions * + *************************/ + + /** + * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the + * L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called + * before the withdrawal is finalized. + . + . + . + */ + function finalizeETHWithdrawal( + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external; +} +``` + +### CrossDomainEnabled {#crossdomainenabled} + +[Este contrato](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/bridge/CrossDomainEnabled.sol) é herdado por ambas pontes ([L1](#the-l1-bridge-contract) e [L2](#the-l2-bridge-contract)) para enviar mensagens para a outra camada. + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +/* Interface Imports */ +import { ICrossDomainMessenger } from "./ICrossDomainMessenger.sol"; +``` + +[Esta interface](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/bridge/ICrossDomainMessenger.sol) mostra ao contrato como enviar mensagens para a outra camada, usando o mensageiro entre domínios. Este mensageiro entre domínios é todo um outro sistema, e merece um artigo próprio, que espero escrever no futuro. + +```solidity +/** + * @title CrossDomainEnabled + * @dev Helper contract for contracts performing cross-domain communications + * + * Compiler used: defined by inheriting contract + */ +contract CrossDomainEnabled { + /************* + * Variables * + *************/ + + // Messenger contract used to send and receive messages from the other domain. + address public messenger; + + /*************** + * Constructor * + ***************/ + + /** + * @param _messenger Address of the CrossDomainMessenger on the current layer. + */ + constructor(address _messenger) { + messenger = _messenger; + } +``` + +O único parâmetro que o contrato precisa saber é o endereço do mensageiro entre domínios nessa camada. Este parâmetro é configurado uma vez, no construtor, e nunca muda. + +```solidity + + /********************** + * Function Modifiers * + **********************/ + + /** + * Enforces that the modified function is only callable by a specific cross-domain account. + * @param _sourceDomainAccount The only account on the originating domain which is + * authenticated to call this function. + */ + modifier onlyFromCrossDomainAccount(address _sourceDomainAccount) { +``` + +O mensageiro entre domínios é acessível por qualquer contrato na blockchain onde estiver rodando (seja Ethereum mainnet ou Optimism). Mas nós precisamos da ponte em cada lado para _apenas_ confiar em certas mensagens se eles vierem da ponte do outro lado. + +```solidity + require( + msg.sender == address(getCrossDomainMessenger()), + "OVM_XCHAIN: messenger contract unauthenticated" + ); +``` + +Somente mensagens do mensageiro entre domínios apropriado (`messenger`, como você vê abaixo) pode ser confiado. + +```solidity + + require( + getCrossDomainMessenger().xDomainMessageSender() == _sourceDomainAccount, + "OVM_XCHAIN: wrong sender of cross-domain message" + ); +``` + +A maneira que o mensageiro entre domínios fornece o endereço que enviou uma mensagem com a outra camada é [a função `.xDomainMessageSender()`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/L1CrossDomainMessenger.sol#L122-L128). Enquanto ele for chamado na transação que foi iniciada pela mensagem, ele pode fornecer esta informação. + +Nós precisamos nos certificar que a mensagem que nós recebemos veio da outra ponte. + +```solidity + + _; + } + + /********************** + * Internal Functions * + **********************/ + + /** + * Gets the messenger, usually from storage. This function is exposed in case a child contract + * needs to override. + * @return The address of the cross-domain messenger contract which should be used. + */ + function getCrossDomainMessenger() internal virtual returns (ICrossDomainMessenger) { + return ICrossDomainMessenger(messenger); + } +``` + +Esta função retorna o mensageiro entre domínios. Nós usamos uma função ao invés da variável `messenger` para permitir contratos que herdam deste para usar um algoritmo para especificar qual mensageiro entre domínios usar. + +```solidity + + /** + * Sends a message to an account on another domain + * @param _crossDomainTarget The intended recipient on the destination domain + * @param _message The data to send to the target (usually calldata to a function with + * `onlyFromCrossDomainAccount()`) + * @param _gasLimit The gasLimit for the receipt of the message on the target domain. + */ + function sendCrossDomainMessage( + address _crossDomainTarget, + uint32 _gasLimit, + bytes memory _message +``` + +Finalmente, a função que envia a mensagem para a outra camada. + +```solidity + ) internal { + // slither-disable-next-line reentrancy-events, reentrancy-benign +``` + +[Slither](https://github.com/crytic/slither)é um analisador estático que a Optimism roda em cada contrato para procurar por vulnerabilidades e outros problemas em potencial. Nesse caso, as seguintes linhas disparam duas vulnerabilidades: + +1. [Eventos de reentrância](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3) +2. [Reentrância Benigna](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2) + +```solidity + getCrossDomainMessenger().sendMessage(_crossDomainTarget, _message, _gasLimit); + } +} +``` + +Neste caso nós não estamos preocupados sobre reentrância. Nós sabemos que `getCrossDomainMessenger()` returna um endereço confiável, mesmo se Slither não tem como saber isso. + +### O contrato da ponte L1 {#the-l1-bridge-contract} + +[O código-fonte para este contrato está aqui](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/L1StandardBridge.sol). + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; +``` + +A interface pode ser parte de outros contratos, então eles têm de suportar uma larga faixa de versões de Solidity. Mas a ponte por ela mesma é o nosso contrato, e nós podemos ser estritos sobre qual versão Solidity ela usa. + +```solidity +/* Interface Imports */ +import { IL1StandardBridge } from "./IL1StandardBridge.sol"; +import { IL1ERC20Bridge } from "./IL1ERC20Bridge.sol"; +``` + +[IL1ERC20Bridge](#IL1ERC20Bridge) e [IL1StandardBridge](#IL1StandardBridge) são explicados acima. + +```solidity +import { IL2ERC20Bridge } from "../../L2/messaging/IL2ERC20Bridge.sol"; +``` + +[Esta interface](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) nos deixa criar mensagens para controlar a ponte padrão em L2. + +```solidity +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +``` + +[Esta interface](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) nos deixa controlar contratos ERC-20. [Você pode ler mais sobre ela aqui](/developers/tutorials/erc20-annotated-code/#the-interface). + +```solidity +/* Library Imports */ +import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; +``` + +[Como explicado acima](#crossdomainenabled), este contrato é usado para mensageria entre camadas. + +```solidity +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; +``` + +[`Lib_PredeployAddresses`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/constants/Lib_PredeployAddresses.sol) tem os endereços dos contratos L2 que sempre tem o mesmo endereço. Isto inclui a ponte padrão em L2. + +```solidity +import { Address } from "@openzeppelin/contracts/utils/Address.sol"; +``` + +[Utilitários de endereços OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol). Ele é usado para distinguir entre endereços de contrato e aqueles pertencentes a contas de propriedade externa (EOA). + +Note que isto não é a solução perfeita, porque não há como distinguir entre chamadas diretas e chamadas feitas de um construtor de contrato, mas pelo menos isto nos deixa identificar e evitar alguns erros comuns de usuário. + +```solidity +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +``` + +[O padrão ERC-20 ](https://eips.ethereum.org/EIPS/eip-20) suporta duas maneiras para um contrato reportar falha: + +1. Revert +2. Return `false` + +Gerenciar ambos casos faria nosso código mais complicado, então ao invés disso, usamos [OpenZeppelin `SafeERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol), que garante [ que todas as falhas resultem num revert](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol#L96). + +```solidity +/** + * @title L1StandardBridge + * @dev The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard + * tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits + * and listening to it for newly finalized withdrawals. + * + */ +contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { + using SafeERC20 for IERC20; +``` + +Esta linha é como especificamos para usar o wrapper `SafeERC20` cada vez que nós usamos a interface `IERC20`. + +```solidity + + /******************************** + * External Contract References * + ********************************/ + + address public l2TokenBridge; +``` + +O endereço de [L2StandardBridge](#the-l2-bridge-contract). + +```solidity + + // Maps L1 token to L2 token to balance of the L1 token deposited + mapping(address => mapping(address => uint256)) public deposits; +``` + +Um [mapeamento](https://www.tutorialspoint.com/solidity/solidity_mappings.htm) em dobro como este é a maneira de você definir uma [array esparsa bi-dimensional](https://en.wikipedia.org/wiki/Sparse_matrix). Valores nesta estrutura de dados são identificados como `deposit[L1 token addr][L2 token addr]`. O valor padrão é zero. Somente células que são configuradas para um valor diferente são escritas no storage. + +```solidity + + /*************** + * Constructor * + ***************/ + + // This contract lives behind a proxy, so the constructor parameters will go unused. + constructor() CrossDomainEnabled(address(0)) {} +``` + +Para querer ser capaz de atualizar este contrato sem ter que copiar todas as variáveis no storage. Para fazer isso, nós usamos um [`Proxy`](https://docs.openzeppelin.com/contracts/3.x/api/proxy), um contrato que usa [`delegatecall`](https://solidity-by-example.org/delegatecall/) para transferir chamadas para um contato separado cujo endereço é armazenado pelo contrato proxy (quando você atualiza, você diz ao proxy para mudar o endereço). Quando você usa `delegatecall` o storage permanece com o valor do contrato _chamador_, então os valores de todas as variáveis de estado do contrato não são afetadas. + +Um efeito deste padrão é que o storage do contrato que é _chamado_ pelo `delegatecall` não é usado, e portanto os valores do construtor passados para ele não importam. Esta é a razão pela qual nós podemos fornecer um valor sem sentido para o construtor `CrossDomainEnabled`. É também a razão que a inicialização abaixo é separada do construtor. + +```solidity + /****************** + * Initialization * + ******************/ + + /** + * @param _l1messenger L1 Messenger address being used for cross-chain communications. + * @param _l2TokenBridge L2 standard bridge address. + */ + // slither-disable-next-line external-function +``` + +Este [teste Slither](https://github.com/crytic/slither/wiki/Detector-Documentation#public-function-that-could-be-declared-external) identifica funções que não são chamadas do código do contrato e poderiam portanto serem declaradas `external` ao invés de `public`. As funções de custo de gas `external` podem ser menores, porque elas podem ser fornecidas com parâmetros no calldata. Funções declaradas `public` têm de ser acessíveis de dentro do contrato. Contratos não podem modificar seus próprios calldata, então os parâmetros têm que estar na memória. Quando esta função é chamada externamente, é necessário copiar o calldata para a memória, que custa gas. Nesse caso a função é chamada somente uma vez, então a ineficiência não importa para nós. + +```solidity + function initialize(address _l1messenger, address _l2TokenBridge) public { + require(messenger == address(0), "Contract has already been initialized."); +``` + +A função `initialize` deve ser chamada só uma vez. Se o endereço do mensageiro entre domínios L1 ou se a ponte do token L2 mudam, nós criamos um novo proxy e uma nova ponte que chama ele. Isto é improvável de acontecer, exceto quando o sistema inteiro é atualizado, uma ocorrência muito rara. + +Note que esta função não tem nenhum mecanismo que restringe _quem_ pode chamá-la. Isto significa que em teoria um atacante poderia esperar até que nós implantassemos o proxy e a primeira versão da ponte e então [front-run](https://solidity-by-example.org/hacks/front-running/)para pegar a função `initialize` antes que o usuário legítimo o faça. Mas há dois métodos para evitar isso: + +1. Se o contrato for implantado não diretamente por um EOA mas [em uma transação que tem outro contrato criando eles,](https://medium.com/upstate-interactive/creating-a-contract-with-a-smart-contract-bdb67c5c8595) o processo inteiro pode ser atômico, e finalizar antes que qualquer outra transação seja executada. +2. Se a chamada legítima para `initialize` falhar, é sempre possível ignorar o proxy recém-criado e fazer a ponte para criar outros novos. + +```solidity + messenger = _l1messenger; + l2TokenBridge = _l2TokenBridge; + } +``` + +Estes são dois parâmetros que a ponte precisa conhecer. + +```solidity + + /************** + * Depositing * + **************/ + + /** @dev Modifier requiring sender to be EOA. This check could be bypassed by a malicious + * contract via initcode, but it takes care of the user error we want to avoid. + */ + modifier onlyEOA() { + // Used to stop deposits from contracts (avoid accidentally lost tokens) + require(!Address.isContract(msg.sender), "Account not EOA"); + _; + } +``` + +É por essa razão que precisamos de utilitários de `Address` do OpenZeppelin. + +```solidity + /** + * @dev This function can be called with no data + * to deposit an amount of ETH to the caller's balance on L2. + * Since the receive function doesn't take data, a conservative + * default amount is forwarded to L2. + */ + receive() external payable onlyEOA { + _initiateETHDeposit(msg.sender, msg.sender, 200_000, bytes("")); + } +``` + +A função existe para finalidade de testes. Note que ela não aparece nas definições de interface - não é para uso corrente. + +```solidity + /** + * @inheritdoc IL1StandardBridge + */ + function depositETH(uint32 _l2Gas, bytes calldata _data) external payable onlyEOA { + _initiateETHDeposit(msg.sender, msg.sender, _l2Gas, _data); + } + + /** + * @inheritdoc IL1StandardBridge + */ + function depositETHTo( + address _to, + uint32 _l2Gas, + bytes calldata _data + ) external payable { + _initiateETHDeposit(msg.sender, _to, _l2Gas, _data); + } +``` + +Estas duas funções são wrappers em volta do `_initiateETHDeposit`, a função que manipula o depósito do ETH real. + +```solidity + /** + * @dev Performs the logic for deposits by storing the ETH and informing the L2 ETH Gateway of + * the deposit. + * @param _from Account to pull the deposit from on L1. + * @param _to Account to give the deposit to on L2. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function _initiateETHDeposit( + address _from, + address _to, + uint32 _l2Gas, + bytes memory _data + ) internal { + // Construct calldata for finalizeDeposit call + bytes memory message = abi.encodeWithSelector( +``` + +A maneira que mensagens entre domínios trabalham é que o contrato de destino é chamado com a mensagem como o seu calldata. Contratos Solidity sempre interpretam seu calldata de acordo com [a especificação ABI](https://docs.soliditylang.org/en/v0.8.12/abi-spec.html). A função Solidity [`abi.encodeWithSelector`](https://docs.soliditylang.org/en/v0.8.12/units-and-global-variables.html#abi-encoding-and-decoding-functions) cria este calldata. + +```solidity + IL2ERC20Bridge.finalizeDeposit.selector, + address(0), + Lib_PredeployAddresses.OVM_ETH, + _from, + _to, + msg.value, + _data + ); +``` + +A mensagem aqui é chamar [a função `finalizeDeposit`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol#L141-L148) com estes parâmetros: + +| Parâmetro | Valores | Significado | +| ----------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| \_l1Token | address(0) | Valor especial para o ETH (que não é um token ERC-20) na L1 | +| \_l2Token | Lib_PredeployAddresses.OVM_ETH | O contrato L2 que gerencia ETH na Optimism, `0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000` (este contrato é apenas para uso interno da Optimism) | +| \_from | \_from | Os endereços na L1 que enviam o ETH | +| \_to | \_to | O endereço na L2 que recebe o ETH | +| amount | msg.value | Quantidade de wei enviado (que já foi enviado para a ponte) | +| \_data | \_data | Dados adicionais para anexar ao depósito | + +```solidity + // Send calldata into L2 + // slither-disable-next-line reentrancy-events + sendCrossDomainMessage(l2TokenBridge, _l2Gas, message); +``` + +Enviar a mensagem através de mensageiro entre domínios. + +```solidity + // slither-disable-next-line reentrancy-events + emit ETHDepositInitiated(_from, _to, msg.value, _data); + } +``` + +Emitir um evento para informar qualquer aplicação descentralizada que escuta esta transferência. + +```solidity + /** + * @inheritdoc IL1ERC20Bridge + */ + function depositERC20( + . + . + . + ) external virtual onlyEOA { + _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _l2Gas, _data); + } + + /** + * @inheritdoc IL1ERC20Bridge + */ + function depositERC20To( + . + . + . + ) external virtual { + _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _l2Gas, _data); + } +``` + +Estas duas funções são wrappers em volta do `_initiateERC20Deposit`, a função que manipula o depósito real do ERC-20. + +```solidity + /** + * @dev Performs the logic for deposits by informing the L2 Deposited Token + * contract of the deposit and calling a handler to lock the L1 funds. (e.g. transferFrom) + * + * @param _l1Token Address of the L1 ERC20 we are depositing + * @param _l2Token Address of the L1 respective L2 ERC20 + * @param _from Account to pull the deposit from on L1 + * @param _to Account to give the deposit to on L2 + * @param _amount Amount of the ERC20 to deposit. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function _initiateERC20Deposit( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) internal { +``` + +Esta função é similiar a `_initiateETHDeposit` acima, com algumas poucas diferenças importantes. A primeira diferença é que esta função recebe o endereço de token e a quantia a transferir como parâmetros. No caso do ETH, a chamada para a ponte já inclui a transferência do ativo para a conta da ponte (`msg.value`). + +```solidity + // When a deposit is initiated on L1, the L1 Bridge transfers the funds to itself for future + // withdrawals. safeTransferFrom also checks if the contract has code, so this will fail if + // _from is an EOA or address(0). + // slither-disable-next-line reentrancy-events, reentrancy-benign + IERC20(_l1Token).safeTransferFrom(_from, address(this), _amount); +``` + +Transferências de tokens ERC-20 seguem um processo diferente do ETH: + +1. O usuário (`_from`) dá uma permissão para a ponte para transferir os tokens apropriados. +2. O usuário chama a ponte com o endereço do contrato do token, a quantia, etc. +3. A ponte transfere os tokens (para ela mesmo) como parte do processo de depósito. + +O primeiro passo pode acontecer em uma transação separada das últimas duas. Entretanto, front-running não é um problema porque as duas funções que chamam `_initiateERC20Deposit` (`depositERC20` e `depositERC20To`) somente chamam essa função com `msg.sender` como parâmetro `_from`. + +```solidity + // Construct calldata for _l2Token.finalizeDeposit(_to, _amount) + bytes memory message = abi.encodeWithSelector( + IL2ERC20Bridge.finalizeDeposit.selector, + _l1Token, + _l2Token, + _from, + _to, + _amount, + _data + ); + + // Send calldata into L2 + // slither-disable-next-line reentrancy-events, reentrancy-benign + sendCrossDomainMessage(l2TokenBridge, _l2Gas, message); + + // slither-disable-next-line reentrancy-benign + deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] + _amount; +``` + +Adicione a quantia depositada de tokens para a estrutura de dados `deposits`. Pode haver múltiplos endereços em L2 que correspondam ao mesmo token ERC-20 L1, portanto não é suficiente usar saldo de ponte de token ERC-20 L1 para rastrear os depósitos. + +```solidity + + // slither-disable-next-line reentrancy-events + emit ERC20DepositInitiated(_l1Token, _l2Token, _from, _to, _amount, _data); + } + + /************************* + * Cross-chain Functions * + *************************/ + + /** + * @inheritdoc IL1StandardBridge + */ + function finalizeETHWithdrawal( + address _from, + address _to, + uint256 _amount, + bytes calldata _data +``` + +A ponte L2 envia uma mensagem para o mensageiro entre domínios L2 que causa o mensageiro entre domínios L1 chamar esta função (uma vez que a [transação que finaliza a mensagem](https://community.optimism.io/docs/developers/bridge/messaging/#fees-for-l2-%E2%87%92-l1-transactions) é submetida no L1, claro). + +```solidity + ) external onlyFromCrossDomainAccount(l2TokenBridge) { +``` + +Certifique-se que isto é uma mensagem _legítima_, vinda do mensageiro entre domínios e originada com o token da ponte L2. Esta função é usada para retirar ETH da ponte, então nós temos que nos certificar que é somente chamada pelo chamador autorizado. + +```solidity + // slither-disable-next-line reentrancy-events + (bool success, ) = _to.call{ value: _amount }(new bytes(0)); +``` + +A maneira de transferir ETH é chamar o recebedor com a quantia de wei no `msg.value`. + +```solidity + require(success, "TransferHelper::safeTransferETH: ETH transfer failed"); + + // slither-disable-next-line reentrancy-events + emit ETHWithdrawalFinalized(_from, _to, _amount, _data); +``` + +Emitir um evento sobre o saque. + +```solidity + } + + /** + * @inheritdoc IL1ERC20Bridge + */ + function finalizeERC20Withdrawal( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external onlyFromCrossDomainAccount(l2TokenBridge) { +``` + +Esta função é similar a `finalizeETHWithdrawal` acima, com as mudanças necessárias para os tokens ERC-20. + +```solidity + deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] - _amount; +``` + +Atualiza a estrutura de dados`deposits`. + +```solidity + + // When a withdrawal is finalized on L1, the L1 Bridge transfers the funds to the withdrawer + // slither-disable-next-line reentrancy-events + IERC20(_l1Token).safeTransfer(_to, _amount); + + // slither-disable-next-line reentrancy-events + emit ERC20WithdrawalFinalized(_l1Token, _l2Token, _from, _to, _amount, _data); + } + + + /***************************** + * Temporary - Migrating ETH * + *****************************/ + + /** + * @dev Adds ETH balance to the account. This is meant to allow for ETH + * to be migrated from an old gateway to a new gateway. + * NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the + * old contract + */ + function donateETH() external payable {} +} +``` + +Houve uma implementação anterior dessa ponte. Quando nos movemos da implementação para esta ponte, tivemos que mover todos os ativos. Tokens ERC-20 podem serem simplesmente movidos. Entretanto, para transferir ETH para um contrato, você precisa da aprovação do contrato, que é o que `donateETH` nos fornece. + +## Tokens ERC-20 na L2 {#erc-20-tokens-on-l2} + +Para um token ERC-20 servir na ponte padrão, ele precisa permitir que a ponte padrão, e _somente_ a ponte padrão, cunhe token. Isto é necessário porque as pontes precisam garantir que o número de tokens circulando na Optimism é igual ao número de tokens travados dentro do contrato da ponte L1. Se houver tokens demais na L2, alguns usuários ficarão incapazes de usar a ponte de volta para os seus ativos para a L1. Ao invés de uma ponte confiável, nós iriamos essencialmente recriar [reserva fracionária bancária](https://www.investopedia.com/terms/f/fractionalreservebanking.asp). Se houver tokens demais em L1, alguns desses tokens estaria travados dentro do contrato da ponte para sempre, porque não há maneira de liberá-los sem queimar tokens L2. + +### IL2StandardERC20 {#il2standarderc20} + +Cada token ERC-20 na L2 que usa a ponte padrão precisa fornecer [esta interface](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/standards/IL2StandardERC20.sol), que tem as funções e eventos que a ponte padrão necessita. + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +``` + +[A interface padrão ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) não inclui as funções `mint` e `burn`. Estes métodos não são necessários pelo [padrão ERC-20](https://eips.ethereum.org/EIPS/eip-20), que não deixa especificado os mecanismos para criar e destruir tokens. + +```solidity +import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +``` + +[A interface ERC-165 ](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol)é usada para especificar que funções um contrato fornece. [Você pode ler o padrão aqui](https://eips.ethereum.org/EIPS/eip-165). + +```solidity +interface IL2StandardERC20 is IERC20, IERC165 { + function l1Token() external returns (address); +``` + +Esta função fornece o endereço do token L1 que usa a ponte para este contrato. Note que nós não temos uma função similar na direção oposta. Nós precisamos ser capazes de usar a ponte para qualquer token L1, independente se o suporte L2 foi planejado quando foi implementado ou não. + +```solidity + + function mint(address _to, uint256 _amount) external; + + function burn(address _from, uint256 _amount) external; + + event Mint(address indexed _account, uint256 _amount); + event Burn(address indexed _account, uint256 _amount); +} +``` + +Funções e eventos para cunhar (criar) e queimar (destruir) tokens. A ponte deveria ser a única entidade que pode rodar estas funções para garantir que o número de tokens esteja correto (igual ao número de tokens travados na L1). + +### L2StandardERC20 {#L2StandardERC20} + +[Essa é a nossa implementação da interface `IL2StandardERC20`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/standards/L2StandardERC20.sol). A não ser que você precise de algum tipo de lógica customizada, você deveria usar esta. + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +``` + +[O contrato ERC-20 OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol). A Optimism não acredita em reinventar a roda, especialmente quando a roda é bem auditada e precisa ser estimada o suficiente para manter ativos. + +```solidity +import "./IL2StandardERC20.sol"; + +contract L2StandardERC20 is IL2StandardERC20, ERC20 { + address public l1Token; + address public l2Bridge; +``` + +Há dois parâmetros de configuração adicionais que nós precisamos, e um ERC-20 normalmente não precisa. + +```solidity + + /** + * @param _l2Bridge Address of the L2 standard bridge. + * @param _l1Token Address of the corresponding L1 token. + * @param _name ERC20 name. + * @param _symbol ERC20 symbol. + */ + constructor( + address _l2Bridge, + address _l1Token, + string memory _name, + string memory _symbol + ) ERC20(_name, _symbol) { + l1Token = _l1Token; + l2Bridge = _l2Bridge; + } +``` + +Primeiro chame o construtor do contrato que nós herdamos (`ERC20(_name, _symbol)`) e então configure suas próprias variáveis. + +```solidity + + modifier onlyL2Bridge() { + require(msg.sender == l2Bridge, "Only L2 Bridge can mint and burn"); + _; + } + + + // slither-disable-next-line external-function + function supportsInterface(bytes4 _interfaceId) public pure returns (bool) { + bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165 + bytes4 secondSupportedInterface = IL2StandardERC20.l1Token.selector ^ + IL2StandardERC20.mint.selector ^ + IL2StandardERC20.burn.selector; + return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface; + } +``` + +Essa é a maneira que o[ERC-165](https://eips.ethereum.org/EIPS/eip-165) funciona. Cada interface é um número de funções suportadas, como identificadas no [ou exclusivo](https://en.wikipedia.org/wiki/Exclusive_or) dos [seletores de funções ABI](https://docs.soliditylang.org/en/v0.8.12/abi-spec.html#function-selector) destas funções. + +A ponte L2 usa ERC-165 como checagem de sanidade para garantir que o contrato ERC-20 para o qual ela envia ativos é um `IL2StandardERC20`. + +**Note:** Não há nada para evitar contratos trapaceiros de fornecer falsas respostas para `supportsInterface`, portanto isto é um mecanismo de checagem de sanidade, _não_ um mecanismo de segurança. + +```solidity + // slither-disable-next-line external-function + function mint(address _to, uint256 _amount) public virtual onlyL2Bridge { + _mint(_to, _amount); + + emit Mint(_to, _amount); + } + + // slither-disable-next-line external-function + function burn(address _from, uint256 _amount) public virtual onlyL2Bridge { + _burn(_from, _amount); + + emit Burn(_from, _amount); + } +} +``` + +Somente a ponte L2 pode cunhar e queimar ativos. + +`_mint` e `_burn` são na verdade definidos no [contrato ERC-20 OpenZeppelin](/developers/tutorials/erc20-annotated-code/#the-_mint-and-_burn-functions-_mint-and-_burn). Este contrato só não os expõem externamente, porque as condições para cunhar e queimar tokens são tão variadas como o número de maneiras de usar ERC-20. + +## Código da ponte L2 {#l2-bridge-code} + +Este é o código que roda na ponte na Optimism. [A fonte deste contrato é aqui](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol). + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* Interface Imports */ +import { IL1StandardBridge } from "../../L1/messaging/IL1StandardBridge.sol"; +import { IL1ERC20Bridge } from "../../L1/messaging/IL1ERC20Bridge.sol"; +import { IL2ERC20Bridge } from "./IL2ERC20Bridge.sol"; +``` + +A interface [IL2ERC20Bridge](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) é muito similar ao [equivalente L1](#IL1ERC20Bridge) que nós vimos acima. Há duas diferenças significantes: + +1. Na L1 você inicia depósitos e finaliza retiradas. Aqui você inicia retiradas e finaliza depósitos. +2. Na L1 é necessário distinguir entre ETH e tokens ERC-20. Na L2 nós podemos usar as mesmas funções para ambos os casos porque internamente saldos ETH na Optimism são manipulados por um token ERC-20 com o endereço [0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000](https://optimistic.etherscan.io/address/0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000). + +```solidity +/* Library Imports */ +import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; +import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; + +/* Contract Imports */ +import { IL2StandardERC20 } from "../../standards/IL2StandardERC20.sol"; + +/** + * @title L2StandardBridge + * @dev The L2 Standard bridge is a contract which works together with the L1 Standard bridge to + * enable ETH and ERC20 transitions between L1 and L2. + * This contract acts as a minter for new tokens when it hears about deposits into the L1 Standard + * bridge. + * This contract also acts as a burner of the tokens intended for withdrawal, informing the L1 + * bridge to release L1 funds. + */ +contract L2StandardBridge is IL2ERC20Bridge, CrossDomainEnabled { + /******************************** + * External Contract References * + ********************************/ + + address public l1TokenBridge; +``` + +Acompanhe o endereço da ponte L1. Observe que, em contraste com o equivalente L1, aqui _precisamos_ desta variável. O endereço da ponte L1 não é conhecido antecipadamente. + +```solidity + + /*************** + * Constructor * + ***************/ + + /** + * @param _l2CrossDomainMessenger Cross-domain messenger used by this contract. + * @param _l1TokenBridge Address of the L1 bridge deployed to the main chain. + */ + constructor(address _l2CrossDomainMessenger, address _l1TokenBridge) + CrossDomainEnabled(_l2CrossDomainMessenger) + { + l1TokenBridge = _l1TokenBridge; + } + + /*************** + * Withdrawing * + ***************/ + + /** + * @inheritdoc IL2ERC20Bridge + */ + function withdraw( + address _l2Token, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) external virtual { + _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _l1Gas, _data); + } + + /** + * @inheritdoc IL2ERC20Bridge + */ + function withdrawTo( + address _l2Token, + address _to, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) external virtual { + _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _l1Gas, _data); + } +``` + +Estas duas funções iniciam retiradas. Observe que não há necessidade de especificar o endereço do token L1. Espera-se que os tokens L2 nos digam o endereço do equivalente L1. + +```solidity + + /** + * @dev Performs the logic for withdrawals by burning the token and informing + * the L1 token Gateway of the withdrawal. + * @param _l2Token Address of L2 token where withdrawal is initiated. + * @param _from Account to pull the withdrawal from on L2. + * @param _to Account to give the withdrawal to on L1. + * @param _amount Amount of the token to withdraw. + * @param _l1Gas Unused, but included for potential forward compatibility considerations. + * @param _data Optional data to forward to L1. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. + */ + function _initiateWithdrawal( + address _l2Token, + address _from, + address _to, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) internal { + // When a withdrawal is initiated, we burn the withdrawer's funds to prevent subsequent L2 + // usage + // slither-disable-next-line reentrancy-events + IL2StandardERC20(_l2Token).burn(msg.sender, _amount); +``` + +Observe que _não_ estamos contando com o parâmetro `_from`, mas com o `msg.sender` que é muito mais difícil de falsificar (impossível, até onde eu sei). + +```solidity + + // Construct calldata for l1TokenBridge.finalizeERC20Withdrawal(_to, _amount) + // slither-disable-next-line reentrancy-events + address l1Token = IL2StandardERC20(_l2Token).l1Token(); + bytes memory message; + + if (_l2Token == Lib_PredeployAddresses.OVM_ETH) { +``` + +Na L1 é necessário distinguir entre ETH e ERC-20. + +```solidity + message = abi.encodeWithSelector( + IL1StandardBridge.finalizeETHWithdrawal.selector, + _from, + _to, + _amount, + _data + ); + } else { + message = abi.encodeWithSelector( + IL1ERC20Bridge.finalizeERC20Withdrawal.selector, + l1Token, + _l2Token, + _from, + _to, + _amount, + _data + ); + } + + // Send message up to L1 bridge + // slither-disable-next-line reentrancy-events + sendCrossDomainMessage(l1TokenBridge, _l1Gas, message); + + // slither-disable-next-line reentrancy-events + emit WithdrawalInitiated(l1Token, _l2Token, msg.sender, _to, _amount, _data); + } + + /************************************ + * Cross-chain Function: Depositing * + ************************************/ + + /** + * @inheritdoc IL2ERC20Bridge + */ + function finalizeDeposit( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes calldata _data +``` + +Essa função é chamada pelo `L1StandardBridge`. + +```solidity + ) external virtual onlyFromCrossDomainAccount(l1TokenBridge) { +``` + +Certifique-se que a origem da mensagem é legítima. Isso é importante porque a função chama `_mint` e poderia ser usada para dar tokens que não foram cobertos pelos tokens que a ponte tem na L1. + +```solidity + // Check the target token is compliant and + // verify the deposited token on L1 matches the L2 deposited token representation here + if ( + // slither-disable-next-line reentrancy-events + ERC165Checker.supportsInterface(_l2Token, 0x1d1d8b63) && + _l1Token == IL2StandardERC20(_l2Token).l1Token() +``` + +Verificações de sanidade: + +1. A interface correta é suportada +2. O endereço L1 do contrato ERC-20 L2 bate com a fonte L1 dos tokens + +```solidity + ) { + // When a deposit is finalized, we credit the account on L2 with the same amount of + // tokens. + // slither-disable-next-line reentrancy-events + IL2StandardERC20(_l2Token).mint(_to, _amount); + // slither-disable-next-line reentrancy-events + emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _data); +``` + +Se a checagem de sanidade passar, finalize o depósito: + +1. Cunhe os tokens +2. Emita o evento apropriado + +```solidity + } else { + // Either the L2 token which is being deposited-into disagrees about the correct address + // of its L1 token, or does not support the correct interface. + // This should only happen if there is a malicious L2 token, or if a user somehow + // specified the wrong L2 token address to deposit into. + // In either case, we stop the process here and construct a withdrawal + // message so that users can get their funds out in some cases. + // There is no way to prevent malicious token contracts altogether, but this does limit + // user error and mitigate some forms of malicious contract behavior. +``` + +Se um usuário fez um erro detectável usando o endereço de token L2 errado, nós queremos cancelar o depósito e retornar os tokens na L1. A única maneira que nós podemos fazer isso de L2 é enviar uma mensagem que irá ter que esperar pelo período de desafio de falha, mas isto é muito melhor para o usuário que perder seus tokens permanentemente. + +```solidity + bytes memory message = abi.encodeWithSelector( + IL1ERC20Bridge.finalizeERC20Withdrawal.selector, + _l1Token, + _l2Token, + _to, // switched the _to and _from here to bounce back the deposit to the sender + _from, + _amount, + _data + ); + + // Send message up to L1 bridge + // slither-disable-next-line reentrancy-events + sendCrossDomainMessage(l1TokenBridge, 0, message); + // slither-disable-next-line reentrancy-events + emit DepositFailed(_l1Token, _l2Token, _from, _to, _amount, _data); + } + } +} +``` + +## Conclusão {#conclusion} + +A ponte padrão é o mecanismo mais flexível para transferência de ativos. Porém, por ser genérico não é sempre o mecanismo mais fácil de usar. Especialmente para retiradas, a maioria dos usuários prefere usar [pontes de terceiros](https://www.optimism.io/apps/bridges) a esperar o período de desafio e também não precisar de uma prova de Merkle para finalizar a retirada. + +Estas pontes tipicamente funcionam tendo ativos na L1, que elas fornecem imediatamente por uma taxa pequena (geralmente menor que o custo de gas para uma retirada de uma ponte padrão). Quando a ponte (ou as pessoas que a administram) antecipa a falta de ativos L1, ela transfere ativos suficientes da L2. Como estes são saques muito grandes, o custo do saque é amortizado por uma larga quantia e é um percentual muito menor. + +Esperamos que este artigo tenha ajudado você a entender mais sobre como a camada 2 funciona, e como escrever um código Solidity claro e seguro. diff --git a/public/content/translations/pt-br/developers/tutorials/reverse-engineering-a-contract/index.md b/public/content/translations/pt-br/developers/tutorials/reverse-engineering-a-contract/index.md new file mode 100644 index 00000000000..fd8d52243ae --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/reverse-engineering-a-contract/index.md @@ -0,0 +1,744 @@ +--- +title: "Engenharia reversa de um contrato" +description: Como entender um contrato quando você não tem o código-fonte +author: Ori Pomerantz +lang: pt-br +tags: + - "evm" + - "códigos de operação" +skill: advanced +published: 2021-12-30 +--- + +## Introdução {#introduction} + +_Não há segredos no blockchain_. Tudo o que acontece é consistente, verificável e está disponível publicamente. O ideal é que os contratos [tenham seu código-fonte publicado e verificado na Etherscan](https://etherscan.io/address/0xb8901acb165ed027e32754e0ffe830802919727f#code). No entanto, [nem sempre isso acontece](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#code). Neste artigo, você aprenderá a usar engenharia reversa em contratos analisando um contrato sem código-fonte, [`0x2510c039cc3b061d79e564b38836da87e31b342f`](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f). + +Existem compiladores reversos, mas eles nem sempre produzem [resultados utilizáveis](https://etherscan.io/bytecode-decompiler?a=0x2510c039cc3b061d79e564b38836da87e31b342f). Neste artigo, você aprenderá como usar engenharia reversa manualmente e entender um contrato dos [opcodes](https://github.com/wolflo/evm-opcodes), além de interpretar os resultados de um descompilador. + +Para entender este artigo, é preciso saber o básico de EVM e pelo menos estar um pouco familiarizado com a montagem de EVM. [Você pode ler sobre estes tópicos aqui](https://medium.com/mycrypto/the-ethereum-virtual-machine-how-does-it-work-9abac2b7c9e). + +## Preparar o Código Executável {#prepare-the-executable-code} + +Você pode obter os opcodes acessando o contrato no Etherscan clicando na guia **Contrato** e depois em **Alternar para a Visualização de Opcodes**. Você poderá visualizar um opcode por linha. + +![Visualização do Opcode no Etherscan](opcode-view.png) + +Para entender os saltos, no entanto, você precisa saber onde no código cada opcode está localizado. Uma maneira de fazer isso é abrir uma planilha do Google e colar os opcodes na coluna C. [Você pode pular as seguintes etapas ao fazer uma cópia desta planilha já preparada](https://docs.google.com/spreadsheets/d/1tKmTJiNjUwHbW64wCKOSJxHjmh0bAUapt6btUYE7kDA/edit?usp=sharing). + +O próximo passo é obter os locais de código corretos para que possamos entender os saltos. Colocaremos o tamanho do opcode na coluna B e o local (em hexadecimal) na coluna A. Digite esta função na célula `B1` e então copie e cole para o resto da coluna B, até o final do código. Depois de fazer isso, você pode ocultar a coluna B. + +``` +=1+IF(REGEXMATCH(C1,"PUSH"),REGEXEXTRACT(C1,"PUSH(\d+)"),0) +``` + +Primeiro essa função adiciona um byte no opcode em si e depois procura por `PUSH`. Opcodes de push são especiais porque eles precisam ter bytes adicionais para o valor que está sendo enviado. Se o opcode é um `PUSH`, extraímos o número de bytes e adicionamos isso. + +Em `A1` coloque o primeiro offset (descolamento de bits), para zero. Depois, em `A2`, insira esta função e copie e cole novamente para o resto da coluna A: + +``` +=dec2hex(hex2dec(A1)+B1) +``` + +Nós precisamos desta função, para nos dar o valor hexadecimal, porque os valores que são enviados antes dos saltos (`JUMP` e `JUMPI`) são dados a nós em hexadecimal. + +## O Ponto de Entrada (0x00) {#the-entry-point-0x00} + +Os contratos são sempre executados a partir do primeiro byte. Essa é a parte inicial do código: + +| Deslocamento | Código de Operação | Montante (depois do opcode) | +| ------------:| ------------------ | --------------------------- | +| 0 | PUSH1 0x80 | 0x80 | +| 2 | PUSH1 0x40 | 0x40, 0x80 | +| 4 | MSTORE | Vazio | +| 5 | PUSH1 0x04 | 0x04 | +| 7 | CALLDATASIZE | CALLDATASIZE 0x04 | +| 8 | LT | CALLDATASIZE<4 | +| 9 | PUSH2 0x005e | 0x5E CALLDATASIZE<4 | +| C | JUMPI | Vazio | + +Esse código faz duas coisas: + +1. Escreva 0x80 como um valor de 32 bytes para locais da memória 0x40-0x5F (0x80 é armazenado em 0x5F, e 0x40-0x5E são todos zeros). +2. Leia o tamanho dos dados de chamada. Normalmente, os dados de chamada para um contrato Ethereum seguem [a ABI (interface binária do aplicativo)](https://docs.soliditylang.org/en/v0.8.10/abi-spec.html), o qual requer no mínimo quatro bytes para o seletor de função. Se o tamanho dos dados da chamada for menor que quatro, pule para 0x5E. + +![Fluxograma para esta parte](flowchart-entry.png) + +### O controlador em 0x5E (para dados de chamada não ABI) {#the-handler-at-0x5e-for-non-abi-call-data} + +| Deslocamento | Código de Operação | +| ------------:| ------------------ | +| 5E | JUMPDEST | +| 5F | CALLDATASIZE | +| 60 | PUSH2 0x007c | +| 63 | JUMPI | + +Este trecho começa com um `JUMPDEST`. Os programas EVM (Máquina Virtual Ethereum) lançam uma exceção se você pular para um opcode que não for `JUMPDEST`. Então, ele examina o CALLDATASIZE e, se for "verdadeiro" (ou seja, não for zero), pula para 0x7C. Veremos isso abaixo. + +| Deslocamento | Código de Operação | Montante (depois do opcode) | +| ------------:| ------------------ | ----------------------------------------------------------------------------- | +| 64 | CALLVALUE | [Wei](/glossary/#wei) fornecido pela chamada. Chamado `msg.value` no Solidity | +| 65 | PUSH1 0x06 | 6 CALLVALUE | +| 67 | PUSH1 0x00 | 0 6 CALLVALUE | +| 69 | DUP3 | CALLVALUE 0 6 CALLVALUE | +| 6A | DUP3 | 6 CALLVALUE 0 6 CALLVALUE | +| 6B | SLOAD | Storage[6] CALLVALUE 0 6 CALLVALUE | + +Portanto, quando não há dados de chamada, nós lemos o valor de Storage[6]. Ainda não sabemos que valor é esse, mas podemos buscar as transações que o contrato recebeu sem nenhum dado de chamada. Transações que apenas transferem ETH sem nenhum dado de chamada (e, portanto, nenhum método) têm no Etherscan o método `Transfer`. De fato, [a primeira transação que o contrato recebeu](https://etherscan.io/tx/0xeec75287a583c36bcc7ca87685ab41603494516a0f5986d18de96c8e630762e7) é uma transferência. + +Se nós olharmos nessa transação e clicarmos em **Clique para ver mais**, veremos que os dados da chamada, chamados de dados de entrada, estão de fato vazios (`0x`). Observe também que o valor é 1.559 ETH, que será relevante mais tarde. + +![Os dados da chamada estão vazios](calldata-empty.png) + +Em seguida, clique na guia o **Estado** e expanda o contrato que estamos fazendo engenharia reversa (0x2510...). Você pode ver que `Storage[6]` (armazenamento) mudou durante a transação e, se você alterar Hex para **Número**, verá que se tornou 1.559.000.000.000.000.000, o valor transferido em wei (adicionei as vírgulas para maior clareza), que corresponde ao próximo valor do contrato. + +![A mudança no Armazenamento[6]](storage6.png) + +Se observarmos as mudanças de estado causadas por [outras transações de `Transfer` (transferência) do mesmo período](https://etherscan.io/tx/0xf708d306de39c422472f43cb975d97b66fd5d6a6863db627067167cbf93d84d1#statechange), vemos que `Storage[6]` rastreou o valor do contrato por um tempo. Por enquanto, vamos chamá-lo de `Value*` (valor). O asterisco (`*`) nos lembra que não _sabemos_ o que esta variável faz, ainda, mas não pode ser apenas para rastrear o valor do contrato porque não há necessidade de usar armazenamento, o que é muito caro, quando você pode obter o saldo de suas contas usando `ADDRESS BALANCE`. O primeiro opcode envia o próprio endereço do contrato. O segundo lê o endereço no topo da pilha e o substitui com o saldo desse endereço. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | --------------------------------------------- | +| 6C | PUSH2 0x0075 | 0x75 Value\* CALLVALUE 0 6 CALLVALUE | +| 6F | SWAP2 | CALLVALUE Value\* 0x75 0 6 CALLVALUE | +| 70 | SWAP1 | Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 71 | PUSH2 0x01a7 | 0x01A7 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 74 | JUMP | | + +Nós continuaremos a rastrear esse código no destino do salto (desvio). + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ------------------------------------------------------------- | +| 1A7 | JUMPDEST | Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1A8 | PUSH1 0x00 | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AA | DUP3 | CALLVALUE 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AB | NOT | 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | + +O `NOT` é bit a bit, portanto, ele inverte o valor de cada bit no valor da chamada. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ------------------------------------------------------------------------------- | +| 1AC | DUP3 | Value\* 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AD | GT | Value\*>2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AE | ISZERO | Value\*<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AF | PUSH2 0x01df | 0x01DF Value\*<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1B2 | JUMPI | | + +Nós pulamos se `Value*` (o valor) for menor que 2^256-CALLVALUE-1 ou igual a ele. Isso parece lógico para evitar vazamento (overflow). E, de fato, vemos que depois de algumas operações sem sentido (escrever na memória que está prestes a ser excluída, por exemplo) no deslocamento 0x01DE, o contrato é revertido se o vazamento for detectado, o que é um comportamento normal. + +Note que esse vazamento é extremamente improvável, porque exigiria que o valor da chamada mais o `Value*` fosse comparável a 2^256 wei, em torno de 10^59 ETH. [O suprimento total de ETH, no momento desta redação, é inferior a duzentos milhões](https://etherscan.io/stat/supply). + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ------------------------------------------- | +| 1DF | JUMPDEST | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1E0 | POP | Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1E1 | ADD | Value\*+CALLVALUE 0x75 0 6 CALLVALUE | +| 1E2 | SWAP1 | 0x75 Value\*+CALLVALUE 0 6 CALLVALUE | +| 1E3 | JUMP | | + +Se chegamos aqui, pegue `Value* + CALLVALUE` e salte para o offset 0x75. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | --------------------------------- | +| 75 | JUMPDEST | Value\*+CALLVALUE 0 6 CALLVALUE | +| 76 | SWAP1 | 0 Value\*+CALLVALUE 6 CALLVALUE | +| 77 | SWAP2 | 6 Value\*+CALLVALUE 0 CALLVALUE | +| 78 | SSTORE | 0 CALLVALUE | + +Se nós chegarmos aqui (o que requer que os dados da chamada estejam vazios), adicionamos o `Value*` ao valor da chamada. Isso é consistente com o que dizemos que as transações de `Transfer` fazem. + +| Deslocamento | Código de Operação | +| ------------:| ------------------ | +| 79 | POP | +| 7A | POP | +| 7B | STOP | + +Finalmente, limpe a pilha (o que não é necessário) e sinalize o fim bem-sucedido da transação. + +Para simplificar tudo, aqui está um fluxograma para o código inicial. + +![Fluxograma do ponto de entrada](flowchart-entry.png) + +## O Controlador em 0x7C {#the-handler-at-0x7c} + +Eu propositalmente não coloquei no cabeçalho o que esse controlador faz. O propósito não é ensinar como esse contrato específico funciona, mas como fazer engenharia reversa de contratos. Você irá aprender o que ele faz da mesma forma que eu, seguindo o código. + +Nós chegamos aqui a partir de vários locais: + +- Se houver dados de chamada de 1, 2 ou 3 bytes (a partir do deslocamento 0x63) +- Se a assinatura do método for desconhecida (dos offsets 0x42 e 0x5D) + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | -------------------- | +| 7C | JUMPDEST | | +| 7D | PUSH1 0x00 | 0x00 | +| 7F | PUSH2 0x009d | 0x9D 0x00 | +| 82 | PUSH1 0x03 | 0x03 0x9D 0x00 | +| 84 | SLOAD | Storage[3] 0x9D 0x00 | + +Esta é outra célula de armazenamento, que não poderia encontrar em nenhuma transação, portanto, é mais difícil saber o que significa. O código abaixo deixará isso mais claro. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------------------------------------- | ------------------------------- | +| 85 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xff....ff Storage[3] 0x9D 0x00 | +| 9A | AND | Storage[3]-as-address 0x9D 0x00 | + +Esses opcodes truncam o valor que lemos do Armazenamento[3] para 160 bits, o tamanho de um endereço Ethereum. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ------------------------------- | +| 9B | SWAP1 | 0x9D Storage[3]-as-address 0x00 | +| 9C | JUMP | Storage[3]-as-address 0x00 | + +Este salto é supérfluo, pois estamos indo para o próximo opcode. Esse código não é tão eficiente em relação ao consumo de gás quanto ele poderia ser. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ------------------------------- | +| 9D | JUMPDEST | Storage[3]-as-address 0x00 | +| 9E | SWAP1 | 0x00 Storage[3]-as-address | +| 9F | POP | Storage[3]-as-address | +| A0 | PUSH1 0x40 | 0x40 Storage[3]-as-address | +| A2 | MLOAD | Mem[0x40] Storage[3]-as-address | + +Bem no início do código, definimos Mem[0x40] como 0x80. Se procurarmos 0x40 posteriormente, veremos que nós não o alteramos - então podemos assumir que é 0x80. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ------------------------------------------------- | +| A3 | CALLDATASIZE | CALLDATASIZE 0x80 Storage[3]-as-address | +| A4 | PUSH1 0x00 | 0x00 CALLDATASIZE 0x80 Storage[3]-as-address | +| A6 | DUP3 | 0x80 0x00 CALLDATASIZE 0x80 Storage[3]-as-address | +| A7 | CALLDATACOPY | 0x80 Storage[3]-as-address | + +Copie todos os dados da chamada para a memória, começando por 0x80. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | -------------------------------------------------------------------------------- | +| A8 | PUSH1 0x00 | 0x00 0x80 Storage[3]-as-address | +| AA | DUP1 | 0x00 0x00 0x80 Storage[3]-as-address | +| AB | CALLDATASIZE | CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AC | DUP4 | 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AD | DUP6 | Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AE | GAS | GAS Storage[3]-as-address 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-as-address | +| AF | DELEGATE_CALL | | + +Agora as coisas estão muito mais claras. Este contrato pode atuar como um [proxy](https://blog.openzeppelin.com/proxy-patterns/), chamando o endereço no Armazenamento[3] para fazer o trabalho real. `DELEGATE_CALL` chama um contrato separado, mas permanece no mesmo armazenamento. Isto significa que o contrato delegado, aquele para o qual somos proxy, acessa o mesmo espaço de armazenamento. Os parâmetros para a chamada são: + +- _Gas_: Todo o gas restante +- _Endereço chamado_: Armazenamento[3] como endereço +- _Dados da chamada_: Os bytes CALLDATASIZE começando em 0x80, que é onde colocamos os dados originais da chamada +- _Dados de retorno_: Nenhum (0x00 - 0x00) Nós vamos obter os dados de retorno por outros meios (veja abaixo) + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | --------------------------------------------------------------------------------------------- | +| B0 | RETURNDATASIZE | RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B1 | DUP1 | RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B2 | PUSH1 0x00 | 0x00 RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B4 | DUP5 | 0x80 0x00 RETURNDATASIZE RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B5 | RETURNDATACOPY | RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | + +Aqui copiamos todos os dados de retorno para o buffer de memória começando em 0x80. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- | +| B6 | DUP2 | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B7 | DUP1 | (((call success/failure))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B8 | ISZERO | (((did the call fail))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| B9 | PUSH2 0x00c0 | 0xC0 (((did the call fail))) (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BC | JUMPI | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BD | DUP2 | RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BE | DUP5 | 0x80 RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| BF | RETURN | | + +Então, após a chamada, nós copiamos os dados de retorno para o buffer 0x80 - 0x80+RETURNDATASIZE e, se a chamada for bem-sucedida, nós então fazemos o `RETURN` com exatamente este buffer. + +### DELEGATECALL falhou {#delegatecall-failed} + +Se chegarmos aqui, para 0xC0, significa que o contrato que chamamos foi revertido. Como somos apenas um proxy para esse contrato, queremos retornar os mesmos dados e também reverter. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ------------------------------------------------------------------------------------------------------------------- | +| C0 | JUMPDEST | (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| C1 | DUP2 | RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| C2 | DUP5 | 0x80 RETURNDATASIZE (((call success/failure))) RETURNDATASIZE (((call success/failure))) 0x80 Storage[3]-as-address | +| C3 | REVERT | | + +Portanto, fazemos o `REVERT` com o mesmo buffer que usamos para o `RETURN` anteriormente: 0x80 - 0x80+RETURNDATASIZE + +![Fluxograma de chamada ao proxy](flowchart-proxy.png) + +## Chamadas da ABI {#abi-calls} + +Se o tamanho dos dados da chamada for quatro bytes ou mais, pode ser uma chamada ABI válida. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ------------------------------------------------- | +| D | PUSH1 0x00 | 0x00 | +| F | CALLDATALOAD | (((First word (256 bits) of the call data))) | +| 10 | PUSH1 0xe0 | 0xE0 (((First word (256 bits) of the call data))) | +| 12 | SHR | (((first 32 bits (4 bytes) of the call data))) | + +O Etherscan nos conta que `1C` é um opcode desconhecido, porque [ele foi adicionado depois que o Etherscan escreveu essa funcionalidade](https://eips.ethereum.org/EIPS/eip-145) e eles não o atualizaram. An [up to date opcode table](https://github.com/wolflo/evm-opcodes) shows us that this is shift right + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | -------------------------------------------------------------------------------------------------------- | +| 13 | DUP1 | (((first 32 bits (4 bytes) of the call data))) (((first 32 bits (4 bytes) of the call data))) | +| 14 | PUSH4 0x3cd8045e | 0x3CD8045E (((first 32 bits (4 bytes) of the call data))) (((first 32 bits (4 bytes) of the call data))) | +| 19 | GT | 0x3CD8045E>first-32-bits-of-the-call-data (((first 32 bits (4 bytes) of the call data))) | +| 1A | PUSH2 0x0043 | 0x43 0x3CD8045E>first-32-bits-of-the-call-data (((first 32 bits (4 bytes) of the call data))) | +| 1D | JUMPI | (((first 32 bits (4 bytes) of the call data))) | + +Ao dividir os testes de correspondência da assinatura do método em dois, dessa forma, economiza metade dos testes, em média. O código que segue imediatamente e o código em 0x43 seguem o mesmo padrão: `DUP1` os primeiros 32 bits dos dados da chamada, `PUSH4 (((method signature>`, executa `EQ` para verificar a igualdade e, então, fazer o `JUMPI` se a assinatura do método corresponder. Aqui estão as assinaturas de método, seus endereços e, se conhecido [a definição de método correspondente](https://www.4byte.directory/): + +| Método | Assinatura do método | Deslocamento por salto | +| -------------------------------------------------------------------------------------- | -------------------- | ---------------------- | +| [splitter()](https://www.4byte.directory/signatures/?bytes4_signature=0x3cd8045e) | 0x3cd8045e | 0x0103 | +| ??? | 0x81e580d3 | 0x0138 | +| [currentWindow()](https://www.4byte.directory/signatures/?bytes4_signature=0xba0bafb4) | 0xba0bafb4 | 0x0158 | +| ??? | 0x1f135823 | 0x00C4 | +| [merkleRoot()](https://www.4byte.directory/signatures/?bytes4_signature=0x2eb4a7ab) | 0x2eb4a7ab | 0x00ED | + +Se nenhuma combinação for encontrada, o código pula para [o controlador do proxy em 0x7C](#the-handler-at-0x7c), na esperança de que o contrato para o qual somos um proxy tenha uma correspondência. + +![Fluxograma de chamadas ABI](flowchart-abi.png) + +## splitter() {#splitter} + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ----------------------------- | +| 103 | JUMPDEST | | +| 104 | CALLVALUE | CALLVALUE | +| 105 | DUP1 | CALLVALUE CALLVALUE | +| 106 | ISZERO | CALLVALUE==0 CALLVALUE | +| 107 | PUSH2 0x010f | 0x010F CALLVALUE==0 CALLVALUE | +| 10A | JUMPI | CALLVALUE | +| 10B | PUSH1 0x00 | 0x00 CALLVALUE | +| 10D | DUP1 | 0x00 0x00 CALLVALUE | +| 10E | REVERT | | + +A primeira coisa que esta função faz é verificar que a chamada não enviou nenhum ETH. Esta função não é [`payable`](https://solidity-by-example.org/payable/) pagável. Se alguém nos enviou ETH, isso deve ser um erro, e queremos fazer o `REVERT` para evitar ter esse ETH que eles não possam recuperá-lo. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------------------------------------- | --------------------------------------------------------------------------- | +| 10F | JUMPDEST | | +| 110 | POP | | +| 111 | PUSH1 0x03 | 0x03 | +| 113 | SLOAD | (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 114 | PUSH1 0x40 | 0x40 (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 116 | MLOAD | 0x80 (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 117 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xFF...FF 0x80 (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 12C | SWAP1 | 0x80 0xFF...FF (((Storage[3] a.k.a the contract for which we are a proxy))) | +| 12D | SWAP2 | (((Storage[3] a.k.a the contract for which we are a proxy))) 0xFF...FF 0x80 | +| 12E | AND | ProxyAddr 0x80 | +| 12F | DUP2 | 0x80 ProxyAddr 0x80 | +| 130 | MSTORE | 0x80 | + +E 0x80 agora contém o endereço do proxy + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | --------- | +| 131 | PUSH1 0x20 | 0x20 0x80 | +| 133 | ADD | 0xA0 | +| 134 | PUSH2 0x00e4 | 0xE4 0xA0 | +| 137 | JUMP | 0xA0 | + +### O código E4 {#the-e4-code} + +Essa é a primeira vez que vemos essas linhas, mas elas são compartilhadas com outros métodos (veja abaixo). Então, vamos chamar o valor na pilha de X, e lembre-se que em `splitter()` o valor desse X é 0xA0. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ----------- | +| E4 | JUMPDEST | X | +| E5 | PUSH1 0x40 | 0x40 X | +| E7 | MLOAD | 0x80 X | +| E8 | DUP1 | 0x80 0x80 X | +| E9 | SWAP2 | X 0x80 0x80 | +| EA | SUB | X-0x80 0x80 | +| EB | SWAP1 | 0x80 X-0x80 | +| EC | RETURN | | + +Portanto, esse código recebe um ponteiro de memória no montante (X) e faz com que o contrato faça o `RETURN` com um buffer que é 0x80 - X. + +No caso do `splitter()`, isto retorna o endereço do qual somos um proxy. O `RETURN` devolve o buffer em 0x80-0x9F, que é onde escrevemos esses dados (offset 0x130 acima). + +## currentWindow() {#currentwindow} + +O código nos deslocamentos 0x158-0x163 é idêntico ao que vimos em 0x103-0x10E em `splitter()` (que não seja o destino `JUMPI`), então sabemos que `currentWindow()` também não é `payable` (pagável). + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | -------------------- | +| 164 | JUMPDEST | | +| 165 | POP | | +| 166 | PUSH2 0x00da | 0xDA | +| 169 | PUSH1 0x01 | 0x01 0xDA | +| 16B | SLOAD | Storage[1] 0xDA | +| 16C | DUP2 | 0xDA Storage[1] 0xDA | +| 16D | JUMP | Storage[1] 0xDA | + +### O código DA {#the-da-code} + +Esse código também é compartilhado com outros métodos. Então, chamaremos o valor na pilha de Y e lembre-se de que em `currentWindow()` o valor desse Y é o Armazenamento[1]. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ---------------- | +| DA | JUMPDEST | Y 0xDA | +| DB | PUSH1 0x40 | 0x40 Y 0xDA | +| DD | MLOAD | 0x80 Y 0xDA | +| DE | SWAP1 | Y 0x80 0xDA | +| DF | DUP2 | 0x80 Y 0x80 0xDA | +| E0 | MSTORE | 0x80 0xDA | + +Escreva Y em 0x80-0x9F. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | -------------- | +| E1 | PUSH1 0x20 | 0x20 0x80 0xDA | +| E3 | ADD | 0xA0 0xDA | + +E o resto já está explicado conforme [acima](#the-e4-code). Portanto, salte para 0xDA, escreva no topo da pilha (Y) para 0x80-0x9F e retorne esse valor. No caso de `currentWindow()`, retorne o Armazenamento[1]. + +## merkleRoot() {#merkleroot} + +O código nos deslocamentos 0xED-0xF8 é idêntico ao que vimos em 0x103-0x10E em `splitter()` (além do alvo `JUMPI`), então sabemos `merkleRoot()` também não é `payable`. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | -------------------- | +| F9 | JUMPDEST | | +| FA | POP | | +| FB | PUSH2 0x00da | 0xDA | +| FE | PUSH1 0x00 | 0x00 0xDA | +| 100 | SLOAD | Storage[0] 0xDA | +| 101 | DUP2 | 0xDA Storage[0] 0xDA | +| 102 | JUMP | Storage[0] 0xDA | + +O que acontece após o salto [já descobrimos](#the-da-code). Portanto, `merkleRoot()` retorna o Armazenamento[0]. + +## 0x81e580d3 {#0x81e580d3} + +O código nos deslocamentos 0x138-0x143 é idêntico ao que vimos em 0x103-0x10E em `splitter()` (além do alvo `JUMPI`), então sabemos que esta função também é não `payable`. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ------------------------------------------------------------ | +| 144 | JUMPDEST | | +| 145 | POP | | +| 146 | PUSH2 0x00da | 0xDA | +| 149 | PUSH2 0x0153 | 0x0153 0xDA | +| 14C | CALLDATASIZE | CALLDATASIZE 0x0153 0xDA | +| 14D | PUSH1 0x04 | 0x04 CALLDATASIZE 0x0153 0xDA | +| 14F | PUSH2 0x018f | 0x018F 0x04 CALLDATASIZE 0x0153 0xDA | +| 152 | JUMP | 0x04 CALLDATASIZE 0x0153 0xDA | +| 18F | JUMPDEST | 0x04 CALLDATASIZE 0x0153 0xDA | +| 190 | PUSH1 0x00 | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 192 | PUSH1 0x20 | 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 194 | DUP3 | 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 195 | DUP5 | CALLDATASIZE 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 196 | SUB | CALLDATASIZE-4 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 197 | SLT | CALLDATASIZE-4<32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 198 | ISZERO | CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 199 | PUSH2 0x01a0 | 0x01A0 CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 19C | JUMPI | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | + +Parece que esta função leva ao menos 32 bytes (uma palavra) de dados da chamada. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | -------------------------------------------- | +| 19D | DUP1 | 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 19E | DUP2 | 0x00 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 19F | REVERT | | + +Se não obtiver os dados da chamada, a transação é revertida sem nenhum dado de retorno. + +Vamos ver o que acontece se a função _obtiver_ os dados de chamada necessários. + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ---------------------------------------- | +| 1A0 | JUMPDEST | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 1A1 | POP | 0x04 CALLDATASIZE 0x0153 0xDA | +| 1A2 | CALLDATALOAD | calldataload(4) CALLDATASIZE 0x0153 0xDA | + +`calldataload(4)` é a primeira palavra dos dados da chamada _após_ a assinatura do método + +| Deslocamento | Código de Operação | Pilha | +| ------------:| ------------------ | ---------------------------------------------------------------------------- | +| 1A3 | SWAP2 | 0x0153 CALLDATASIZE calldataload(4) 0xDA | +| 1A4 | SWAP1 | CALLDATASIZE 0x0153 calldataload(4) 0xDA | +| 1A5 | POP | 0x0153 calldataload(4) 0xDA | +| 1A6 | JUMP | calldataload(4) 0xDA | +| 153 | JUMPDEST | calldataload(4) 0xDA | +| 154 | PUSH2 0x016e | 0x016E calldataload(4) 0xDA | +| 157 | JUMP | calldataload(4) 0xDA | +| 16E | JUMPDEST | calldataload(4) 0xDA | +| 16F | PUSH1 0x04 | 0x04 calldataload(4) 0xDA | +| 171 | DUP2 | calldataload(4) 0x04 calldataload(4) 0xDA | +| 172 | DUP2 | 0x04 calldataload(4) 0x04 calldataload(4) 0xDA | +| 173 | SLOAD | Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA | +| 174 | DUP2 | calldataload(4) Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA | +| 175 | LT | calldataload(4))`, e outro é `isClaimed()`, então parece como um contrato airdrop. Em vez de passar pelo restante opcode por opcode, podemos [tentar o descompilador](https://etherscan.io/bytecode-decompiler?a=0x2f81e57ff4f4d83b40a9f719fd892d8e806e0761), que produz resultados uteis para três funções deste contrato. A engenharia reversa dos outros é deixada como um exercício para o leitor. + +### scaleAmountByPercentage {#scaleamountbypercentage} + +Isso é o que o descompilador nos fornece para essa função: + +```python +def unknown8ffb5c97(uint256 _param1, uint256 _param2) payable: + require calldata.size - 4 >=′ 64 + if _param1 and _param2 > -1 / _param1: + revert with 0, 17 + return (_param1 * _param2 / 100 * 10^6) +``` + +O primeiro `require` testa que os dados da chamada tenham, além dos quatro bytes da assinatura da função, ao menos 64 bytes, suficientes para os dois parâmetros. Do contrário, obviamente, há algo errado. + +A instrução `if` da sentença parece verificar que `_param1` não é zero e que `_param1 * _param2` não é negativo. Provavelmente, isso é para evitar casos de desvios. + +Finalmente, a função retorna um valor em escala. + +### Reivindicação {#claim} + +O código que o descompilador cria é complexo, e nem todo ele é relevante para nós. Vou pular algumas partes para focar nas linhas que acredito fornecerem informações úteis + +```python +def unknown2e7ba6ef(uint256 _param1, uint256 _param2, uint256 _param3, array _param4) payable: + ... + require _param2 == addr(_param2) + ... + if currentWindow <= _param1: + revert with 0, 'cannot claim for a future window' +``` + +Vemos aqui duas coisas importantes: + +- `_param2`, embora esteja declarado como um `uint256`, é na verdade um endereço +- `_param1` é a janela que está sendo reivindicada, o qual tem de ser `currentWindow` ou a anterior. + +```python + ... + if stor5[_claimWindow][addr(_claimFor)]: + revert with 0, 'Account already claimed the given window' +``` + +Ou seja, agora sabemos que Armazenamento[5] é uma matriz de janelas e endereços e se o endereço reivindicou a recompensa por essa janela. + +```python + ... + idx = 0 + s = 0 + while idx < _param4.length: + ... + if s + sha3(mem[(32 * _param4.length) + 328 len mem[(32 * _param4.length) + 296]]) > mem[(32 * idx) + 296]: + mem[mem[64] + 32] = mem[(32 * idx) + 296] + ... + s = sha3(mem[_62 + 32 len mem[_62]]) + continue + ... + s = sha3(mem[_66 + 32 len mem[_66]]) + continue + if unknown2eb4a7ab != s: + revert with 0, 'Invalid proof' +``` + +Sabemos que `unknown2eb4a7ab` é na verdade a função `merkleRoot()`, então este código parece estar verificando um [prova de merkle](https://medium.com/crypto-0-nite/merkle-proofs-explained-6dd429623dc5). Isso significa que `_param4` é uma prova de merkle. + +```python + call addr(_param2) with: + value unknown81e580d3[_param1] * _param3 / 100 * 10^6 wei + gas 30000 wei +``` + +É assim que um contrato transfere seu próprio ETH para outro endereço (de contrato ou de propriedade externa). Ele o chama com um valor que é a quantidade a ser transferida. Logo, parece que isso é um airdrop do ETH. + +```python + if not return_data.size: + if not ext_call.success: + require ext_code.size(stor2) + call stor2.deposit() with: + value unknown81e580d3[_param1] * _param3 / 100 * 10^6 wei +``` + +As duas linhas mais abaixo nos dizem que o Armazenamento[2] também é um contrato que chamamos. Se nós [olharmos a transação do construtor](https://etherscan.io/tx/0xa1ea0549fb349eb7d3aff90e1d6ce7469fdfdcd59a2fd9b8d1f5e420c0d05b58#statechange), veremos que este contrato é o [0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2), um contrato de Ether encapsulado [cujo código-fonte foi carregado no Etherscan](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code). + +Assim, parece que os contratos tentam enviar ETH para `_param2`. Se puder fazer isso, ótimo. Se não, ele tenta enviar [WETH](https://weth.io/). Se `_param2` for uma conta de propriedade externa (EOA), então ele sempre pode receber ETH, mas os contratos podem se recusar a receber ETH. No entanto, WETH é ERC-20 e os contratos não podem se recusar a aceitar isso. + +```python + ... + log 0xdbd5389f: addr(_param2), unknown81e580d3[_param1] * _param3 / 100 * 10^6, bool(ext_call.success) +``` + +No final da função, nós vemos uma entrada de log sendo gerada. [Veja as entradas de log geradas](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#events) e filtre pelo tópico que começa com `0xdbd5...`. Se nós [clicarmos em uma das transações que gerou tal entrada](https://etherscan.io/tx/0xe7d3b7e00f645af17dfbbd010478ef4af235896c65b6548def1fe95b3b7d2274), veremos que realmente parece uma reivindicação - a conta enviou uma mensagem para o contrato, que estamos fazendo engenharia reversa e, em troca, recebemos ETH. + +![Uma transação de reivindicação](claim-tx.png) + +### 1e7df9d3 {#1e7df9d3} + +Esta função é muito semelhante à [`claim`](#claim) (reinvidicação) acima. Ela também verifica uma prova de merkle, que tenta transferir ETH para o primeiro e produz o mesmo tipo de entrada de log. + +```python +def unknown1e7df9d3(uint256 _param1, uint256 _param2, array _param3) payable: + ... + idx = 0 + s = 0 + while idx < _param3.length: + if idx >= mem[96]: + revert with 0, 50 + _55 = mem[(32 * idx) + 128] + if s + sha3(mem[(32 * _param3.length) + 160 len mem[(32 * _param3.length) + 128]]) > mem[(32 * idx) + 128]: + ... + s = sha3(mem[_58 + 32 len mem[_58]]) + continue + mem[mem[64] + 32] = s + sha3(mem[(32 * _param3.length) + 160 len mem[(32 * _param3.length) + 128]]) + ... + if unknown2eb4a7ab != s: + revert with 0, 'Invalid proof' + ... + call addr(_param1) with: + value s wei + gas 30000 wei + if not return_data.size: + if not ext_call.success: + require ext_code.size(stor2) + call stor2.deposit() with: + value s wei + gas gas_remaining wei + ... + log 0xdbd5389f: addr(_param1), s, bool(ext_call.success) +``` + +A principal diferença é que o primeiro parâmetro, a janela para retirada, não está lá. Em vez disso, há um loop em todas as janelas que podem ser reivindicadas. + +```python + idx = 0 + s = 0 + while idx < currentWindow: + ... + if stor5[mem[0]]: + if idx == -1: + revert with 0, 17 + idx = idx + 1 + s = s + continue + ... + stor5[idx][addr(_param1)] = 1 + if idx >= unknown81e580d3.length: + revert with 0, 50 + mem[0] = 4 + if unknown81e580d3[idx] and _param2 > -1 / unknown81e580d3[idx]: + revert with 0, 17 + if s > !(unknown81e580d3[idx] * _param2 / 100 * 10^6): + revert with 0, 17 + if idx == -1: + revert with 0, 17 + idx = idx + 1 + s = s + (unknown81e580d3[idx] * _param2 / 100 * 10^6) + continue +``` + +Portanto, parece uma variante da `claim` que reivindica todas as janelas. + +## Conclusão {#conclusion} + +A esta altura, você já deveria saber como entender os contratos cujo código-fonte não está disponível, usando os opcodes ou (quando funciona) o descompilador. Como é evidente na extensão deste artigo, a engenharia reversa de um contrato não é trivial, mas em um sistema em que a segurança é essencial, é uma habilidade importante ser capaz de verificar se os contratos funcionam como prometido. diff --git a/public/content/translations/pt-br/developers/tutorials/run-node-raspberry-pi/index.md b/public/content/translations/pt-br/developers/tutorials/run-node-raspberry-pi/index.md index 668e366fb63..94b31639d96 100644 --- a/public/content/translations/pt-br/developers/tutorials/run-node-raspberry-pi/index.md +++ b/public/content/translations/pt-br/developers/tutorials/run-node-raspberry-pi/index.md @@ -1,6 +1,6 @@ --- title: Como transformar o Raspberry Pi 4 em um nó apenas instalando o cartão MicroSD -description: Formate seu Raspberry Pi 4, conecte um cabo de ethernet e um disco SSD, e ligue o dispositivo. Desta maneira, você terá transformado seu Raspberry Pi 4 em um full node de Ethereum, executando a camada de execução, ou a camada de consendo (Beacon Chain/validador) +description: Piscar seu Raspberry Pi 4, plugar em um cabo ethernet, conectar o disco SSD e ligar o dispositivo para transformar o Raspberry Pi 4 em um nó Ethereum completo + validador author: "EthereumOnArm" tags: - "clientes" @@ -9,258 +9,177 @@ tags: - "nós" lang: pt-br skill: intermediate -published: 2020-05-07 -source: r/ethereum -sourceUrl: https://www.reddit.com/r/ethereum/comments/gf3nhg/ethereum_on_arm_raspberry_pi_4_images_release/ +published: 2022-06-10 +source: Ethereum on ARM +sourceUrl: https://ethereum-on-arm-documentation.readthedocs.io/en/latest/ --- -**TL;DR**: formate seu Raspberry Pi 4, conecte um cabo de rede e um disco SSD, e ligue o dispositivo. Desta maneira, você terá transformado seu Raspberry Pi 4 em um nó completo do Ethereum, executando a camada de execução, ou a camada de consenso (Beacon Chain/validador) +**A Ethereum on Arm é uma imagem personalizada de Linux que pode transformar um Raspberry Pi em um nó Ethereum.** -[Aprenda sobre as implementações no Ethereum](/roadmap/) +Para usar Ethereum on Arm para transformar um Raspberry Pi em um nó Ethereum, recomenda-se o seguinte hardware: -Um pouco de contexto primeiro. Como você sabe, tivemos alguns problemas de memória [[1]](/developers/tutorials/run-node-raspberry-pi/#references) com a imagem do Raspberry Pi 4, já que o Raspbian OS ainda está em 32 bits [[2]](/developers/tutorials/run-node-raspberry-pi/#references) (pelo menos no nível de usuário). Embora preferíssemos manter o sistema operacional oficial, chegamos à conclusão que, para resolver esses problemas, precisamos migrar para um sistema operacional nativo de 64 bits. - -Além disso, os clientes de consenso não suportam binários de 32 bits, então usar o sistema operacional Raspbian impediria que o Raspberry Pi executasse um nó da camada de consenso (e também a possibilidade de fazer staking). - -Portanto, após vários testes, estamos lançando 2 imagens diferentes baseadas no Ubuntu 20.04 de 64 bits [[3]](/developers/tutorials/run-node-raspberry-pi/#references): edições para a camada de execução e para camada de consenso. - -Basicamente, ambos são a mesma imagem e incluem as mesmas funcionalidades das imagens baseadas em Raspbian. Mas elas estão configuradas para executar o “software” da camada de execução ou da camada de consenso por padrão. - -**As imagens cuidam de todos os passos necessários**, desde configurar o ambiente e formatar o disco SSD até instalar e executar o “software” Ethereum, bem como iniciar a sincronização da blockchain. - -## Principais recursos {#main-features} - -- Baseado no Ubuntu 20.04 de 64 bits -- Particionamento e formatação automáticas do disco USB -- Adiciona memória de troca (módulo de “kernel” ZRAM + um arquivo de troca) com base no trabalho do Armbian [[7]](/developers/tutorials/run-node-raspberry-pi/#references) -- Muda o nome do computador para algo como "ethnode-e2a3e6fe" baseado no hash MAC -- Executa o “software” como um serviço systemd e começa a sincronizar a Blockchain -- Inclui um repositório APT para instalar e atualizar o “software” Ethereum -- Inclui um painel de monitoramento baseado no Grafana/Prometheus - -## Software incluído {#software-included} - -Ambas as imagens incluem os mesmos pacotes, a única diferença entre elas é que, por padrão, a versão de execução executa o Geth e a versão de consenso executa o Prysm Beacon Chain. - -### Clientes de execução {#execution-clients} - -- Geth [[8]](/developers/tutorials/run-node-raspberry-pi/#references): 1.9.13 (binário oficial) -- Parity [[9]](/developers/tutorials/run-node-raspberry-pi/#references): 2.7.2 (compilação cruzada) -- Nethermind [[10]](/developers/tutorials/run-node-raspberry-pi/#references): 1.8.28 (compilação cruzada) -- Hyperledger Besu [[11]](/developers/tutorials/run-node-raspberry-pi/#references): 1.4.4 (compilado) - -### Clientes de consenso {#consensus-clients} - -- Prysm [[12]](/developers/tutorials/run-node-raspberry-pi/#references): 1.0.0-alpha6 (binário oficial) -- Lighthouse [[13]](/developers/tutorials/run-node-raspberry-pi/#references): 0.1.1 (compilado) - -### Estrutura Ethereum {#ethereum-framework} - -- Swarm [[14]](/developers/tutorials/run-node-raspberry-pi/#references): 0.5.7 (binário oficial) -- Raiden Network[[15]](/developers/tutorials/run-node-raspberry-pi/#references): 0.200.0~rc1 (binário oficial) -- IPFS [[16]](/developers/tutorials/run-node-raspberry-pi/#references): 0.5.0 (binário oficial) -- Statusd [[17]](/developers/tutorials/run-node-raspberry-pi/#references): 0.52.3 (compilado) -- Vipnode [[18]](/developers/tutorials/run-node-raspberry-pi/#references): 2.3.3 (binário oficial) - -## Guia de instalação e uso {#installation-guide-and-usage} - -### Configuração e equipamentos recomendados {#recommended-hardware-and-setup} - -- Raspberry 4 (modelo B) - 4GB +- Raspberry 4 (modelo B 8 GB), placa mãe Odroid M1 ou Rock 5B (8 GB/16 GB RAM) - Cartão MicroSD (mínimo 16 GB Classe 10) -- Disco SSD 3.0 (ver seção de armazenamento) +- 2 TB SSD minimum USB 3.0 disk ou um SSD com USB para SATA case. - Fonte de alimentação -- Cabo de rede -- Redirecionamento da porta 30303 (camada de execução) e da porta 13000 (camada de consenso) [[4]](/developers/tutorials/run-node-raspberry-pi/#references) -- Um gabinete com dissipador de calor e ventilador (opcional, mas altamente recomendado) -- Teclado USB, Monitor e cabo HDMI (microHDMI) (opcional) +- Cabo da Ethernet +- Encaminhamento de porta (consulte os clientes para obter mais informações) +- Uma case com dissipador de calor e cooler +- Teclado USB, Monitor e cabo HDMI (micro-HDMI) (Opcional) -## Armazenamento {#storage} +## Por que executar Ethereum no ARM? {#why-run-ethereum-on-arm} -Você precisará de um SSD para executar os clientes Ethereum (sem um drive SSD não há absolutamente nenhuma chance de sincronizar a blockchain Ethereum). Existem 2 opções: +Os painéis ARM são computadores muito acessíveis, flexíveis e pequenos. Eles são boas escolhas para rodar os nós do Ethereum porque são baratos, configurados de forma que todos os recursos foquem em apenas um nó, tornando-os mais eficiente; eles consomem energia e são fisicamente menores, assim cabendo em qualquer casa. Também é muito fácil de rodar nós porque o cartão de memória do Raspberry Pi pode simplesmente ser ligado com uma imagem pré montada, sem precisar de download ou software de montagem. -- Use um disco SSD portátil USB, como o SSD Portátil Samsung T5. -- Use um disco externo USB 3.0 com um disco SSD. No nosso caso, utilizamos um disco rígido de 2,5 polegadas Inateck FE2011. Certifique-se de comprar um "case" com um chip compatível com UAS, particularmente, um desses: JMicron (JMS567 or JMS578) ou ASMedia (ASM1153E). +## Como funciona? {#how-does-it-work} -Em ambos os casos, evite obter discos SSD de baixa qualidade, pois é um componente fundamental do seu nó e pode afetar drasticamente o desempenho (e o tempo de sincronização). +O cartão de memória do Raspberry Pi já vem com uma imagem pré montada. Esta imagem contém tudo o que é necessário para executar um nó da Ethereum. Com um cartão flash, tudo o que o usuário precisa fazer é ligar o Raspberry Pi. Todos os processos necessários para executar o nó são iniciados automaticamente. Isso funciona porque o cartão de memória contém um sistema operacional baseado no Linux (OS) na qual os processos em nível de sistema rodam automaticamente e se tornam a unidade em um nó de Ethereum. -Tenha em mente que você precisa conectar o disco a uma porta USB 3.0 (azul) +O Ethereum não pode rodar usando o popular Raspberry Pi Linux "Raspbian" porque o Raspbian ainda usa uma arquitetura de 32 bits que leva os Usuários do Ethereum a ter problemas com memória e o cliente de consenso não suporta binários de 32-bits. Para superar isso, a Ethereum on Arm migrou para um OS nativo de 64 bits chamado "Armbian". -## Download e instalação de imagens {#image-download-and-installation} +**As imagens cuidam de todos os passos necessários**, desde configurar o ambiente e formatar o disco SSD até instalar e executar o “software” Ethereum, bem como iniciar a sincronização da blockchain. + +## Execução de acoplamento e clientes de consenso {#note-on-execution-and-consensus-clients} + +A imagem do Ethereum on Arm incluí uma execução pré construída e o cliente de consenso como serviços. Um nó Ethereum exige que ambos os clientes estejam sincronizados e executados. Você só precisa fazer o download, instalar a imagem flash e iniciar os serviços. A imagem é pré carregada com os seguintes clientes de execução: -### 1. Baixar as imagens das camadas de execução e de consenso {#1-download-execution-or-consensus-images} +- Geth +- Nethermind +- Besu - - Baixar imagem da camada de execução - +e os seguintes clientes de consenso: -sha256 7fa9370d13857dd6abcc8fde637c7a9a7e3a66b307d5c28b0c0d29a09c73c55c +- Lighthouse +- Nimbus +- Prysm +- Teku - - Baixar imagem da camada de consenso - +Você deve escolher um de cada para executar - todos os clientes de execução são compatíveis com todos os clientes de consenso. Se você não selecionar explicitamente um cliente, o nó vai voltar aos seus padrões - Geth e Lighthouse - e executá-los automaticamente quando o quadro estiver ligado. Você precisa abrir a porta 30303 no seu roteador para o Geth Encontrar e conectar-se aos pares. -sha256 74c0c15b708720e5ae5cac324f1afded6316537fb17166109326755232cd316e +## Baixando imagem {#downloading-the-image} -### 2. Instalar a imagem {#2-flash-the-image} +A imagem Ethereum Raspberry Pi 4 é uma imagem "plug and play" que vai instalar automaticamente e configurar ambos clientes de consenso e de execução, configurando-os para conversarem entre si e conectarem-se à rede Ethereum. Tudo o que o usuário precisa fazer é iniciar seus processos usando um simples comando. -Insira o microSD no seu computador e baixe o arquivo (camada de execução, por exemplo): +Baixe a imagem do Raspberry Pi em [Ethereum no Arm](https://ethereumonarm-my.sharepoint.com/:u:/p/dlosada/Ec_VmUvr80VFjf3RYSU-NzkBmj2JOteDECj8Bibde929Gw?download=1) e verifique o hash SHA256: -```bash -wget https://ethraspbian.com/downloads/ubuntu-20.04-preinstaladod-server-arm64+raspi-eth1.img.zip +```sh +# From directory containing the downloaded image +shasum -a 256 ethonarm_22.04.00.img.zip +# Hash should output: fb497e8f8a7388b62d6e1efbc406b9558bee7ef46ec7e53083630029c117444f ``` -Nota: Se você não estiver cômodo com a linha de comando ou se estiver executando o Windows, você pode usar o [Etcher](https://etcher.io) +Note que as imagens para as placas Rock 5B e Odroid M1 estão disponíveis no Ethereum-On-Arm [página de downloads](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/quick-guide/download-and-install.html). -Abra um terminal e verifique o nome do seu MicroSD em execução: +## Instalando o MicroSD {#flashing-the-microsd} -```bash -sudo fdisk -l -``` +O cartão MicroSD que vai ser usado no Raspberry Pi deve ser primeiro inserido em um desktop ou laptop para que seja instalado. Em seguida, os seguintes comandos do terminal instalarão a imagem baixada no cartão SD: -Você deve ver um dispositivo chamado mmcblk0 ou sdd. Descompactar e instalar a imagem: +```shell +# check the MicroSD card name +sudo fdisk -l -```bash -unzip ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img.zip sudo dd bs=1M if=ubuntu-20.04-preinstalled-server-arm64+raspi-eth1.img of=/dev/mmcblk0 && sync +>> sdxxx ``` -### 3. Insira o MicroSD no Raspberry Pi 4. Conecte um cabo de rede e conecte o disco SSD USB (certifique-se de estar usando uma porta azul). {#3-insert-the-microsd-into-the-raspberry-pi-4-connect-an-ethernet-cable-and-attach-the-usb-ssd-disk-make-sure-you-are-using-a-blue-port} - -### 4. Ligue o dispositivo {#4-power-on-the-device} +É muito importante se atentar ao nome correto pois o próximo comando inclui`dd` que apaga completamente o conteúdo existente do cartão antes de instalar a imagem dentro nele. Para continuar, navegue até o diretório que contém a imagem compactada: -O sistema operacional Ubuntu se iniciará em menos de um minuto, mas **você precisará esperar aproximadamente 10 minutos** para permitir que o script execute as tarefas necessárias para transformar o dispositivo em um nó Ethereum e reiniciar o Raspberry. +```shell +# unzip and flash image +unzip ethonarm_22.04.00.img.zip +sudo dd bs=1M if=ethonarm_22.04.00.img of=/dev/ conv=fdatasync status=progress +``` -Dependendo da imagem, você estará executando: +O cartão esta instalado, para que seja inserido no Raspberry Pi. -- Cliente de execução: Geth como o cliente padrão que sincroniza a blockchain -- Cliente de consenso: Prysm como cliente padrão que sincroniza a Beacon Chain (rede de teste Goerli) +## Inicie o nó {#start-the-node} -### 5. Iniciar sessão {#5-log-in} +Com o cartão SD inserido no Raspberry Pi, conecte o cabo Ethernet e SSD e então ligue o aparelho. O OS vai iniciar e automaticamente começará a executar as tarefas pré-configuradas que transformam o Raspberry Pi em um nó de Ethereum, incluindo a instalação e construção de um software cliente. Isso levará provavelmente 10-15 minutos. -Você pode fazer login através do SSH ou usando o console (se você tiver um monitor e teclado conectados) +Assim que tudo estiver instalado e configurado, faça login no dispositivo via uma conecção ssh ou usando o terminal diretamente se um monitor e teclado estiverem conectados à placa. Use a conta `ethereum` para logar, pois isso tem as permissões necessárioas para iniciar o nó. -```bash +```shell Usuário: ethereum Senha: Ethereum ``` -Você será solicitado a alterar a senha no primeiro login, então você precisará se conectar duas vezes. - -### 6. Abra a porta 30303 para Geth e 13000 se estiver executando a Beacon Chain Prysm. Se você não sabe como fazer isso, faça uma busca no Google de "encaminhamento de porta", seguido pelo seu modelo de roteador. {#6-open-30303-port-for-geth-and-13000-if-you-are-running-prysm-beacon-chain-if-you-dont-know-how-to-do-this-google-port-forwarding-followed-by-your-router-model} - -### 7. Ver a saída no console {#7-get-console-output} - -Você pode ver o que está acontecendo em segundo plano digitando: +O cliente de execução padrão, Geth, irá iniciar automaticamente. Você pode confirmar isso checando os logs usando o seguinte comando no terminal: -```bash -sudo tail -f /var/log/syslog +```sh +sudo journalctl -u geth -f ``` -**Parabéns. Agora você está executando um nó Ethereum completo no seu Raspberry Pi 4.** - -## Sincronizando a Blockchain {#syncing-the-blockchain} - -Agora você precisa esperar que a blockchain seja sincronizada. No caso da camada de execução, esse processo levará alguns dias dependendo de vários fatores, mas você pode esperar algo entre 5 – 7 dias. - -Se está executando a rede de teste Goerli para a camada de consenso, você pode esperar entre 1–2 dias para a sincronização da Beacon Chain. Lembre-se de que precisará configurar o validador mais tarde para iniciar o processo de apostas. [Como executar o validador da camada de consenso](/developers/tutorials/run-node-raspberry-pi/#validator) - -## Painéis de monitoramento {#monitoring-dashboards} - -Para esta primeira versão, incluímos 3 dashboards de monitoramento com base no Prometheus [[5]](/developers/tutorials/run-node-raspberry-pi/#references) / Grafana [[6]](/developers/tutorials/run-node-raspberry-pi/#references) para monitorar os dados do nó e dos clientes (Geth e Besu). Você pode acessar através do seu navegador: +O cliente de consenso precisa de ser iniciado explicitamente. Para fazer isso, primeiro abra a porta 9000 no seu roteador para que o farol possa encontrar e se conectar a pares. Então habilite e inicie o serviço de lighthouse: -```bash -URL: http://your_raspberrypi_IP:3000 -Usuário: admin -Senha: ethereum +```sh +sudo systemctl enable lighthouse-beacon +sudo systemctl start lighthouse-beacon ``` -## Alternando clientes {#switching-clients} +Verifique o cliente usando os logs: -Todos os clientes são executados como um serviço systemd. Isto é importante porque, se surgir um problema, o sistema recomeçará automaticamente o processo. - -Geth and Prysm beacon chain run by default (depending on what you are synchronizing, execution layer or consensus layer) so, if you want to switch to other clients (from Geth to Nethermind, for instance), you need to stop and disable Geth first, and enable and start the other client: - -```bash -sudo systemctl stop geth && sudo systemctl disable geth +```sh +sudo journalctl -u lighthouse-beacon ``` -Comandos para habilitar e iniciar cada cliente de execução: +Observe que o cliente de consenso irá sincronizar em alguns minutos porque ele usa a sincronização do ponto de controle. O cliente de execução vai levar mais tempo - Potencialmente algumas horas, e ele não vai executar até que o cliente de consenso termine de sincronizar (isso porque o cliente de execução precisa de um alvo para sincronizar, que o cliente de consenso sincronizado fornece). -```bash -sudo systemctl habilita besu && sudo systemctl start besu -sudo systemctl enable nethermind && sudo systemctl start nethermind -sudo systemctl enable parity && sudo systemctl start parity -``` +Com os serviços Geth e Lighthouse sincronizados e rodando, seu Raspberry Pi agora é um nó de Ethereum! É mais comum interagir com a rede Ethereum utilizando o console Javascript do Geth, que pode ser anexado ao cliente Geth na porta 8545. Também é possível enviar comandos formatados como objetos JSON usando uma ferramenta de solicitação como o Curl. Veja mais em [Documentação Geth](https://geth.ethereum.org/). -Clientes de consenso: +Geth é pré configurado para enviar relatórios pro painel Grafana, que pode ser visto no seu navegador. Usuários mais avançados podem querer usar este recurso para monitorar a saúde do seu nó navegando para `ipaddress.3000`, passing`usuário: admin` e `senha:ethereum`. -```bash -sudo systemctl stop prysm-beacon && sudo systemctl disable prysm-beacon -sudo systemctl start lighthouse && sudo systemctl enable light thouse -``` +## Validadores {#validators} -## Modificando parâmetros {#changing-parameters} +Um validador também pode ser opcionalmente adicionado ao cliente de consenso. O software validador permite seu nó de participar ativamente no consenso e fornece a rede com segurança criptoeconomica. Você será recompensado por este trabalho em ETH. Para rodar um validador, você precisa primeiro ter 32 ETH, que precisa ser depositado em um contrato de depósito. **Este é um termo de compromisso a longo prazo - ainda não é possível sacar este ETH!**. O depósito pode ser feito seguindo o passo a passo no [Launchpad](https://launchpad.ethereum.org/). Faça isso em um desktop/laptop, mas não gere chaves — isso pode ser feito diretamente no Raspberry Pi. -Os arquivos de configuração do cliente estão localizados no diretório /etc/ethereum/. Você pode editar esses arquivos e reiniciar o serviço do sistema para que as alterações tenham efeito. A única exceção é o Nethermind que, além disso, tem um arquivo de configuração Mainnet localizado aqui: +Abra um terminal no Raspberry Pi e execute o seguinte comando para gerar as chaves de depósito: -```bash -/etc/nethermind/configs/mainnet.cfg ``` - -Os dados dos clientes Blockchain são armazenados no diretório inicial da conta Ethereum do seguinte modo (observe o ponto antes do nome do diretório): - -### Camada de execução {#execution-layer} - -```bash -/home/ethereum/.geth -/home/ethereum/.parity -/home/ethereum/.besu -/home/ethereum/.nethermind +sudo apt-get update +sudo apt-get install staking-deposit-cli +cd && deposit new-mnemonic --num_validators 1 ``` -### Camada de consenso {#consensus-layer} +Mantenha a frase mnemônica segura! O comando acima gerou dois arquivos no keystore: as chaves validadoras e um arquivo de dados de depósito. Os dados do depósito precisam ser carregados no launchpad, portanto, devem ser copiados do Raspberry Pi para o desktop/laptop. Isso pode ser feito usando uma conexão ssh ou qualquer outro método de copiar/colar. -```bash -/home/ethereum/.eth2 -/home/ethereum/.eth2validators -/home/ethereum/.lighthouse -``` +Uma vez que o arquivo de dados do depósito estiver disponível no computador que executa o launchpad, ele pode ser arrastado e solto no `+` na tela do launchpad. Siga as instruções na tela para enviar uma transação para o contrato de depósito. -## Nethermind e Hyperledger Besu {#nethermind-and-hyperledger-besu} +De volta ao Raspberry Pi, um validador pode ser iniciado. Isso requer importar as chaves do validador, definir o endereço para coletar recompensas e, em seguida, iniciar o processo do validador pré-configurado. O exemplo abaixo é para o Lighthouse - instruções para outros clientes de consenso estão disponíveis na [Ethereum on Arm docs](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/): -Estes 2 grandes clientes de execução tornaram-se uma ótima alternativa ao Geth e Parity. Quanto maior a diversidade na rede melhor. Testá-los contribui para a integridade da rede. +```shell +# import the validator keys +lighthouse account validator import --directory=/home/ethereum/validator_keys -Ambos precisam de mais testes, por isso sinta-se livre para testá-los e compartilhar suas impressões. +# set the reward address +sudo sed -i 's/' /etc/ethereum/lighthouse-validator.conf -## Como gerenciar o validador do consenso (staking) {#validator} +# start the validator +sudo systemctl start lighthouse-validator +``` -Uma vez que a Beacon Chain da rede de teste Goerli for sincronizada, você vai poder executar um validador no mesmo dispositivo. Você precisará seguir [essas etapas de participação](https://prylabs.net/participate). +Parabéns, agora você tem um nó Ethereum completo e um validador rodando em um Raspberry Pi! -Na primeira vez, você precisa criar uma conta manualmente executando o binário "validador" e configurando uma senha. Depois de concluir esta etapa, você pode adicionar a senha a `/etc/ethereum/prysm-validator.conf` e iniciar o validador como um serviço systemd. +## Mais detalhes {#more-details} -## Agradecemos o feedback {#feedback-appreciated} +Esta página deu uma visão geral de como configurar um nó e validador Geth-Lighthouse usando Raspberry Pi. Instruções mais detalhadas estão disponíveis no [site Ethereum-on-Arm](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/index.html). -Nos esforçamos muito para configurar o Raspberry Pi 4 como um nó Ethereum completo, pois sabemos que a base de usuários massiva deste dispositivo pode causar um impacto muito positivo na rede. +## Agradecemos o feedback {#feedback-appreciated} -Como esta é a primeira imagem baseada no Ubuntu 20.04, pode haver alguns erros. Caso haja, informe o problema no [GitHub](https://github.com/diglos/ethereumonarm) ou entre em contato conosco no [Twitter](https://twitter.com/EthereumOnARM). +Sabemos que o Raspberry Pi tem uma enorme base de usuários, que pode ter um impacto muito positivo na saúde da rede Ethereum. Por favor, explore os detalhes deste tutorial, tente rodar em redes de teste, confira o Ethereum on Arm pelo GitHub, dê feedback, levante questões e pull requests e ajude a avançar a tecnologia e a documentação! ## Referências {#references} -1. [geth falha repetidamente com SIGSEGV](https://github.com/ethereum/go-ethereum/issues/20190) -2. [https://github.com/diglos/ethereumonarm](https://github.com/diglos/ethereumonarm) -3. https://ubuntu.com/download/raspberry-pi -4. https://wikipedia.org/wiki/Port_forwarding -5. https://prometheus.io -6. https://grafana.com -7. https://forum.armbian.com/topic/5565-zram-vs-swap/ -8. https://geth.ethereum.org -9. **Note que o OpenEthereum [foi descontinuado](https://medium.com/openethereum/gnosis-joins-erigon-formerly-turbo-geth-to-release-next-gen-ethereum-client-c6708dd06dd) e não está mais sendo mantido.** Use-o com cuidado e de preferência mude para outra implementação de cliente. -10. https://nethermind.io -11. https://www.hyperledger.org/projects/besu -12. https://github.com/prysmaticlabs/prysm -13. https://lighthouse.sigmaprime.io -14. https://ethersphere.github.io/swarm-home -15. https://raiden.network -16. https://ipfs.io -17. https://status.im -18. https://vipnode.org +1. https://ubuntu.com/download/raspberry-pi +2. https://wikipedia.org/wiki/Port_forwarding +3. https://prometheus.io +4. https://grafana.com +5. https://forum.armbian.com/topic/5565-zram-vs-swap/ +6. https://geth.ethereum.org +7. https://nethermind.io +8. https://www.hyperledger.org/projects/besu +9. https://github.com/prysmaticlabs/prysm +10. https://lighthouse.sigmaprime.io +11. https://ethersphere.github.io/swarm-home +12. https://raiden.network +13. https://ipfs.io +14. https://status.im +15. https://vipnode.org diff --git a/public/content/translations/pt-br/developers/tutorials/secure-development-workflow/index.md b/public/content/translations/pt-br/developers/tutorials/secure-development-workflow/index.md new file mode 100644 index 00000000000..4a20bad7f85 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/secure-development-workflow/index.md @@ -0,0 +1,56 @@ +--- +title: Checklist de segurança para smart contracts +description: Um workflow sugerido para escrever smart contracts seguros +author: "Trailofbits" +tags: + - "contratos inteligentes" + - "segurança" + - "solidity" +skill: intermediate +lang: pt-br +published: 2020-09-07 +source: Construindo contratos seguros +sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/workflow.md +--- + +## Processo de desenvolvimento do contrato inteligente {#smart-contract-development-checklist} + +Aqui temos um processo de alto nível que recomendamos seguir enquanto você escreve seus contratos inteligentes. + +Verificar problemas de segurança conhecidos: + +- Reveja seus contratos com o [Slither](https://github.com/crytic/slither). Tem mais de 40 detectores internos para vulnerabilidades comuns. Execute em cada check-in com um novo código e certifique-se de que ele recebe um relatório limpo (ou use o modo de triagem para silenciar certos problemas). +- Reveja seus contratos com o [Crytic](https://crytic.io/). Ele verifica 50 problemas que o Slither não tem. O Crytic também pode ajudar sua equipe a se manter atualizada, resolvendo problemas de segurança facilmente nas solicitações de pull no GitHub. + +Considere as características especiais do seu contrato: + +- Os seus contratos são atualizáveis? Verifique se há defeitos em seu código de capacidade de atualização com o [`slither-check-upgradeability`](https://github.com/crytic/slither/wiki/Upgradeability-Checks) ou [Crytic](https://blog.trailofbits.com/2020/06/12/upgradeable-contracts-made-safer-with-crytic/). Documentamos 17 situações em que as atualizações podem correr mal. +- Seus contratos pretendem estar em conformidade com os ERCs? Verifique com [`slither-check-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance). Esta ferramenta identifica instantaneamente desvios de seis especificações comuns. +- Você tem testes de unidade no Truffle? Verifique com [`slither-check-erc`](https://github.com/crytic/slither/wiki/Property-generation). Ele gera automaticamente um robusto conjunto de propriedades de segurança para recursos do ERC20 com base no seu código específico. +- Você faz integrações com tokens de outras empresas? Revise nossa [lista de verificação de integração de tokens](/developers/tutorials/token-integration-checklist/) antes de confiar em contratos externos. + +Visualmente inspecione recursos críticos de segurança com seu código: + +- Analise o printer [inheritance-graph](https://github.com/trailofbits/slither/wiki/Printer-documentation#inheritance-graph) do Slither. Evite problemas de linearização de sombras e C3 involuntários. +- Analise o printer [inheritance-graph](https://github.com/trailofbits/slither/wiki/Printer-documentation#function-summary) do Slither. Reporta a visibilidade da função e os controles de acesso. +- Analise o printer [vars-and-auth](https://github.com/trailofbits/slither/wiki/Printer-documentation#variables-written-and-authorization) do Slither. Ele relata os controles de acesso às variáveis de estado. + +Propriedades de segurança críticas do documento e use geradores de testes automatizados para avaliá-las: + +- Aprenda com [as propriedades de segurança de documentos para o seu código](/developers/tutorials/guide-to-smart-contract-security-tools/). É difícil no início, mas é a atividade mais importante para alcançar um bom resultado. Também é um pré-requisito para usar qualquer uma das técnicas avançadas neste tutorial. +- Defina as propriedades de segurança no Solidity, para usar com [Echidna](https://github.com/crytic/echidna) e [Manticore](https://manticore.readthedocs.io/en/latest/verifier.html). Concentre-se na sua máquina do estado, controles de acesso, operações aritméticas, interações externas e padrões de conformidade. +- Defina as propriedades de segurança com [API Python do Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/). Concentre-se na herança, nas dependências variáveis, nos controles de acesso e em outras questões estruturais. +- Execute seus testes de propriedade em cada commit com [Crytic](https://crytic.io). Critica pode consumir e avaliar testes de propriedade de segurança para que todos na sua equipe possam facilmente ver que eles passam no GitHub. Os testes que falharam podem bloquear os commits. + +Finalmente, esteja atento a questões que as ferramentas automatizadas não conseguem facilmente encontrar: + +- Falta de privacidade: todos os outros podem ver suas transações enquanto são enfileiradas no pool +- Transações principais em execução +- Operações criptográficas +- Interações arriscadas com componentes externos de DeFi + +## Pedir ajuda {#ask-for-help} + +[Horário de escritório Ethereum](https://calendly.com/dan-trailofbits/ethereum-office-hours) executa todas as terças da tarde. Essas sessões presenciais de uma hora são uma oportunidade para você nos fazer quaisquer perguntas que sobre segurança, solucionar problemas usando nossas ferramentas e obter comentários de especialistas sobre sua abordagem atual. Vamos ajudá-lo a trabalhar neste guia. + +Junte-se ao nosso Slack: [Empire Hacking](https://join.slack.com/t/empirehacking/shared_invite/zt-h97bbrj8-1jwuiU33nnzg67JcvIciUw). Sempre estaremos disponíveis nos canais #crytic e #ethereum caso tenha alguma dúvida. diff --git a/public/content/translations/pt-br/developers/tutorials/send-token-etherjs/index.md b/public/content/translations/pt-br/developers/tutorials/send-token-etherjs/index.md new file mode 100644 index 00000000000..f57529f2ef8 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/send-token-etherjs/index.md @@ -0,0 +1,212 @@ +--- +title: Envio de fichas usando ethers.js +description: Guia amigo para iniciantes enviarem tokens usando ethers.js. +author: Kim YongJun +tags: + - "ETHERS.JS" + - "ERC-20" + - "TOKENS" +skill: beginner +lang: pt-br +published: 2021-04-06 +--- + +## Enviar Token usando ethers.js(5.0) {#send-token} + +### Neste tutorial, você aprenderá {#you-learn-about} + +- Importar ethers.js +- Transferência de tokens +- Defina o preço do gás de acordo com a situação do tráfego de rede + +### Iniciado {#to-get-started} + +Para começar, primeiro devemos importar a biblioteca ethers.js para nossa javascript Incluir ethers.js(5.0) + +### Instalando {#install-ethersjs} + +```shell +/home/ricmoo> npm install --save ethers +``` + +ES6 no Navegador + +```html + +``` + +ES3(UMD) no Navegador + +```html + +``` + +### Parâmetros {#param} + +1. **`contract_address`**: Endereço do contrato do token (o endereço do contrato é necessário quando o token que você deseja transferir não for ether) +2. **`send_token_amount`**: A quantia que você deseja enviar para o destinatário +3. **`to_address`**: O endereço do destinatário +4. **`to_address`**: O endereço do destinatário +5. **`private_key`**: Chave privada do remetente para assinar a transação e realmente transferir os tokens + +## Nota {#notice} + +`signTransaction(tx)` foi removido porque `sendTransaction()` fez isso internamente. + +## Enviando Procedimentos {#procedure} + +### 1. Conectar à rede (testnet) {#connect-to-network} + +#### Definir Provedor (Infura) {#set-provider} + +Conecte-se à rede de teste Ropsten + +```javascript +window.ethersProvider = new ethers.providers.InfuraProvider("ropsten") +``` + +### 2. Criar Carteira {#create-wallet} + +```javascript +let wallet = new ethers.Wallet(private_key) +``` + +### 3. Conectar carteira à rede {#connect-wallet-to-net} + +```javascript +let walletSigner = wallet.connect(window.ethersProvider) +``` + +### 4. Obter o atual preço do gás {#get-gas} + +```javascript +window.ethersProvider.getGasPrice() // gasPrice +``` + +### 5. Definir a Transação {#define-transaction} + +Essas variáveis definidas abaixo dependem de `send_token()` + +### Parâmetros de transação {#transaction-params} + +1. **`send_account`**: endereço do remetente do token +2. **`to_address`**: endereço do receptor do token +3. **`send_token_amount`**: a quantidade de tokens a serem enviados +4. **`gas_limit`**: limite de gas +5. **`gas_price`**: preço do gas + +[Veja abaixo como usar](#how-to-use) + +```javascript +const tx = { + from: send_account, + to: to_address, + value: ethers.utils.parseEther(send_token_amount), + nonce: window.ethersProvider.getTransactionCount(send_account, "latest"), + gasLimit: ethers.utils.hexlify(gas_limit), // 100000 + gasPrice: gas_price, +} +``` + +### 6. Transferir {#transfer} + +```javascript +walletSigner.sendTransaction(tx).then((transaction) => { + console.dir(transaction) + alert("Send finished!") +}) +``` + +## Como usar {#how-to-use} + +```javascript +let private_key = + "41559d28e936dc92104ff30691519693fc753ffbee6251a611b9aa1878f12a4d" +let send_token_amount = "1" +let to_address = "0x4c10D2734Fb76D3236E522509181CC3Ba8DE0e80" +let send_address = "0xda27a282B5B6c5229699891CfA6b900A716539E6" +let gas_limit = "0x100000" +let wallet = new ethers.Wallet(private_key) +let walletSigner = wallet.connect(window.ethersProvider) +let contract_address = "" +window.ethersProvider = new ethers.providers.InfuraProvider("ropsten") + +send_token( + contract_address, + send_token_amount, + to_address, + send_address, + private_key +) +``` + +### Sucesso! {#success} + +![imagem da transação realizada com sucesso](./successful-transaction.png) + +## send_token() {#send-token-method} + +```javascript +function send_token( + contract_address, + send_token_amount, + to_address, + send_account, + private_key +) { + let wallet = new ethers.Wallet(private_key) + let walletSigner = wallet.connect(window.ethersProvider) + + window.ethersProvider.getGasPrice().then((currentGasPrice) => { + let gas_price = ethers.utils.hexlify(parseInt(currentGasPrice)) + console.log(`gas_price: ${gas_price}`) + + if (contract_address) { + // general token send + let contract = new ethers.Contract( + contract_address, + send_abi, + walletSigner + ) + + // How many tokens? + let numberOfTokens = ethers.utils.parseUnits(send_token_amount, 18) + console.log(`numberOfTokens: ${numberOfTokens}`) + + // Send tokens + contract.transfer(to_address, numberOfTokens).then((transferResult) => { + console.dir(transferResult) + alert("sent token") + }) + } // ether send + else { + const tx = { + from: send_account, + to: to_address, + value: ethers.utils.parseEther(send_token_amount), + nonce: window.ethersProvider.getTransactionCount( + send_account, + "latest" + ), + gasLimit: ethers.utils.hexlify(gas_limit), // 100000 + gasPrice: gas_price, + } + console.dir(tx) + try { + walletSigner.sendTransaction(tx).then((transaction) => { + console.dir(transaction) + alert("Send finished!") + }) + } catch (error) { + alert("failed to send!!") + } + } + }) +} +``` diff --git a/public/content/translations/pt-br/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md b/public/content/translations/pt-br/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md new file mode 100644 index 00000000000..0e1b489cdc3 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md @@ -0,0 +1,206 @@ +--- +title: Enviando transações usando Web3 +description: "Este é um guia amigável para iniciantes enviarem transações Ethereum usando web3. Existem três etapas principais para enviar uma transação para a blockchain Ethereum: criar, assinar e transmitir. Analisaremos todas as três." +author: "Elan Halpern" +tags: + - "transações" + - "web3.js" + - "alchemy" +skill: intermediate +lang: pt-br +published: 2020-11-04 +source: Documentação do Alchemy +sourceUrl: https://docs.alchemy.com/alchemy/tutorials/sending-txs +--- + +Este é um guia amigável para iniciantes enviarem transações Ethereum usando web3. Existem três etapas principais para enviar uma transação para a blockchain Ethereum: criar, assinar e transmitir. Analisaremos todas as três, esperamos responder a quaisquer perguntas que você possa ter! Neste tutorial, estaremos usando [Alchemy](https://www.alchemy.com/) para enviar as nossas transações para a cadeia Ethereum. Você pode [criar uma conta Alchemy grátis aqui](https://auth.alchemyapi.io/signup). + +**NOTA:** Este guia é para assinar suas transações no _back-end_ do seu aplicativo. Se você quer integrar a assinatura de suas transações no front-end, verifique a integração [Web3 com um provedor de navegador](https://docs.alchemy.com/reference/api-overview#with-a-browser-provider). + +## O básico {#the-basics} + +Como a maioria dos desenvolvedores blockchain quando iniciam, você pode ter feito algumas pesquisas sobre como enviar uma transação (algo que deve ser bem simples) e encontrado com uma infinidade de guias, cada um deles diz coisas diferentes e te deixa um pouco sobrecarregado e confuso. Se você está naquele barco, não se preocupe, todos estivemos em algum momento! Então, antes de começarmos, vamos ver algumas coisas certas: + +### 1\. Alchemy não armazena suas chaves privadas {#alchemy-does-not-store-your-private-keys} + +- Isso significa que Alchemy não pode assinar e enviar transações em seu nome. A razão para isso é a questão da segurança. Alchemy nunca vai te pedir para compartilhar sua chave privada, e você nunca deve compartilhar sua chave privada com um nó hospedado (ou alguém para isso). +- Você pode ler a partir da blockchain usando a API principal do Alchemy, mas para gravar nela, você precisará usar outra coisa para assinar suas transações antes de enviá-las por meio do Alchemy (assim como para qualquer outro [serviço de nó](/developers/docs/nodes-and-clients/nodes-as-a-service/)). + +### 2\. O que é um “assinante”? {#what-is-a-signer} + +- Assinantes assinarão transações para você usando sua chave privada. Neste tutorial iremos utilizar [Alchemy web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3) para assinar a nossa transação, mas também poderia utilizar qualquer outra biblioteca web3. +- No front-end, um bom exemplo de assinante seria o [MetaMask](https://metamask.io/), que assinará e enviará transações em seu nome. + +### 3\. Por que preciso assinar minhas transações? {#why-do-i-need-to-sign-my-transactions} + +- Cada usuário que desejar enviar uma transação na rede Ethereum deve assinar a transação (usando sua chave privada), a fim de validar a autenticidade da origem da transação. +- É super importante proteger esta chave privada, uma vez que o acesso a ela concede controle total sobre a sua conta Ethereum, permitindo que você (ou qualquer um com acesso) realize transações em seu nome. + +### 4\. Como eu protejo minha chave privada? {#how-do-i-protect-my-private-key} + +- Há muitas maneiras de proteger a sua chave privada e usá-la para enviar transações. Neste tutorial, usaremos um arquivo `.env`. No entanto, você também pode usar um provedor separado que armazena chaves privadas, usa um arquivo de keystore ou outras opções. + +### 5\. Qual é a diferença entre `eth_sendTransaction` e `eth_sendRawTransaction`? {#difference-between-send-and-send-raw} + +`eth_sendTransaction` e `eth_sendRawTransaction` são ambas funções da API da Ethereum que transmitem uma transação para a rede Ethereum, então ela será adicionada a um bloco futuro. Eles diferem na forma como lidam com a assinatura das transações. + +- [`eth_sendTransaction`](https://docs.web3js.org/api/web3-eth/function/sendTransaction) é usado para enviar _transações_ não assinadas, o que significa que o nó que você está enviando deve gerenciar a sua chave privada para que possa assinar a transação antes de transmiti-la para a cadeia. Como o Alchemy não possui as chaves privadas do usuário, eles não oferecem suporte a esse método. +- [`eth_sendRawTransaction`](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction) é usado para transmitir transações que já foram assinadas. Isso significa que você deve primeiro usar [`signTransaction(tx, private_key)`](https://docs.web3js.org/api/web3-eth-accounts/function/signTransaction), e então transmitir o resultado para `eth_sendRawTransaction`. + +Ao usar o web3, `eth_sendRawTransaction` é acessado ao chamar a função [web3.eth.sendSignedTransaction](https://docs.web3js.org/api/web3-eth/function/sendSignedTransaction). + +Isso é o que nós usaremos neste tutorial. + +### 6\. Qual é a biblioteca de web3? {#what-is-the-web3-library} + +- Web3.js é uma biblioteca wrapper em torno das chamadas JSON-RPC padrão que é bastante comum de usar no desenvolvimento de Ethereum. +- Há várias bibliotecas Web3 para diferentes tipos de linguagem. Neste tutorial, estaremos usando [Alchemy Web3](https://docs.alchemy.com/reference/api-overview) que está escrito em JavaScript. Você pode verificar outras opções [aqui](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries) como [ethers.js](https://docs.ethers.org/v5/). + +Ok, agora que temos esclarecemos esses pontos, passemos para o tutorial. Sinta-se à vontade para fazer perguntas a qualquer momento no [discord](https://discord.gg/gWuC7zB) do Alchemy! + +### 7\. Como enviar transações seguras, otimizadas de gás e privadas? {how-to-send-secure-gas-optimized-and-private-transactions} + +- [Alchemy tem um conjunto de APIs para Transações](https://docs.alchemy.com/reference/transact-api-quickstart). Você pode usá-los para reforçar transações, simular transações antes que elas aconteçam, enviar transações privadas e enviar transações otimizadas de gás +- Você também pode usar a [API de notificação](https://docs.alchemy.com/docs/alchemy-notify) para ser alertado quando sua transação for retirada do mempool e adicionada à cadeia + +**NOTA:** Este guia requer uma conta Alchemy, um endereço Ethereum ou carteira MetaMask, NodeJs e npm instalados. Se não, siga estes passos: + +1. [Crie uma conta gratuita em Alchemy](https://auth.alchemyapi.io/signup) +2. [Crie uma conta MetaMask](https://metamask.io/) (ou obtenha um endereço Ethereum) +3. [Siga estes passos para instalar o NodeJs e NPM](https://docs.alchemy.com/alchemy/guides/alchemy-for-macs) + +## Passos para enviar sua transação {#steps-to-sending-your-transaction} + +### 1\. Crie um aplicativo Alchemy na rede de testes Sepolia {#create-an-alchemy-app-on-the-sepolia-testnet} + +Navegue até o seu [Painel da Alchemy](https://dashboard.alchemyapi.io/) e crie um novo aplicativo, escolhendo Sepolia (ou qualquer outra rede de teste) para sua rede. + +### 2\. Solicite ETH do faucet Sepolia {#request-eth-from-sepolia-faucet} + +Siga as instruções na [torneira Sepolia da Alchemy](https://www.sepoliafaucet.com/) para receber ETH. Certifique-se de incluir seu endereço do Ethereum **Sepolia** (da MetaMask) e não outra rede. Após seguir as instruções, verifique novamente se você recebeu o ETH em sua carteira. + +### 3\. Crie um novo diretório do projeto e insira `cd` {#create-a-new-project-direction} + +Crie um novo diretório de projetos a partir da linha de comando (terminal para macs) e navegue até ele: + +``` +mkdir sendtx-example +cd sendtx-example +``` + +### 4\. Instale o Alchemy Web3 (ou qualquer biblioteca web3) {#install-alchemy-web3} + +Execute o seguinte comando em seu diretório do projeto para instalar [Alchemy Web3](https://docs.alchemy.com/reference/api-overview): + +Note que, se você quiser usar a biblioteca ethers.js, [siga as instruções aqui](https://docs.alchemy.com/docs/how-to-send-transactions-on-ethereum). + +``` +yarn add @alch/alchemy-web3 +``` + +### 5\. Instale o dotenv {#install-dotenv} + +Usaremos um arquivo `.env` para armazenar com segurança nossa chave de API e a chave privada. + +``` +npm install dotenv --save +``` + +### 6\. Crie o arquivo `.env` {#create-the-dotenv-file} + +Crie um arquivo `.env` no diretório de seu projeto e adicione o seguinte (substituindo “`your-api-url`" e "`your-private-key` ") + +- Para encontrar o URL da API de Alchemy, navegue até a página de detalhes do aplicativo que você acabou de criar no seu painel, clique em "Ver Chave" no canto superior direito e pegue a URL HTTP. +- Para encontrar sua chave privada usando MetaMask, confira este [guia](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key). + +``` +API_URL = "your-api-url" +PRIVATE_KEY = "your-private-key" +``` + + +No faça commit do .env! Por favor, tenha certeza de nunca compartilhar ou expor seu arquivo .env com ninguém, pois estará comprometendo suas partes secretas ao fazê-lo. Se estiver usando um controle de versão, adicione seu .env ao arquivo gitignore + + +### 7\. Crie um arquivo `iframe.ts` {#create-sendtx-js} + +Ótimo, agora que temos nossos dados confidenciais protegidos em um arquivo `.env`, vamos começar a codificar. Para nosso exemplo de envio de transação, enviaremos ETH de volta para o faucet Sepolia. + +Criar um `sendTx. s` arquivo, que é onde vamos configurar e enviar nossa transação de exemplo, e adicionar as seguintes linhas de código a ele: + +``` +async function main() { + require('dotenv').config(); + const { API_URL, PRIVATE_KEY } = process.env; + const { createAlchemyWeb3 } = require("@alch/alchemy-web3"); + const web3 = createAlchemyWeb3(API_URL); + const myAddress = '0x610Ae88399fc1687FA7530Aac28eC2539c7d6d63' //TODO: replace this address with your own public address + + const nonce = await web3.eth.getTransactionCount(myAddress, 'latest'); // nonce starts counting from 0 + + const transaction = { + 'to': '0x31B98D14007bDEe637298086988A0bBd31184523', // faucet address to return eth + 'value': 1000000000000000000, // 1 ETH + 'gas': 30000, + 'nonce': nonce, + // optional data field to send message or execute smart contract + }; + + const signedTx = await web3.eth.accounts.signTransaction(transaction, PRIVATE_KEY); + + web3.eth.sendSignedTransaction(signedTx.rawTransaction, function(error, hash) { + if (!error) { + console.log("🎉 The hash of your transaction is: ", hash, "\n Check Alchemy's Mempool to view the status of your transaction!"); + } else { + console.log("❗Something went wrong while submitting your transaction:", error) + } + }); +} + +main(); +``` + +Certifique-se de substituir o endereço na **linha 6** pelo seu próprio endereço público. + +Agora, antes de nós começarmos a executar este código, vamos falar sobre alguns dos componentes aqui. + +- `nonce` : A especificação nonce é usada para acompanhar o número de transações enviadas a partir do seu endereço. Precisamos disso para fins de segurança e para evitar [replay de ataques](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce). Para obter o número de transações enviadas a partir do seu endereço, usamos [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount). +- `transação`: O objeto da transação tem alguns aspectos que precisamos especificar + - `para`: Este é o endereço para o qual queremos enviar ETH. Nesse caso, reenviamos ETH para o [faucet Sepolia](https://sepoliafaucet.com/) no qual fizemos a solicitação inicialmente. + - `valor`: Este é o valor que desejamos enviar, especificado em Wei onde 10^18 Wei = 1 ETH + - `gás`: Há muitas maneiras de determinar a quantidade de gás certa a ser incluída na sua transação. Alchemy até tem um [webhook de preço de gás](https://docs.alchemyapi.io/guides/alchemy-notify#address-activity-1) para notificá-lo quando o preço do gás cai dentro de um determinado limiar. Para transações na Mainnet, é uma boa prática verificar um estimador de gás como [ETH Gas Station](https://ethgasstation.info/), para determinar a quantidade certa de gás a incluir. 21000 é a quantidade mínima de gás que uma operação na Ethereum usará. Portanto, para garantir que nossa transação será executada, colocamos 30000 aqui. + - `nonce`: ver acima nonce definição. Nonce começa a contagem de zero. + - Dados [OPTATIVOS]: Usados para enviar informações adicionais com a sua transferência, ou para chamar um contrato inteligente, não necessário para transferências de saldo, confira a nota abaixo. +- `signedTx`: Para assinar nosso objeto de transação, usaremos o método `signTransaction` com nosso `PRIVATE_KEY` +- `sendSignedTransação`: Uma vez assinada, teremos uma transação assinada. podemos enviá-lo para ser incluído em um bloco subsequente usando `sendSignedTransaction` + +**Uma observação sobre os dados** Existem dois tipos principais de transações que podem ser enviadas ao Ethereum. + +- Transferência de saldo: Envie ETH de um endereço para outro. Não é necessário campo de dados, no entanto, se você quiser enviar informações adicionais junto com sua transação, você pode incluir essas informações no formato HEX neste campo. + - Por exemplo, digamos que nós queríamos escrever o hash de um documento IPFS para a cadeia Ethereum, para dar a ele um timestamp (registro de data e hora) imutável. Nosso campo de dados deveria se parecer com data: `web3.utils.toHex('IPFS hash')`. E agora, qualquer pessoa pode consultar a cadeia e ver quando esse documento foi adicionado. +- Transação de contrato inteligente: Execute algum código de contrato inteligente na cadeia. Nesse caso, o campo de dados deveria conter a função inteligente, que você deseja executar, juntamente com quaisquer parâmetros. + - Para um exemplo prático, confira a Etapa 8 neste [Tutorial Olá Mundo](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#step-8-create-the-transaction). + +### 8\. Execute o código usando `node sendTx.js` {#run-the-code-using-node-sendtx-js} + +Navegue de volta ao seu terminal ou linha de comando e execute: + +``` +node sendTx.js +``` + +### 9\. Consultar suas transações no Mempool {#see-your-transaction-in-the-mempool} + +Abra a página de [Mempool](https://dashboard.alchemyapi.io/mempool) no painel de controle de Alchemy e filtre pelo app que você criou para encontrar sua transação. É aqui que podemos assistir nossa transição de um estado pendente para um estado minerado (se bem-sucedida) ou estado descartado em caso de falha. Certifique-se de mantê-lo em "Todos" para capturar as transações "mineradas", "pendentes", e "descartadas". Também é possível procurar sua transação procurando por transações enviadas para o endereço `0x31b98d14007bdee637298086988a0bbd31184523`. + +Para ver os detalhes da sua transação assim que encontrá-la, selecione o hash tx, que deve levar você a uma visão que se parece com isso: + +![Captura do observador Mempool](./mempool.png) + +A partir daí, você pode ver sua transação no Etherscan clicando no ícone circulado em vermelho! + +**Eba! Você acabou de enviar a sua primeira transação Ethereum usando Alchemy 🎉** + +_Para enviar comentários e sugestões sobre este guia, entre em contato com Elan no [Discord da Alchemy](https://discord.gg/A39JVCM)!_ + +_Publicado originalmente em [https://docs.alchemyapi.io/tutorials/sending-transactions-using-web3-and-alchemy](https://docs.alchemyapi.io/tutorials/sending-transactions-using-web3-and-alchemy)_ diff --git a/public/content/translations/pt-br/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md b/public/content/translations/pt-br/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md new file mode 100644 index 00000000000..04b61740046 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md @@ -0,0 +1,94 @@ +--- +title: Configure o web3.js para usar a Ethereum blockchain em JavaScript +description: Como usar um contrato inteligente para interagir com um token usando a linguagem Solidity +author: "jdourlens" +tags: + - "web3.js" + - "javascript" +skill: intermediate +lang: pt-br +published: 2020-04-11 +source: EthereumDev +sourceUrl: https://ethereumdev.io/setup-web3js-to-use-the-ethereum-blockchain-in-javascript/ +address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" +--- + +Neste tutorial, vamos ver como começar com [web3.js](https://web3js.readthedocs.io/) para interagir com a blockchain Ethereum. Web3.js podem ser usados em frontend e backends para ler dados da blockchain, fazer transações e até mesmo implantar contratos inteligentes. + +O primeiro passo é incluir web3.js no seu projeto. Para usá-la em uma página da web, você pode importar a biblioteca diretamente usando um CDN como JSDeliver. + +```html + +``` + +Se você preferir instalar a biblioteca para usar em seu backend ou um projeto do frontend que usa build, você pode instalá-la usando o npm: + +```bash +npm install web3 --save +``` + +Em seguida, para importar o Web3.js em um script Node.js ou projeto front-end do Browserify, você pode usar a seguinte linha de JavaScript: + +```js +const Web3 = require("web3") +``` + +Agora que incluímos a biblioteca no projeto, precisamos inicializá-la. Seu projeto precisa ser capaz de se comunicar com a blockchain. A maioria das bibliotecas Ethereum se comunicam com um [nó](/developers/docs/nodes-and-clients/) através de chamadas RPC. Para iniciar nosso provedor Web3, nós criaremos uma instância Web3 passando como construtor a URL do provedor. Se você tiver uma instância de um nó ou [ganache executando no seu computador](https://ethereumdev.io/testing-your-smart-contract-with-existing-protocols-ganache-fork/) será parecido com isto: + +```js +const web3 = new Web3("http://localhost:8545") +``` + +Se você deseja acessar diretamente um nó hospedado, poderá encontrar opções em [nós como um serviço](/developers/docs/nodes-and-clients/nodes-as-a-service). + +```js +const web3 = new Web3("https://cloudflare-eth.com") +``` + +Para testar se configuramos corretamente nossa instância Web3, tentaremos recuperar o número do último bloco usando a função `getBlockNumber`. Esta função aceita uma chamada de callback como parâmetro e retorna o número do bloco como um inteiro. + +```js +var Web3 = require("web3") +const web3 = new Web3("https://cloudflare-eth.com") + +web3.eth.getBlockNumber(function (error, result) { + console.log(result) +}) +``` + +Se você executar este programa, ele simplesmente imprimirá o bloco mais recente: o topo do blockchain. Você também pode usar chamadas de função `await/async` para evitar aninhar (encadear por identação) chamadas de callback em seu código: + +```js +async function getBlockNumber() { + const latestBlockNumber = await web3.eth.getBlockNumber() + console.log(latestBlockNumber) + return latestBlockNumber +} + +getBlockNumber() +``` + +Você pode ver todas as funções disponíveis da instância Web3 na [documentação oficial do web3.js](https://docs.web3js.org/). + +A maioria das bibliotecas Web3 são assíncronas porque em segundo plano a biblioteca faz chamadas JSON RPC para o nó que envia os resultados. + + + +Se você estiver trabalhando no navegador, algumas carteiras injetam diretamente uma instância Web3, e você deveria tentar usá-la sempre que possível, especialmente se planeja interagir com o endereço Ethereum do usuário para fazer transações. + +Aqui está o trecho de código para detectar se uma carteira MetaMask está disponível e tentar habilitá-la se estiver. Isso permitirá mais tarde você ler o saldo do usuário e permitir-lhe-á validar as transações que gostaria de fazer na blockchain Ethereum: + +```js +if (window.ethereum != null) { + state.web3 = new Web3(window.ethereum) + try { + // Request account access if needed + await window.ethereum.enable() + // Accounts now exposed + } catch (error) { + // User denied account access... + } +} +``` + +Alternativas para web3.js como [Ethers.js](https://docs.ethers.io/) existem e também são comumente usadas. No próximo tutorial, veremos [como escutar facilmente novos blocos recebidos na blockchain e ver o que eles contêm](https://ethereumdev.io/listening-to-new-transactions-happening-on-the-blockchain/). diff --git a/public/content/translations/pt-br/developers/tutorials/short-abi/index.md b/public/content/translations/pt-br/developers/tutorials/short-abi/index.md new file mode 100644 index 00000000000..4ce396e010e --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/short-abi/index.md @@ -0,0 +1,550 @@ +--- +title: "ABIs curtos para otimização de dados de chamada" +description: Otimizando contratos inteligentes para Rollups Otimistas +author: Ori Pomerantz +lang: pt-br +tags: + - "camada 2" +skill: intermediate +published: 2022-04-01 +--- + +## Introdução {#introduction} + +Neste artigo, você aprenderá sobre [optimistic rollups](/developers/docs/scaling/optimistic-rollups), os custos das transações e como essa estrutura de custos diferente nos obriga a otimizar coisas diferentes do que fazemos na Ethereum Mainnet. Você também aprenderá como implementar essa otimização. + +### Divulgação completa {#full-disclosure} + +Eu sou funcionário em tempo integral da [Optimism](https://www.optimism.io/), então os exemplos neste artigo serão executados na Optimism. No entanto, a técnica explicada aqui deve funcionar para outras rollups também. + +### Terminologia {#terminology} + +Quando se discute rollups, o termo 'camada 1' (L1) é usado para a Mainnet, a rede Ethereum de produção. O termo 'camada 2' (L2) é usado para a rollup ou qualquer outro sistema que depende do L1 para segurança, mas faz a maior parte de seu processamento fora da cadeia + +## Como podemos reduzir ainda mais o custo das transações L2? {#how-can-we-further-reduce-the-cost-of-L2-transactions} + +[Optimistic rollups](/developers/docs/scaling/optimistic-rollups) tem que preservar um registro de cada transação histórica para que qualquer pessoa possa passar por elas e verificar se o estado atual está correto. A forma mais barata de obter dados na Ethereum Mainnet é escrevê-los como calldata. Esta solução foi escolhida por ambos [Optimism](https://help.optimism.io/hc/en-us/articles/4413163242779-What-is-a-rollup-) e [Arbitrum](https://developer.offchainlabs.com/docs/rollup_basics#intro-to-rollups). + +### Custo das transações L2 {#cost-of-l2-transactions} + +O custo das transações L2 é composto por dois componentes: + +1. Processamento L2, que geralmente é extremamente barato +2. Armazenamento L1, vinculado aos custos de gas da Mainnet + +No momento em que escrevo isso, no Optimism, o custo do gas L2 é de 0,001 [Gwei](/developers/docs/gas/#pre-london). O custo do gas na L1 é de aproximadamente 40 gwei. [Você pode ver os preços atuais aqui](https://public-grafana.optimism.io/d/9hkhMxn7z/public-dashboard?orgId=1&refresh=5m). + +Um byte de dado da chamada custa, ou 4 gas (se for zero), ou 16 gas (se for qualquer outro valor). Uma das operações mais caras no EVM é escrever no storage. O custo máximo de escrever uma palavra de 32 bytes para armazenamento na L2 é de 22100 gas. Atualmente, isso é 22.1 gwei. Portanto, se nós pudermos salvar um único byte zero de calldata, poderemos gravar cerca de 200 bytes no armazenamento e ainda sairemos ganhando. + +### O ABI {#the-abi} + +A grande maioria das transações acessa um contrato de uma conta de propriedade externa. A maioria dos contratos é escrita em Solidity e interpreta seu campo de dados de acordo com a [interface binária do aplicativo (ABI)](https://docs.soliditylang.org/en/latest/abi-spec.html#formal-specification-of-the-encoding). + +No entanto, a ABI foi projetada para L1, em que um byte de dados da chamada custa aproximadamente o mesmo que quatro operações aritméticas, não para L2, em que um byte de dados da chamada custa mais de mil operações aritméticas. Por exemplo, [aqui está uma transação de transferência ERC-20](https://kovan-optimistic.etherscan.io/tx/0x7ce4c144ebfce157b4de99d8ad53a352ae91b57b3fa06d8a1c79439df6bfa998). Os dados da chamada são divididos da seguinte forma: + +| Seção | Comprimento | Bytes | Bytes gastos | Gas gasto | Bytes necessários | Gas necessário | +| ------------------- | -----------:| -----:| ------------:| ---------:| -----------------:| --------------:| +| Seletor de função | 4 | 0-3 | 3 | 48 | 1 | 16 | +| Zeros | 12 | 4-15 | 12 | 48 | 0 | 0 | +| Endereço de destino | 20 | 16-35 | 0 | 0 | 20 | 320 | +| Quantidade | 32 | 16-35 | 17 | 64 | 15 | 240 | +| Total | 68 | | | 576 | | 576 | + +Explicação: + +- **Seletor de funções**: O contrato tem menos de 256 funções, portanto podemos distingui-las com um único byte. Esses bytes são tipicamente diferentes de zero e, portanto, [custam dezesseis gás](https://eips.ethereum.org/EIPS/eip-2028). +- **Zeros**: Esses bytes são sempre zero porque um endereço de vinte bytes não requer uma palavra de trinta e dois bytes para usá-lo. Bytes que possuem zero custam quatro gas ([consulte o yellow paper](https://ethereum.github.io/yellowpaper/paper.pdf), Apêndice G, pág. 27, o valor para `G``txdatazero`). +- **Quantia**: Se nós assumirmos que neste contrato `decimais` são dezoito (o valor normal) e o valor máximo de tokens que nós transferimos será 1018, nós temos uma quantia máxima de 1036. 25615 > 1036, então quinze bytes são suficientes. + +Um gasto de 160 gas na L1 é normalmente insignificante. Uma transação custa pelo menos [21.000 gas](https://yakkomajuri.medium.com/blockchain-definition-of-the-week-ethereum-gas-2f976af774ed), então um extra de 0,8% não importa. Entretanto, na L2, as coisas são diferentes. Quase o custo inteiro da transação é escrevendo-o na L1. Em adição ao calldata da transação, há 109 bytes de cabeçalho de transação (endereço de destino, assinatura, etc.). O custo total é portanto `109*16+576+160=2480`, e nós estamos desperdiçando cerca de 6,5% disso. + +## Reduzindo custos quando você não controla o destino {#reducing-costs-when-you-dont-control-the-destination} + +Assumindo que você não tem controle sobre o contrato de destino, você pode ainda usar uma solução similar a [esta](https://github.com/qbzzt/ethereum.org-20220330-shortABI). Vamos passar pelos arquivos relevantes. + +### Token.sol {#token-sol} + +[Este é o contrato destino](https://github.com/qbzzt/ethereum.org-20220330-shortABI/blob/master/contracts/Token.sol). É um contrato ERC-20 padrão, com um recurso adicional. Esta função `faucet` permite qualquer usuário obter algum token para usar. Ele faria o contrato de produção ERC-20 inútil, mas ele facilita a vida quando um ERC-20 existe somente para facilitar o teste. + +```solidity + /** + * @dev Gives the caller 1000 tokens to play with + */ + function faucet() external { + _mint(msg.sender, 1000); + } // function faucet +``` + +[Você pode ver um exemplo deste contrato sendo implantado aqui](https://kovan-optimistic.etherscan.io/address/0x950c753c0edbde44a74d3793db738a318e9c8ce8). + +### CalldataInterpreter.sol {#calldatainterpreter-sol} + +[Este é o contrato que transações devem chamar com calldata menor](https://github.com/qbzzt/ethereum.org-20220330-shortABI/blob/master/contracts/CalldataInterpreter.sol). Vamos passar por ele linha a linha. + +```solidity +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + + +import { OrisUselessToken } from "./Token.sol"; +``` + +Nós precisamos da função do token para saber como chamá-lo. + +```solidity +contract CalldataInterpreter { + + OrisUselessToken public immutable token; +``` + +O endereço do token para o qual nós somos um proxy. + +```solidity + + /** + * @dev Specify the token address + * @param tokenAddr_ ERC-20 contract address + */ + constructor( + address tokenAddr_ + ) { + token = OrisUselessToken(tokenAddr_); + } // constructor +``` + +O endereço do token é o único parâmetro que nós precisamos especificar. + +```solidity + function calldataVal(uint startByte, uint length) + private pure returns (uint) { +``` + +Ler um valor do calldata. + +```solidity + uint _retVal; + + require(length < 0x21, + "calldataVal length limit is 32 bytes"); + + require(length + startByte <= msg.data.length, + "calldataVal trying to read beyond calldatasize"); +``` + +Nós iremos carregar uma simples palavra de 32-bytes (256-bit) para a memória e remover os bytes que não são parte do campo que nós queremos. Este algoritmo não funciona para valores maiores que 32 bytes, e claro, não podemos ler depois do fim do calldata. Na L1 pode ser necessário pular estes testes para economizar gas, mas na L2 o gas é extremamente barato, o que permite qualquer checagem de sanidade que possamos pensar. + +```solidity + assembly { + _retVal := calldataload(startByte) + } +``` + +Nós poderiamos ter copiado os dados da chamada ao `fallback()` (veja abaixo), mas é mais fácil usar [Yul](https://docs.soliditylang.org/en/v0.8.12/yul.html), a linguagem de montagem da EVM. + +Aqui nós usamos [o opcode CALLDATALOAD](https://www.evm.codes/#35) para ler bytes `startByte` até `startByte+31` na pilha. Em geral, a sintaxe de um opcode em Yul é `(,...)`. + +```solidity + + _retVal = _retVal >> (256-length*8); +``` + +Somente os bytes mais `length` significantes são parte do campo, então nós fazemos [right-shift](https://en.wikipedia.org/wiki/Logical_shift) para se livrar dos outros valores. Isto tem a vantagem adicional de mover o valor para a direita do campo, então é o valor por ele mesmo, ao invés do valor vezes 256alguma coisa. + +```solidity + + return _retVal; + } + + + fallback() external { +``` + +Quando uma chamada a um contrato Solidity não encontra nenhuma das assinaturas de função, ela chama a função [the `fallback()`](https://docs.soliditylang.org/en/v0.8.12/contracts.html#fallback-function) (assumindo que exista uma). No caso de `CalldataInterpreter`, _qualquer_ chamada chega aqui porque não há outras funções `external` ou `public`. + +```solidity + uint _func; + + _func = calldataVal(0, 1); +``` + +Leia o primeiro byte do calldata, que nos conta a função. Há duas razões porque uma função não estaria disponível aqui: + +1. Funções que são `pure` ou `view` não mudam seu estado e não custam gas (quando chamadas off-chain). Não faz sentido tentar reduzir seus custos de gas. +2. Funções que confiam em [`msg.sender`](https://docs.soliditylang.org/en/v0.8.12/units-and-global-variables.html#block-and-transaction-properties). O valor de `msg.sender` será o endereço do `CalldataInterpreter`, não o chamador. + +Infelizmente, [olhando as especificações do ERC-20](https://eips.ethereum.org/EIPS/eip-20), isto deixa apenas uma função, `transfer`. Isto nos deixa com somente duas funções: `transfer` (porque nós podemos chamar `transferFrom`) e `faucet` (porque nós podemos transferir os tokens de volta a quem quer tenha nos chamado). + +```solidity + + // Call the state changing methods of token using + // information from the calldata + + // faucet + if (_func == 1) { +``` + +Uma chamada para `faucet()`, que não tem parâmetros. + +```solidity + token.faucet(); + token.transfer(msg.sender, + token.balanceOf(address(this))); + } +``` + +Depois que nós chamamos `token.faucet()` nós obtivemos tokens. Entretanto, como o contrato proxy, nós não **precisamos** de tokens. O EOA (externally owned account) ou contrato que nos chamou o faz. Então nós transferimos todos nossos tokens para quem quer tenha nos chamado. + +```solidity + // transfer (assume we have an allowance for it) + if (_func == 2) { +``` + +Transferir tokens requer dois parâmetros: o endereço de destino e a quantidade. + +```solidity + token.transferFrom( + msg.sender, +``` + +Nós apenas permitimos chamadores transferir tokens que eles possuam + +```solidity + address(uint160(calldataVal(1, 20))), +``` + +O endereço de destino começa no byte 1 (o byte 0 é a função). Como um endereço, ele tem 20-bytes de comprimento. + +```solidity + calldataVal(21, 2) +``` + +Para esse contrato em particular nós assumimos que o número máximo de tokens que qualquer um poderia querer transferir cabe em dois bytes (menos que 65536). + +```solidity + ); + } +``` + +Em geral, uma transferência pega 35 bytes de calldata: + +| Seção | Comprimento | Bytes | +| ------------------- | -----------:| -----:| +| Seletor de função | 1 | 0 | +| Endereço de destino | 32 | 1-32 | +| Quantidade | 2 | 33-34 | + +```solidity + } // fallback + +} // contract CalldataInterpreter +``` + +### test.js {#test-js} + +[Este teste unitário JavaScript](https://github.com/qbzzt/ethereum.org-20220330-shortABI/blob/master/test/test.js) nos mostra como usar este mecanismo (e como verificar que ele trabalha corretamente). Parto do princípio que você entendeu [chai](https://www.chaijs.com/) e [ethers](https://docs.ethers.io/v5/) e apenas explicar as partes que especificamente se aplicam ao contrato. + +```js +const { expect } = require("chai"); + +describe("CalldataInterpreter", function () { + it("Should let us use tokens", async function () { + const Token = await ethers.getContractFactory("OrisUselessToken") + const token = await Token.deploy() + await token.deployed() + console.log("Token addr:", token.address) + + const Cdi = await ethers.getContractFactory("CalldataInterpreter") + const cdi = await Cdi.deploy(token.address) + await cdi.deployed() + console.log("CalldataInterpreter addr:", cdi.address) + + const signer = await ethers.getSigner() +``` + +Nós começamos por implantar ambos contratos. + +```javascript + // Get tokens to play with + const faucetTx = { +``` + +Nós não podemos usar funções de alto nível que nós normalmente usamos (como `token.faucet()`) para criar transações, porque nós não seguimos o ABI. Ao invés disso, nós temos que construir a transação nós mesmos e enviá-la. + +```javascript + to: cdi.address, + data: "0x01" +``` + +Há dois parâmetros que nós precisamos fornecer para a transação: + +1. `to`, o endereço de destino. Isto é o contrato interpretador do calldata. +2. `data`, o calldata a enviar. No caso de uma chamada de faucet, o dado é um único byte, `0x01`. + +```javascript + + } + await (await signer.sendTransaction(faucetTx)).wait() +``` + +Nós chamamos o método `sendTransaction` do [assinante](https://docs.ethers.io/v5/api/signer/#Signer-sendTransaction) porque nós já especificamos o destino (`faucetTx.to`) e nós precisamos que a transação seja assinada. + +```javascript +// Check the faucet provides the tokens correctly +expect(await token.balanceOf(signer.address)).to.equal(1000) +``` + +Aqui nós verificamos o saldo. Não há necessidade de economizar gas em funções `view`, então nós só as rodamos normalmente. + +```javascript +// Give the CDI an allowance (approvals cannot be proxied) +const approveTX = await token.approve(cdi.address, 10000) +await approveTX.wait() +expect(await token.allowance(signer.address, cdi.address)).to.equal(10000) +``` + +Dar ao intérprete calldata uma permissão para ser capaz de fazer transferências. + +```javascript +// Transfer tokens +const destAddr = "0xf5a6ead936fb47f342bb63e676479bddf26ebe1d" +const transferTx = { + to: cdi.address, + data: "0x02" + destAddr.slice(2, 42) + "0100", +} +``` + +Criar uma transação de transferência. O primeiro byte é "0x02", seguido pelo endereço de destino, e finalmente a quantia (0x0100, que é 256 em decimal). + +```javascript + await (await signer.sendTransaction(transferTx)).wait() + + // Check that we have 256 tokens less + expect (await token.balanceOf(signer.address)).to.equal(1000-256) + + // And that our destination got them + expect (await token.balanceOf(destAddr)).to.equal(256) + }) // it +}) // describe +``` + +### Exemplo {#example} + +Se você quiser ver estes arquivos em ação sem precisar rodá-los, siga estes links: + +1. [Implantação de `OrisUselessToken`](https://kovan-optimistic.etherscan.io/tx/1410744) no [endereço `0x950c753c0edbde44a74d3793db738a318e9c8ce8`](https://kovan-optimistic.etherscan.io/address/0x950c753c0edbde44a74d3793db738a318e9c8ce8). +2. [Implantação de `CalldataInterpreter`](https://kovan-optimistic.etherscan.io/tx/1410745) no [endereço `0x16617fea670aefe3b9051096c0eb4aeb4b3a5f55`](https://kovan-optimistic.etherscan.io/address/0x16617fea670aefe3b9051096c0eb4aeb4b3a5f55). +3. [Chamada para `faucet()`](https://kovan-optimistic.etherscan.io/tx/1410746). +4. [Chamada para `OrisUselessToken.approve()`](https://kovan-optimistic.etherscan.io/tx/1410747). Esta chamada tem de ir diretamente para o contrato do token porque o processamento confia no `msg.sender`. +5. [Chamada para `transfer()`](https://kovan-optimistic.etherscan.io/tx/1410748). + +## Reduzindo o custo quando você controla o contrato destino {#reducing-the-cost-when-you-do-control-the-destination-contract} + +Se você realmente tem controle sobre o contrato destino, você pode criar funções que ignoram as checagens do `msg.sender` porque eles acreditam no intérprete do calldata. [Você pode ver um exemplo de como isto funciona aqui, no branch `control-contract`](https://github.com/qbzzt/ethereum.org-20220330-shortABI/tree/control-contract). + +Se o contrato estiver respondendo somente para transações externas, nós poderíamos ter apenas um contrato. Entretanto, isso iria quebrar [a capacidade de composição](/developers/docs/smart-contracts/composability/). É bem melhor ter um contrato que responda a chamadas ERC-20 normais, e outro contrato que responda a transações com chamadas curtas de dados. + +### Token.sol {#token-sol-2} + +Neste exemplo nós podemos modificar `Token.sol`. Isto nos deixa ter um número de funções que somente o proxy pode chamar. Eis aqui as novas partes: + +```solidity + // The only address allowed to specify the CalldataInterpreter address + address owner; + + // The CalldataInterpreter address + address proxy = address(0); +``` + +O contrato ERC-20 precisa saber a identidade do proxy autorizado. Entretanto, nós não podemos configurar esta variável no construtor, porque nós não sabemos o valor ainda. Este contrato é instanciado primeiro porque o proxy espera o endereço do token no seu construtor. + +```solidity + /** + * @dev Calls the ERC20 constructor. + */ + constructor( + ) ERC20("Oris useless token-2", "OUT-2") { + owner = msg.sender; + } +``` + +O endereço do criador (chamado`owner`) é armazenado aqui porque este é o único endereço permitido para configurar o proxy. + +```solidity + /** + * @dev set the address for the proxy (the CalldataInterpreter). + * Can only be called once by the owner + */ + function setProxy(address _proxy) external { + require(msg.sender == owner, "Can only be called by owner"); + require(proxy == address(0), "Proxy is already set"); + + proxy = _proxy; + } // function setProxy +``` + +O proxy tem acesso privilegiado, porque ele pode ignorar checagens de segurança. Para garantir que nós podemos acreditar no proxy, nós somente deixamos `owner` chamar esta função, e somente uma vez. Uma vez que `proxy` tenha um valor real (não zero), este valor não pode mudar, então mesmo se o proprietário decide se tornar trapaceiro, ou caso o mnemônico seja revelado a ele, nós ainda estamos seguros. + +```solidity + /** + * @dev Some functions may only be called by the proxy. + */ + modifier onlyProxy { +``` + +Isto é uma função [`modifier`](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm), ela modifica a maneira que outras funções trabalham. + +```solidity + require(msg.sender == proxy); +``` + +Primeiro, verifique que nós fomos chamados pelo proxy e ninguém mais. Se não, `revert`. + +```solidity + _; + } +``` + +Neste caso, rode a função que nós modificamos. + +```solidity + /* Functions that allow the proxy to actually proxy for accounts */ + + function transferProxy(address from, address to, uint256 amount) + public virtual onlyProxy() returns (bool) + { + _transfer(from, to, amount); + return true; + } + + function approveProxy(address from, address spender, uint256 amount) + public virtual onlyProxy() returns (bool) + { + _approve(from, spender, amount); + return true; + } + + function transferFromProxy( + address spender, + address from, + address to, + uint256 amount + ) public virtual onlyProxy() returns (bool) + { + _spendAllowance(from, spender, amount); + _transfer(from, to, amount); + return true; + } +``` + +Há três operações que normalmente requerem que a mensagem venha direto da entidade transferindo tokens ou aprovando uma permissão. Aqui nós temos uma versão de proxy destas operações que: + +1. É modificada pelo `onlyProxy()`, de modo que ninguém mais tem permissão de controlá-los. +2. Pega o endereço que seria normalmente `msg.sender` como um parâmetro extra. + +### CalldataInterpreter.sol {#calldatainterpreter-sol-2} + +O interpretador calldata é praticamente idêntico ao acima, exceto que as funções com proxy recebem um parâmetro `msg.sender` e não há necessidade de permissão `transfer`. + +```solidity + // transfer (no need for allowance) + if (_func == 2) { + token.transferProxy( + msg.sender, + address(uint160(calldataVal(1, 20))), + calldataVal(21, 2) + ); + } + + // approve + if (_func == 3) { + token.approveProxy( + msg.sender, + address(uint160(calldataVal(1, 20))), + calldataVal(21, 2) + ); + } + + // transferFrom + if (_func == 4) { + token.transferFromProxy( + msg.sender, + address(uint160(calldataVal( 1, 20))), + address(uint160(calldataVal(21, 20))), + calldataVal(41, 2) + ); + } +``` + +### Test.js {#test-js-2} + +Há pequenas mudanças entre o código de teste anterior e este. + +```js +const Cdi = await ethers.getContractFactory("CalldataInterpreter") +const cdi = await Cdi.deploy(token.address) +await cdi.deployed() +await token.setProxy(cdi.address) +``` + +Nós precisamos contar ao contrato ERC-20 qual proxy acreditar + +```js +console.log("CalldataInterpreter addr:", cdi.address) + +// Need two signers to verify allowances +const signers = await ethers.getSigners() +const signer = signers[0] +const poorSigner = signers[1] +``` + +Para checar `approve()` e `transferFrom()` nós precisamos de um segundo assinante. Nós o chamamos de `poorSigner` porque ele não pega nenhum de nossos tokens (ele precisa ter ETH, claro). + +```js +// Transfer tokens +const destAddr = "0xf5a6ead936fb47f342bb63e676479bddf26ebe1d" +const transferTx = { + to: cdi.address, + data: "0x02" + destAddr.slice(2, 42) + "0100", +} +await (await signer.sendTransaction(transferTx)).wait() +``` + +Como o contrato ERC-20 confia no proxy (`cdi`), nós não precisamos de uma permissão para confiar em transferências. + +```js +// approval and transferFrom +const approveTx = { + to: cdi.address, + data: "0x03" + poorSigner.address.slice(2, 42) + "00FF", +} +await (await signer.sendTransaction(approveTx)).wait() + +const destAddr2 = "0xE1165C689C0c3e9642cA7606F5287e708d846206" + +const transferFromTx = { + to: cdi.address, + data: "0x04" + signer.address.slice(2, 42) + destAddr2.slice(2, 42) + "00FF", +} +await (await poorSigner.sendTransaction(transferFromTx)).wait() + +// Check the approve / transferFrom combo was done correctly +expect(await token.balanceOf(destAddr2)).to.equal(255) +``` + +Teste as duas novas funções. Note que `transferFromTx` requer dois parâmetros de endereço: o que deu a permissão e o recebedor. + +### Exemplo {#example-2} + +Se você quiser ver estes arquivos em ação sem precisar rodá-los, siga estes links: + +1. [Implantação de `OrisUselessToken-2`](https://kovan-optimistic.etherscan.io/tx/1475397) no endereço [`0xb47c1f550d8af70b339970c673bbdb2594011696`](https://kovan-optimistic.etherscan.io/address/0xb47c1f550d8af70b339970c673bbdb2594011696). +2. [Implantação de `CalldataInterpreter`](https://kovan-optimistic.etherscan.io/tx/1475400) no endereço [`0x0dccfd03e3aaba2f8c4ea4008487fd0380815892`](https://kovan-optimistic.etherscan.io/address/0x0dccfd03e3aaba2f8c4ea4008487fd0380815892). +3. [Chamada para `transfer()`](https://kovan-optimistic.etherscan.io/tx/1475402). +4. [Chamada para `faucet()`](https://kovan-optimistic.etherscan.io/tx/1475409). +5. [Chamada para `transferProxy()`](https://kovan-optimistic.etherscan.io/tx/1475416). +6. [Chamada para `approveProxy()`](https://kovan-optimistic.etherscan.io/tx/1475419). +7. [Chamada para `transferFromFProxy()`](https://kovan-optimistic.etherscan.io/tx/1475421). Note que esta chamada vem de um endereço diferente dos outros, `poorSigner` ao invés de `signer`. + +## Conclusão {#conclusion} + +Ambos [Optimism](https://medium.com/ethereum-optimism/the-road-to-sub-dollar-transactions-part-2-compression-edition-6bb2890e3e92) e [Arbitrum](https://developer.offchainlabs.com/docs/special_features) estão procurando por maneiras de reduzir o tamanho do calldata escrito no L1 e portanto o custo das transações. Entretanto, como provedores de infraestrutura procurando por soluções genéricas, nossas habilidades são limitadas. Como desenvolvedor dapp, você tem conhecimento específico de aplicações, o que te leva a otimizar seu calldata muito melhor do que nós poderíamos com uma solução genérica. Esperamos que este artigo ajude você a encontrar a solução ideal para as suas necessidades. diff --git a/public/content/translations/pt-br/developers/tutorials/smart-contract-security-guidelines/index.md b/public/content/translations/pt-br/developers/tutorials/smart-contract-security-guidelines/index.md new file mode 100644 index 00000000000..6053257ce85 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/smart-contract-security-guidelines/index.md @@ -0,0 +1,94 @@ +--- +title: Diretrizes de segurança do contrato inteligente +description: Uma lista de verificações de diretrizes de segurança a considerar ao construir seu dapp +author: "Trailofbits" +tags: + - "solidity" + - "contratos inteligentes" + - "segurança" +skill: intermediate +lang: pt-br +published: 2020-09-06 +source: Construindo contratos seguros +sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/guidelines.md +--- + +Siga estas recomendações de alto nível para construir contratos inteligentes mais seguros. + +## Padrões de design {#design-guidelines} + +O design do contrato deve ser discutido antecipadamente, antes de escrever qualquer linha de código. + +### Documentação e especificações {#documentation-and-specifications} + +A documentação pode ser escrita em diferentes níveis, e deve ser atualizada durante a implementação dos contratos: + +- **Uma descrição simples em inglês do sistema**, descrevendo o que os contratos fazem e qualquer suposição no código. +- **Esquemas e diagramas arquitetônicos**, incluindo as interações de contratos e a máquina de estado do sistema. [Impressoras do Slither](https://github.com/crytic/slither/wiki/Printer-documentation) podem ajudar a gerar esses esquemas. +- **Documentação de código Thorough**, o [formato Natspec](https://solidity.readthedocs.io/en/develop/natspec-format.html) pode ser usado para Solidity. + +### Computação on-chain vs off-chain {#on-chain-vs-off-chain-computation} + +- **Mantenha o máximo de código que puder off-chain (fora da cadeia).** Mantenha a menor camada on-chain (dentro da cadeia). Pré-processe dados com código off-chain de tal forma que a verificação on-chain torne-se simples. Você precisa de uma lista ordenada? Ordene a lista off-chain, então apenas verifique a ordem on-chain. + +### Capacidade de Atualização {#upgradeability} + +Nós discutimos as diferentes soluções de atualização em [nosso blog](https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/). Faça ou não uma escolha deliberada para apoiar a capacidade de atualização antes de escrever qualquer código. A decisão irá influenciar como você estrutura nosso código. Em geral, recomendamos: + +- **Favorecer a [migração do contrato](https://blog.trailofbits.com/2018/10/29/how-contract-migration-works/) sobre a atualização.** O sistema de migração tem muitas das mesmas vantagens do que ser atualizável, sem suas desvantagens. +- **Usando o padrão de separação de dados sobre o proxy delegatecallproxy.** Se o seu projeto tem uma separação de abstração clara, a atualizabilidade usando a separação de dados exigirá apenas alguns ajustes. O delegatecallproxy exige conhecimento de EVM e é altamente susceptível de erros. +- **Documentar o procedimento de migração/atualização antes da implantação.** Se você tiver que reagir sob o estresse sem quaisquer diretrizes, você cometerá erros. Escreva o procedimento a seguir com antecedência. Ele deve incluir: + - As exigências que iniciam os novos contratos + - Onde são armazenadas as chaves e como acessá-las + - Como verificar a implantação de arquivos! Desenvolva e teste um script de pós-implantação. + +## Orientações de implementação {#implementation-guidelines} + +**Esforço pela simplicidade.** Sempre use a solução mais simples que se encaixa em seu propósito. Qualquer membro da sua equipe deve ser capaz de entender a sua solução. + +### Composição de funções {#function-composition} + +A arquitetura da sua base de código deve facilitar a revisão do seu código. Evite escolhas arquitetônicas que diminuam a capacidade de raciocínio sobre sua exatidão. + +- **Divida a lógica do seu sistema**, seja por meio de vários contratos ou agrupando funções semelhantes juntas (por exemplo, autenticação, aritmética, ...). +- **Escreva funções pequenas, com um propósito claro.** Isso facilitará uma revisão mais tranquila e permitirá o teste de componentes individuais. + +### Herança {#inheritance} + +- **Mantenha a herança gerenciável.** A herança deve ser usada para dividir a lógica, no entanto, seu projeto deve visar minimizar a profundidade e a largura da árvore de herança. +- **Use a [impressora de herança de Slither](https://github.com/crytic/slither/wiki/Printer-documentation#inheritance-graph) para verificar a hierarquia dos contratos.** A impressora de herança irá ajudá-lo a rever o tamanho da hierarquia. + +### Eventos {#events} + +- **Registre todas as operações cruciais.** Os eventos ajudarão a depurar o contrato durante o desenvolvimento e a monitorá-lo após a implantação. + +### Evite armadilhas conhecidas {#avoid-known-pitfalls} + +- **Esteja ciente dos problemas de segurança mais comuns.** Há muitos recursos on-line para aprender sobre problemas comuns, como [Ethernaut CTF](https://ethernaut.openzeppelin.com/), [Capture o Ether](https://capturetheether.com/), ou [ contratos não tão inteligentes](https://github.com/crytic/not-so-smart-contracts/). +- **Esteja ciente das seções de avisos na [documentação Solidity](https://solidity.readthedocs.io/en/latest/)** As seções de avisos irão informá-lo sobre comportamentos não óbvios da linguagem. + +### Dependências {#dependencies} + +- **Use bibliotecas testadas.** A importação de código de bibliotecas testadas reduzirá a probabilidade de você escrever código com erros. Se você deseja escrever um contrato ERC20, use [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20). +- **Use um gerenciador de dependências; evite "copiar-e-colar" códigos.** Se você estiver contando com uma fonte externa, então você deve mantê-lo atualizado com a fonte original. + +### Teste e Validação {#testing-and-verification} + +- **Escreva testes unitários completos.** Um conjunto extenso de testes é crucial para construir softwares de alta qualidade. +- **Escreva propriedades e verificações personalizadas com [Slither](https://github.com/crytic/slither), [Echidna](https://github.com/crytic/echidna) e [Manticore](https://github.com/trailofbits/manticore).** Ferramentas automatizadas ajudarão a garantir que o seu contrato é seguro. Revise o resto deste guia para aprender a escrever propriedades e verificações eficientes. +- **Use o [crytic.io](https://crytic.io/).** O Critic integra-se ao Github, fornece acesso a detectores privados do Slither e executa verificações de propriedade personalizadas pelo Echidna. + +### Solidity {#solidity} + +- **Favoreça a Solidity 0.5 em vez de 0.4 e 0.6.** Em nossa opinião, a Solidity 0.5 é mais seguro e tem melhores práticas incorporadas que a 0.4. A Solidity 0.6 provou ser demasiado instável para produção e precisa de tempo para amadurecer. +- **Use um lançamento estável para compilar; use a versão mais recente para verificar se há avisos.** Verifique se o seu código não relatou problemas com a versão mais recente do compilador. No entanto, a Solidity tem um ciclo de lançamento rápido e tem um histórico de erros do compilador, então não recomendamos a versão mais recente para implantar (veja a [recomendação de versão solc do Slither](https://github.com/crytic/slither/wiki/Detector-Documentation#recommendation-33)). +- **Não use montagem embutida.** A montagem requer experiência em EVM. Não escreva o código EVM se você não tiver _dominado_ o Yellow Paper da Ethereum. + +## Orientações de implantação {#deployment-guidelines} + +Uma vez que o contrato tenha sido desenvolvido e implantado: + +- **Monitore seus contratos.** Observe os acessos e esteja pronto para reagir em caso de comprometimento do contrato ou da carteira. +- **Adicione suas informações de contato em [contatos de segurança da blockchain](https://github.com/crytic/blockchain-security-contacts).** Essa lista ajuda a terceiros a entrar em contato com você caso uma falha de segurança seja descoberta. +- **Proteja as carteiras de usuários privilegiados.** Siga nossas [melhores práticas](https://blog.trailofbits.com/2018/11/27/10-rules-for-the-secure-use-of-cryptocurrency-hardware-wallets/) se você armazenar chaves em carteiras físicas (hardware). +- **Tenha uma resposta ao plano de incidentes.** Considere que seus contratos inteligentes possam ser comprometidos. Mesmo que seus contratos estejam livres de erros, um invasor pode assumir o controle das chaves do proprietário do contrato. diff --git a/public/content/translations/pt-br/developers/tutorials/solidity-and-truffle-continuous-integration-setup/index.md b/public/content/translations/pt-br/developers/tutorials/solidity-and-truffle-continuous-integration-setup/index.md new file mode 100644 index 00000000000..df50e1e3c93 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/solidity-and-truffle-continuous-integration-setup/index.md @@ -0,0 +1,194 @@ +--- +title: "Configuração contínua de integração Solidity e Truffle" +description: Como configurar o Travis ou Circle CI para testes deTruffle, juntamente com plugins úteis +author: Markus Waas +lang: pt-br +tags: + - "solidez" + - "contratos inteligentes" + - "testando" + - "truffle" + - "ganache" +skill: intermediate +published: 2020-06-05 +source: soliditydeveloper.com +sourceUrl: https://soliditydeveloper.com/continuous-integration +--- + +A integração contínua (CI) com o Truffle é excelente para desenvolvimento assim que você tiver um conjunto básico de testes implementados. Isso permite que você execute testes muito longos, garantir que todos os testes passem antes de mesclar um [pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request) e para manter o controle de várias estatísticas usando ferramentas adicionais. + +Usaremos o [Truffle Metacoin Box](https://www.trufflesuite.com/boxes/metacoin) para configurar nossa integração contínua. Você pode escolher o Travis CI ou o Circle CI. + +## Configurando Travis CI {#setting-up-travis-ci} + +Adicionando [Travis CI](https://travis-ci.org/) é reta. Você só precisará adicionar um arquivo de configuração `.travis.yml` na pasta raiz do projeto: + +```yml +language: node_js +node_js: + - 10 + +cache: npm + +before_script: + - echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p + +script: + - npm test +``` + +Nós estamos mantendo tudo simples por enquanto e estamos executando apenas o script de teste que executa os testes de unidade Truffle. Mas temos um problema, não haverá uma blockchain disponível na máquina Travis CI. Uma correção simples para isso é `npm install ganache-cli` e simplesmente executá-lo antes do teste. Você pode fazer isso adicionando um bash script com a linha npx `ganache-cli > /dev/null` e antes da chamada `npx truffle`. O [script bash completo de exemplo](https://github.com/gorgos/Truffle-CI-Example/blob/master/scripts/run_tests.sh). + +## Configurando o Circle CI {#setting-up-circle-ci} + +[CircleCi](https://circleci.com/) requer um arquivo de configuração mais longo. O comando adicional [`npm ci`](https://docs.npmjs.com/cli/ci.html) é feito automaticamente no Travis. Ele instala as dependências mais rápido e mais seguro do que o `npm install` faz. Nós usamos novamente o mesmo script da versão de Travis para rodar ganache-cli antes dos testes. + +```yml +version: 2 + +aliases: + - &defaults + docker: + - image: circleci/node:10 + + - &cache_key_node_modules + key: v1-node_modules-{{ checksum "package-lock.json" }} + +jobs: + dependencies: + <<: *defaults + steps: + - checkout + - restore_cache: + <<: *cache_key_node_modules + - run: + name: Install npm dependencies + command: | + if [ ! -d node_modules ]; then + npm ci + fi + - persist_to_workspace: + root: . + paths: + - node_modules + - build + - save_cache: + paths: + - node_modules + <<: *cache_key_node_modules + + test: + <<: *defaults + steps: + - checkout + - attach_workspace: + at: . + - run: + name: Unit tests + command: npm test + +workflows: + version: 2 + everything: + jobs: + - dependencies + - test: + requires: + - dependencies +``` + +## Adicionando o plugin eth-gas-reportter {#adding-the-eth-gas-reporter-plugin} + +O plugin eth-gas-reportter é bastante útil para manter o controle dos custos de gas de suas funções de contrato inteligente. Tê-lo em seu CI será mais útil para mostrar diffs ao adicionar pull requests. + +### Passo 1: Instale o plugin eth-gas-reportter e as verificações de código {#step-1-install-the-eth-gas-reporter-plugin-and-codechecks} + +```bash +npm install --save-dev eth-gas-reporter +npm install --save-dev @codechecks/client +``` + +### Etapa 2: Adicione o plugin nas configurações do mocha dentro do arquivo truffle-config.js {#step-2-add-the-plugin-to-the-mocha-settings-inside-your-truffle-configjs} + +[Ver opções](https://github.com/cgewecke/eth-gas-reporter#options) + +```js +module.exports = { + networks: { ... }, + mocha: { + reporter: 'eth-gas-reporter', + reporterOptions: { + excludeContracts: ['Migrations'] + } + } +}; +``` + +### Passo 3: Adicione um codechecks.yml ao diretório raiz do seu projeto {#step-3-add-a-codechecksyml-to-your-projects-root-directory} + +```yml +checks: + - name: eth-gas-reporter/codechecks +``` + +### Passo 4: Execute verificações de código após o comando de teste {#step-4-run-codechecks-after-the-test-command} + +```bash +- npm test +- npx codechecks +``` + +### Passo 5: Crie uma conta no Codechecks {#step-5-create-a-codechecks-account} + +- Crie uma conta com [Codechecks](http://codechecks.io/). +- Adicionar o repositório do Github a ele. +- Copie o segredo e adicione o `CC_SECRET=SEGRET COPIADO` ao seu CI (veja aqui para [Travis](https://docs.travis-ci.com/user/environment-variables/),, aqui para [CircleCi](https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-project)). +- Agora vá em frente e crie um pull request. + +É isso. Agora você vai encontrar um bom relatório sobre mudanças nos custos de gas do seu pull request. + +![Exemplos de relatórios de gas](./gas-reports.png) + +## Adicionando o plugin Solidity-coverage {#adding-the-solidity-coverage-plugin} + +Com o plugin Solidity-coverage, você pode verificar a quantidade de caminhos de seu código cobertos por seus testes. Adicionar isto à sua criação de CI é muito conveniente quando for criado. + +### Passo 1: Crie um projeto metacoin e instale ferramentas de cobertura {#step-1-create-a-metacoin-project-and-install-coverage-tools} + +```bash +npm install --save-dev truffle coveralls solidity-coverage +``` + +### Etapa 2: Adicionar solidity-coverage para o array de plugins em truffle-config.js {#step-2-add-solidity-coverage-to-the-plugins-array-in-truffle-configjs} + +```js +module.exports = { + networks: {...}, + plugins: ["solidity-coverage"] +} +``` + +### Passo 3: Adicione os comandos de cobertura ao arquivo .travis.yml ou Circle CI config.yml {#step-3-add-the-coverage-commands-to-the-travisyml-or-circle-ci-configyml} + +```bash +- npx truffle run coverage +- cat coverage/lcov.info | npx coveralls +``` + +A cobertura da Solidity começa seu próprio ganache-cli, então não precisamos nos preocupar com isso. Não substitua o comando de teste regular, porém, a cobertura de ganache-cli funciona de forma diferente e, portanto, não é substituto para a execução de testes de unidade regulares. + +### Passo 4: Adicionar repositório às coberturas {#step-4-add-repository-to-coveralls} + +- Crie uma conta com [Codechecks](https://coveralls.io/). +- Adicionar o repositório do Github a ele. +- Agora vá em frente e crie um pull request. + +![Exemplo de cobertura](./coverall.png) + +## Mais idéias {#further-ideas} + +- [MitX](https://mythx.io/): Com MythX você pode analisar automaticamente a segurança de seu contrato inteligente. Então faz muito sentido [adicionar isto ao seu CI](https://blog.mythx.io/howto/mythx-and-continuous-integration-part-1-circleci/). +- [Linting](https://wikipedia.org/wiki/Lint_%28software%29): Um bom código pode ser aplicado até certo ponto com ferramentas de linting. [Eslint](https://eslint.org/) funciona muito bem para JavaScript, é [ fácil de configurar](https://eslint.org/docs/user-guide/getting-started), enquanto [Solhint](https://protofire.github.io/solhint/) pode ser usado para Solidity. +- Testes longos: Às vezes, você pode querer adicionar testes extremos, por exemplo, testar contratos com centenas de usuários. Isto leva muito tempo. Em vez de executar aqueles em cada execução de teste, adicione-os ao CI. + +Aí está o que tem. A integração contínua é uma estratégia muito útil para os seus desenvolvimentos. Você pode conferir um exemplo completo em [Truffle-CI-Example](https://github.com/gorgos/Truffle-CI-Example). Basta remover o Circle-CI ou Travis, um é suficiente! diff --git a/public/content/translations/pt-br/developers/tutorials/testing-erc-20-tokens-with-waffle/index.md b/public/content/translations/pt-br/developers/tutorials/testing-erc-20-tokens-with-waffle/index.md new file mode 100644 index 00000000000..8e3afcb9a68 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/testing-erc-20-tokens-with-waffle/index.md @@ -0,0 +1,1138 @@ +--- +title: Testando tokens ERC-20 com Waffle +description: Aprenda como testar contratos inteligentes do Solidity e usar "matchers" de contratos inteligentes com o Waffle. +author: Vladislav Starostenko +tags: + - "waffle" + - "contratos inteligentes" + - "solidity" + - "testando" + - "erc-20" +skill: intermediate +lang: pt-br +published: 2020-10-16 +--- + +Neste tutorial, você aprenderá: + +- Crie testes para contratos inteligentes com Waffle +- Use alguns matchers populares para testar contratos inteligentes com Waffle + +Pressupostos: + +- você pode conseguir em um terminal, +- você pode criar um novo projeto de `JavaScript`, +- você escreveu algumas linhas de código `Solidity`, +- você escreveu alguns testes em `JavaScript`, +- você usou `yarn` or `npm`, o instalador de pacotes de JavaScript. + +Novamente. Caso algum desse tópicos não se apliquem, ou você não planeja reproduzir o código desse artigo, você provavelmente vai conseguir acompanhar o que vem a seguir. + +## Algumas palavras sobre Waffle {#a-few-words-about-waffle} + +[Waffle](https://getwaffle.io) é a biblioteca mais avançada para escrever e testar contratos inteligentes. + +Funciona com a [API JavaScript](/developers/docs/apis/javascript/) ethers-js. + +Você pode ler mais detalhes na [documentação Waffle](https://ethereum-waffle.readthedocs.io/en/latest/#waffle-documentation)! + +## O tutorial rápido {#the-quick-tutorial} + +Primeiro as coisas primeiras, crie um novo projeto de `JavaScript` ou `TypeScript` (Vou usar `TS`, mas se você usa `JS` não é um problema) : + +Alguma coisa como esta : + +
      +package.json + + { + "name": "tutorial", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "test": "export NODE_ENV=test && mocha", + "lint": "eslint '{src,test}/**/*.ts'", + "lint:fix": "eslint --fix '{src,test}/**/*.ts'", + "build": "waffle" + }, + "devDependencies": { + "@types/mocha": "^5.2.7", + "@typescript-eslint/eslint-plugin": "^2.30.0", + "@typescript-eslint/parser": "^2.30.0", + "eslint": "^6.8.0", + "eslint-plugin-import": "^2.20.2", + "ethers": "^5.0.17", + "mocha": "^7.1.2", + "ts-node": "^8.9.1", + "typescript": "^3.8.3" + } + } + +
      + +
      +tsconfig.json + + { + "compilerOptions": { + "declaration": true, + "esModuleInterop": true, + "lib": [ + "ES2018" + ], + "module": "CommonJS", + "moduleResolution": "node", + "outDir": "dist", + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2018" + } + } + +
      + +
      +.gitignore + + node_modules + build + +
      + +
      +.eslintrc.js + + module.exports = { + "env": { + "es6": true + }, + "extends": [ + "plugin:@typescript-eslint/recommended", + "plugin:import/errors", + "plugin:import/warnings", + "plugin:import/typescript" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "./tsconfig.json", + "sourceType": "module" + }, + "rules": { + "@typescript-eslint/camelcase": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/explicit-member-accessibility": [ + "error", + { + "accessibility": "no-public", + "overrides": { + "parameterProperties": "off" + } + } + ], + "@typescript-eslint/indent": [ + "error", + 2, + { + "ArrayExpression": 1, + "CallExpression": { + "arguments": 1 + }, + "FunctionDeclaration": { + "body": 1, + "parameters": 1 + }, + "FunctionExpression": { + "body": 1, + "parameters": 1 + }, + "ImportDeclaration": 1, + "MemberExpression": 1, + "ObjectExpression": 1, + "SwitchCase": 1, + "VariableDeclarator": 1, + "flatTernaryExpressions": false, + "ignoreComments": false, + "outerIIFEBody": 1 + } + ], + "@typescript-eslint/interface-name-prefix": "off", + "@typescript-eslint/member-delimiter-style": [ + "error", + { + "multiline": { + "delimiter": "semi", + "requireLast": true + }, + "singleline": { + "delimiter": "semi", + "requireLast": false + } + } + ], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-parameter-properties": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "args": "none", + "ignoreRestSiblings": true, + "vars": "all" + } + ], + "@typescript-eslint/no-use-before-define": "off", + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/no-var-requires": "warn", + "accessor-pairs": "error", + "array-bracket-spacing": [ + "error", + "never" + ], + "arrow-spacing": [ + "error", + { + "after": true, + "before": true + } + ], + "block-spacing": [ + "error", + "always" + ], + "brace-style": [ + "error", + "1tbs", + { + "allowSingleLine": true + } + ], + "camelcase": "off", + "comma-dangle": [ + "error", + { + "arrays": "never", + "exports": "never", + "functions": "never", + "imports": "never", + "objects": "never" + } + ], + "comma-spacing": [ + "error", + { + "after": true, + "before": false + } + ], + "comma-style": [ + "error", + "last" + ], + "computed-property-spacing": [ + "error", + "never" + ], + "constructor-super": "error", + "curly": [ + "error", + "multi-line" + ], + "dot-location": [ + "error", + "property" + ], + "eol-last": "error", + "eqeqeq": [ + "error", + "always", + { + "null": "ignore" + } + ], + "func-call-spacing": [ + "error", + "never" + ], + "generator-star-spacing": [ + "error", + { + "after": true, + "before": true + } + ], + "handle-callback-err": [ + "error", + "^(err|error)$" + ], + "import/default": "off", + "import/named": "off", + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": false + } + ], + "import/no-unresolved": "off", + "indent": "off", + "key-spacing": [ + "error", + { + "afterColon": true, + "beforeColon": false + } + ], + "keyword-spacing": [ + "error", + { + "after": true, + "before": true + } + ], + "linebreak-style": [ + "error", + "unix" + ], + "lines-between-class-members": [ + "error", + "always", + { + "exceptAfterSingleLine": true + } + ], + "max-len": [ + "error", + { + "code": 120 + } + ], + "new-cap": [ + "error", + { + "capIsNew": false, + "newIsCap": true + } + ], + "new-parens": "error", + "no-array-constructor": "error", + "no-async-promise-executor": "error", + "no-caller": "error", + "no-class-assign": "error", + "no-compare-neg-zero": "error", + "no-cond-assign": "error", + "no-const-assign": "error", + "no-constant-condition": [ + "error", + { + "checkLoops": false + } + ], + "no-control-regex": "error", + "no-debugger": "error", + "no-delete-var": "error", + "no-dupe-args": "error", + "no-dupe-keys": "error", + "no-duplicate-case": "error", + "no-empty-character-class": "error", + "no-empty-pattern": "error", + "no-eval": "error", + "no-ex-assign": "error", + "no-extend-native": "error", + "no-extra-bind": "error", + "no-extra-boolean-cast": "error", + "no-extra-parens": [ + "error", + "functions" + ], + "no-fallthrough": "error", + "no-floating-decimal": "error", + "no-func-assign": "error", + "no-global-assign": "error", + "no-implied-eval": "error", + "no-inner-declarations": [ + "error", + "functions" + ], + "no-invalid-regexp": "error", + "no-irregular-whitespace": "error", + "no-iterator": "error", + "no-label-var": "error", + "no-labels": [ + "error", + { + "allowLoop": false, + "allowSwitch": false + } + ], + "no-lone-blocks": "error", + "no-misleading-character-class": "error", + "no-mixed-operators": [ + "error", + { + "allowSamePrecedence": true, + "groups": [ + [ + "==", + "!=", + "===", + "!==", + ">", + ">=", + "<", + "<=" + ], + [ + "&&", + "||" + ], + [ + "in", + "instanceof" + ] + ] + } + ], + "no-mixed-spaces-and-tabs": "error", + "no-multi-spaces": "error", + "no-multi-str": "error", + "no-multiple-empty-lines": [ + "error", + { + "max": 1, + "maxEOF": 0 + } + ], + "no-negated-in-lhs": "error", + "no-new": "error", + "no-new-func": "error", + "no-new-object": "error", + "no-new-require": "error", + "no-new-symbol": "error", + "no-new-wrappers": "error", + "no-obj-calls": "error", + "no-octal": "error", + "no-octal-escape": "error", + "no-path-concat": "error", + "no-proto": "error", + "no-prototype-builtins": "error", + "no-redeclare": [ + "error", + { + "builtinGlobals": false + } + ], + "no-regex-spaces": "error", + "no-return-assign": [ + "error", + "except-parens" + ], + "no-return-await": "error", + "no-self-assign": "error", + "no-self-compare": "error", + "no-sequences": "error", + "no-shadow-restricted-names": "error", + "no-sparse-arrays": "error", + "no-tabs": "error", + "no-template-curly-in-string": "error", + "no-this-before-super": "error", + "no-throw-literal": "error", + "no-trailing-spaces": "error", + "no-unexpected-multiline": "error", + "no-unmodified-loop-condition": "error", + "no-unneeded-ternary": [ + "error", + { + "defaultAssignment": false + } + ], + "no-unreachable": "error", + "no-unsafe-finally": "error", + "no-unsafe-negation": "error", + "no-use-before-define": [ + "error", + { + "classes": false, + "functions": false, + "variables": false + } + ], + "no-useless-call": "error", + "no-useless-catch": "error", + "no-useless-computed-key": "error", + "no-useless-escape": "error", + "no-useless-rename": "error", + "no-useless-return": "error", + "no-whitespace-before-property": "error", + "no-with": "error", + "object-curly-spacing": [ + "error", + "never" + ], + "object-property-newline": [ + "error", + { + "allowMultiplePropertiesPerLine": true + } + ], + "one-var": [ + "error", + { + "initialized": "never" + } + ], + "operator-linebreak": [ + "error", + "after", + { + "overrides": { + ":": "before", + "?": "before" + } + } + ], + "padded-blocks": [ + "error", + { + "blocks": "never", + "classes": "never", + "switches": "never" + } + ], + "prefer-const": [ + "error", + { + "destructuring": "all" + } + ], + "prefer-promise-reject-errors": "error", + "quote-props": [ + "error", + "as-needed" + ], + "quotes": [ + "error", + "single" + ], + "rest-spread-spacing": [ + "error", + "never" + ], + "semi": [ + "error", + "always" + ], + "semi-spacing": [ + "error", + { + "after": true, + "before": false + } + ], + "space-before-blocks": [ + "error", + "always" + ], + "space-before-function-paren": [ + "error", + { + "anonymous": "always", + "named": "never", + "asyncArrow": "always" + } + ], + "space-in-parens": [ + "error", + "never" + ], + "space-infix-ops": "error", + "space-unary-ops": [ + "error", + { + "nonwords": false, + "words": true + } + ], + "spaced-comment": [ + "error", + "always", + { + "block": { + "balanced": true, + "exceptions": [ + "*" + ], + "markers": [ + "*package", + "!", + ",", + ":", + "::", + "flow-include" + ] + }, + "line": { + "markers": [ + "*package", + "!", + "/", + ",", + "=" + ] + } + } + ], + "symbol-description": "error", + "template-curly-spacing": [ + "error", + "never" + ], + "template-tag-spacing": [ + "error", + "never" + ], + "unicode-bom": [ + "error", + "never" + ], + "use-isnan": "error", + "valid-typeof": [ + "error", + { + "requireStringLiterals": true + } + ], + "wrap-iife": [ + "error", + "any", + { + "functionPrototypeMethods": true + } + ], + "yield-star-spacing": [ + "error", + "both" + ], + "yoda": [ + "error", + "never" + ] + }, + "overrides": [ + { + "files": [ + "test/**/*.ts" + ], + "rules": { + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-var-requires": "off", + "no-unused-expressions": "off", + "prefer-promise-reject-errors": "off", + "import/no-extraneous-dependencies": [ + "error", + { + "devDependencies": true + } + ] + } + } + ] + } + +
      + +## Passo #1: Instale o waffle no seu projeto [Link para o documento](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#installation) {#step-1-install-waffle-in-your-project} + +To get started, install `ethereum-waffle`. Neste tutorial, eu usarei `yarn`, então para instalar `ethereum-waffle` executar: + +```bash + yarn add --dev ethereum-waffle +``` + +## Passo #2: Escreva um contrato inteligente [Link para documento](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-a-contract) {#step-2-write-a-smart-contract} + +Neste tutorial, usarei o [ERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/ded2b0a55c9c13731963ab7b85a70c8e73504bab/contracts/token/ERC20/ERC20.sol) token de [OpenZeppelin](https://openzeppelin.com). + +Então, adicione `OpenZeppelin` instalando-o com `yarn`: + +```bash + yarn add @openzeppelin/contracts -D +``` + +Em seguida, crie o contrato `BasicToken.sol` no diretório `src`: + +```solidity +pragma solidity ^0.6.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +// Example class - a mock class using delivering from ERC20 +contract BasicToken is ERC20 { + constructor(uint256 initialBalance) ERC20("Basic", "BSC") public { + _mint(msg.sender, initialBalance); + } +} + +``` + +## Passo #3: Escreva um contrato inteligente [Link para documento](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#compiling-the-contract) {#step-3-compile-your-smart-contract} + +Para compilar seu contrato inteligente, adicione a seguinte entrada no `package.json` do seu projeto: + +```json +{ + "scripts": { + "test": "jest" + } +} +``` + +Além disso, adicione o arquivo `waffle.json` na pasta principal do seu projeto. + +Um exemplo da configuração do `waffle.json`: + +```json +{ + "compilerType": "solcjs", + "compilerVersion": "0.6.2", + "sourceDirectory": "./contracts", + "outputDirectory": "./build" +} +``` + +Leia mais sobre a configuração do Waffle [aqui](https://ethereum-waffle.readthedocs.io/en/latest/configuration.html#configuration). + +Em seguida, execute `yarn build` para compilar seu contrato inteligente. + +Você deve ver que Waffle compilou seu contrato e colocou a saída JSON resultante dentro da pasta `compilação`. + +
      +BasicToken.json + + { + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "initialBalance", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "evm": { + "bytecode": { + "linkReferences": {}, + "object": "60806040523480156200001157600080fd5b506040516200153938038062001539833981810160405260208110156200003757600080fd5b81019080805190602001909291905050506040518060400160405280600581526020017f42617369630000000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f42534300000000000000000000000000000000000000000000000000000000008152508160039080519060200190620000cc92919062000389565b508060049080519060200190620000e592919062000389565b506012600560006101000a81548160ff021916908360ff16021790555050506200011633826200011d60201b60201c565b5062000438565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620001c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b620001d560008383620002fb60201b60201c565b620001f1816002546200030060201b62000f2d1790919060201c565b6002819055506200024f816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546200030060201b62000f2d1790919060201c565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b505050565b6000808284019050838110156200037f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620003cc57805160ff1916838001178555620003fd565b82800160010185558215620003fd579182015b82811115620003fc578251825591602001919060010190620003df565b5b5090506200040c919062000410565b5090565b6200043591905b808211156200043157600081600090555060010162000417565b5090565b90565b6110f180620004486000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80633950935111610071578063395093511461025f57806370a08231146102c557806395d89b411461031d578063a457c2d7146103a0578063a9059cbb14610406578063dd62ed3e1461046c576100a9565b806306fdde03146100ae578063095ea7b31461013157806318160ddd1461019757806323b872dd146101b5578063313ce5671461023b575b600080fd5b6100b66104e4565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f65780820151818401526020810190506100db565b50505050905090810190601f1680156101235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61017d6004803603604081101561014757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610586565b604051808215151515815260200191505060405180910390f35b61019f6105a4565b6040518082815260200191505060405180910390f35b610221600480360360608110156101cb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506105ae565b604051808215151515815260200191505060405180910390f35b610243610687565b604051808260ff1660ff16815260200191505060405180910390f35b6102ab6004803603604081101561027557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061069e565b604051808215151515815260200191505060405180910390f35b610307600480360360208110156102db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610751565b6040518082815260200191505060405180910390f35b610325610799565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561036557808201518184015260208101905061034a565b50505050905090810190601f1680156103925780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103ec600480360360408110156103b657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061083b565b604051808215151515815260200191505060405180910390f35b6104526004803603604081101561041c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610908565b604051808215151515815260200191505060405180910390f35b6104ce6004803603604081101561048257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610926565b6040518082815260200191505060405180910390f35b606060038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561057c5780601f106105515761010080835404028352916020019161057c565b820191906000526020600020905b81548152906001019060200180831161055f57829003601f168201915b5050505050905090565b600061059a6105936109ad565b84846109b5565b6001905092915050565b6000600254905090565b60006105bb848484610bac565b61067c846105c76109ad565b6106778560405180606001604052806028815260200161102660289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061062d6109ad565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e6d9092919063ffffffff16565b6109b5565b600190509392505050565b6000600560009054906101000a900460ff16905090565b60006107476106ab6109ad565b8461074285600160006106bc6109ad565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610f2d90919063ffffffff16565b6109b5565b6001905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108315780601f1061080657610100808354040283529160200191610831565b820191906000526020600020905b81548152906001019060200180831161081457829003601f168201915b5050505050905090565b60006108fe6108486109ad565b846108f98560405180606001604052806025815260200161109760259139600160006108726109ad565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e6d9092919063ffffffff16565b6109b5565b6001905092915050565b600061091c6109156109ad565b8484610bac565b6001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610a3b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806110736024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610ac1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610fde6022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602581526020018061104e6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610cb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610fbb6023913960400191505060405180910390fd5b610cc3838383610fb5565b610d2e81604051806060016040528060268152602001611000602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e6d9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610dc1816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610f2d90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290610f1a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610edf578082015181840152602081019050610ec4565b50505050905090810190601f168015610f0c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015610fab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b50505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122081c840f087cef92feccb03fadc678b2708c331896ec5432b5d4c675f27b6d3e664736f6c63430006020033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH3 0x11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x40 MLOAD PUSH3 0x1539 CODESIZE SUB DUP1 PUSH3 0x1539 DUP4 CODECOPY DUP2 DUP2 ADD PUSH1 0x40 MSTORE PUSH1 0x20 DUP2 LT ISZERO PUSH3 0x37 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x4261736963000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP PUSH1 0x40 MLOAD DUP1 PUSH1 0x40 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x3 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x4253430000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP DUP2 PUSH1 0x3 SWAP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 PUSH3 0xCC SWAP3 SWAP2 SWAP1 PUSH3 0x389 JUMP JUMPDEST POP DUP1 PUSH1 0x4 SWAP1 DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 PUSH3 0xE5 SWAP3 SWAP2 SWAP1 PUSH3 0x389 JUMP JUMPDEST POP PUSH1 0x12 PUSH1 0x5 PUSH1 0x0 PUSH2 0x100 EXP DUP2 SLOAD DUP2 PUSH1 0xFF MUL NOT AND SWAP1 DUP4 PUSH1 0xFF AND MUL OR SWAP1 SSTORE POP POP POP PUSH3 0x116 CALLER DUP3 PUSH3 0x11D PUSH1 0x20 SHL PUSH1 0x20 SHR JUMP JUMPDEST POP PUSH3 0x438 JUMP JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH3 0x1C1 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x1F DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH32 0x45524332303A206D696E7420746F20746865207A65726F206164647265737300 DUP2 MSTORE POP PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH3 0x1D5 PUSH1 0x0 DUP4 DUP4 PUSH3 0x2FB PUSH1 0x20 SHL PUSH1 0x20 SHR JUMP JUMPDEST PUSH3 0x1F1 DUP2 PUSH1 0x2 SLOAD PUSH3 0x300 PUSH1 0x20 SHL PUSH3 0xF2D OR SWAP1 SWAP2 SWAP1 PUSH1 0x20 SHR JUMP JUMPDEST PUSH1 0x2 DUP2 SWAP1 SSTORE POP PUSH3 0x24F DUP2 PUSH1 0x0 DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH3 0x300 PUSH1 0x20 SHL PUSH3 0xF2D OR SWAP1 SWAP2 SWAP1 PUSH1 0x20 SHR JUMP JUMPDEST PUSH1 0x0 DUP1 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 DUP2 SWAP1 SSTORE POP DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF DUP4 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 ADD SWAP1 POP DUP4 DUP2 LT ISZERO PUSH3 0x37F JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x1B DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH32 0x536166654D6174683A206164646974696F6E206F766572666C6F770000000000 DUP2 MSTORE POP PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP1 SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 PUSH1 0x1F ADD PUSH1 0x20 SWAP1 DIV DUP2 ADD SWAP3 DUP3 PUSH1 0x1F LT PUSH3 0x3CC JUMPI DUP1 MLOAD PUSH1 0xFF NOT AND DUP4 DUP1 ADD OR DUP6 SSTORE PUSH3 0x3FD JUMP JUMPDEST DUP3 DUP1 ADD PUSH1 0x1 ADD DUP6 SSTORE DUP3 ISZERO PUSH3 0x3FD JUMPI SWAP2 DUP3 ADD JUMPDEST DUP3 DUP2 GT ISZERO PUSH3 0x3FC JUMPI DUP3 MLOAD DUP3 SSTORE SWAP2 PUSH1 0x20 ADD SWAP2 SWAP1 PUSH1 0x1 ADD SWAP1 PUSH3 0x3DF JUMP JUMPDEST JUMPDEST POP SWAP1 POP PUSH3 0x40C SWAP2 SWAP1 PUSH3 0x410 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST PUSH3 0x435 SWAP2 SWAP1 JUMPDEST DUP1 DUP3 GT ISZERO PUSH3 0x431 JUMPI PUSH1 0x0 DUP2 PUSH1 0x0 SWAP1 SSTORE POP PUSH1 0x1 ADD PUSH3 0x417 JUMP JUMPDEST POP SWAP1 JUMP JUMPDEST SWAP1 JUMP JUMPDEST PUSH2 0x10F1 DUP1 PUSH3 0x448 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xA9 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x39509351 GT PUSH2 0x71 JUMPI DUP1 PUSH4 0x39509351 EQ PUSH2 0x25F JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x2C5 JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x31D JUMPI DUP1 PUSH4 0xA457C2D7 EQ PUSH2 0x3A0 JUMPI DUP1 PUSH4 0xA9059CBB EQ PUSH2 0x406 JUMPI DUP1 PUSH4 0xDD62ED3E EQ PUSH2 0x46C JUMPI PUSH2 0xA9 JUMP JUMPDEST DUP1 PUSH4 0x6FDDE03 EQ PUSH2 0xAE JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x131 JUMPI DUP1 PUSH4 0x18160DDD EQ PUSH2 0x197 JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x1B5 JUMPI DUP1 PUSH4 0x313CE567 EQ PUSH2 0x23B JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB6 PUSH2 0x4E4 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xF6 JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0xDB JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x123 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x17D PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x147 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x586 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x19F PUSH2 0x5A4 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x221 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x60 DUP2 LT ISZERO PUSH2 0x1CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x5AE JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x243 PUSH2 0x687 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 PUSH1 0xFF AND PUSH1 0xFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x2AB PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x275 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x69E JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x307 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x2DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x751 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x325 PUSH2 0x799 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x365 JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0x34A JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x392 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x3EC PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x3B6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x83B JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x452 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x41C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x908 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x4CE PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x482 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x926 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x60 PUSH1 0x3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0x57C JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x551 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x57C JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x55F JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x59A PUSH2 0x593 PUSH2 0x9AD JUMP JUMPDEST DUP5 DUP5 PUSH2 0x9B5 JUMP JUMPDEST PUSH1 0x1 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x2 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x5BB DUP5 DUP5 DUP5 PUSH2 0xBAC JUMP JUMPDEST PUSH2 0x67C DUP5 PUSH2 0x5C7 PUSH2 0x9AD JUMP JUMPDEST PUSH2 0x677 DUP6 PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x28 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x1026 PUSH1 0x28 SWAP2 CODECOPY PUSH1 0x1 PUSH1 0x0 DUP12 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 PUSH1 0x0 PUSH2 0x62D PUSH2 0x9AD JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH2 0xE6D SWAP1 SWAP3 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH2 0x9B5 JUMP JUMPDEST PUSH1 0x1 SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x5 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH1 0xFF AND SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x747 PUSH2 0x6AB PUSH2 0x9AD JUMP JUMPDEST DUP5 PUSH2 0x742 DUP6 PUSH1 0x1 PUSH1 0x0 PUSH2 0x6BC PUSH2 0x9AD JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 PUSH1 0x0 DUP10 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH2 0xF2D SWAP1 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH2 0x9B5 JUMP JUMPDEST PUSH1 0x1 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x4 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0x831 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x806 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x831 JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x814 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x8FE PUSH2 0x848 PUSH2 0x9AD JUMP JUMPDEST DUP5 PUSH2 0x8F9 DUP6 PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x25 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x1097 PUSH1 0x25 SWAP2 CODECOPY PUSH1 0x1 PUSH1 0x0 PUSH2 0x872 PUSH2 0x9AD JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 PUSH1 0x0 DUP11 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH2 0xE6D SWAP1 SWAP3 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH2 0x9B5 JUMP JUMPDEST PUSH1 0x1 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x91C PUSH2 0x915 PUSH2 0x9AD JUMP JUMPDEST DUP5 DUP5 PUSH2 0xBAC JUMP JUMPDEST PUSH1 0x1 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 PUSH1 0x0 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 CALLER SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xA3B JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x24 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH2 0x1073 PUSH1 0x24 SWAP2 CODECOPY PUSH1 0x40 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xAC1 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x22 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH2 0xFDE PUSH1 0x22 SWAP2 CODECOPY PUSH1 0x40 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP1 PUSH1 0x1 PUSH1 0x0 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 PUSH1 0x0 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 DUP2 SWAP1 SSTORE POP DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925 DUP4 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xC32 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x25 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH2 0x104E PUSH1 0x25 SWAP2 CODECOPY PUSH1 0x40 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xCB8 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x23 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH2 0xFBB PUSH1 0x23 SWAP2 CODECOPY PUSH1 0x40 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0xCC3 DUP4 DUP4 DUP4 PUSH2 0xFB5 JUMP JUMPDEST PUSH2 0xD2E DUP2 PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x26 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x1000 PUSH1 0x26 SWAP2 CODECOPY PUSH1 0x0 DUP1 DUP8 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH2 0xE6D SWAP1 SWAP3 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH1 0x0 DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 DUP2 SWAP1 SSTORE POP PUSH2 0xDC1 DUP2 PUSH1 0x0 DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH2 0xF2D SWAP1 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH1 0x0 DUP1 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 DUP2 SWAP1 SSTORE POP DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF DUP4 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 DUP4 GT ISZERO DUP3 SWAP1 PUSH2 0xF1A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xEDF JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0xEC4 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0xF0C JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH1 0x0 DUP4 DUP6 SUB SWAP1 POP DUP1 SWAP2 POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP3 DUP5 ADD SWAP1 POP DUP4 DUP2 LT ISZERO PUSH2 0xFAB JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x1B DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH32 0x536166654D6174683A206164646974696F6E206F766572666C6F770000000000 DUP2 MSTORE POP PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP1 SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST POP POP POP JUMP INVALID GASLIMIT MSTORE NUMBER ORIGIN ADDRESS GASPRICE KECCAK256 PUSH21 0x72616E7366657220746F20746865207A65726F2061 PUSH5 0x6472657373 GASLIMIT MSTORE NUMBER ORIGIN ADDRESS GASPRICE KECCAK256 PUSH2 0x7070 PUSH19 0x6F766520746F20746865207A65726F20616464 PUSH19 0x65737345524332303A207472616E7366657220 PUSH2 0x6D6F PUSH22 0x6E7420657863656564732062616C616E636545524332 ADDRESS GASPRICE KECCAK256 PUSH21 0x72616E7366657220616D6F756E7420657863656564 PUSH20 0x20616C6C6F77616E636545524332303A20747261 PUSH15 0x736665722066726F6D20746865207A PUSH6 0x726F20616464 PUSH19 0x65737345524332303A20617070726F76652066 PUSH19 0x6F6D20746865207A65726F2061646472657373 GASLIMIT MSTORE NUMBER ORIGIN ADDRESS GASPRICE KECCAK256 PUSH5 0x6563726561 PUSH20 0x656420616C6C6F77616E63652062656C6F77207A PUSH6 0x726FA2646970 PUSH7 0x735822122081C8 BLOCKHASH CREATE DUP8 0xCE 0xF9 0x2F 0xEC 0xCB SUB STATICCALL 0xDC PUSH8 0x8B2708C331896EC5 NUMBER 0x2B 0x5D 0x4C PUSH8 0x5F27B6D3E664736F PUSH13 0x63430006020033000000000000 ", + "sourceMap": "142:152:5:-:0;;;177:115;8:9:-1;5:2;;;30:1;27;20:12;5:2;177:115:5;;;;;;;;;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;177:115:5;;;;;;;;;;;;;;;;2013:141:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2093:4;2085:5;:12;;;;;;;;;;;;:::i;:::-;;2117:6;2107:7;:16;;;;;;;;;;;;:::i;:::-;;2145:2;2133:9;;:14;;;;;;;;;;;;;;;;;;2013:141;;252:33:5::1;258:10;270:14;252:5;;;:33;;:::i;:::-;177:115:::0;142:152;;7835:370:2;7937:1;7918:21;;:7;:21;;;;7910:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7986:49;8015:1;8019:7;8028:6;7986:20;;;:49;;:::i;:::-;8061:24;8078:6;8061:12;;:16;;;;;;:24;;;;:::i;:::-;8046:12;:39;;;;8116:30;8139:6;8116:9;:18;8126:7;8116:18;;;;;;;;;;;;;;;;:22;;;;;;:30;;;;:::i;:::-;8095:9;:18;8105:7;8095:18;;;;;;;;;;;;;;;:51;;;;8182:7;8161:37;;8178:1;8161:37;;;8191:6;8161:37;;;;;;;;;;;;;;;;;;7835:370;;:::o;10695:92::-;;;;:::o;874:176:1:-;932:7;951:9;967:1;963;:5;951:17;;991:1;986;:6;;978:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1042:1;1035:8;;;874:176;;;;:::o;142:152:5:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;" + }, + "deployedBytecode": { + "linkReferences": {}, + "object": "608060405234801561001057600080fd5b50600436106100a95760003560e01c80633950935111610071578063395093511461025f57806370a08231146102c557806395d89b411461031d578063a457c2d7146103a0578063a9059cbb14610406578063dd62ed3e1461046c576100a9565b806306fdde03146100ae578063095ea7b31461013157806318160ddd1461019757806323b872dd146101b5578063313ce5671461023b575b600080fd5b6100b66104e4565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f65780820151818401526020810190506100db565b50505050905090810190601f1680156101235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61017d6004803603604081101561014757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610586565b604051808215151515815260200191505060405180910390f35b61019f6105a4565b6040518082815260200191505060405180910390f35b610221600480360360608110156101cb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506105ae565b604051808215151515815260200191505060405180910390f35b610243610687565b604051808260ff1660ff16815260200191505060405180910390f35b6102ab6004803603604081101561027557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061069e565b604051808215151515815260200191505060405180910390f35b610307600480360360208110156102db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610751565b6040518082815260200191505060405180910390f35b610325610799565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561036557808201518184015260208101905061034a565b50505050905090810190601f1680156103925780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103ec600480360360408110156103b657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061083b565b604051808215151515815260200191505060405180910390f35b6104526004803603604081101561041c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610908565b604051808215151515815260200191505060405180910390f35b6104ce6004803603604081101561048257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610926565b6040518082815260200191505060405180910390f35b606060038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561057c5780601f106105515761010080835404028352916020019161057c565b820191906000526020600020905b81548152906001019060200180831161055f57829003601f168201915b5050505050905090565b600061059a6105936109ad565b84846109b5565b6001905092915050565b6000600254905090565b60006105bb848484610bac565b61067c846105c76109ad565b6106778560405180606001604052806028815260200161102660289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061062d6109ad565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e6d9092919063ffffffff16565b6109b5565b600190509392505050565b6000600560009054906101000a900460ff16905090565b60006107476106ab6109ad565b8461074285600160006106bc6109ad565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610f2d90919063ffffffff16565b6109b5565b6001905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156108315780601f1061080657610100808354040283529160200191610831565b820191906000526020600020905b81548152906001019060200180831161081457829003601f168201915b5050505050905090565b60006108fe6108486109ad565b846108f98560405180606001604052806025815260200161109760259139600160006108726109ad565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e6d9092919063ffffffff16565b6109b5565b6001905092915050565b600061091c6109156109ad565b8484610bac565b6001905092915050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610a3b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806110736024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610ac1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180610fde6022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602581526020018061104e6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610cb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180610fbb6023913960400191505060405180910390fd5b610cc3838383610fb5565b610d2e81604051806060016040528060268152602001611000602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e6d9092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610dc1816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610f2d90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000838311158290610f1a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610edf578082015181840152602081019050610ec4565b50505050905090810190601f168015610f0c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b600080828401905083811015610fab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b50505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122081c840f087cef92feccb03fadc678b2708c331896ec5432b5d4c675f27b6d3e664736f6c63430006020033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0xA9 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x39509351 GT PUSH2 0x71 JUMPI DUP1 PUSH4 0x39509351 EQ PUSH2 0x25F JUMPI DUP1 PUSH4 0x70A08231 EQ PUSH2 0x2C5 JUMPI DUP1 PUSH4 0x95D89B41 EQ PUSH2 0x31D JUMPI DUP1 PUSH4 0xA457C2D7 EQ PUSH2 0x3A0 JUMPI DUP1 PUSH4 0xA9059CBB EQ PUSH2 0x406 JUMPI DUP1 PUSH4 0xDD62ED3E EQ PUSH2 0x46C JUMPI PUSH2 0xA9 JUMP JUMPDEST DUP1 PUSH4 0x6FDDE03 EQ PUSH2 0xAE JUMPI DUP1 PUSH4 0x95EA7B3 EQ PUSH2 0x131 JUMPI DUP1 PUSH4 0x18160DDD EQ PUSH2 0x197 JUMPI DUP1 PUSH4 0x23B872DD EQ PUSH2 0x1B5 JUMPI DUP1 PUSH4 0x313CE567 EQ PUSH2 0x23B JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0xB6 PUSH2 0x4E4 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xF6 JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0xDB JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x123 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x17D PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x147 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x586 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x19F PUSH2 0x5A4 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x221 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x60 DUP2 LT ISZERO PUSH2 0x1CB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x5AE JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x243 PUSH2 0x687 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 PUSH1 0xFF AND PUSH1 0xFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x2AB PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x275 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x69E JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x307 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x20 DUP2 LT ISZERO PUSH2 0x2DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x751 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x325 PUSH2 0x799 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x365 JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0x34A JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0x392 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x3EC PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x3B6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x83B JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x452 PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x41C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x908 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 ISZERO ISZERO ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x4CE PUSH1 0x4 DUP1 CALLDATASIZE SUB PUSH1 0x40 DUP2 LT ISZERO PUSH2 0x482 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 ADD SWAP1 DUP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND SWAP1 PUSH1 0x20 ADD SWAP1 SWAP3 SWAP2 SWAP1 POP POP POP PUSH2 0x926 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x60 PUSH1 0x3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0x57C JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x551 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x57C JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x55F JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x59A PUSH2 0x593 PUSH2 0x9AD JUMP JUMPDEST DUP5 DUP5 PUSH2 0x9B5 JUMP JUMPDEST PUSH1 0x1 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x2 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x5BB DUP5 DUP5 DUP5 PUSH2 0xBAC JUMP JUMPDEST PUSH2 0x67C DUP5 PUSH2 0x5C7 PUSH2 0x9AD JUMP JUMPDEST PUSH2 0x677 DUP6 PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x28 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x1026 PUSH1 0x28 SWAP2 CODECOPY PUSH1 0x1 PUSH1 0x0 DUP12 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 PUSH1 0x0 PUSH2 0x62D PUSH2 0x9AD JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH2 0xE6D SWAP1 SWAP3 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH2 0x9B5 JUMP JUMPDEST PUSH1 0x1 SWAP1 POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x5 PUSH1 0x0 SWAP1 SLOAD SWAP1 PUSH2 0x100 EXP SWAP1 DIV PUSH1 0xFF AND SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x747 PUSH2 0x6AB PUSH2 0x9AD JUMP JUMPDEST DUP5 PUSH2 0x742 DUP6 PUSH1 0x1 PUSH1 0x0 PUSH2 0x6BC PUSH2 0x9AD JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 PUSH1 0x0 DUP10 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH2 0xF2D SWAP1 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH2 0x9B5 JUMP JUMPDEST PUSH1 0x1 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x60 PUSH1 0x4 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 PUSH1 0x1F ADD PUSH1 0x20 DUP1 SWAP2 DIV MUL PUSH1 0x20 ADD PUSH1 0x40 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 SWAP3 SWAP2 SWAP1 DUP2 DUP2 MSTORE PUSH1 0x20 ADD DUP3 DUP1 SLOAD PUSH1 0x1 DUP2 PUSH1 0x1 AND ISZERO PUSH2 0x100 MUL SUB AND PUSH1 0x2 SWAP1 DIV DUP1 ISZERO PUSH2 0x831 JUMPI DUP1 PUSH1 0x1F LT PUSH2 0x806 JUMPI PUSH2 0x100 DUP1 DUP4 SLOAD DIV MUL DUP4 MSTORE SWAP2 PUSH1 0x20 ADD SWAP2 PUSH2 0x831 JUMP JUMPDEST DUP3 ADD SWAP2 SWAP1 PUSH1 0x0 MSTORE PUSH1 0x20 PUSH1 0x0 KECCAK256 SWAP1 JUMPDEST DUP2 SLOAD DUP2 MSTORE SWAP1 PUSH1 0x1 ADD SWAP1 PUSH1 0x20 ADD DUP1 DUP4 GT PUSH2 0x814 JUMPI DUP3 SWAP1 SUB PUSH1 0x1F AND DUP3 ADD SWAP2 JUMPDEST POP POP POP POP POP SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x8FE PUSH2 0x848 PUSH2 0x9AD JUMP JUMPDEST DUP5 PUSH2 0x8F9 DUP6 PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x25 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x1097 PUSH1 0x25 SWAP2 CODECOPY PUSH1 0x1 PUSH1 0x0 PUSH2 0x872 PUSH2 0x9AD JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 PUSH1 0x0 DUP11 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH2 0xE6D SWAP1 SWAP3 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH2 0x9B5 JUMP JUMPDEST PUSH1 0x1 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x91C PUSH2 0x915 PUSH2 0x9AD JUMP JUMPDEST DUP5 DUP5 PUSH2 0xBAC JUMP JUMPDEST PUSH1 0x1 SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x1 PUSH1 0x0 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 PUSH1 0x0 DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 CALLER SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xA3B JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x24 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH2 0x1073 PUSH1 0x24 SWAP2 CODECOPY PUSH1 0x40 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xAC1 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x22 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH2 0xFDE PUSH1 0x22 SWAP2 CODECOPY PUSH1 0x40 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP1 PUSH1 0x1 PUSH1 0x0 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 PUSH1 0x0 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 DUP2 SWAP1 SSTORE POP DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925 DUP4 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xC32 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x25 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH2 0x104E PUSH1 0x25 SWAP2 CODECOPY PUSH1 0x40 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP3 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ ISZERO PUSH2 0xCB8 JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE PUSH1 0x23 DUP2 MSTORE PUSH1 0x20 ADD DUP1 PUSH2 0xFBB PUSH1 0x23 SWAP2 CODECOPY PUSH1 0x40 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0xCC3 DUP4 DUP4 DUP4 PUSH2 0xFB5 JUMP JUMPDEST PUSH2 0xD2E DUP2 PUSH1 0x40 MLOAD DUP1 PUSH1 0x60 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x26 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x1000 PUSH1 0x26 SWAP2 CODECOPY PUSH1 0x0 DUP1 DUP8 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH2 0xE6D SWAP1 SWAP3 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH1 0x0 DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 DUP2 SWAP1 SSTORE POP PUSH2 0xDC1 DUP2 PUSH1 0x0 DUP1 DUP6 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 SLOAD PUSH2 0xF2D SWAP1 SWAP2 SWAP1 PUSH4 0xFFFFFFFF AND JUMP JUMPDEST PUSH1 0x0 DUP1 DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP2 MSTORE PUSH1 0x20 ADD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x0 KECCAK256 DUP2 SWAP1 SSTORE POP DUP2 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND DUP4 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH32 0xDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF DUP4 PUSH1 0x40 MLOAD DUP1 DUP3 DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP4 DUP4 GT ISZERO DUP3 SWAP1 PUSH2 0xF1A JUMPI PUSH1 0x40 MLOAD PUSH32 0x8C379A000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0xEDF JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0xEC4 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0xF0C JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST POP PUSH1 0x0 DUP4 DUP6 SUB SWAP1 P + +
      + +## Passo #4: Escreva um contrato inteligente [Link para documento](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-tests) {#step-4-test-your-smart-contract} + +### Passo #4.1: Instale o waffle no seu projeto [Link para o documento](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-tests) {#step-4-1} + +Depois de criarmos com sucesso um Contrato Inteligente, podemos testá-lo. Vamos usar o `Waffle` para fazer isso. + +Os testes em `Waffle` são escritos usando `Mocha` juntamente com `Chai`. Podemos usar um ambiente de teste diferente mas `Waffle` matchers só trabalham com `Chai`. + +Então, precisamos adicionar `Chai` a nossas dependências : + +```bash + yarn add --dev mocha chai +``` + +### Passo #4.2: Escreva um contrato inteligente [Link para documento](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-tests) {#step-4-2} + +Para escrever nosso teste precisamos criar o arquivo `BasicToken.test.ts` em nosso diretório de teste. + +```ts +import { expect, use } from "chai" +import { Contract } from "ethers" +import { deployContract, MockProvider, solidity } from "ethereum-waffle" +import BasicToken from "../build/BasicToken.json" + +use(solidity) + +describe("BasicToken", () => { + const [wallet, walletTo] = new MockProvider().getWallets() + let token: Contract + + beforeEach(async () => { + token = await deployContract(wallet, BasicToken, [1000]) + }) +}) +``` + +Então, usamos o `deployContract` método de `Waffle`para publicar nosso token. Como argumentos, devemos passar a carteira ``, o arquivo json compilado de nosso contrato e saldo padrão. + +`Waffle` também nos permite criar uma `carteira`, o que facilita a implantação de um contrato. + +Você pode ler mais sobre a `carteira` [aqui](https://ethereum-waffle.readthedocs.io/en/latest/basic-testing.html?highlight=wallet#getting-wallets) e pode ler mais sobre a função de implantação [aqui](https://ethereum-waffle.readthedocs.io/en/latest/basic-testing.html?highlight=wallet#deploying-contracts). + +Vamos escrever um teste simples para verificar o saldo da nossa carteira. Desde que enviamos o valor 1000 durante a implantação do nosso contrato, o saldo de nossa carteira deve ser 1000 tokens, que podemos fazer check-in no primeiro teste. + +```ts +it("Assigns initial balance", async () => { + expect(await token.balanceOf(wallet.address)).to.equal(1000) +}) +``` + +Para executar o teste, use `yarn test` + +### Passo #4.3 Emitindo eventos [Link para o documento](https://ethereum-waffle.readthedocs.io/en/latest/matchers.html?highlight=changeBalance#emitting-events) {#step-4-3} + +Neste tutorial, eu quero mostrar a você as correspondências mais úteis do `Waffle`, então vamos começar com o primeiro. + +`Waffle` nos permite testar quais eventos foram emitidos. + +Neste tutorial, vou testar o método de `transfer` do nosso contrato. + +Neste teste, farei uma transferência de uma carteira para outra e verificarei se o evento `transfer` foi chamado. + +```ts +it("Transfer emits event", async () => { + await expect(token.transfer(walletTo.address, 7)) + .to.emit(token, "Transfer") + .withArgs(wallet.address, walletTo.address, 7) +}) +``` + +Além disso, uma grande vantagem desse "matcher" é que podemos verificar com quais argumentos este evento foi chamado adicionando `withArgs` ao teste. + +Isso permitir-nos-á ter a certeza de que a nossa função está a ser chamada corretamente! + +### Passo #4.4 Emitindo eventos [Link para o documento](https://ethereum-waffle.readthedocs.io/en/latest/matchers.html?highlight=changeBalance#revert-with-message) {#step-4-4} + +`Waffle` nos permite testar quais eventos foram emitidos. + +Usaremos `revertedWith` "matcher" em nosso teste para verificar. + +Podemos escrever um teste no qual realizaremos uma transferência por um valor maior do que o que fizemos na nossa carteira. E então verificaremos se a transação reverteu com a mensagem exata! + +```ts +it("Can not transfer above the amount", async () => { + await expect(token.transfer(walletTo.address, 1007)).to.be.revertedWith( + "VM Exception while processing transaction: revert ERC20: transfer amount exceeds balance" + ) +}) +``` + +### Passo #4.5 Emitindo eventos [Link para o documento](https://ethereum-waffle.readthedocs.io/en/latest/matchers.html?highlight=changeBalance#change-balance) {#step-4-5} + +`Waffle` nos permite verificar se há mudanças nos saldos das carteiras! + +Podemos usar o matcher `changeTokenBalance` para verificar a mudança do saldo ou o `changeTokenBalances` para uma conta múltipla. + +O matcher pode aceitar `números`, `strings` e `BigNumbers` como uma alteração de saldo, enquanto o endereço deve ser especificado como uma carteira ou um contrato. + +Vamos escrever o próximo teste: + +```ts +it("Send transaction changes receiver balance", async () => { + await expect(() => + wallet.sendTransaction({ to: walletTo.address, gasPrice: 0, value: 200 }) + ).to.changeBalance(walletTo, 200) +}) +``` + +O teste acima é um teste para uma única carteira. + +E a próxima para múltiplas carteiras: + +```ts +it("Send transaction changes receiver balance", async () => { + await expect(() => + wallet.sendTransaction({ to: walletTo.address, gasPrice: 0, value: 200 }) + ).to.changeBalance(walletTo, 200) +}) +``` + +A transação é esperada para ser passada como um callback (precisamos verificar o saldo antes da chamada) ou como uma resposta de transação. + +## Parabéns {#congratulations} + +**Parabéns! Você o fez através do meu tutorial. Você deu o seu primeiro grande passo para testar contratos inteligentes com Waffle.** + +**O código deste tutorial que você pode encontrar [aqui](https://github.com/VladStarostenko/tutorial-for-ethereum-org-website).** + +**Mais documentação sobre `Waffle` disponível [aqui](https://getwaffle.io).** diff --git a/public/content/translations/pt-br/developers/tutorials/the-graph-fixing-web3-data-querying/index.md b/public/content/translations/pt-br/developers/tutorials/the-graph-fixing-web3-data-querying/index.md new file mode 100644 index 00000000000..d87753ec150 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/the-graph-fixing-web3-data-querying/index.md @@ -0,0 +1,313 @@ +--- +title: "The Graph: Consertando a consulta de dados da Web3" +description: Blockchain é como um banco de dados, mas sem SQL. Todos os dados estão lá, mas não há maneira de acessá-los. Deixe-me mostrar a você como consertar isso com The Graph e GraphQL. +author: Markus Waas +lang: pt-br +tags: + - "solidez" + - "smart contracts" + - "consultando" + - "the Graph" + - "create-eth-app" + - "react" +skill: intermediate +published: 2020-09-06 +source: soliditydeveloper.com +sourceUrl: https://soliditydeveloper.com/thegraph +--- + +Dessa vez, daremos uma olhada mais de perto no The Graph que essencialmente se tornou parte do stack padrão para o desenvolvimento de Dapps no último ano. Primeiro, vamos ver como faríamos as coisas da maneira tradicional... + +## Sem The Graph... {#without-the-graph} + +Então vamos começar com um exemplo simples para propósitos ilustrativos. Todos nós gostamos de jogos, então imagine um jogo simples com os usuários fazendo apostas: + +```solidity +pragma solidity 0.7.1; + +contract Game { + uint256 totalGamesPlayerWon = 0; + uint256 totalGamesPlayerLost = 0; + event BetPlaced(address player, uint256 value, bool hasWon); + + function placeBet() external payable { + bool hasWon = evaluateBetForPlayer(msg.sender); + + if (hasWon) { + (bool success, ) = msg.sender.call{ value: msg.value * 2 }(''); + require(success, "Transfer failed"); + totalGamesPlayerWon++; + } else { + totalGamesPlayerLost++; + } + + emit BetPlaced(msg.sender, msg.value, hasWon); + } +} +``` + +Agora, digamos em nosso dapp, queremos exibir as apostas totais, os jogos perdidos/ganhos e também atualizá-lo sempre que alguém jogar novamente. A abordagem seria: + +1. Busca `totalGamesPlayerWon`. +2. Busca `totalGamesPlayerWon`. +3. Inscreva-se nos eventos `BetPlaced`. + +Nós podemos escutar [evento na Web3](https://docs.web3js.org/api/web3/class/Contract#events) como mostrado à direita, mas isso requer manipular alguns casos. + +```solidity +AmeContract.events.BetPlaced({ + fromBlock: 0 +}, function(error, event) { console.log(event); }) +.on('data', function(event) { + // event fired +}) +.on('changed', function(event) { + // event was removed again +}) +.on('error', function(error, receipt) { + // tx rejected +}); +``` + +Por hora está de bom tamanho nosso simples exemplo. Mas digamos que queremos exibir as quantidades das apostas perdidas/ganhas apenas para o jogador atual. Se estivermos sem sorte, você pode implantar um novo contrato que armazena esses valores e busca. E agora imagine um contrato inteligente e um Dapp muito mais complicados. As coisas podem ficar confusas rapidamente. + +![Não basta uma simples consulta](./one-does-not-simply-query.jpg) + +Você pode ver que isso não é ideal: + +- Não funciona para contratos já implementados. +- Custos de gas adicionais para armazenar esses valores. +- Requer outra chamada para obter os dados para um nó Ethereum. + +![Não é bom o suficiente](./not-good-enough.jpg) + +Agora vamos ver uma solução melhor. + +## Deixe-me apresentá-lo ao GraphQL {#let-me-introduce-to-you-graphql} + +Primeiro, vamos falar sobre GraphQL, originalmente projetado e implementado pelo Facebook. Você deve estar familiarizado com o modelo tradicional da Rest API. Agora imagine que você poderia escrever uma consulta para exatamente os dados que você queria: + +![GraphQL API vs. REST API](./graphql.jpg) + + + +As duas imagens capturam praticamente a essência do GraphQL. Com a consulta à direita, podemos definir exactamente quais os dados que queremos, assim aí temos tudo ao alcance e nada mais do que aquilo de que precisamos. Um servidor GraphQL lida com a busca de todos os dados necessários, então é incrivelmente fácil para o lado frontend do consumidor. [Esta é uma bela explicação](https://www.apollographql.com/blog/graphql-explained-5844742f195e/) de como exatamente o servidor lida com uma consulta se estiver interessado. + +Agora com esse conhecimento, vamos finalmente adentrar o espaço da blockchain e The Graph. + +## O que é The Graph? {#what-is-the-graph} + +Um blockchain é um banco de dados descentralizado, mas em contraste com o que é geralmente o caso, nós não temos uma linguagem de consulta para esse banco de dados. Soluções para a obtenção de dados são dolorosas ou completamente impossíveis. The Graph é um protocolo descentralizado para indexação e consulta de dados da blockchain. E você pode ter adivinhado, ele está usando GraphQL como idioma de consulta. + +![The Graph](./thegraph.png) + +Os exemplos são sempre os melhores para entender algo, então vamos usar The Graph para o nosso exemplo de GameContract. + +## Como criar um Subgraph {#how-to-create-a-subgraph} + +A definição de como indexar dados é chamada de subgráfico. Requer três componentes: + +1. Manifesto (`subgraph.yaml`) +2. Esquema (`schema.graphql`) +3. Mapping (`mapping.ts`) + +### Manifesto (`subgraph.yaml`) {#manifest} + +O manifesto é nosso arquivo de configuração e define: + +- que contratos inteligentes indexar (endereço, rede, ABI...) +- quais eventos ouvir +- outras coisas para ouvir como chamadas de função ou blocos +- as fnções de mapping sendo chamadas (conferir `mapping.ts` below) + +Aqui você pode definir vários contratos e manipuladores. Uma configuração típica teria uma pasta de subgráfico dentro do projeto Truffle/Hardhat com seu próprio repositório. Então você pode facilmente se referir ao ABI. + +Por conveniência você também pode querer usar uma ferramenta modelo tipo um bigode. Em seguida, você cria um `subgraph.template.yaml` e insere os endereços com base nas mais recentes implantações. Para uma configuração de exemplo mais avançada, veja, por exemplo, o [repositório de subgráfico Aave](https://github.com/aave/aave-protocol/tree/master/thegraph). + +E a documentação completa pode ser vista [aqui](https://thegraph.com/docs/en/developing/creating-a-subgraph/#the-subgraph-manifest). + +```yaml +specVersion: 0.0.1 +description: Placing Bets on Ethereum +repository: - GitHub link - +schema: + file: ./schema.graphql +dataSources: + - kind: ethereum/contract + name: GameContract + network: mainnet + source: + address: '0x2E6454...cf77eC' + abi: GameContract + startBlock: 6175244 + mapping: + kind: ethereum/events + apiVersion: 0.0.1 + language: wasm/assemblyscript + entities: + - GameContract + abis: + - name: GameContract + file: ../build/contracts/GameContract.json + eventHandlers: + - event: PlacedBet(address,uint256,bool) + handler: handleNewBet + file: ./src/mapping.ts +``` + +### Esquema (`schema.graphql`) {#schema} + +O esquema é a definição de dados do GraphQL. Permitirá que você defina quais entidades existem e seus tipos. Tipos suportados do The Graph são + +- Bytes +- ID +- String +- Booleano +- Int +- BigInt +- BigDecimal + +Você também pode usar entidades como tipo para definir relações. No nosso exemplo, definimos uma relação entre 1 e muitos entre jogadores e apostas. O ! significa que o valor não pode ser vazio. A documentação completa pode ser vista [aqui](https://thegraph.com/docs/en/developing/creating-a-subgraph/#the-subgraph-manifest). + +```graphql +type Bet @entity { + id: ID! + player: Player! + playerHasWon: Boolean! + time: Int! +} + +type Player @entity { + id: ID! + totalPlayedCount: Int + hasWonCount: Int + hasLostCount: Int + bets: [Bet]! +} +``` + +### Mapping (`mapping.ts`) {#mapping} + +O arquivo de mapeamento no The Graph define nossas funções que transformam eventos recebidos em entidades. É escrito em AssemblyScript, um subconjunto de Typescript. Isto significa que pode ser compilado em WASM (WebAssembly) para uma execução mais eficiente e portátil do mapeamento. + +Você precisará definir cada função nomeada no arquivo `subgraph.yaml`, portanto, no nosso caso, precisamos apenas uma: `handleNewBet`. Primeiro, tentamos carregar a entidade Jogador a partir do endereço do remetente como id. Se não existir, nós criamos uma nova entidade e a preenchemos com os valores iniciais. + +Em seguida, criamos uma nova entidade Bet. O ID para isso sempre `event.transaction.hash.toHex() + "-" + event.logIndex.toString()` garantirá um valor exclusivo. Usar somente o hash não é o suficiente porque alguém pode chamar a função placeBet várias vezes em uma transação através de um contrato inteligente. + +Finalmente, nós podemos atualizar a entidade "Player" com todos os dados. Arrays não podem ser empurrados diretamente, mas precisam ser atualizados como mostrado aqui. Usamos o id para fazer referência à aposta. E `.save()` é necessário no final para armazenar uma entidade. + +A documentação completa pode ser vista aqui: https://thegraph.com/docs/en/developing/creating-a-subgraph/#writing-mappings. Você também pode adicionar a saída do log ao arquivo de mapeamento, consultando [aqui](https://thegraph.com/docs/assemblyscript-api#api-reference). + +```typescript +import { Bet, Player } from "../generated/schema" +import { PlacedBet } from "../generated/GameContract/GameContract" + +export function handleNewBet(event: PlacedBet): void { + let player = Player.load(event.transaction.from.toHex()) + + if (player == null) { + // create if doesn't exist yet + player = new Player(event.transaction.from.toHex()) + player.bets = new Array(0) + player.totalPlayedCount = 0 + player.hasWonCount = 0 + player.hasLostCount = 0 + } + + let bet = new Bet( + event.transaction.hash.toHex() + "-" + event.logIndex.toString() + ) + bet.player = player.id + bet.playerHasWon = event.params.hasWon + bet.time = event.block.timestamp + bet.save() + + player.totalPlayedCount++ + if (event.params.hasWon) { + player.hasWonCount++ + } else { + player.hasLostCount++ + } + + // update array like this + let bets = player.bets + bets.push(bet.id) + player.bets = bets + + player.save() +} +``` + +## Usando isso no Frontend {#using-it-in-the-frontend} + +Usando algo como Apollo Boost, você pode facilmente integrar o The Graph em seu React Dapp (ou Apollo-Vue). Especialmente ao usar React hooks e Apollo, buscar dados é tão simples quanto escrever uma única consulta GraphQl no seu componente. Uma típica configuração pode se parecer com isso: + +```javascript +// See all subgraphs: https://thegraph.com/explorer/ +const client = new ApolloClient({ + uri: "{{ subgraphUrl }}", +}) + +ReactDOM.render( + + + , + document.getElementById("root") +) +``` + +E agora podemos escrever, por exemplo, uma consulta como esta. Isso vai nos ajudar + +- quantas vezes o usuário atual ganhou +- quantas vezes o usuário atual perdeu +- uma lista de horários com todas as suas apostas anteriores + +Tudo em um único pedido para o servidor do GraphQL. + +```javascript +const myGraphQlQuery = gql` + players(where: { id: $currentUser }) { + totalPlayedCount + hasWonCount + hasLostCount + bets { + time + } + } +` + +const { loading, error, data } = useQuery(myGraphQlQuery) + +React.useEffect(() => { + if (!loading && !error && data) { + console.log({ data }) + } +}, [loading, error, data]) +``` + +![Magic](./magic.jpg) + +Mas precisamos de uma última peça do quebra-cabeças: o servidor. Você pode também executá-lo por conta própria ou usar o serviço hospedado. + +## Servidor The Graph {#the-graph-server} + +### Graph Explorer: o serviço hospedado {#graph-explorer-the-hosted-service} + +O jeito mais fácil é usar o serviço hospedado. Siga as instruções [aqui](https://thegraph.com/docs/en/deploying/deploying-a-subgraph-to-hosted/) para publicar um subgráfico. Para muitos projetos, você pode encontrar subgrafos existentes no [explorer](https://thegraph.com/explorer/). + +![O Graph-Explorer](./thegraph-explorer.png) + +### Executando seu próprio nó {#running-your-own-node} + +Como alternativa, você pode executar seu próprio nó. Documentação [aqui](https://github.com/graphprotocol/graph-node#quick-start). Uma das razões para isso: você pode estar usando uma rede não suportada pelo serviço hospedado. As redes que contam atualmente com suporte [podem ser encontradas aqui](https://thegraph.com/docs/en/developing/supported-networks/). + +## O futuro descentralizado {#the-decentralized-future} + +GraphQL também suporta streams para os próximos eventos. Elas tem suporte no grafo por meio de [Subfluxos](https://thegraph.com/docs/en/substreams/), que se encontram atualmente em versão beta de código aberto. + +Em [2021](https://thegraph.com/blog/mainnet-migration/) O Grafo iniciou sua transição para uma rede de indexação descentralizada. Leia mais sobre a arquitetura dessa rede de indexação descentralizada [aqui](https://thegraph.com/docs/en/network/explorer/). + +Dois aspectos fundamentais são: + +1. Os usuários pagam aos indexadores pelas perguntas. +2. Os indexadores fazem stake dos Graph Tokens (GRT). diff --git a/public/content/translations/pt-br/developers/tutorials/token-integration-checklist/index.md b/public/content/translations/pt-br/developers/tutorials/token-integration-checklist/index.md new file mode 100644 index 00000000000..e8b891a158a --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/token-integration-checklist/index.md @@ -0,0 +1,84 @@ +--- +title: Checklist de integração do token +description: Uma lista de coisas a considerar ao interagir com tokens +author: "Trailofbits" +lang: pt-br +tags: + - "solidity" + - "contratos inteligentes" + - "segurança" + - "tokens" +skill: intermediate +published: 2020-08-13 +source: Construindo contratos seguros +sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/token_integration.md +--- + +Siga este checklist ao interagir com tokens arbitrários. Certifique-se de que você entende os riscos associados a cada item e justifique qualquer exceção a essas regras. + +Por conveniência, todos os [utilitários](https://github.com/crytic/slither#tools) do Slither podem ser executados diretamente em um endereço de token, como: + +[Usando Tutorial do Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) + +```bash +slither-check-erc 0xdac17f958d2ee523a2206206994597c13d831ec7 TetherToken +``` + +Para seguir esta lista de verificação, você vai querer ter essa saída do Slither para o token: + +```bash +- slither-check-erc [target] [contractName] [optional: --erc ERC_NUMBER] +- slither [target] --print human-summary +- slither [target] --print contract-summary +- slither-prop . --contract ContractName # requer configuração, e uso de Echidna e Manticore +``` + +## Considerações gerais {#general-considerations} + +- **O contrato tem uma revisão de segurança.** Evite interagir com contratos que não tenham uma revisão de segurança. Verifique a duração da avaliação (também conhecida como "nível de esforço"), a reputação da empresa de segurança e o número e a gravidade das descobertas. +- **Você entrou em contato com os desenvolvedores.** Talvez você precise alertar sua equipe para um incidente. Procure por contatos apropriados em [blockchain-security-contacts](https://github.com/crytic/blockchain-security-contacts). +- **Eles têm uma lista de e-mails de segurança para anúncios críticos.** Sua equipe deve aconselhar usuários (como você!) quando são encontrados problemas críticos ou quando ocorrem atualizações. + +## Conformidade do ERC {#erc-conformity} + +O Slither inclui um utilitário, [slither-check-erc](https://github.com/crytic/slither/wiki/ERC-Conformance), que analisa a conformidade de um token com vários padrões de ERC relacionados. Use slither-check-erc para revisar que: + +- **Transfer e transferFrom retornam um booleano.** Vários tokens não retornam um booleano nessas funções. Como resultado, suas chamadas no contrato podem falhar. +- **As funções "name", "decimals" e "symbol" estão presentes se usados.** Essas funções são opcionais no padrão do ERC20 e podem não estar presentes. +- **"Decimals" retorna um uint8.** Vários tokens retornam uma uint256 incorretamente. Se este for o caso, certifique-se de que o valor retornado é inferior a 255. +- **O token mitiga a conhecida condição de corrida do [ERC20](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729).** O padrão ERC20 possui uma condição de corrida conhecida do ERC20 que deve ser mitigada para evitar que invasores roubem tokens. +- **O token não é um token ERC777 e não tem nenhuma chamada de função externa na "transfer" e "transferFrom".** Chamadas externas nas funções de transferência podem levar a reentradas. + +O Slither inclui um utilitário, [slither-prop](https://github.com/crytic/slither/wiki/Property-generation), que gera testes unitários e propriedades de segurança que podem descobrir muitas falhas comuns do ERC. Use slither-check-erc para revisar que: + +- **O contrato passa em todos os testes unitários e propriedades de segurança do slither-prop.** Execute os testes unitários gerados e então verifique as propriedades com [Echidna](https://github.com/crytic/echidna) e [Manticore](https://manticore.readthedocs.io/en/latest/verifier.html). + +Por último, há certas características que são difíceis de identificar automaticamente. Revisão destas condições manualmente: + +- **"Transfer" e "transferFrom" não devem cobrar taxas.** Os tokens deflacionários podem levar a um comportamento inesperado. +- **Os potenciais juros obtidos com os token são retirados da conta.** Alguns tokens distribuem juros para os titulares (holders) de tokens. Estes juros podem estar atados ao contrato caso não tenham sido retirados da conta. + +## Composição do contrato {#contract-composition} + +- **O contrato evita a complexidade desnecessária.** O token deve ser um contrato simples; um token com código complexo requer um padrão de revisão mais alto. Use o [human-summary printer](https://github.com/crytic/slither/wiki/Printer-documentation#human-summary) do Slither para identificar um código complexo. +- **O contrato usa SafeMath.** Contratos que não usam SafeMath requerem um padrão de revisão mais elevado. Inspecione o contrato manualmente para uso de SafeMath. +- **O contrato tem apenas algumas funções "non–token-related".** Funções "non–token-related" aumentam a probabilidade de ocorrência de problemas no contrato. Use o [contract-summary printer](https://github.com/crytic/slither/wiki/Printer-documentation#contract-summary) do Slither para revisar amplamente o código usado no contrato. +- **O token tem apenas um endereço.** Tokens com vários pontos de entrada para atualizações de saldo podem quebrar a contabilidade interna com base no endereço (Ex.: `balances[token_address][msg.sender]` pode não refletir o saldo atual). + +## Privilégios do proprietário {#owner-privileges} + +- **O token não é atualizável.** Contratos atualizáveis podem mudar suas regras ao longo do tempo. Use a impressora de [resumo-humano do Slither](https://github.com/crytic/slither/wiki/Printer-documentation#contract-summary) para identificar um código complexo. +- **O proprietário tem capacidades limitadas de cunhagem.** Os proprietários maliciosos ou comprometidos podem abusar das capacidades de cunhagem. Use a impressora [de resumo humano do Sliter](https://github.com/crytic/slither/wiki/Printer-documentation#contract-summary) para revisar as capacidades de cunhagem e considere revisar manualmente o código. +- **O token não é pausável.** Os proprietários maliciosos ou comprometidos podem capturar contratos que dependem de tokens pausáveis. Identifique o código pauseável à mão. +- **O proprietário não pode bloquear o contrato.** Donos maliciosos ou comprometidos podem prender contratos dependendo de tokens com uma lista negra. Identifique os recursos da lista negra à mão. +- **A equipe por trás do token é conhecida e pode ser considerada responsável por abusos.** Contratos com equipes de desenvolvimento anônimas, ou que residam em abrigos legais devem exigir um padrão de revisão mais elevado. + +## Escassez de token {#token-scarcity} + +Revisões de problemas de escassez de tokens requerem revisão manual. Verifique estas condições: + +- **Nenhum usuário é dono da maior parte do abastecimento.** Se alguns usuários possuem a maioria dos tokens, eles podem influenciar operações baseadas na repartição do token. +- **A oferta total é suficiente.** Tokens com uma oferta baixa podem ser facilmente manipulados. +- **Os tokens estão localizados em mais de algumas trocas.** Se todos os tokens estiverem em uma troca, um compromisso da troca pode comprometer o contrato que depende do token. +- **Os usuários entendem os riscos associados a grandes fundos ou flash loans.** Contratos que dependem do saldo do token devem levar cuidadosamente em consideração ataques com grandes fundos ou ataques por meio de flash loans. +- **O token não permite flash minting**. O "Flash minting" pode levar a oscilações substanciais na balança e no fornecimento total, o que exige verificações de overflow rigorosas e abrangentes na operação do token. diff --git a/public/content/translations/pt-br/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md b/public/content/translations/pt-br/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md index 64d2f3820c0..6426998c4ea 100644 --- a/public/content/translations/pt-br/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md +++ b/public/content/translations/pt-br/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md @@ -6,7 +6,6 @@ tags: - "contratos inteligentes" - "tokens" - "solidity" - - "introdução" - "erc-20" skill: intermediate lang: pt-br @@ -18,7 +17,7 @@ address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" No tutorial anterior, estudamos [a estrutura de um token ERC-20 no Solidity](/developers/tutorials/understand-the-erc-20-token-smart-contract/)usado na blockchain Ethereum. Nesse artigo, veremos como usar um contrato inteligente para interagir com um token usando a linguagem Solidity. -Para esse contrato inteligente, vamos criar uma troca descentralizada realmente robusta na qual o usuário pode negociar o Ethereum com o nosso recém-implantado [token ERC-20](/developers/docs/standards/tokens/erc-20/). +Para este contrato inteligente, nós criaremos uma corretora descentralizada realmente fictícia, na qual um usuário pode trocar ether por nosso [token ERC-20](/developers/docs/standards/tokens/erc-20/) recém-implantado. Para este tutorial, usaremos o código que escrevemos no tutorial anterior como uma base. Nosso DEX instanciará um contrato em seu construtor e realizará as operações de: @@ -141,7 +140,7 @@ Vamos programar a função de compra. Primeiro, precisaremos verificar a quantid Observe que, se chamarmos a função `require` em caso de um erro, o ether enviado será diretamente revertido e retornado para o usuário. -To keep things simple, we just exchange 1 token for 1 Wei. +Para simplificar, apenas trocamos 1 "token" por 1 "Wei". ```solidity function buy() payable public { @@ -160,7 +159,7 @@ No caso de a compra ser bem-sucedida, devemos ver dois eventos na transação: o ## A função de venda {#the-sell-function} -A função responsável pela venda primeiro exigirá que o usuário tenha aprovado o valor, chamando a função approve antecipadamente. Approving the transfer requires the ERC20Basic token instantiated by the DEX to be called by the user. This can be achieved by first calling the DEX contract's `token()` function to retrieve the address where DEX deployed the ERC20Basic contract called `token`. Then we create an instance of that contract in our session and call its `approve` function. Then we are able to call the DEX's `sell` function and swap our tokens back for ether. For example, this is how this looks in an interactive brownie session: +A função responsável pela venda primeiro exigirá que o usuário tenha aprovado o valor, chamando a função `approve` antecipadamente. Aprovar a transferência requer que o token ERC20Basic instanciado pelo DEX seja chamado pelo usuário. Isso pode ser feito chamando a função `token()` do contrato da DEX para recuperar o endereço onde a DEX implantou o contrato ERC20Basic chamado `token`. Em seguida, criamos uma instância desse contrato em nossa sessão e chamamos sua função `approve`. Então podemos chamar a função `sell` da DEX e trocar nossos tokens de volta por ether. Por exemplo, é assim que fica em uma sessão interativa usando brownie: ```python #### Python in interactive brownie console... @@ -184,7 +183,7 @@ token.approve(dex.address, 3e18, {'from':account2}) ``` -Então quando a função `sell` é chamada, verificamos se a transferência do endereço do remetente para o endereço do contrato foi bem-sucedida e depois enviamos os Ethers para o endereço de chamada. +Então quando a função sell é chamada, verificamos se a transferência do endereço do remetente para o endereço do contrato foi bem-sucedida e depois enviamos os Ethers para o endereço de chamada. ```solidity function sell(uint256 amount) public { @@ -197,7 +196,7 @@ function sell(uint256 amount) public { } ``` -Se tudo funcionar, você deve ver 2 eventos (um `Transfer` e `Sold`) na transação, e o seu saldo de token e saldo de Ethereum atualizados. +Se tudo funcionar, você deverá ver 2 eventos (uma `Transferência` e `Vendido`) na transação e seu saldo de token e saldo de ether atualizados. ![Dois eventos na transação: transferência e venda](./transfer-and-sold-events.png) @@ -205,7 +204,7 @@ Se tudo funcionar, você deve ver 2 eventos (um `Transfer` e `Sold`) na transaç Neste tutorial, vimos como verificar o saldo e a dedução de um token ERC-20 e também como chamar a `Transfer` e `TransferFrom` de um contrato inteligente ERC20 usando a interface. -Once you make a transaction we have a JavaScript tutorial to [wait and get details about the transactions](https://ethereumdev.io/waiting-for-a-transaction-to-be-mined-on-ethereum-with-js/) that were made to your contract and a [tutorial to decode events generated by token transfers or any other events](https://ethereumdev.io/how-to-decode-event-logs-in-javascript-using-abi-decoder/) as long as you have the ABI. +Uma vez feita a transação, temos um tutorial JavaScript [esperando e pegando detalhes de uma transação](https://ethereumdev.io/waiting-for-a-transaction-to-be-mined-on-ethereum-with-js/) feitas para seu contrato e um [tutorial para decodificar eventos gerados em transferências de tokens e outros eventos](https://ethereumdev.io/how-to-decode-event-logs-in-javascript-using-abi-decoder/) desde que você tenha um ABI. Aqui está o código completo para o tutorial: diff --git a/public/content/translations/pt-br/developers/tutorials/understand-the-erc-20-token-smart-contract/index.md b/public/content/translations/pt-br/developers/tutorials/understand-the-erc-20-token-smart-contract/index.md index 2c7b488b713..655f1f643c2 100644 --- a/public/content/translations/pt-br/developers/tutorials/understand-the-erc-20-token-smart-contract/index.md +++ b/public/content/translations/pt-br/developers/tutorials/understand-the-erc-20-token-smart-contract/index.md @@ -7,7 +7,7 @@ tags: - "tokens" - "solidity" - "erc-20" -skill: beginner +skill: intermediate lang: pt-br published: 2020-04-05 source: EthereumDev diff --git a/public/content/translations/pt-br/developers/tutorials/uniswap-v2-annotated-code/index.md b/public/content/translations/pt-br/developers/tutorials/uniswap-v2-annotated-code/index.md index b49ae45db1a..abb2688c1cb 100644 --- a/public/content/translations/pt-br/developers/tutorials/uniswap-v2-annotated-code/index.md +++ b/public/content/translations/pt-br/developers/tutorials/uniswap-v2-annotated-code/index.md @@ -202,13 +202,13 @@ A forma como o par de troca decide sobre a taxa de câmbio entre o token0 e o to Veja um exemplo. Note que para manter a simplicidade a tabela mostra apenas três dígitos após a vírgula decimal e ignoramos a taxa de negociação de 0,3%, portanto os números não são precisos. | Evento | reserve0 | reserve1 | reserve0 \* reserve1 | Taxa de câmbio média (token1 / token0) | -| ------------------------------------------- | --------: | --------: | -------------------: | -------------------------------------- | -| Configuração Inicial | 1.000,000 | 1.000,000 | 1.000.000 | | -| Trader A troca 50 token0 por 47,619 token1 | 1.050,000 | 952,381 | 1.000.000 | 0,952 | -| Trader B troca 10 token0 por 8,984 token1 | 1.060,000 | 943,396 | 1.000.000 | 0,898 | -| Trader C troca 40 token0 por 34,305 token1 | 1.100,000 | 909,090 | 1.000.000 | 0,858 | -| Trader D troca 100 token1 por 109,01 token0 | 990,990 | 1.009,090 | 1.000.000 | 0,917 | -| Trader E troca 10 token0 por 10,079 token1 | 1.000,990 | 999,010 | 1.000.000 | 1,008 | +| ------------------------------------------- | ---------:| ---------:| ----------------------:| -------------------------------------- | +| Configuração Inicial | 1.000,000 | 1.000,000 | 1.000.000 | | +| Trader A troca 50 token0 por 47,619 token1 | 1.050,000 | 952,381 | 1.000.000 | 0,952 | +| Trader B troca 10 token0 por 8,984 token1 | 1.060,000 | 943,396 | 1.000.000 | 0,898 | +| Trader C troca 40 token0 por 34,305 token1 | 1.100,000 | 909,090 | 1.000.000 | 0,858 | +| Trader D troca 100 token1 por 109,01 token0 | 990,990 | 1.009,090 | 1.000.000 | 0,917 | +| Trader E troca 10 token0 por 10,079 token1 | 1.000,990 | 999,010 | 1.000.000 | 1,008 | À medida que os traders fornecem mais token0, o valor relativo do token1 aumenta, e vice-versa, baseado na oferta e na demanda. @@ -362,12 +362,12 @@ Se o tempo decorrido não for zero, isso significa que somos a primeira transaç } ``` -Cada acumulador de custo é atualizado com o último custo (reserva do outro token/reserva desse token) vezes o tempo decorrido em segundos. Para obter um preço médio, deve-se ler o preço cumulativo de dois pontos no tempo e dividir pela diferença de tempo entre eles. Por exemplo, suponha esta sequência de eventos: +Cada acumulador de custo é atualizado com o último custo (reserva do outro token/reserva desse token) vezes o tempo decorrido em segundos. Para obter um preço médio, tome o preço acumulado em dois pontos no tempo e divida-o pela diferença de tempo entre eles. Por exemplo, suponha esta sequência de eventos: -| Evento | reserva0 | reserva1 | carimbo de data/hora | Taxa de câmbio marginal (reserve1 / reserve0) | price0CumulativeLast | -| ----------------------------------------------------- | --------: | --------: | -------------------- | --------------------------------------------: | -------------------------: | -| Configuração Inicial | 1.000,000 | 1.000,000 | 5.000 | 1.000 | 0 | -| Trader A deposita 50 token0 e recebe 47,619 token1 | 1.050,000 | 952,381 | 5.020 | 0,907 | 20 | +| Evento | reserva0 | reserva1 | carimbo de data/hora | Taxa de câmbio marginal (reserve1 / reserve0) | price0CumulativeLast | +| ----------------------------------------------------- | ---------:| ---------:| -------------------- | ---------------------------------------------:| ----------------------------:| +| Configuração Inicial | 1.000,000 | 1.000,000 | 5.000 | 1.000 | 0 | +| Trader A deposita 50 token0 e recebe 47,619 token1 | 1.050,000 | 952,381 | 5.020 | 0,907 | 20 | | Trader B deposita 10 token0 e recebe 8,984 token1 | 1.060,000 | 943,396 | 5.030 | 0,890 | 20+10\*0,907 = 29,07 | | Trader C deposita 40 token0 e recebe 34,305 token1 | 1.100,000 | 909,090 | 5.100 | 0,826 | 29,07+70\*0,890 = 91,37 | | Trader D deposita 100 token1 e recupera 109,01 token0 | 990,990 | 1.009,090 | 5.110 | 1.018 | 91,37+10\*0,826 = 99,63 | @@ -499,9 +499,9 @@ No momento do primeiro depósito, não sabemos o valor relativo dos dois tokens, Podemos confiar nisso, pois é do interesse do depositante oferecer o mesmo valor para evitar perda de valor por arbitragem. Digamos que o valor dos dois tokens é idêntico, mas nosso depositante depositou quatro vezes mais o **Token1** do que o **Token0**. Um trader pode usar o fato de que o par de troca pensa que o **Token0** é mais valioso para extrair valor dessa situação. | Evento | reserva0 | reserva1 | reserva0 \* reserva1 | Valor do pool (reserve0 + reserve1) | -| -------------------------------------------------------------- | -------: | -------: | -------------------: | ----------------------------------: | -| Configuração Inicial | 8 | 32 | 256 | 40 | -| O trader deposita 8 tokens **Token0** e recupera 16 **Token1** | 16 | 16 | 256 | 32 | +| -------------------------------------------------------------- | --------:| --------:| ----------------------:| -----------------------------------:| +| Configuração Inicial | 8 | 32 | 256 | 40 | +| O trader deposita 8 tokens **Token0** e recupera 16 **Token1** | 16 | 16 | 256 | 32 | Como você pode ver, o trader ganhou 8 tokens extra, que vêm de uma redução do valor do pool, prejudicando o depositante que a possui. @@ -515,12 +515,12 @@ Em todos os depósitos subsequentes, já conhecemos a taxa de câmbio entre os d Seja um depósito inicial, seja um depósito subsequente, o número de tokens de liquidez que fornecemos é igual à raiz quadradada da alteração em `reserve0*reserve1` e o valor do token de liquidez não muda (a menos que obtenhamos um depósito com valores diferentes nos dois tipos, então, neste caso, a "multa" é distribuída). Aqui está outro exemplo com dois tokens que têm o mesmo valor, com três depósitos bons e um ruim (depósito de apenas um tipo de token, portanto, ele não produz nenhum token de liquidez). | Evento | reserva0 | reserva1 | reserva0 \* reserva1 | Valor do Pool (reserve0 + reserve1) | Tokens de liquidez cunhados para este depósito | Total de tokens de liquidez | valor de cada token de liquidez | -| ------------------------------- | -------: | -------: | -------------------: | ----------------------------------: | ---------------------------------------------: | --------------------------: | ------------------------------: | -| Configuração Inicial | 8,000 | 8,000 | 64 | 16,000 | 8 | 8 | 2,000 | -| Depósito de quatro de cada tipo | 12,000 | 12,000 | 144 | 24,000 | 4 | 12 | 2,000 | -| Depósito de dois de cada tipo | 14,000 | 14,000 | 196 | 28,000 | 2 | 14 | 2,000 | -| Depósito de valores desiguais | 18,000 | 14,000 | 252 | 32,000 | 0 | 14 | ~2,286 | -| Após a arbitragem | ~15,874 | ~15,874 | 252 | ~31,748 | 0 | 14 | ~2,267 | +| ------------------------------- | --------:| --------:| ----------------------:| -----------------------------------:| ----------------------------------------------:| ---------------------------:| -------------------------------:| +| Configuração Inicial | 8,000 | 8,000 | 64 | 16,000 | 8 | 8 | 2,000 | +| Depósito de quatro de cada tipo | 12,000 | 12,000 | 144 | 24,000 | 4 | 12 | 2,000 | +| Depósito de dois de cada tipo | 14,000 | 14,000 | 196 | 28,000 | 2 | 14 | 2,000 | +| Depósito de valores desiguais | 18,000 | 14,000 | 252 | 32,000 | 0 | 14 | ~2,286 | +| Após a arbitragem | ~15,874 | ~15,874 | 252 | ~31,748 | 0 | 14 | ~2,267 | ```solidity } @@ -985,7 +985,7 @@ Provedores de liquidez especificam um mínimo, geralmente porque querem limitar Por exemplo, imagine um caso em que a taxa de câmbio é de um para um, e o provedor de liquidez especifica esses valores: | Parâmetro | Valor | -| -------------- | ----: | +| -------------- | -----:| | amountADesired | 1.000 | | amountBDesired | 1.000 | | amountAMin | 900 | diff --git a/public/content/translations/pt-br/developers/tutorials/using-websockets/index.md b/public/content/translations/pt-br/developers/tutorials/using-websockets/index.md new file mode 100644 index 00000000000..15e52f84e95 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/using-websockets/index.md @@ -0,0 +1,249 @@ +--- +title: Usando WebSockets +description: Guia para usar WebSockets e Alchemy para fazer solicitações JSON-RPC e escutar eventos. +author: "Elan Halpern" +lang: pt-br +tags: + - "alchemy" + - "websocket" + - "consultando" + - "javascript" +skill: intermediate +source: Docs Alchemy +sourceUrl: https://docs.alchemyapi.io/guides/using-websockets +published: 2020-12-01 +--- + +Este é um guia de nível de entrada para usar WebSockets e Alchemy para fazer solicitações para a blockchain Ethereum. + +## WebSockets vs. HTTP {#websockets-vs-http} + +Ao contrário da HTTP, com WebSockets, você não precisa continuamente fazer solicitações quando quiser informações específicas. WebSockets mantêm uma conexão de rede para você (se for feito corretamente) e ouvem por mudanças. + +Como em qualquer conexão de rede, você não deve assumir que um WebSocket permanecerá aberto para sempre sem interrupção, mas o processamento correto de conexões descartadas e reconexão à mão podem ser desafiadores pra acertar. Outro lado negativo dos WebSockets é que você não obtém códigos de status HTTP na resposta, mas apenas a mensagem de erro. + +£[Alquimia Web3](https://docs.alchemy.com/reference/api-overview) adiciona automaticamente manipulação em falhas de WebSocket e obtém sem a configuração necessária. + +## Experimente {#try-it-out} + +A maneira mais fácil de testar WebSockets é instalar uma ferramenta de linha de comando para fazer solicitações de WebSocket como [wscat](https://github.com/websockets/wscat). Usando o wscat, você pode enviar solicitações da seguinte forma: + +_Nota: se você tem uma conta da Alchemy, você pode substituir `demo` com sua própria chave de API. [Cadastre-se para uma conta de Alquimia gratuita aqui!](https://auth.alchemyapi.io/signup)_ + +``` +wscat -c wss://eth-mainnet.ws.alchemyapi.io/ws/demo + +> {"jsonrpc": "2.0", "id": 0, "method": "eth_gasPrice"} + +< {"jsonrpc": "2.0", "result": "0xb2d05e00", "id": 0} + +``` + +## Como usar WebSockets {#how-to-use-websockets} + +Para começar, abra um WebSocket usando a URL de WebSocket para seu aplicativo. Você pode encontrar a URL de WebSocket do seu aplicativo abrindo a página do aplicativo no [seu painel](https://dashboard.alchemyapi.io/) e clicando em "Visualizar chave". Note que a URL do seu aplicativo para WebSockets é diferente da URL para solicitações HTTP, mas ambos podem ser encontrados clicando em "Ver Chave". + +![Onde encontrar a sua URL de WebSocket no seu painel Alchemy](./use-websockets.gif) + +Qualquer uma das APIs listadas na [Referência API do Alquimia](https://docs.alchemyapi.io/documentation/alchemy-api-reference/) pode ser usada via WebSocket. Para fazer isso, use o mesmo payload que seria enviado como corpo de uma solicitação HTTP POST, mas ao invés disso, envie esse payload através do WebSocket. + +## Com Web3 {#with-web3} + +A transição para WebSockets enquanto se usa uma biblioteca de clientes como a Web3 é simples. Simplesmente passe a URL de WebSocket em vez da URL HTTP ao instanciar seu cliente Web3. Por exemplo: + +```js +const web3 = new Web3("wss://eth-mainnet.ws.alchemyapi.io/ws/your-api-key") + +web3.eth.getBlockNumber().then(console.log) // -> 7946893 +``` + +## Assinatura {#subscription-api} + +Quando conectado através de um WebSocket, você pode usar dois métodos adicionais: `eth_subscribe` e `eth_unsubscribe`. Esses métodos permitirão que você ouça eventos específicos e seja notificado imediatamente. + +### `eth_subscribe` {#eth-subscribe} + +Cria uma nova assinatura para eventos específicos. [Saiba mais sobre `eth_subscribe`](https://docs.alchemy.com/reference/eth-subscribe). + +#### Parâmetros {#parameters} + +1. Tipos de assinatura +2. Parâmetros opcionais + +O primeiro argumento especifica o tipo de evento para o qual ouvir. O segundo argumento contém opções adicionais que dependem do primeiro argumento. Os diferentes tipos de descrição, suas opções e suas cargas de evento são descritos abaixo. + +#### Retorna {#returns} + +O ID de subscrição: Este ID será anexado a qualquer evento recebido, e também pode ser usado para cancelar a assinatura usando `eth_unsubscribe`. + +#### Eventos de assinatura {#subscription-events} + +Enquanto a assinatura estiver ativa, você receberá eventos que são objetos com os seguintes campos: + +- `jsonrpc`: Sempre "2.0" +- `método`: Sempre "eth_subscription" +- `params`: Um objeto com os seguintes campos: + - `subscription`: O ID de assinatura retornado pela chamada `eth_subscription` que criou essa assinatura. + - `resultado`: Um objeto cujo conteúdo varia dependendo do tipo de assinatura. + +#### Tipos de assinatura {#subscription-types} + +1. `alchemy_newFullPendingTransactions` + +Retorna as informações de transação para todas as transações que são adicionadas ao estado pendente. Este tipo de assinatura se inscreve em transações pendentes, similar à chamada Web3 padrão `web3.eth. ubscribe("pendingTransações")`, mas difere do que emite _informações completas de transação_ ao invés de apenas hashes de transação. + +Exemplo: + +```json +> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["alchemy_newFullPendingTransactions"]} + +< {"id":1,"result":"0x9a52eeddc2b289f985c0e23a7d8427c8","jsonrpc":"2.0"} +< { + "jsonrpc":"2.0", + "method":"eth_subscription", + "params":{ + "result":{ + "blockHash":null, + "blockNumber":null, + "from":"0xa36452fc31f6f482ad823cd1cf5515177d57667f", + "gas":"0x1adb0", + "gasPrice":"0x7735c4d40", + "hash":"0x50bff0736c713458c92dd1848d12f3354149be1363123dae35e94e0f2a9d56bf", +"input":"0xa9059cbb0000000000000000000000000d0707963952f2fba59dd06f2b425ace40b492fe0000000000000000000000000000000000000000000015b1111266cfca100000", + "nonce":"0x0", + "to":"0xea38eaa3c86c8f9b751533ba2e562deb9acded40", + "transactionIndex":null, + "value":"0x0", + "v":"0x26", + "r":"0x195c2c1ed126088e12d290aa93541677d3e3b1d10f137e11f86b1b9227f01e3b", + "s":"0x60fc4edbf1527832a2a36dbc1e63ed6193a6eee654472fbebbf88ef1750b5344"}, + "subscription":"0x9a52eeddc2b289f985c0e23a7d8427c8" + } + } + +``` + +2. `newHeads` + +Emite um evento a qualquer momento que um novo cabeçalho seja adicionado à cadeia, incluindo durante uma reorganização em cadeia. + +Quando ocorre uma reorganização da cadeia, esta assinatura emitirá um evento contendo todos os novos cabeçalhos da nova cadeia. Em particular, isso significa que você pode ver vários cabeçalhos emitidos com a mesma altura, e quando isso acontecer, o cabeçalho mais recente deve ser tomado como o correto após uma reorganização. + +Exemplo: + +```json +> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["newHeads"]} + +< {"jsonrpc":"2.0","id":2,"result":"0x9ce59a13059e417087c02d3236a0b1cc"} +< { + "jsonrpc": "2.0", + "method": "eth_subscription", + "params": { + "result": { + "extraData": "0xd983010305844765746887676f312e342e328777696e646f7773", + "gasLimit": "0x47e7c4", + "gasUsed": "0x38658", + "logsBloom": +"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x084149998194cc5f", + "number": "0x1348c9", + "parentHash": "0x7736fab79e05dc611604d22470dadad26f56fe494421b5b333de816ce1f25701", + "receiptRoot": "0x2fab35823ad00c7bb388595cb46652fe7886e00660a01e867824d3dceb1c8d36", + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "stateRoot": "0xb3346685172db67de536d8765c43c31009d0eb3bd9c501c9be3229203f15f378", + "timestamp": "0x56ffeff8", + "transactionsRoot": "0x0167ffa60e3ebc0b080cdb95f7c0087dd6c0e61413140e39d94d3468d7c9689f" + }, + "subscription": "0x9ce59a13059e417087c02d3236a0b1cc" + } +} + +``` + +3. `logs` + +Emite logs que fazem parte dos blocos recém-adicionados que correspondem aos critérios de filtro especificado. + +Quando ocorre uma reorganização da cadeia, logs que fazem parte dos blocos da cadeia antiga serão emitidos novamente com a propriedade `removido` definido como `verdadeiro`. Além disso, são emitidos registros que fazem parte dos blocos da nova cadeia, significando que é possível ver logs para a mesma transação várias vezes no caso de uma reorganização. + +Parâmetros + +1. Um objeto com os seguintes campos: + - `endereço` (opcional): ou uma string representanda por um endereço, ou um array de tais strings. + - Somente logs criados a partir de um desses endereços serão emitidos. + - `Tópicos`: um array de especificadores de tópicos. + - Cada especialista de tópico é `null` uma string que representa um tópico, ou uma matriz de strings. + - Cada posição no array que não é `nulo` restringe os logs emitidos para apenas aqueles que têm um dos tópicos indicados nessa posição. + +Alguns exemplos de especificações de tópico: + +- `[]`: Qualquer tópico permitido. +- `[A]`: A na primeira posição (e qualquer coisa depois). +- `[null, B]`: Qualquer coisa na primeira posição e B na segunda posição (e qualquer coisa depois). +- `[null, B]`: Qualquer coisa na primeira posição e B na segunda posição (e qualquer coisa depois). +- .`[[A, B], [A, B]]`: (A or B) na primeira posição e (A or B) na segunda posição (e nada depois). + +Exemplo: + +```json +> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics": ["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]} + +< {"jsonrpc":"2.0","id":2,"result":"0x4a8a4c0517381924f9838102c5a4dcb7"} +< { + "jsonrpc": "2.0", + "method": "eth_subscription", + "params": { + "subscription": "0x4a8a4c0517381924f9838102c5a4dcb7", + "result": { + "address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", + "blockHash": "0x61cdb2a09ab99abf791d474f20c2ea89bf8de2923a2d42bb49944c8c993cbf04", + "blockNumber": "0x29e87", + "data": "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003", + "logIndex":"0x0", + "topics":["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"], + "transactionHash": "0xe044554a0a55067caafd07f8020ab9f2af60bdfe337e395ecd84b4877a3d1ab4", + "transactionIndex": "0x0" + } + } +} + +``` + +### `eth_unsubscribe` {#eth-unsubscribe} + +Cancela uma assinatura existente para que não sejam enviados mais eventos. + +Parâmetros + +1. Inscrição ID, como retornado anteriormente de uma chamada de `eth_subscribe`. + +Retornos + +`true` se uma assinatura foi cancelada com sucesso, ou `false` se não existir nenhuma assinatura com o ID fornecido. + +Exemplo: + +**Requisição** + +``` +curl https://eth-mainnet.alchemyapi.io/v2/your-api-key +-X POST +-H "Content-Type: application/json" +-d '{"id": 1, "method": "eth_unsubscribe", "params": ["0x9cef478923ff08bf67fde6c64013158d"]}' + + +``` + +**Resultado** + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": true +} +``` + +--- + +[Cadastre-se com o Alchemy](https://auth.alchemyapi.io/signup) gratuitamente, confira [a nossa documentação](https://docs.alchemyapi.io/), e para receber as últimas notícias, siga-nos no [Twitter](https://twitter.com/AlchemyPlatform). diff --git a/public/content/translations/pt-br/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md b/public/content/translations/pt-br/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md new file mode 100644 index 00000000000..166750fb68b --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md @@ -0,0 +1,298 @@ +--- +title: "Waffle: simulações dinâmicas e testando chamadas de contrato" +description: Tutorial avançado de Waffle para usar simulação dinâmica e testar chamadas contratuais +author: "Daniel Izdebski" +tags: + - "waffle" + - "Contratos Inteligentes" + - "solidity" + - "Testes" + - "simulando" +skill: intermediate +lang: pt-br +published: 2020-11-14 +--- + +## Do que se trata esse tutorial? {#what-is-this-tutorial-about} + +Neste tutorial, você aprenderá: + +- use simulação dinâmica +- testar interações entre contratos inteligentes + +Pressupostos: + +- você já sabe como escrever um contrato inteligente simples em `Solidity` +- você conhece o seu `JavaScript` e `TypeScript` +- você fez outros `tutoriais` do Waffle ou sabe alguma coisa sobre isso + +## Simulação dinâmica {#dynamic-mocking} + +Por que a simulação dinâmica é útil? Bem, isso permite-nos escrever testes unitários em vez de testes de integração. O que isso significa? Isso significa que não precisamos nos preocupar com as dependências dos contratos inteligentes, assim podemos testar todos eles em total isolamento. Deixe-me te mostrar como exatamente você pode fazer isso. + +### **1. Projeto** {#1-project} + +Antes de começar, precisamos preparar um projeto simples no node.js: + +```bash +mkdir dynamic-mocking +cd dynamic-mocking +mkdir contracts src + +yarn init +# or if you're using npm +npm init +``` + +Vamos começar adicionando typescript e testes de dependências - mocha & chai: + +```bash +yarn add --dev @types/chai @types/mocha chai mocha ts-node typescript +# or if you're using npm +npm install @types/chai @types/mocha chai mocha ts-node typescript --save-dev +``` + +Agora vamos adicionar `Waffle` e `ethers`: + +```bash +yarn add --dev ethereum-waffle ethers +# or if you're using npm +npm install ethereum-waffle ethers --save-dev +``` + +A nossa estrutura de projetos deverá ficar assim: + +``` +. +├── contracts +├── package.json +└── test +``` + +### **2. Contrato inteligente** {#2-smart-contract} + +Para iniciar uma simulação dinâmica, precisamos de um contrato inteligente com dependências. Não se preocupe, nós ajudamos você! + +Aqui está um simples contrato inteligente escrito na `Solidity` cujo único objetivo é conferir se somos ricos. Ele usa o token ERC20 para verificar se temos tokens suficientes. Coloque em `./contracts/AmIRichAlready.sol`. + +```solidity +pragma solidity ^0.6.2; + +interface IERC20 { + function balanceOf(address account) external view returns (uint256); +} + +contract AmIRichAlready { + IERC20 private tokenContract; + uint public richness = 1000000 * 10 ** 18; + + constructor (IERC20 _tokenContract) public { + tokenContract = _tokenContract; + } + + function check() public view returns (bool) { + uint balance = tokenContract.balanceOf(msg.sender); + return balance > richness; + } +} +``` + +Como queremos usar simulação dinâmica, não precisamos de todo o ERC20, é por isso que estamos usando a interface IERC20 com apenas uma função. + +É hora de construir este contrato! Para isso, usaremos o `Waffle`. Primeiro, vamos criar um arquivo de configuração simples `waffle.json` que especifica as opções de compilação. + +```json +{ + "compilerType": "solcjs", + "compilerVersion": "0.6.2", + "sourceDirectory": "./contracts", + "outputDirectory": "./build" +} +``` + +Agora estamos prontos para construir o contrato com Waffle: + +```bash +npx waffle +``` + +Fácil, certo? Na pasta `de compilação/` dois arquivos correspondentes ao contrato e a interface apareceu. Nós os utilizaremos mais tarde para testar. + +### **3. Testando** {#3-testing} + +Vamos criar um arquivo chamado `AmIRichAlready.test.ts` para os testes reais. Em primeiro lugar, temos de lidar com as importações. Nós precisaremos deles para mais tarde: + +```typescript +import { expect, use } from "chai" +import { Contract, utils, Wallet } from "ethers" +import { + deployContract, + deployMockContract, + MockProvider, + solidity, +} from "ethereum-waffle" +``` + +Exceto para dependências JS, precisamos importar nossa interface e contrato construídos: + +```typescript +import IERC20 from "../build/IERC20.json" +import AmIRichAlready from "../build/AmIRichAlready.json" +``` + +Waffle usa `chai` para testes. No entanto, antes de podermos usá-lo, temos que injetar os "matchers" de Waffle em si mesmo: + +```typescript +use(solidity) +``` + +Precisamos implementar a função `beforeEach()` que irá redefinir o estado do contrato antes de cada teste. Primeiro, vamos pensar no que precisamos lá. Para implantar um contrato, precisamos de duas coisas: uma carteira e um contrato ERC20 implementado para passá-la como um argumento para o contrato `AmIRichalready`. + +Em primeiro lugar, criamos uma carteira: + +```typescript +const [wallet] = new MockProvider().getWallets() +``` + +Depois, precisamos de implantar um contrato do ERC20. Aqui está a parte complicada - nós temos apenas uma interface. Esta é a parte em que Waffle vem nos salvar. Waffle tem uma função mágica `deployMockContract()` que cria um contrato usando apenas o _abi_ da interface: + +```typescript +const mockERC20 = await deployMockContract(wallet, IERC20.abi) +``` + +Agora com a carteira e o ERC20 implantados, podemos ir em frente e implantar o contrato `AmIRichalready` (Contrato: + +```typescript +const contract = await deployContract(wallet, AmIRichAlready, [ + mockERC20.address, +]) +``` + +Com tudo isso, nossa função `beforeEach()` está terminada. Até agora o seu arquivo `AmIRichAlready.test.ts` deve se parecer com isto: + +```typescript +import { expect, use } from "chai" +import { Contract, utils, Wallet } from "ethers" +import { + deployContract, + deployMockContract, + MockProvider, + solidity, +} from "ethereum-waffle" + +import IERC20 from "../build/IERC20.json" +import AmIRichAlready from "../build/AmIRichAlready.json" + +use(solidity) + +describe("Am I Rich Already", () => { + let mockERC20: Contract + let contract: Contract + let wallet: Wallet + + beforeEach(async () => { + ;[wallet] = new MockProvider().getWallets() + mockERC20 = await deployMockContract(wallet, IERC20.abi) + contract = await deployContract(wallet, AmIRichAlready, [mockERC20.address]) + }) +}) +``` + +Vamos fazer o primeiro teste para o contrato `AmIRichalready`. Sobre o que acha que o nosso teste deveria ser? Sim, você tem razão! Deveríamos verificar se já somos ricos :) + +Um, pera um segundo. Como o nosso contrato simulado saberá quais valores retornar? Não implementamos nenhuma lógica para a função `balanceOf()`. Mais uma vez, Waffle pode ajudar aqui. Nosso contrato simulado tem algumas coisas novas e bonitas agora: + +```typescript +await mockERC20.mock..returns() +await mockERC20.mock..withArgs().returns() +``` + +Com esse conhecimento, podemos finalmente escrever nosso primeiro teste: + +```typescript +it("returns false if the wallet has less than 1000000 tokens", async () => { + await mockERC20.mock.balanceOf.returns(utils.parseEther("999999")) + expect(await contract.check()).to.be.equal(false) +}) +``` + +Vamos travar esse teste em partes: + +1. Definimos nosso contrato simulado no ERC20 para sempre devolver o saldo de tokens de 9999999999. +2. Verifique se o método `contract.check()` retorna `false`. + +Nós estamos prontos para disparar a fera: + +![Um test passando](test-one.png) + +Então o teste funciona, mas... ainda há espaço para melhorias. A função `saldoOf()` sempre retornará 99999. Podemos melhorá-la especificando uma carteira para a qual a função deve retornar algo - como um contrato de verdade: + +```typescript +it("returns false if the wallet has less than 1000001 tokens", async () => { + await mockERC20.mock.balanceOf + .withArgs(wallet.address) + .returns(utils.parseEther("999999")) + expect(await contract.check()).to.be.equal(false) +}) +``` + +Até agora, nós testamos apenas o caso em que não estamos ricos o suficiente. Em vez disso, vamos testar o oposto: + +```typescript +it("returns true if the wallet has at least 1000001 tokens", async () => { + await mockERC20.mock.balanceOf + .withArgs(wallet.address) + .returns(utils.parseEther("1000001")) + expect(await contract.check()).to.be.equal(true) +}) +``` + +Você executa os testes... + +![Dois testes passando](test-two.png) + +E aqui está você! Nosso contrato parece funcionar como pretendido :) + +## Testando chamadas de contrato {#testing-contract-calls} + +Vamos resumir o que fez até agora. Nós testamos a funcionalidade do nosso contrato de `AmIRichalready` e parece que ele está funcionando corretamente. Isso significa que estamos prontos, né? Não exatamente! Waffle permite-nos testar ainda mais o nosso contrato. Mas o quanto exatamente? Bem, no arsenal de Waffle há um `calledOnContract()` e `calledOnContractWith()` correspondentes. Eles nos permitirão verificar se nosso contrato chamado de simulação (mock, em inglês) do ERC20. Aqui está um teste básico com um desses matchers: + +```typescript +it("checks if contract called balanceOf on the ERC20 token", async () => { + await mockERC20.mock.balanceOf.returns(utils.parseEther("999999")) + await contract.check() + expect("balanceOf").to.be.calledOnContract(mockERC20) +}) +``` + +Podemos ir ainda mais longe e melhorar este teste com o outro "matcher" que eu te falei: + +```typescript +it("checks if contract called balanceOf with certain wallet on the ERC20 token", async () => { + await mockERC20.mock.balanceOf + .withArgs(wallet.address) + .returns(utils.parseEther("999999")) + await contract.check() + expect("balanceOf").to.be.calledOnContractWith(mockERC20, [wallet.address]) +}) +``` + +Vamos verificar se os testes estão corretos: + +![Três testes passando](test-three.png) + +Ótimo, todos os testes são verdes. + +Testar chamadas de contrato com Waffle é super fácil. E aqui está a melhor parte. Esses "matchers" trabalham com contratos normais e simulados! É porque o Waffle registra e filtra chamadas EVM em vez de injetar código, como é no caso de bibliotecas de teste populares de outras tecnologias. + +## A Linha de Chegada {#the-finish-line} + +Parabéns! Agora você sabe como usar Waffle para testar chamadas de contrato e contratos simulados dinamicamente. Há características muito mais interessantes para descobrir. Recomendo mergulhar na documentação do Waffle. + +A documentação do Waffle está disponível [aqui](https://ethereum-waffle.readthedocs.io/). + +O código fonte deste tutorial pode ser encontrado [aqui](https://github.com/EthWorks/Waffle/tree/master/examples/dynamic-mocking-and-testing-calls). + +Você pode também estar interessado em: + +- [Testando contratos inteligentes com Waffle](/developers/tutorials/testing-smart-contract-with-waffle/) diff --git a/public/content/translations/pt-br/developers/tutorials/waffle-say-hello-world-with-hardhat-and-ethers/index.md b/public/content/translations/pt-br/developers/tutorials/waffle-say-hello-world-with-hardhat-and-ethers/index.md new file mode 100644 index 00000000000..851cb979840 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/waffle-say-hello-world-with-hardhat-and-ethers/index.md @@ -0,0 +1,202 @@ +--- +title: "Tutorial Waffle diz hello world com hardhat e ethers" +description: Faça seu primeiro projeto Waffle com hardhat e ethers.js +author: "MiZiet" +tags: + - "waffle" + - "contratos inteligentes" + - "solidity" + - "testando" + - "hardhat" + - "ethers.js" +skill: intermediate +lang: pt-br +published: 2020-10-16 +--- + +Neste [tutorial do Waffle](https://ethereum-waffle.readthedocs.io), aprenderemos como criar um simples projeto de contrato inteligente "Hello world", usando [hardhat](https://hardhat.org/) e [ethers. s](https://docs.ethers.io/v5/). Em seguida, aprenderemos como adicionar uma nova funcionalidade ao nosso contrato inteligente e como testá-lo com Waffle. + +Vamos começar criando um novo projeto: + +```bash +yarn init +``` + +ou + +```bash +npm init +``` + +e instalando os pacotes necessários: + +```bash +yarn add -D hardhat @nomiclabs/hardhat-ethers ethers @nomiclabs/hardhat-waffle ethereum-waffle chai +``` + +ou + +```bash +npm install -D hardhat @nomiclabs/hardhat-ethers ethers @nomiclabs/hardhat-waffle ethereum-waffle chai +``` + +O próximo passo é criar um projeto hardhat de amostra, executando `npx hardhat`. + +```bash +888 888 888 888 888 +888 888 888 888 888 +888 888 888 888 888 +8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 +888 888 "88b 888P" d88" 888 888 "88b "88b 888 +888 888 .d888888 888 888 888 888 888 .d888888 888 +888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. +888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 + +👷 Welcome to Hardhat v2.0.3 👷‍ + +? O que você deseja fazer? … +★ Crie um projeto de exemplo +Crie um hardhat.config.js vazio +Saia +``` + +Selecione `Create a sample project` + +A nossa estrutura de projetos deverá ficar assim: + +``` +MyWaffleProject +├── contracts +│ └── Greeter.sol +├── node_modules +├── scripts +│ └── sample-script.js +├── test +│ └── sample-test.js +├── .gitattributs +├── .gitignore +├── hardhat.config.js +└── package.json +``` + +### Agora vamos falar sobre alguns desses arquivos: {#now-lets-talk} + +- Greeter.sol - nosso smart contract escrito em Solidity; + +```solidity +contract Greeter { +string greeting; + +constructor(string memory _greeting) public { +console.log("Deploying a Greeter with greeting:", _greeting); +greeting = _greeting; +} + +function greet() public view returns (string memory) { +return greeting; +} + +function setGreeting(string memory _greeting) public { +console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); +greeting = _greeting; +} +} +``` + +Nosso contrato inteligente pode ser dividido em três partes: + +1. constructor - onde declaramos uma variável de tipo string chamada `greeting`, +2. function greet - função que retornará `greeting` quando chamada, +3. function setGreeting - uma função que nos permite alterar o valor da função `greeting`. + +- sample-test.js - nosso arquivo de testes + +```js +describe("Greeter", function () { + it("Should return the new greeting once it's changed", async function () { + const Greeter = await ethers.getContractFactory("Greeter") + const greeter = await Greeter.deploy("Hello, world!") + + await greeter.deployed() + expect(await greeter.greet()).to.equal("Hello, world!") + + await greeter.setGreeting("Hola, mundo!") + expect(await greeter.greet()).to.equal("Hola, mundo!") + }) +}) +``` + +### O próximo passo consiste em compilar nosso contrato e executar testes: {#compiling-and-testing} + +Testes de Waffle usam Mocha (um framework de teste) com Chai (uma biblioteca de asserção). Tudo o que você precisa fazer é executar `npx hardhat test` e esperar que a seguinte mensagem apareça. + +```bash +✓ Deve retornar a nova saudação uma vez alterada +``` + +### Tudo parece ótimo até agora, vamos adicionar mais complexidade ao nosso projeto {#adding-complexity} + +Imagine uma situação quando alguém adiciona uma string vazia como saudação. Não seria uma saudação calorosa, né? +Vamos nos certicar que isso não aconteça: + +Queremos usar o `revert` do Solidity quando alguém passar uma string vazia. Uma coisa boa é que podemos facilmente testar esta funcionalidade com o chai matcher do Waffle `to.be.revertedWith()`. + +```js +it("Should revert when passing an empty string", async () => { + const Greeter = await ethers.getContractFactory("Greeter") + const greeter = await Greeter.deploy("Hello, world!") + + await greeter.deployed() + await expect(greeter.setGreeting("")).to.be.revertedWith( + "Greeting should not be empty" + ) +}) +``` + +Parece que o nosso novo teste não passou: + +```bash +Implantando um Greeter com saudação: Olá, mundo! +Mude de saudação de 'Hello, world!' para 'Hola, mundo!' + ✓ Deve devolver a nova saudação uma vez que ela tenha sido alterada (1514ms) +Implantando um Greeter com saudação: Olá, mundo! +Mudar saudação de 'Olá, mundo!' para '' + 1) Deve reverter quando passar uma seqüência vazia + + + 1 passagem (2s) + 1 falhando +``` + +Vamos implementar esta funcionalidade em nosso contrato inteligente: + +```solidity +require(bytes(_greeting).length > 0, "Greeting message is empty"); +``` + +Agora, nossa função setGreeting se parece com isso: + +```solidity +function setGreeting(string memory _greeting) public { +require(bytes(_greeting).length > 0, "Greeting should not be empty"); +console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); +greeting = _greeting; +} +``` + +Vamos executar os testes novamente: + +```bash +✓ Deve retornar a nova saudação quando ela for alterada (1467ms) +✓ Deve reverter quando passar uma string vazia (276ms) + +2 passagem (2s) +``` + +Parabéns! Você terminou :) + +### Conclusão {#conclusion} + +Fizemos um projeto simples com Waffle, Hardhat e ethers.js. Aprendemos como criar um projeto, adicionar um teste e implementar novas funcionalidades. + +Para mais combinações excelentes de chai para testar seus smart contracts, confira a [documentação oficial da Waffle](https://ethereum-waffle.readthedocs.io/en/latest/matchers.html). diff --git a/public/content/translations/pt-br/developers/tutorials/waffle-test-simple-smart-contract/index.md b/public/content/translations/pt-br/developers/tutorials/waffle-test-simple-smart-contract/index.md new file mode 100644 index 00000000000..1a3ade19e87 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/waffle-test-simple-smart-contract/index.md @@ -0,0 +1,203 @@ +--- +title: Testando um contrato inteligente simples com a biblioteca Waffle +description: Tutorial para iniciantes +author: Ewa Kowalska +tags: + - "contratos inteligentes" + - "solidity" + - "Waffle" + - "testando" +skill: intermediate +lang: pt-br +published: 2021-02-26 +--- + +## Neste tutorial, você aprenderá como {#in-this-tutorial-youll-learn-how-to} + +- Testar as mudanças do saldo da carteira +- Testar a emissão de eventos com argumentos especificados +- Assegurar que uma transação foi revertida + +## Suposições {#assumptions} + +- Você pode criar um novo projeto JavaScript ou TypeScript +- Você tem alguma experiência básica com testes em JavaScript +- Você tem usado gerenciadores de pacotes como Yarn ou NPM +- Você possui um conhecimento muito básico de contratos inteligentes e Solidity + +# Introdução {#getting-started} + +O tutorial demonstra a configuração do teste e a execução usando yarn, mas não há problema se você preferir npm - Eu fornecerei referências adequadas a [documentação](https://ethereum-waffle.readthedocs.io/en/latest/index.html) oficial do Waffle. + +## Instalando Dependências {#install-dependencies} + +[Adicione](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#installation) as dependências do ethereum-waffle e typescript às dependências de desenvolvimento do seu projeto. + +```bash +yarn add --dev ethereum-waffle ts-node typescript @types/jest +``` + +## Exemplo de contrato inteligente {#example-smart-contract} + +Durante o tutorial, nós trabalharemos em um exemplo de contrato inteligente simples - EtherSplitter. Não faz nada de mais, além de permitir que qualquer um envie somas em wei e divida-as igualmente entre dois destinatários predefinidos. A função split exige que a quantidade de wei seja par, caso contrário, ela será anulada. Para ambos os destinatários, ela realiza uma transferência em wei, seguido da emissão do evento Transferir. + +Coloque o trecho de código EtherSplitter em `src/EtherSplitter.sol`. + +```solidity +pragma solidity ^0.6.0; + +contract EtherSplitter { + address payable receiver1; + address payable receiver2; + + event Transfer(address from, address to, uint256 amount); + + constructor(address payable _address1, address payable _address2) public { + receiver1 = _address1; + receiver2 = _address2; + } + + function split() public payable { + require(msg.value % 2 == 0, 'Uneven wei amount not allowed'); + receiver1.transfer(msg.value / 2); + emit Transfer(msg.sender, receiver1, msg.value / 2); + receiver2.transfer(msg.value / 2); + emit Transfer(msg.sender, receiver2, msg.value / 2); + } +} +``` + +## Compilar o contrato {#compile-the-contract} + +Para [compilar](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#compiling-the-contract) o contrato, adicione a seguinte entrada ao arquivo package.json: + +```json +"scripts": { + "build": "waffle" + } +``` + +Em seguida, crie o arquivo de configuração do Waffle, no diretório raiz do projeto - `waffle.json` - e então cole a seguinte configuração lá: + +```json +{ + "compilerType": "solcjs", + "compilerVersion": "0.6.2", + "sourceDirectory": "./contracts", + "outputDirectory": "./build" +} +``` + +Execute `yarn build`. Como resultado, o diretório `build` aparecerá com o contrato compilado, EtherSplitter, no formato JSON. + +## Teste de configuração {#test-setup} + +Testar com Waffle requer usar os matchers (comparadores) Chai e Mocha, então você precisa [adicionar](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-tests) ao seu projeto. Atualize seu arquivo package.json e adicione a entrada `test` na parte de scripts: + +```json +"scripts": { + "build": "waffle", + "test": "export NODE_ENV=test && mocha -r ts-node/register 'test/**/*.test.ts'" + } +``` + +Se você quiser [executar](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#running-tests) seus testes, basta executar `yarn test`. + +# Testando {#testing} + +Agora crie o diretório `test` e crie o novo arquivo `test\EtherSplitter.test.ts`. Copie o trecho de código abaixo e cole-o em nosso arquivo de teste. + +```ts +import { expect, use } from "chai" +import { Contract } from "ethers" +import { deployContract, MockProvider, solidity } from "ethereum-waffle" +import EtherSplitter from "../build/EtherSplitter.json" + +use(solidity) + +describe("Ether Splitter", () => { + const [sender, receiver1, receiver2] = new MockProvider().getWallets() + let splitter: Contract + + beforeEach(async () => { + splitter = await deployContract(sender, EtherSplitter, [ + receiver1.address, + receiver2.address, + ]) + }) + + // add the tests here +}) +``` + +Algumas palavras antes de começarmos. O `MockProvider` vem com uma versão em mock (simulada de um objeto real) da blockchain. Ele também fornece o mock de carteiras que nos servirão para testar o contrato EtherSplitter. Podemos obter até dez carteiras chamando o método `getWallets()` no provedor. No exemplo, nós obtemos três carteiras - para o remetente e duas para os destinatários. + +Em seguida, declaramos uma variável chamada 'splitter' - este é o nosso contrato mock EtherSplitter. Ele é criado antes de cada execução de um único teste pelo método `deployContract`. Este método simula a implantação de um contrato, da carteira passada como primeiro parâmetro (a carteira do remetente em nosso caso). O segundo parâmetro é a ABI e o bytecode do contrato testado — passamos para lá o arquivo json do contrato EtherSplitter compilado no diretório `build`. O terceiro parâmetro é uma matriz com os argumentos do construtor do contrato que, no nosso caso, são os dois endereços dos destinatários. + +## changeBalances {#changebalances} + +Primeiro, verificaremos se o método split realmente altera os saldos das carteiras dos destinatários. Se dividirmos 50 wei da conta do remetente, nós esperaríamos que os saldos de ambos os destinatários aumentassem em 25 wei. Nós usaremos o matcher `changeBalances` do Waffle: + +```ts +it("Changes accounts balances", async () => { + await expect(() => splitter.split({ value: 50 })).to.changeBalances( + [receiver1, receiver2], + [25, 25] + ) +}) +``` + +Como o primeiro parâmetro do matcher, nós passamos um array de carteiras dos destinatários e, como segundo - um array de aumentos esperados nas contas correspondentes. Se nós quiséssemos verificar o saldo de uma carteira específica, também poderíamos usar o matcher `changeBalance`, que não requer a passagem de arrays, como no exemplo abaixo: + +```ts +it("Changes account balance", async () => { + await expect(() => splitter.split({ value: 50 })).to.changeBalance( + receiver1, + 25 + ) +}) +``` + +Observe que, em ambos os casos de `changeBalance` e de `changeBalances`, transmitimos a função split como um retorno de chamada, pois o comparador precisa acessar o estado dos saldos antes e depois da chamada. + +A seguir, testaremos se o evento Transfer foi emitido após cada transferência de wei. Vamos passar para outro comparador do Waffle: + +## Emit {#emit} + +```ts +it("Emits event on the transfer to the first receiver", async () => { + await expect(splitter.split({ value: 50 })) + .to.emit(splitter, "Transfer") + .withArgs(sender.address, receiver1.address, 25) +}) + +it("Emits event on the transfer to the second receiver", async () => { + await expect(splitter.split({ value: 50 })) + .to.emit(splitter, "Transfer") + .withArgs(sender.address, receiver2.address, 25) +}) +``` + +O matcher `emit` nos permite verificar, se um contrato emitiu um evento ao chamar um método. Como parâmetros para o matcher `emit`, nós fornecemos o mock do contrato, que prevemos para emitir o evento, juntamente com o nome desse evento. Em nosso caso, o contrato simulado é o `splitter` e o nome do evento é `Transfer`. Nós também podemos verificar os valores precisos dos argumentos, com os quais o evento foi emitido - nós passamos tantos argumentos para o matcher `withArgs`, como espera a nossa declaração de evento. No caso do contrato EtherSplitter, passamos os endereços do remetente e do destinatário, juntamente com a quantia de wei transferida. + +## revertedWith {#revertedwith} + +Como último exemplo, nós verificaremos se a transação foi revertida, em caso de número desigual de wei. Usaremos o matcher `revertedWith`: + +```ts +it("Reverts when Vei amount uneven", async () => { + await expect(splitter.split({ value: 51 })).to.be.revertedWith( + "Uneven wei amount not allowed" + ) +}) +``` + +O teste, se aprovado, nos garantirá que a transação foi revertida de fato. No entanto, também deve haver uma correspondência exata entre as mensagens que passamos, na instrução `require` e a mensagem que esperamos em `revertedWith`. Se voltarmos ao código do contrato EtherSplitter, na declaração `require` para a quantidade wei, fornecemos a mensagem: 'Quantidade de wei desigual não permitida'. Isso corresponde à mensagem que esperamos em nosso teste. Se eles não fossem iguais, o teste falharia. + +# Parabéns! {#congratulations} + +Você acabou de dar seu primeiro grande passo para testar contratos inteligentes com Waffle! Caso esteja interessado em outros tutoriais do Waffle: + +- [Testando ERC20 com Waffle](/developers/tutorials/testing-erc-20-tokens-with-waffle/) +- [Waffle: simulações dinâmicas e testando chamadas de contrato](/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/#gatsby-focus-wrapper) +- [Waffle diga olá mundo tutorial com capacete de segurança e ethers](/developers/tutorials/waffle-hello-world-with-buidler-tutorial/) diff --git a/public/content/translations/pt-br/developers/tutorials/yellow-paper-evm/index.md b/public/content/translations/pt-br/developers/tutorials/yellow-paper-evm/index.md new file mode 100644 index 00000000000..5aced52da90 --- /dev/null +++ b/public/content/translations/pt-br/developers/tutorials/yellow-paper-evm/index.md @@ -0,0 +1,264 @@ +--- +title: Entendendo as especificações do Yellow Paper da EVM +description: Entendendo a parte do Yellow Paper, a especificação formal do Ethereum, você entenderá a Máquina Virtual Ethereum (EVM). +author: "qbzzt" +tags: + - "evm" +skill: intermediate +lang: pt-br +published: 2022-05-15 +--- + +[O Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) é uma especificação formal do Ethereum. Exceto onde alterado pelo [processo EIP](/eips/), ele contém a descrição exata de como tudo funciona. Ele foi escrito como um documento matemático, que inclui terminologia que programadores podem não achar familiar. Nesse documento você aprende como lê-lo, e por extensão outros documentos matemáticos relacionados. + +## Qual Yellow Paper? {#which-yellow-paper} + +Como quase tudo mais no Ethereum, o Yellow Paper evolui com o tempo. Para ser capaz de se referir a uma versão específica, eu fiz o upload [da versão atual](yellow-paper-berlin.pdf). A seção, página e números de equação que eu uso irão se referir a esta versão. É uma boa ideia tê-lo aberto em uma janela diferente enquanto você lê esse documento. + +### Por que a EVM? {#why-the-evm} + +O yellow paper original foi escrito logo no começo do desenvolvimento do Ethereum. Ele descreve o mecanismo de consenso original baseado em proof-of-work que foi originalmente usado para proteger a rede. Entretanto, o Ethereum desligou o proof-of-work e começou a usar consenso baseado em proof-of-stake em setembro de 2022. Este tutorial focará nas partes do yellow paper que definem a Máquina Virtual Ethereum. A EVM ficou inalterada pela transição para proof-of-stake (exceto pelo valor de retorno do opcode DIFFICULTY). + +## Modelo de execução 9 {#9-execution-model} + +Esta seção (pág. 12.14) inclui a maioria da definição da EVM. + +O termo _estado do sistema_ inclui tudo que você precisa saber sobre o sistema para rodá-lo. Em um computador comum, isto significa memória, conteúdo dos registradores, etc. + +Uma [máquina de Turing](https://en.wikipedia.org/wiki/Turing_machine) é um modelo computacional. Essencialmente, é uma versão simplificada de um computador, que comprovadamente tem a mesma habilidade de executar computações que um computador normal tem (tudo que um computador pode calcular, uma máquina de Turing pode calcular, e vice-versa). Este modelo facilita provar vários teoremas sobre o que é e o que não é computável. + +O termo [Turing-completo](https://en.wikipedia.org/wiki/Turing_completeness) significa um computador que pode rodar os mesmos cálculos que uma máquina de Turing. Máquinas de Turing pode entrar em laços infinitos, e a EVM não pode porque ela irá ficar sem gas, então é somente quase-Turing-completa. + +## Básico 9.1 {#91-basics} + +Esta seção fornece o básico sobre EVM e como ela se equipara a outros modelos computacionais. + +A [máquina de pilha](https://en.wikipedia.org/wiki/Stack_machine) é um computador que armazena dados intermediários não em registros, mas em uma [**pilha**](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)). Esta é a arquitetura preferida para máquinas virtuais porque é fácil de implementar, significando que bugs e a vulnerabilidades de segurança são bem menos prováveis. A memória na pilha é dividida em palavras de 256-bit. Esta escolha foi tomada por ser a mais conveniente às operações criptográficas do núcleo do Ethereum, como as computações de hash Keccak-256 e curva elíptica. O tamanho máximo da pilha é 1.024 bytes. Quando opcodes são executados, eles geralmente estão pegando seus parâmetros da pilha. Há opcodes especificamente para reorganizar elementos na pilha, como `POP` (remove item do topo da pilha), `DUP_N` (N-ésimo item duplicado na pilha), etc. + +A EVM também tem um espaço volátil chamado **memory** que é usado para armazenar dados durante execução. Esta memória é organizada em palavras de 32-byte. Todas as locações de memória são inicializadas em zero. Se você executar este código [Yul](https://docs.soliditylang.org/en/latest/yul.html) para adicionar uma palavra na memória, ele irá preencher 32 bytes de memória preenchendo o espaço vazio na palavra com zeros, ou seja, ele cria uma palavra - com zeros nos locais 0-29, 0x60 a 30, e 0xA7 a 31. + +```yul +mstore(0, 0x60A7) +``` + +`mstore` é um dos três opcodes que a EVM fornece para interação com a memória - ele carrega uma palavra na memória. Os outros dois são `mstore8`, que carrega um único byte na memória, e `mload`, que move uma palavra da memória para a pilha. + +A EVM também tem um modelo separado não volátil chamado **storage**, que é mantido como parte do estado do sistema - esta memória é organizada em arrays de palavras (ao contrário de arrays de byte endereçáveis por palavra na pilha). Esta storage é quando contratos mantém dados resistentes - um contrato pode somente interagir com o seu própria storage. Storage é organizado em mapeamentos chave-valor. + +Apesar de não ser mencionado nessa seção do Yellow Paper, é útil também saber que há um quarto tipo de memória. **Calldata** é uma memória endereçável por byte, somente de leitura, usada para armazenar o valor passado com o parâmetro `data` da transação. A EVM tem opcodes específicos para gerenciamento de `calldata`. `calldatasize` retorna o tamanho dos dados. `calldataload` carrega os dados na pilha. `calldatacopy` copia os dados na memória. + +A [arquitetura Von Neumann](https://en.wikipedia.org/wiki/Von_Neumann_architecture) armazena código e dados na mesma memória. A EVM não segue este padrão por razões de segurança - compartilhar memória volátil torna possível mudar o código do programa. Ao invés disso, o código é gravado na storage. + +Há apenas dois casos em que o código é executado da memória: + +- Quando um contrato cria outro contrato (usando [`CREATE`](https://www.evm.codes/#f0) ou [`CREATE2`](https://www.evm.codes/#f5)), o código do construtor do contrato vem da memória. +- Durante a criação de _qualquer_ contrato, o código do construtor roda e então retorna com o código do contrato real, também da memória. + +O termo execução excepcional significa uma exceção que causa a interrupção da execução do contrato atual. + +## 9.2 Visão geral de taxas {#92-fees-overview} + +Esta seção explica como as taxas de gas são calculadas. Há três custos: + +### Custo de opcode {#opcode-cost} + +O custo herdado de um opcode específico. Para obter este valor, encontre o grupo de custo do opcode no apêndice H (p. 28, sob equação (327)), e encontre o grupo de custo na equação (324). Isto te dá uma função do custo, que na maioria dos casos usa parâmetros do apêndice G (p. 27). + +Por exemplo, o opcode [`CALLDATACOPY`](https://www.evm.codes/#37) é um membro do grupo _Wcopy_. O custo de opcode para este grupo é _Gverylow+Gcopy×⌈μs[2]÷32⌉_. Olhando no apêndice G, nós vemos que ambas constantes são 3, o que nos dá _3+3×⌈μs[2]÷32⌉_. + +Nós ainda precisamos decifrar a expressão _⌈μs[2]÷32⌉_. A parte mais de fora, _⌈ \ ⌉_ é a função ceiling, uma função em que é dado valor onde retorna o menor inteiro que ainda não é menor que o valor. Por exemplo, _⌈2.5⌉ = ⌈3⌉ = 3_. A parte mais interna é _μs[2]÷32_. Olhando na seção 3 (Convenções) na p. 3, _μ_ é o estado da máquina. O estado da máquina é definido na seção 9.4.1 na p. 13. De acordo com essa seção, um dos parâmetros do estado da máquina é _s_ para a pilha. Colocando tudo junto, parece que _μs[2]_ é a locação número 2 na pilha. Olhando o [opcode](https://www.evm.codes/#37), a locação número dois na pilha é o tamanho do dado em bytes. Olhando em outros opcodes do grupo Wcopy, [`CODECOPY`](https://www.evm.codes/#39) e [`RETURNDATACOPY`](https://www.evm.codes/#3e), eles também têm um tamanho de dado na mesma locação. Então,_⌈μs[2]÷32⌉_ é o número de 32 byte necessário para armazenar o dado sendo copiado. Colocando tudo junto, o custo herdado de [`CALLDATACOPY`](https://www.evm.codes/#37) é 3 gas mais 3 por palavra de dado sendo copiada. + +### Custo de execução {#running-cost} + +O custo de rodar o código que nós estamos chamando. + +- No caso do [`CREATE`](https://www.evm.codes/#f0) e [`CREATE2`](https://www.evm.codes/#f5), o construtor para o novo contrato. +- No caso do [`CALL`](https://www.evm.codes/#f1), [`CALLCODE`](https://www.evm.codes/#f2), [`STATICCALL`](https://www.evm.codes/#fa), ou [`DELEGATECALL`](https://www.evm.codes/#f4), o contrato que nós chamamos. + +### Expandindo o custo de memória {#expanding-memory-cost} + +O custo de expandir a memória (se necessário). + +Na equação 324, este valor é escrito como _Cmemi')-Cmemi)_. Olhando na seção 9.4.1 novamente, nós vemos que _μi_ é o número de palavras na memória. Então, _μi_ é o número de palavras na memória antes do opcode e _μi'_ é o número de palavras na memória depois do opcode. + +A função _Cmem_ é definida na equação 326: _Cmem(a) = Gmemory × a + ⌊a2 ÷ 512⌋_. _⌊x⌋_ é a função floor, uma função que dado um valor, retorna o maior inteiro que ainda não é maior que o valor. Por exemplo, _⌊2.5⌋ = ⌊2⌋ = 2._ Quando_ a < √512_, _a2 < 512_, e o resultado da função floor é zero. Então para as primeiras 22 palavras (704 bytes), o custo sobe linearmente com o número de palavras na memória necessárias. Além desse ponto _⌊a2 ÷ 512⌋_ é positivo. Quando a memória necessária é grande o suficiente, o custo de gas é proporcional ao quadrado da quantidade de memória. + +**Note** que estes fatores somente influenciam o custo de gas _herdado_ - ele não leva em conta a taxa de mercado ou gorjetas aos validadores que determinam quanto um usuário final precisa pagar - isto é apenas o custo líquido de rodar uma operação particular na EVM. + +[Leia mais sobre gas](/developers/docs/gas/). + +## Ambiente de execução 9.3 {#93-execution-env} + +O ambiente de execução é uma tupla, _I_, que inclui informações que não são parte do estado do blockchain ou da EVM. + +| Parâmetro | Opcode para acessar o dado | Código Solidity para acessar o dado | +| --------------- | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| _Ia_ | [`ADDRESS`](https://www.evm.codes/#30) | `address(this)` | +| _Io_ | [`ORIGIN`](https://www.evm.codes/#32) | `tx.origin` | +| _Ip_ | [`GASPRICE`](https://www.evm.codes/#3a) | `tx.gasprice` | +| _Id_ | [`CALLDATALOAD`](https://www.evm.codes/#35), etc. | `msg.data` | +| _Is_ | [`CALLER`](https://www.evm.codes/#33) | `msg.sender` | +| _Iv_ | [`CALLVALUE`](https://www.evm.codes/#34) | `msg.value` | +| _Ib_ | [`CODECOPY`](https://www.evm.codes/#39) | `address(this).code` | +| _IH_ | Campos do cabeçalho do bloco, como [`NUMBER`](https://www.evm.codes/#43) e [`DIFFICULTY`](https://www.evm.codes/#44) | `block.number`, `block.difficulty`, etc. | +| _Ie_ | Profundidade da pilha de chamada para chamadas entre contratos (incluindo criação de contrato) | | +| _Iw_ | A EVM tem permissão de mudar de estado, ou está rodando estaticamente | | + +Alguns outros poucos parâmetros são necessários para entender o resto da seção 9: + +| Parâmetro | Definido na seção | Significado | +| --------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _σ_ | 2 (p. 2, equação 1) | O estado do blockchain | +| _g_ | 9.3 (p. 13) | Gas remanescente | +| _A_ | 6.1 (p. 8) | Substrato acumulado (muda agendado para quando a transação termina) | +| _o_ | 9.3 (p. 13) | Saída - o resultado retornado no caso de transação interna (quando um contrato chama outro) e chamadas para funções view (quando você está apenas perguntando por informação, então não há necessidade de esperar pela transação) | + +## Visão geral da execução 9.4 {#94-execution-overview} + +Agora que temos todas as preliminares, nós podemos finalmente começar a trabalhar como a EVM trabalha. + +Equações 137-142 nos dá as condições iniciais para rodar a EVM: + +| Símbolo | Valor inicial | Significado | +| ---------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| _μg_ | _g_ | Gas remanescente | +| _μpc_ | _0_ | Contador do programa, o endereço da próxima instrução para executar | +| _μm_ | _(0, 0, ...)_ | Memória, inicializada toda com zeros | +| _μi_ | _0_ | Maior locação de memória usada | +| _μs_ | _()_ | A pilha, inicialmente vazia | +| _μo_ | _∅_ | O resultado, conjunto vazio até e, a não ser que nós paremos ou com os dados de retorno ([`RETURN`](https://www.evm.codes/#f3) ou [`REVERT`](https://www.evm.codes/#fd)) ou sem ele ([`STOP`](https://www.evm.codes/#00) ou [`SELFDESTRUCT`](https://www.evm.codes/#ff)). | + +A equação 143 nos conta que há quatro condições possíveis em cada ponto no tempo durante a execução, e o que fazer com elas: + +1. `Z(σ,μ,A,I)`. Z representa uma função que testa se uma operação cria uma transição de estado inválida (veja [parada excepcional](#942-exceptional-halting)). Se ele for avaliado para True, o novo estado é idêntico ao antigo (exceto o gas que foi queimado) porque as mudanças não foram implementadas. +2. Se o the opcode sendo executado é [`REVERT`](https://www.evm.codes/#fd), o novo estado é o mesmo que o antigo estado, algum gas é perdido. +3. Se a sequência de operações for finalizada, como significa um [`RETURN`](https://www.evm.codes/#f3)), o estado é atualizado para o novo estado. +4. Se não estivermos em uma das condições finais 1-3, continua rodando. + +## Estado da Máquina 9.4 {#941-machine-state} + +Esta seção explica o estado da máquina em maiores detalhes. Ela especifica que _w_ é o opcode atual. Se _μpc_ é menor que _||Ib||_, o tamanho do código, então aquele byte (_Ibpc]_) é o opcode. Caso contrário, o opcode é definido como [`STOP`](https://www.evm.codes/#00). + +Como esse é uma [máquina de pilha](https://en.wikipedia.org/wiki/Stack_machine), nós precisamos rastrear o número de itens que apareceram (_δ_) e empurraram em (_α_) por cada opcode. + +## Interrupção excepcional 9.4.2 {#942-exceptional-halt} + +Esta seção define a função _Z_, a qual especifica quando nós temos uma terminação anormal. Isto é uma função [booleana](https://en.wikipedia.org/wiki/Boolean_data_type), então ela usa [_∨_ para um ou lógico](https://en.wikipedia.org/wiki/Logical_disjunction) e [_∧_ para um e lógico](https://en.wikipedia.org/wiki/Logical_conjunction). + +Nós temos uma parada excepcional se qualquer destas condições for verdadeira: + +- **_μg < C(σ,μ,A,I)_** Como vimos na seção 9.2, _C_ é a função que especifica o custo de gas. Não há gas suficiente deixado para cobrir o próximo opcode. + +- **_δw=∅_** Se o número de itens que apareceram para um opcode é indefinido, então o opcode em si é indefinido. + +- **_|| μs || < δw_** Underflow de pilha, itens não suficientes na pilha para o opcode atual. + +- **_w = JUMP ∧ μs[0]∉D(Ib)_** O opcode é [`JUMP`](https://www.evm.codes/#56) e o endereço não é um [`JUMPDEST`](https://www.evm.codes/#5b). Saltos são _somente_ válidos quando o destino é um [`JUMPDEST`](https://www.evm.codes/#5b). + +- **_w = JUMPI ∧ μs[1]≠0 ∧ μs[0] ∉ D(Ib)_** O opcode é [`JUMPI`](https://www.evm.codes/#57), a condição é verdadeira (não zero) então o salto pode acontecer, e o endereço não é um [`JUMPDEST`](https://www.evm.codes/#5b). Saltos são _somente_ válidos quando o destino é um [`JUMPDEST`](https://www.evm.codes/#5b). + +- **_w = RETURNDATACOPY ∧ μs[1]+μs[2]>|| μo ||_** O opcode é [`RETURNDATACOPY`](https://www.evm.codes/#3e). Neste elemento da pilha de opcode _μs[1]_ é o offset de onde se lê no buffer de retorno de dados, e elemento da pilha _μs[2]_ é o tamanho do dado. A condição ocorre quando você tenta ler além do fim do buffer de dado de retorno. Note que não há uma condição similar para o calldata ou para o código ele mesmo. Quando você tentar ler além do fim destes buffers, você obtém somente zeros. + +- **_|| μs || - δw + αw > 1024_** + + Overflow de pilha. Se rodando o opcode resultar em uma pilha com mais de 1.024 itens, aborte. + +- **_¬Iw ∧ W(w,μ)_** Estamos rodando estaticamente ([¬ é negação](https://en.wikipedia.org/wiki/Negation) e_Iw_ é verdade quando nós somos permitidos mudar o estado do blockchain)? Se sim, e nós estamos tentando mudar o estado da operação, ela pode acontecer. + + A função _W(w,μ)_ é definida mais tarde na equação 150. _W(w,μ)_ é verdade se uma destas condições for verdadeira: + + - **_w ∈ {CREATE, CREATE2, SSTORE, SELFDESTRUCT}_** Estes opcodes mudando o estado, ou criando um novo contrato, armazenando valor, ou destruindo o contrato atual. + + - **_LOG0≤w ∧ w≤LOG4_** Se nãos formos chamados estaticamente, nós não podemos emitir entradas de log. Os opcodes de log estão todos na faixa entre [`LOG0` (A0)](https://www.evm.codes/#a0) e [`LOG4` (A4)](https://www.evm.codes/#a4). O número depois do opcode de log especifica quantos tópicos a entrada de log contém. + - **_w=CALL ∧ μs[2]≠0_** Você pode chamar um outro contrato quando você está estático, mas se você o fizer, você não pode transferir ETH para ele. + +- **_w = SSTORE ∧ μg ≤ Gcallstipend_** Você não pode rodar [`SSTORE`](https://www.evm.codes/#55) a não ser que você tenha mais que Gcallstipend (definido como 2300 no apêndice G) gas. + +## Validade do Destino do Salto 9.4.3 {#943-jump-dest-valid} + +Aqui nós definimos formalmente quais são os opcodes [`JUMPDEST`](https://www.evm.codes/#5b). Nós não podemos apenas procurar por valor de byte 0x5B, porque ele pode estar dentro de um PUSH (e, portanto, dado, não um opcode). + +Na equação (153) nós definimos a função, _N(i,w)_. O primeiro parâmetro, _i_, é a localização do opcode. A segunda, _w_, é o próprio opcode. Se _w∈[PUSH1, PUSH32]_ que significa que o opcode é um PUSH (colchetes definem uma faixa que inclui os endpoints). Se esse caso, o próximo opcode é em _i+2+(w−PUSH1)_. Para [`PUSH1`](https://www.evm.codes/#60) nós precisamos avançar dois bytes (o PUSH propriamente dito e o valor de um byte), para [`PUSH2`](https://www.evm.codes/#61) nós precisamos avançar três bytes porque é um valor de dois bytes, etc. Todos os outros opcodes EVM são apenas um byte de comprimento, então em todos os outros casos _N(i,w)=i+1_. + +Esta função é usada na equação (152) para definir _DJ(c,i)_, o qual é o [conjunto](https://en.wikipedia.org/wiki/Set_(mathematics)) de todos as destinações válidas de salto no código _c_, começando com a localização do opcode _i_. Esta função é definida recursivamente. Se _i≥||c||_, isto significa que nós estamos no fim do código ou depois dele. Nós não vamos descobrir mais nenhuma destinação de salto, então apenas retorna um conjunto vazio. + +Em todos os outros casos nós estamos olhando no resto do código indo para o próximo opcode e obtendo o conjunto iniciando dele. _c[i]_ é o opcode atual, então _N(i,c[i])_ é a localização do próximo opcode. _DJ(c,N(i,c[i]))_ é portanto o conjunto de destinos válidos de jump que começa no próximo opcode. Se o opcode atual não é um`JUMPDEST`, apenas retorne aquele conjunto. Se ele é `JUMPDEST`, inclua-o no conjunto de resultado e retorne-o. + +## Parada normal 9.4.4 {#944-normal-halt} + +A função halting _H_, pode retornar três tipos de valores. + +- Se nós não estivermos em um opcode halt, retorne _∅_, o conjunto vazio. Por convenção, este valor é interpretado como o falso booleano. +- Se nós temos um opcode halt que não produz saída (seja um [`STOP`](https://www.evm.codes/#00) ou [`SELFDESTRUCT`](https://www.evm.codes/#ff)), retorna uma sequência de tamanho zero bytes como valor de retorno. Note que isto é muito diferente do conjunto vazio. Este valor significa que a EVM realmente parou, apenas não há dados de retorno para ler. +- Se nós tivermos um opcode de halt que produz sim saída (seja [`RETURN`](https://www.evm.codes/#f3) ou [`REVERT`](https://www.evm.codes/#fd)), retorna a sequência de bytes especificada por este opcode. Esta sequência é pega da memória, o valor no topo da pilha (_μs[0]_) é o primeiro byte, e o valor depois dele (_μs[1]_) é o comprimento. + +## Conjunto de instruções H.2 {#h2-instruction-set} + +Antes de nós irmos para a subseção final da EVM, 9.5, vamos ver as instruções propriamente ditas. Elas estão definidas no apêndice H.2 que começa na página 29. Qualquer coisa que não esteja especificada como mudança com este específico opcode é esperada que continue o mesmo. Variáveis que realmente mudam são especificadas como \′. + +Por exemplo, vamos olhar o opcode [`ADD`](https://www.evm.codes/#01). + +| Valor | Mnemônico | δ | α | Descrição | +| -----:| --------- | - | - | --------------------------------------------------------- | +| 0x01 | ADD | 2 | 1 | Operação adição. | +| | | | | _μ′s[0] ≡ μs[0] + μs[1]_ | + +_δ_ é o número de valores que nós pegamos da pilha. Neste caso dois, porque nós estamos adicionando no topo dois valores. + +_α_ é o número de valores que nós retrocedemos. Neste caso um, a soma. + +Então o novo topo da pilha (_μ′s[0]_) é a soma do velho topo da pilha (_μs[0]_) e o velho valor abaixo dele (_μs[1]_). + +Ao invés de passar por todos os opcodes com olhos vidrados na lista, este artigo explica somente aqueles opcodes que introduzem algo novo. + +| Valor | Mnemônico | δ | α | Descrição | +| -----:| --------- | - | - | ---------------------------------------------------------------------------------------------------------- | +| 0x20 | KECCAK256 | 2 | 1 | Computa o hash Keccak-256. | +| | | | | _μ′s[0] ≡ KEC(μms[0] . . . (μs[0] + μs[1] − 1)])_ | +| | | | | _μ′i ≡ M(μis[0],μs[1])_ | + +Este é o primeiro opcode que acessa memória (nesse caso, somente leitura). Entretanto, ele pode expandir além dos limites atuais de memória, portanto nós precisamos atualizar _μi._ Nós fazemos isso usando a função _M_ definida na equação 328 na pág. 29. + +| Valor | Mnemônico | δ | α | Descrição | +| -----:| --------- | - | - | ---------------------------- | +| 0x31 | BALANCE | 1 | 1 | Obtém o saldo de dada conta. | +| | | | | ... | + +O endereço destes saldos que nós precisamos encontrar é _μs[0] mod 2160_. O topo da pilha é o endereço, mas por endereços serem somente 160 bits, nós calculamos o valor [modulo](https://en.wikipedia.org/wiki/Modulo_operation) 2160. + +Se _σ[μs[0] mod 2160] ≠ ∅_, isto significa que há informação sobre este endereço. Neste caso, _σ[μs[0] mod 2160]b_ é o saldo para aquele endereço. Se _σ[μs[0] mod 2160] = ∅_, significa que este endereço não está inicializado e que o saldo é zero. Você pode ver a lista de campos de informações de contas na seção 4.1 na página 4. + +A segunda equação, _A'a ≡ Aa ∪ {μs[0] mod 2160}_, é relacionada com a diferença no custo entre acesso à warm storage (storage que foi recenteimente acessada e é provável que esteja em cache) e cold storage (storage que não tem sido acessada e provavelmente esteja em uma storage mais lenta, que é mais cara para se recuperar). _Aa_ é a lista de endereços previamente acessados pela transação, que deveria, portanto ser de acesso mais barato, como definido na seção 6.1 na página 8. Você pode ler mais sobre este assunto em [EIP-2929](https://eips.ethereum.org/EIPS/eip-2929). + +| Valor | Mnemônico | δ | α | Descrição | +| -----:| --------- | -- | -- | --------------------------------------- | +| 0x8F | DUP16 | 16 | 17 | Duplica o 16o item da pilha. | +| | | | | _μ′s[0] ≡ μs[15]_ | + +Note que para usar qualquer item da pilha, nós precisamos pegá-lo, o que significa que nós também precisamos pegar todos os itens da pilha acima dele. No caso de [`DUP`](https://www.evm.codes/#8f) e [`SWAP`](https://www.evm.codes/#9f), isto significa ter que pegar e então empurrar os dezesseis valores. + +## O ciclo de execução 9.5 {#95-exec-cycle} + +Agora que nós temos todas as partes, nós podemos finalmente entender como o ciclo de execução da EVM é documentado. + +A equação (155) diz que dado o estado: + +- _σ_ (estado global do blockchain) +- _μ_ (estado da EVM) +- _A_ (sub-estado, mudanças a acontecer quando a transação terminar) +- _I_ (ambiente de execução) + +O novo estado é _(σ', μ', A', I')_. + +Equações (156)-(158) definem a pilha e a mudança nela devido a um opcode (_μs_). Equação (159) é a mudança em gas (_μg_). Equação (160) é a mudança no contador do programa (_μpc_). Finalmente, equações (161)-(164) especificam que os outros parâmetros continuam iguais, salvo explicitamente mudados pelo opcode. + +Com isto, a EVM está totalmente definida. + +## Conclusão {#conclusion} + +Notação matemática é precisa e tem permitido o Yellow Paper especificar cada detalhe do Ethereum. Entretanto, ela tem realmente algumas desvantagens: + +- Ela só pode ser entendida por humanos, o que significa que [testes de conformidade](https://github.com/ethereum/tests) devem ser escritos manualmente. +- Programadores entendem código de computador. Eles podem ou não entender notação matemática. + +Talvez por estas razões, a mais nova [especificação da camada de consenso](https://github.com/ethereum/consensus-specs/blob/dev/tests/core/pyspec/README.md) seja escrita em Python. Estas são [especificações da camada de execução em Python](https://ethereum.github.io/execution-specs), mas elas não estão completas. Até que, ou a não ser que, o Yellow Paper inteiro esteja também traduzido para Python ou linguagem similar, o Yellow Paper continuará em serviço, e é útil ser capaz de lê-lo. diff --git a/public/content/translations/pt-br/enterprise/index.md b/public/content/translations/pt-br/enterprise/index.md index 06041f03963..55796b31763 100644 --- a/public/content/translations/pt-br/enterprise/index.md +++ b/public/content/translations/pt-br/enterprise/index.md @@ -57,11 +57,13 @@ Diversas organizações trabalharam juntas para tornar o Ethereum amigável para - O [Hyperledger Besu](https://www.hyperledger.org/use/besu) _é um cliente Ethereum de código aberto desenvolvido sob licença Apache 2.0 e escrito em Java_ - O [Infura](https://infura.io/) _é uma API escalável de acesso às redes Ethereum e IPFS_ - O [Kaleido](https://kaleido.io/) _é uma plataforma de desenvolvimento focada em empresas que oferece uma cadeia de blocos simplificada e aplicativos de ativos digitais_ +- [NodeReal](https://nodereal.io/) _fornece infraestrutura de blockchain escalável e a API do provedor de serviços para o ecossistema Web3_ - O [Provide](https://provide.services/) _fornece infraestrutura e APIs para aplicativos Web3 para empresas_ - O [QuickNode](https://www.quicknode.com/) _fornece nós confiáveis e rápidos com APIs de alto nível como NFT API, Token API, entre outras, enquanto entrega um pacote unificado de produtos e soluções de nível empresarial_ - [Tenderly](https://tenderly.co) _é uma plataforma de desenvolvimento Web3 que fornece blocos de depuração de infraestrutura, observação e construção para desenvolvimento, teste, monitoramento e operação de contratos inteligentes_ - A [Unibright](https://unibright.io/) _é uma equipe de especialistas, arquitetos, desenvolvedores e consultores da blockchain, com mais de 20 anos de experiência em processos de negócios e integração_ - [Zero Services GmbH](https://www.zeroservices.eu/) _é um provedor de serviços gerenciados espalhado por locais compartilhados na Europa e na Ásia. Opera e monitora seus nós de forma segura e confiável_ +- [Zeeve](https://www.zeeve.io/) _fornece uma variedade de produtos e ferramentas de criação no Ethereum, além de infraestrutura e APIs para aplicativos Web3 para empresas._ ### Ferramentas e bibliotecas {#tooling-and-libraries} diff --git a/public/content/translations/pt-br/enterprise/private-ethereum/index.md b/public/content/translations/pt-br/enterprise/private-ethereum/index.md index cafab5463b4..88829be24b7 100644 --- a/public/content/translations/pt-br/enterprise/private-ethereum/index.md +++ b/public/content/translations/pt-br/enterprise/private-ethereum/index.md @@ -25,3 +25,4 @@ Diversas organizações trabalharam juntas para tornar o Ethereum amigável para - [Hyperledger Burrow](https://www.hyperledger.org/projects/hyperledger-burrow) _cliente de cadeia de blocos modular com um intérprete de contratos inteligentes autorizados, parcialmente desenvolvido para a especificação da Máquina Virtual do Ethereum (EVM)_ - [Kaleido](https://kaleido.io/) _ é uma plataforma de pilha completa para construção e execução de ecossistemas empresariais multinuvem e híbridos_ - [Quorum](https://consensys.net/quorum/) _ é uma plataforma de cadeia de blocos para empresas de código aberto baseada em Ethereum, com recursos avançados de nível empresarial, oferecendo privacidade, permissões e desempenho_ +- [Zeeve](https://www.zeeve.io/) _fornece uma variedade de produtos e ferramentas de criação no Ethereum, além de infraestrutura e APIs para aplicativos Web3 para empresas_ diff --git a/public/content/translations/pt-br/foundation/index.md b/public/content/translations/pt-br/foundation/index.md index 42fa4af0da1..f2c680d4287 100644 --- a/public/content/translations/pt-br/foundation/index.md +++ b/public/content/translations/pt-br/foundation/index.md @@ -27,7 +27,7 @@ Desde 2014, a Fundação Ethereum organiza a Devcon, uma conferência anual para Você pode acessar todo o conteúdo de vídeo das conferências de cada ano em [archive.devcon.org](https://archive.devcon.org/). -Saiba mais em [devcon.org](https://devcon.org/), confira o [Blog da Devcon](https://devcon.org/en/blogs/) ou siga [@efdevcon](https://twitter.com/EFDevcon) para ler os últimos comunicados. +Saiba mais em [devcon.org](https://devcon.org/), confira o [Blog da Devcon](https://blog.ethereum.org/category/devcon/) ou siga [@efdevcon](https://twitter.com/EFDevcon) para ler os últimos comunicados. ### Programa de Bolsas {#fellowship-program} diff --git a/public/content/translations/pt-br/roadmap/account-abstraction/index.md b/public/content/translations/pt-br/roadmap/account-abstraction/index.md index 88cdc8a6cca..b8d4f7fcfef 100644 --- a/public/content/translations/pt-br/roadmap/account-abstraction/index.md +++ b/public/content/translations/pt-br/roadmap/account-abstraction/index.md @@ -32,7 +32,7 @@ Se você perder as suas chaves, elas não poderão ser recuperadas, e as chaves As carteiras de contratos inteligentes são a solução para esses problemas, mas atualmente são difíceis de programar porque, no final, qualquer lógica que elas implementem precisa ser traduzida em um conjunto de transações EOA antes que possam ser processadas pelo Ethereum. A abstração de conta permite que contratos inteligentes iniciem as próprias transações. Dessa forma, qualquer lógica que o usuário queira implementar poderá ser codificada na própria carteira de contrato inteligente e executada no Ethereum. -Em última análise, a abstração de contas melhora o suporte a carteiras de contratos inteligentes, tornando-as mais fáceis de criar e mais seguras de usar. No final, com a abstração de conta, os usuários podem aproveitar todos os benefícios do Ethereum sem precisar conhecer ou se preocupar com a tecnologia subjacente. +Na realidade, é a abstração de contas que melhora o suporte a carteiras de contratos inteligentes, tornando-as mais fáceis de criar e mais seguras de usar. No final, com a abstração de conta, os usuários podem aproveitar todos os benefícios do Ethereum sem precisar conhecer ou se preocupar com a tecnologia subjacente. ## Além das frases sementes {#beyond-seed-phrases} @@ -47,8 +47,8 @@ Por exemplo, as chaves de backup podem ser adicionadas a uma carteira para que, - **Autorização multisig**: você pode compartilhar credenciais de autorização entre várias pessoas ou dispositivos confiáveis. Em seguida, o contrato pode ser configurado de modo que as transações superiores a um valor predefinido exijam autorização de uma proporção específica (por exemplo, 3/5) das partes confiáveis. Por exemplo, transações de alto valor podem exigir a aprovação de um dispositivo móvel e de uma carteira de hardware, ou assinaturas de contas distribuídas a familiares confiáveis. - **Congelamento de conta**: se um dispositivo for perdido ou comprometido, a conta pode ser bloqueada a partir de outro dispositivo autorizado, protegendo os ativos do usuário. - **Recuperação de conta**: perdeu um dispositivo ou esqueceu uma senha? No paradigma atual, isso significa que os seus ativos podem ser congelados para sempre. Com uma carteira de contrato inteligente, você pode definir algumas contas pré-aprovadas que podem autorizar novos dispositivos e redefinir o acesso. -- **Definir limites de transação**: especifique limites diários de quanto valor pode ser transferido da conta em um dia/semana/mês. Isso significa que, se um invasor obtiver acesso à sua conta, ele não poderá ficar com tudo de uma vez e você terá oportunidades de congelar e redefinir o acesso. -- **Criar listas de permissões**: permita transações apenas para endereços específicos, que você sabe que são seguros. Isso significa que, _mesmo_ em caso de roubo da sua chave privada, o invasor não poderia enviar fundos para contas de destino não autorizadas. Essas listas de permissão exigiriam várias assinaturas para alterá-las, de modo que um invasor não poderia adicionar o endereço dele à lista, a menos que tivesse acesso a diversas das suas chaves de backup. +- **Definição de limites de transações**: especifique limites diários de transferência de valores da conta em um dia/semana/mês. Isso significa que, se um invasor obtiver acesso à sua conta, ele não poderá ficar com tudo de uma vez e você terá oportunidades de congelar e redefinir o acesso. +- **Criação de listas de permissões**: só permita transações para determinados endereços tidos como seguros. Isso significa que, _mesmo_ em caso de roubo da sua chave privada, o invasor não poderia enviar fundos para contas de destino não autorizadas. Essas listas de permissão exigiriam várias assinaturas para alterá-las, de modo que um invasor não poderia adicionar o endereço dele à lista, a menos que tivesse acesso a diversas das suas chaves de backup. ## Melhor experiência do usuário {#better-user-experience} diff --git a/public/content/translations/pt-br/roadmap/index.md b/public/content/translations/pt-br/roadmap/index.md index 22cdf38bada..3bab123ac1c 100644 --- a/public/content/translations/pt-br/roadmap/index.md +++ b/public/content/translations/pt-br/roadmap/index.md @@ -3,7 +3,7 @@ title: Planejamento Ethereum description: O caminho para mais escalabilidade, segurança e sustentabilidade no Ethereum. lang: pt-br template: roadmap -image: /roadmap/roadmap-main.png +image: /heroes/roadmap-hub-hero.jpg alt: "Planejamento Ethereum" summaryPoints: buttons: @@ -59,7 +59,7 @@ O Ethereum recebe melhorias regulares que aprimoram a escalabilidade, a seguran -O planejamento é, em grande parte, o resultado de anos de trabalho de pesquisadores e desenvolvedores, pois o protocolo é muito técnico, mas qualquer pessoa motivada pode participar. As ideias geralmente começam como discussões em um fórum, como [ethresear.ch](https://ethresear.ch/), [Ethereum magicians](https://www.figma.com/exit?url=https%3A%2F%2Fethereum-magicians.org%2F) ou no servidor Eth R&D no Discord. Elas podem ser respostas a novas vulnerabilidades constatadas, sugestões de organizações que trabalham na camada de aplicativos (como dApps e corretoras) ou de atritos conhecidos junto a usuários finais (como custos ou velocidades de transação). Quando essas ideias amadurecem, elas podem ser apresentadas como [Propostas de melhorias do Ethereum] (https://eips.ethereum.org/). Tudo isso é feito abertamente, e qualquer pessoa da comunidade pode dar sua opinião, a qualquer momento. +O planejamento é, em grande parte, o resultado de anos de trabalho de pesquisadores e desenvolvedores, pois o protocolo é muito técnico, mas qualquer pessoa motivada pode participar. As ideias geralmente começam como discussões em um fórum, como [ethresear.ch](https://ethresear.ch/), [Ethereum magicians](https://ethereum-magicians.org) ou no servidor Eth R&D no Discord. Elas podem ser respostas a novas vulnerabilidades constatadas, sugestões de organizações que trabalham na camada de aplicativos (como dApps e corretoras) ou de atritos conhecidos junto a usuários finais (como custos ou velocidades de transação). Quando essas ideias amadurecem, elas podem ser apresentadas como [Propostas de melhorias do Ethereum] (https://eips.ethereum.org/). Tudo isso é feito abertamente, e qualquer pessoa da comunidade pode dar sua opinião, a qualquer momento. [Mais sobre a governança do Ethereum](/governance/) diff --git a/public/content/translations/pt-br/roadmap/single-slot-finality/index.md b/public/content/translations/pt-br/roadmap/single-slot-finality/index.md index 56a8f504565..da52f022deb 100644 --- a/public/content/translations/pt-br/roadmap/single-slot-finality/index.md +++ b/public/content/translations/pt-br/roadmap/single-slot-finality/index.md @@ -37,7 +37,7 @@ Com o design do mecanismo atual, para reduzir o tempo de finalização, é neces O mecanismo de consenso atual combina atestações de diversos validadores, conhecidos como "comitês", para reduzir o número de mensagens que cada validador precisa processar para validar um bloco. Cada validador tem a oportunidade de atestar em cada época (32 espaços), mas em cada espaço, apenas um subconjunto de validadores, conhecido como uma atestação de "comitê". Eles fazem isso ao se dividir em sub-redes, nas quais alguns validadores são selecionados para serem "agregadores". Esses agregadores combinam, em uma única assinatura agregada, todas as assinaturas que observam de outros validadores na respectiva sub-rede. O agregador que inclui o maior número de contribuições individuais passa a assinatura agregada ao proponente do bloco, que a inclui no bloco juntamente com a assinatura agregada dos demais comitês. -Esse processo oferece capacidade suficiente para cada validador votar em cada época, porque "32 espaços _ 64 comitês _ 256 validadores por comitê = 524.288 validadores por época". No momento da redação deste artigo (fevereiro de 2023), há aproximadamente 513.000 validadores ativos. +Esse processo oferece capacidade suficiente para cada validador votar em cada época, porque "32 espaços * 64 comitês * 256 validadores por comitê = 524.288 validadores por época". No momento da redação deste artigo (fevereiro de 2023), há aproximadamente 513.000 validadores ativos. Nesse esquema, só é possível que cada validador vote em um bloco se distribuir as respectivas atestações por toda a época. Entretanto, há potencialmente maneiras de aprimorar o mecanismo para que _cada validador tenha a chance de atestar em cada espaço_. diff --git a/public/content/translations/pt-br/roadmap/statelessness/index.md b/public/content/translations/pt-br/roadmap/statelessness/index.md index 4b19b709a66..56fc288c4f5 100644 --- a/public/content/translations/pt-br/roadmap/statelessness/index.md +++ b/public/content/translations/pt-br/roadmap/statelessness/index.md @@ -66,7 +66,7 @@ Sem estado fraco envolve alterações na maneira como os nós Ethereum verificam **Em sem estado fraco, propor blocos exige acesso a dados de estado completos, mas verificar blocos não exige dados do estado** -Para que isso aconteça, [Verkle Trees](/roadmap/verkle-trees) já devem ter sido implementadas nos clientes Ethereum. As Verkle Trees são uma estrutura de dados de substituição para armazenar dados de estado do Ethereum que permitem que "testemunhas" pequenas e de tamanho fixo dos dados sejam transmitidas entre pares e utilizadas para verificar blocos, em vez de verificar blocos com relação aos bancos de dados locais. A [separação entre proponente e construtor](/roadmap/pbs/) também é necessária, porque isso permite que os construtores de blocos sejam nós especializados com hardware mais poderoso, e esses são os que exigem acesso aos dados de estado completos. +Para que isso aconteça, [Verkle Trees](/roadmap/verkle-trees/) já devem ter sido implementadas nos clientes Ethereum. As Verkle Trees são uma estrutura de dados de substituição para armazenar dados de estado do Ethereum que permitem que "testemunhas" pequenas e de tamanho fixo dos dados sejam transmitidas entre pares e utilizadas para verificar blocos, em vez de verificar blocos com relação aos bancos de dados locais. A [separação entre proponente e construtor](/roadmap/pbs/) também é necessária, porque isso permite que os construtores de blocos sejam nós especializados com hardware mais poderoso, e esses são os que exigem acesso aos dados de estado completos. @@ -81,7 +81,7 @@ O conceito "sem estado fraco" está em um estado avançado de pesquisa, mas depe ### Sem estado forte {#strong-statelessness} -O conceito "sem estado forte" remove a necessidade de armazenamento de dados do estado por qualquer bloco. Em vez disso, as transações são enviadas com testemunhas que podem ser agregadas pelos produtores de blocos. Portanto, os produtores de blocos serão responsáveis por armazenar apenas o estado necessário para gerar testemunhas para as contas relevantes. A responsabilidade pelo estado é quase totalmente transferida para os usuários, pois eles enviam testemunhas e "listas de acesso" para declarar com quais contas e chaves de armazenamento estão interagindo. +O conceito "sem estado forte" remove a necessidade de armazenamento de dados do estado por qualquer bloco. Em vez disso, as transações são enviadas com testemunhas que podem ser agregadas pelos produtores de blocos. Portanto, os produtores de blocos serão responsáveis por armazenar apenas o estado necessário para gerar testemunhas para as contas relevantes. A responsabilidade pelo estado é quase totalmente transferida para os usuários, pois eles enviam testemunhas e "listas de acesso" para declarar com quais contas e chaves de armazenamento estão interagindo. Embora isso permitiria nódulos altamente leves, seria mais difícil realizar trtansações conm contratos inteligentes. O conceito "sem estado forte" foi investigado por pesquisadores, mas atualmente não se espera que faça parte do planejamento do Ethereum. É mais provável que o sem estado fraco seja suficiente para as necessidades de escalabilidade do Ethereum. diff --git a/public/content/translations/pt-br/whitepaper/index.md b/public/content/translations/pt-br/whitepaper/index.md index 51924a1ce68..cc27215b19e 100644 --- a/public/content/translations/pt-br/whitepaper/index.md +++ b/public/content/translations/pt-br/whitepaper/index.md @@ -3,6 +3,7 @@ title: Whitepaper sobre o Ethereum description: Um documento de introdução ao Ethereum, publicado em 2013 antes de seu lançamento. lang: pt-br sidebarDepth: 2 +hideEditButton: true --- # Whitepaper do Ethereum {#ethereum-whitepaper} @@ -11,7 +12,7 @@ _Este artigo de introdução foi publicado em 2014 por Vitalik Buterin, o fundad _Apesar de já terem se passado alguns anos desde sua publicação, nós o mantivemos porque ele continua a ser uma referência útil e uma autêntica representação do Ethereum e de sua visão. Para aprender sobre os desenvolvimentos mais recentes do Ethereum e como as mudanças no protocolo são feitas, recomendamos [este manual](/learn/)._ -[Abra o whitepaper do Ethereum em PDF](./whitepaper-pdf/Ethereum_Whitepaper_-_Buterin_2014.pdf) +[Pesquisadores e acadêmicos que buscam uma versão histórica ou uma versão canônica do whitepaper [de Dezembro de 2014] devem usar este PDF.](./whitepaper-pdf/Ethereum_Whitepaper_-_Buterin_2014.pdf) ## Uma nova geração de contrato inteligente e plataforma de aplicativos descentralizada {#a-next-generation-smart-contract-and-decentralized-application-platform} @@ -134,7 +135,7 @@ Mesmo sem nenhuma extensão, o protocolo Bitcoin realmente facilita uma versão No entanto, o idioma de scripting conforme implementado no Bitcoin tem várias limitações importantes: - **A falta de completude de Turing** - ou seja, embora haja um grande subconjunto de computação que a linguagem de script de Bitcoin suporta, ele nem de perto suporta tudo. A principal categoria que está faltando são laços (loops). Isso é feito para evitar loops infinitos durante a verificação da transação. Teoricamente é um obstáculo para programadores de script, já que qualquer loop pode ser simulado simplesmente repetindo o código, muitas vezes com uma instrução if, mas leva a scripts que são muito ineficientes em termos de espaço. Por exemplo, a implementação de um algoritmo alternativo de assinatura de curva elíptica provavelmente exigiria 256 rodadas de multiplicação repetidas, todas incluídas individualmente no código. -- **Valor blindado** - não há como um script UTXO fornecer controle fino sobre o valor que pode ser sacado. Por exemplo, um caso de uso poderoso de um contrato Oracle seria um contrato de hedge, em que A e B colocam BTC 1000 e, após 30 dias, o script envia BTC 1000 para A e o restante para B. Isto exigiria um Oracle para determinar o valor de BTC 1 em USD, mesmo assim é uma grande melhoria em termos de confiança e requisitos de infraestrutura em relação às soluções totalmente centralizadas que estão disponíveis agora. No entanto, como UTXOs são tudo ou nada, a única maneira de conseguir isso é com o hack muito ineficiente de ter muitos UTXO de denominações variadas (por exemplo, um UTXO de 2k para todo k até 30) e fazendo com que O escolha qual UTXO enviar para A e qual para B. +- **Valor blindado** - não há como um script UTXO fornecer controle fino sobre o valor que pode ser sacado. Por exemplo, um caso de uso poderoso de um contrato Oracle seria um contrato de hedge, em que A e B colocam BTC 1000 e, após 30 dias, o script envia BTC 1000 para A e o restante para B. Isto exigiria um Oracle para determinar o valor de BTC 1 em USD, mesmo assim é uma grande melhoria em termos de confiança e requisitos de infraestrutura em relação às soluções totalmente centralizadas que estão disponíveis agora. No entanto, como os UTXO são tudo ou nada, a única forma de alcançar isso é através do hack muito ineficiente de ter muitos UTXO de denominações variadas (por exemplo, um UTXO de 2k para cada k até 30) e fazer com que o oráculo escolha qual UTXO enviar para A e qual para B. - **Falta de estado** - UTXOs podem ser gastos ou não. Contratos multiestados ou scripts que mantenham qualquer outro estado interno além disso não são possíveis. Isso dificulta a criação de contratos de opções multiestados, ofertas de troca descentralizadas ou protocolos de compromisso criptográfico de dois estágios (necessários para recompensas computacionais seguras). Isso também significa que o UTXO só pode ser usado para construir contratos pontuais simples e não contratos "com estado" mais complexos (como organizações descentralizadas) torna os meta-protocolos difíceis de implementar. O estado binário combinado com o valor blindado também significa que a importante aplicação de limites de retirada é possível. - **Blockchain blindada** - o UTXO é blindado para os dados de blockchain, como nonce, carimbos de tempo e hashes de blocos anteriores. Isto limita extremamente as aplicações em jogos de azar e várias outras categorias, privando a linguagem de script de uma fonte potencialmente valiosa de aleatoriedade. @@ -229,7 +230,7 @@ O código nos contratos Ethereum é escrito em linguagem bytecode "stack-based" O código também pode acessar o valor, o remetente e os dados da mensagem entrante, bem como os dados do cabeçalho do bloco. Ele também pode retornar um array de bytes como resultado. -O modelo de execução formal do código EVM é bem simples. Enquanto a máquina virtual Ethereum está em execução, seu estado computacional completo pode ser definido pela tupla `(block_state, transaction, message, code, memory, stack, pc, gas)`, em que `block_state` é o estado global que contém todas as contas e inclui saldos e armazenamento. No início de cada rodada de execução, a instrução atual é encontrada pegando o `pc`ésimo byte de `code` (ou 0 se `pc >= len(code)`), e cada instrução tem sua própria definição em termos de como ela afeta a tupla. Por exemplo, `ADD` retira dois itens do stack e adiciona a soma deles, reduz `gas` em 1, incrementa `pc` em 1 e `SSTORE` retira os dois itens do stack, finalmente insere o segundo item no armazenamento do contrato no índice especificado pelo primeiro item. Embora existam muitas maneiras de otimizar a execução da máquina virtual Ethereum por meio de compilação just-in-time, a implementação básica do Ethereum pode ser feita com poucas centenas de linhas de código. +O modelo de execução formal do código EVM é bem simples. Enquanto a máquina virtual Ethereum está em execução, seu estado computacional completo pode ser definido pela tupla `(block_state, transaction, message, code, memory, stack, pc, gas)`, em que `block_state` é o estado global que contém todas as contas e inclui saldos e armazenamento. No início de cada rodada de execução, a instrução atual é encontrada pegando o `pc`ésimo byte de `code` (ou 0 se `pc >= len(code)`), e cada instrução tem sua própria definição em termos de como ela afeta a tupla. Por exemplo, `ADD` retira dois itens da pilha e coloca sua soma, reduz o `gás` em 1 e incrementa o `pc` em 1 e o ` SSTORE` remove os dois primeiros itens da pilha e insere o segundo item no armazenamento do contrato, no índice especificado pelo primeiro item. Embora existam muitas maneiras de otimizar a execução da máquina virtual Ethereum por meio de compilação just-in-time, a implementação básica do Ethereum pode ser feita com poucas centenas de linhas de código. ### Blocos e mineração {#blockchain-and-mining} @@ -314,7 +315,7 @@ Um esboço geral de como codificar uma DAO é o seguinte: o design mais simples - `[1,i]` para registrar um voto a favor da proposta `i` - `[2,i]` para finalizar a proposta `i` se houver votos suficientes -O contrato teria, então, cláusulas para cada uma dessas transações. Ele manteria um registro de todas as mudanças no armazenamento aberto, e uma lista de quem votou nelas. Haveria também uma lista de todos os membros. Quando qualquer alteração de armazenamento chega a dois terços dos membros votando nela, uma transação finalizada poderia executar a mudança. Um esqueleto mais sofisticado também teria capacidade de votação integrada para recursos como enviar uma transação, adicionar e remover membros e poderia até fornecer delegação de votos no estilo [democracia líquida](https://wikipedia.org/wiki/Delegative_democracy), em que qualquer um pode designar alguém para votar em seu lugar, e a designação é transitiva: se A designa B e B designa C, então C determina o voto de A. Este desenho faria a DAO crescer de forma orgânica como comunidade descentralizada, permitindo que pessoas eventualmente delegassem a tarefa de filtrar quem é um membro a especialistas, diferente do "sistema atual" em que especialistas podem aparecer e desaparecer ao longo do tempo à medida que os membros individuais da comunidade mudam seus alinhamentos. +O contrato teria, então, cláusulas para cada uma dessas transações. Ele manteria um registro de todas as mudanças no armazenamento aberto, e uma lista de quem votou nelas. Haveria também uma lista de todos os membros. Quando qualquer alteração de armazenamento chega a dois terços dos membros votando nela, uma transação finalizada poderia executar a mudança. Um esqueleto mais sofisticado também teria a capacidade de votação integrada para recursos, como enviar uma transação, adicionar e remover membros, e poderia até fornecer uma delegação de votos no estilo [Democracia Líquida](https://wikipedia.org/wiki/Liquid_democracy) (ou seja, qualquer pessoa pode designar alguém para votar em seu lugar, e a designação é transitiva: se A designa B e B designa C, então C determina o voto de A). Este desenho faria a DAO crescer de forma orgânica como comunidade descentralizada, permitindo que pessoas eventualmente delegassem a tarefa de filtrar quem é um membro a especialistas, diferente do "sistema atual" em que especialistas podem aparecer e desaparecer ao longo do tempo à medida que os membros individuais da comunidade mudam seus alinhamentos. Um modelo alternativo seria o de empresa descentralizada, onde qualquer conta pode ter zero ou mais ações, e dois terços das ações são necessários para se tomar uma decisão. Um esqueleto completo envolveria a funcionalidade de gerenciamento de ativos, a capacidade de fazer uma oferta de compra ou venda de ações, e a capacidade de aceitar ofertas (de preferência com um mecanismo de correspondência de pedidos dentro do contrato). A delegação também existiria no estilo democracia líquida, generalizando o conceito de "conselho de administração". @@ -501,15 +502,15 @@ O conceito de uma função de transição de estado arbitrária implementada pel 10. [Whitepaper sobre moedas coloridas](https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit) 11. [Whitepaper sobre Mastercoin](https://github.com/mastercoin-MSC/spec) 12. [Empresas autônomas descentralizadas, Bitcoin Magazine](http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/) -13. [Verificação de pagamento simplificado](https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification) +13. [Verificação de pagamento simplificado](https://en.bitcoin.it/wiki/Scalability#Simplified_payment_verification) 14. [Árvores de Merkle](https://wikipedia.org/wiki/Merkle_tree) 15. [Árvores Patricia](https://wikipedia.org/wiki/Patricia_tree) 16. [GHOST](https://eprint.iacr.org/2013/881.pdf) 17. [StorJ e agentes autónomos, Jeff Garzik](http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html) -18. [Mike Hearn fala sobre propriedades inteligentes no Festival de Turing](http://www.youtube.com/watch?v=Pu4PAMFPo5Y) +18. [Mike Hearn fala sobre propriedades inteligentes no Festival de Turing](https://www.youtube.com/watch?v=MVyv4t0OKe4) 19. [Ethereum RLP](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP) 20. [Árvores Ethereum Merkle Patricia](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree) -21. [Pedro Todd sobre árvores da soma Merkle](http://sourceforge.net/p/bitcoin/mailman/message/31709140/) +21. [Pedro Todd sobre árvores da soma Merkle](https://web.archive.org/web/20140623061815/http://sourceforge.net/p/bitcoin/mailman/message/31709140/) _Para a história do whitepaper, veja [esta wiki](https://github.com/ethereum/wiki/blob/old-before-deleting-all-files-go-to-wiki-wiki-instead/old-whitepaper-for-historical-reference.md)._ diff --git a/public/content/translations/ru/community/get-involved/index.md b/public/content/translations/ru/community/get-involved/index.md index 6acc443a8d5..58c4e3c7a0d 100644 --- a/public/content/translations/ru/community/get-involved/index.md +++ b/public/content/translations/ru/community/get-involved/index.md @@ -28,7 +28,7 @@ lang: ru - Составьте или рассмотрите предложение по улучшению Ethereum (EIP) - Составьте EIP 1. Представьте свою идею на [Ethereum Magicians](https://ethereum-magicians.org) - 2. Прочтите [EIP-1](https://eip.ethereum.org/EIPS/eip-1) — **да, это _весь_ документ.** + 2. Прочтите [EIP-1](https://eips.ethereum.org/EIPS/eip-1). **Да, это _весь_ документ.** 3. Следуйте указаниям из документа EIP-1. Ссылайтесь на него при составлении черновика. - Узнайте, как стать [редактором EIP](https://eips.ethereum.org/EIPS/eip-5069) - Теперь вы можете рассматривать EIP других участников! Просматривайте [открытые запросы на включение изменений с тегом `e-review`](https://github.com/ethereum/EIPs/pulls?q=is%3Apr+is%3Aopen+label%3Ae-review). Давайте обратную связь относительно технических аспектов по ссылке `discussion-to`. diff --git a/public/content/translations/ru/community/grants/index.md b/public/content/translations/ru/community/grants/index.md index aa7cadd9287..1628070804f 100644 --- a/public/content/translations/ru/community/grants/index.md +++ b/public/content/translations/ru/community/grants/index.md @@ -1,5 +1,5 @@ --- -title: Фонд Ethereum и программы грантов сообщества +title: Фонд Ethereum Foundation и программы грантов сообщества description: Список программ грантов в рамках экосистемы Ethereum. lang: ru --- @@ -15,31 +15,27 @@ lang: ru Эти программы поддерживают обширную экосистему Ethereum, предлагая гранты для широкого круга проектов. Они включают решения по масштабируемости, созданию сообществ, безопасности, конфиденциальности и не только. Эти гранты не относятся к какой-либо конкретной платформе Ethereum и являются хорошей отправной точкой, если вы не уверены в себе. - [Программа поддержки экосистемы EF](https://esp.ethereum.foundation) — _финансирование проектов с открытым исходным кодом, которые приносят пользу Ethereum, с особым акцентом на универсальные инструменты, инфраструктуру, исследования и общественные блага_ -- [Запросы предложений (RFP) Ethereum](https://github.com/ethereum/requests-for-proposals) — _запросы предложений Фондом Ethereum для работы и проектов в экосистеме Ethereum_ -- [MetaCartel](https://www.metacartel.org/grants/) — _разработка децентрализованных приложений, создание DAO_ -- [Децентрализованная автономная организация (DAO) Moloch](https://www.molochdao.com/) — _конфиденциальность, масштабирование второго уровня, безопасность клиентов и многое другое_ -- [Открытые гранты](https://opengrants.com/explore) -- [Гранты DAO](https://docs.google.com/spreadsheets/d/1XHc-p_MHNRdjacc8uOEjtPoWL86olP4GyxAJOFO0zxY/edit#gid=0) — _таблица Google организаций, предлагающих гранты_ -- [Аналог Crunchbase для грантов по Web3](https://www.cryptoneur.xyz/web3-grants) — _отфильтровывайте и ищите гранты по категории, назначению, количеству и другим характеристикам. Внесите свой вклад, чтобы помочь другим найти нужный грант._ -- [Академические гранты](https://esp.ethereum.foundation/academic-grants) — _гранты на поддержку академической работы, связанной с Ethereum_ +- [MetaCartel](https://www.metacartel.org/grants/): _разработка децентрализованных приложений, создание DAO._ +- [DAO Moloch](https://www.molochdao.com/): _конфиденциальность, масштабирование второго уровня, безопасность клиентов и многое другое._ +- [Гранты DAO](https://docs.google.com/spreadsheets/d/1XHc-p_MHNRdjacc8uOEjtPoWL86olP4GyxAJOFO0zxY/edit#gid=0): _Google-таблица организаций, предлагающих гранты._ +- [Crunchbase для грантов по Web3](https://www.cryptoneur.xyz/web3-grants): _отфильтровывайте и ищите гранты по категории, назначению, количеству и другим характеристикам. Помогите другим найти нужный грант._ +- [Академические гранты](https://esp.ethereum.foundation/academic-grants): _гранты на поддержку академической работы, связанной с Ethereum._ +- [Blockworks Grantfarm](https://blockworks.co/grants/programs): _компания Blockworks составила полный каталог всех грантов, запросов предложений (RFP) и наград за найденные ошибки._ ## Отдельные проекты {#project-specific} В рамках этих проектов созданы их собственные гранты, направленные на разработку и тестирование собственных технологий. - [Программа грантов Aave](https://aavegrants.org/) — _гранты DAO от [Aave](https://aave.com/)_ -- [Balancer](https://balancergrants.notion.site/Balancer-Community-Grants-23e562c5bc4347cd8304637bff0058e6) — _фонд экосистемы [Balancer](https://balancer.fi/)_ +- [Balancer](https://quark-ceres-740.notion.site/Balancer-Grants-938f1b979810427f8d903a904315da41): _фонд экосистемы [Balancer](https://balancer.fi/)._ - [Программа грантов Chainlink](https://chain.link/community/grants) — _гранты сообщества [Chainlink](https://chain.link/)_ -- [Программа грантов Compound](https://compoundgrants.org/) — _финансовая экосистема [Compound](https://compound.finance/)_ -- [ Программа грантов Decentraland](https://governance.decentraland.org/grants/) — _метавселенная децентрализованных автономных организаций (DAO) [Decentraland](https://decentraland.org/)_ -- [Организация грантов экосистемы Lido (LEGO)](https://lego.lido.fi/) — _финансовая экосистема [Lido](https://lido.fi/)_ -- [ Программа MetaMask](https://metamaskgrants.org/) — _децентрализованная автономная организация (DAO) по выдаче грантов, возглавляемая сотрудниками [MetaMask](https://metamask.io/)_ -- [Программа грантов mStable](https://docs.mstable.org/advanced/grants-program) — _сообщество [mStable](https://mstable.org/)_ -- [Программа грантов SKALE Network](https://skale.space/developers#grants) — _экосистема [SKALE Network](https://skale.space/)_ -- [The Graph](https://airtable.com/shrdfvnFvVch3IOVm) — _экосистема [The Graph](https://thegraph.com/)_ -- [Программа грантов UMA](https://grants.umaproject.org/) — _поддержка разработчиков [UMA](https://umaproject.org/)_ -- [Программа грантов Uniswap](https://www.unigrants.org/) — _сообщество [Uniswap](https://uniswap.org/)_ -- [Гранты по Web3](https://web3grants.net) — _большой список грантовых программ по Web3/криптовалютам_ +- [ Программа грантов Decentraland](https://governance.decentraland.org/grants/): _метавселенная DAO [Decentraland](https://decentraland.org/)._ +- [Организация грантов экосистемы Lido (LEGO)](https://lido.fi/lego): _финансовая экосистема [Lido](https://lido.fi/)._ +- [ Программа MetaMask](https://metamaskgrants.org/): _DAO по выдаче грантов под руководством сотрудников [MetaMask](https://metamask.io/)._ +- [Программа грантов SKALE Network](https://skale.space/developers#grants): _экосистема [SKALE Network](https://skale.space/)._ +- [The Graph](https://airtable.com/shrdfvnFvVch3IOVm): _экосистема [The Graph](https://thegraph.com/)._ +- [Программа грантов Uniswap](https://www.uniswapfoundation.org/apply-for-a-grant): _сообщество [Uniswap](https://uniswap.org/)._ +- [Web3 Grants](https://web3grants.net): _обширный список грантов, связанных с web3/криптовалютами._ ## Квадратичное финансирование {#quadratic-funding} diff --git a/public/content/translations/ru/community/language-resources/index.md b/public/content/translations/ru/community/language-resources/index.md index cd59f0875a1..bdd13c751e9 100644 --- a/public/content/translations/ru/community/language-resources/index.md +++ b/public/content/translations/ru/community/language-resources/index.md @@ -72,7 +72,7 @@ lang: ru - [Gwei.cz](https://gwei.cz) — локальное сообщество на тему Web3, создает образовательный контент, организует очные и онлайн-мероприятия - [Gwei.cz Příručka](https://prirucka.gwei.cz/) — руководство по Ethereum для начинающих - [DAO Příručka](https://dao.gwei.cz/) — руководство для начинающих по DAO -- [Mastering Ethereum](https://ipfs.infura-ipfs.io/ipfs/bafybeidvuxhnsgfx3tncpfxheqglkjwmdxclknlgd7s7qggd2a6bzgb27m) — о тонкостях работы Ethereum на чешском языке +- [Mastering Ethereum](https://ipfs.io/ipfs/bafybeidvuxhnsgfx3tncpfxheqglkjwmdxclknlgd7s7qggd2a6bzgb27m) — о тонкостях работы Ethereum на чешском языке ### Французский {#fr} diff --git a/public/content/translations/ru/community/online/index.md b/public/content/translations/ru/community/online/index.md index 59daaa04008..5fb05c7d98f 100644 --- a/public/content/translations/ru/community/online/index.md +++ b/public/content/translations/ru/community/online/index.md @@ -24,10 +24,10 @@ lang: ru Ethereum Cat Herders — сообщество, нацеленное на помощь с управлением проектами при разработке Ethereum Ethereum Hackers — чат Discord, управляемый ETHGlobal: онлайн-сообщество для хакеров Ethereum со всего мира CryptoDevs — сообщество Discord, сконцентрированное на разработке Ethereum -Сообщество EthStaker на Discord — сообщество для образования, наставничества, поддержки и предоставления ресурсов для существующих и потенциальных стейкеров +Сообщество EthStaker на Discord — сообщество для образования, наставничества, поддержки и предоставления ресурсов для существующих и потенциальных стейкеров Команда сайта Ethereum.org — возможность решить проблемы и поговорить о разработке и дизайне ethereum.org с командой и членами сообщества Matos Discord — сообщество создателей Web3, где собираются разработчики, видные представители отрасли и энтузиасты Ethereum. Мы заинтересованы в разработке, дизайне и культуре Web3. Создавайте вместе с нами. -Solidity Gitter — чат для разработки Solidity (Gitter) +Solidity Gitter — чат для разработки Solidity (Gitter) Solidity Matrix — чат для разработки Solidity (Matrix) Ethereum Stack Exchange *— форум вопросов и ответов* Peeranha *— децентрализованный форум вопросов и ответов* diff --git a/public/content/translations/ru/community/research/index.md b/public/content/translations/ru/community/research/index.md index aa6914a9cbb..5fb2fab1cea 100644 --- a/public/content/translations/ru/community/research/index.md +++ b/public/content/translations/ru/community/research/index.md @@ -124,7 +124,7 @@ lang: ru - [Введение в блокчейн-мосты](/bridges/) - [Виталик о мостах](https://old.reddit.com/r/ethereum/comments/rwojtk/ama_we_are_the_efs_research_team_pt_7_07_january/hrngyk8/) - [Статья о блокчейн-мостах](https://medium.com/1kxnetwork/blockchain-bridges-5db6afac44f8) -- [Значения, заблокированные в мостах]() +- [Значения, заблокированные в мостах](https://dune.com/eliasimos/Bridge-Away-(from-Ethereum)) #### Новейшие исследования {#recent-research-3} @@ -156,7 +156,7 @@ lang: ru #### Новейшие исследования {#recent-research-5} -- [ecdsa в FGPA](https://ethresear.ch/t/does-ecdsa-on-fpga-solve-the-scaling-problem/6738) +- [ECDSA на основе программируемых пользователем вентильных матриц (FPGA)](https://ethresear.ch/t/does-ecdsa-on-fpga-solve-the-scaling-problem/6738) ## Безопасность {#security} @@ -346,7 +346,6 @@ lang: ru - [Фреймворки для разработчиков](/developers/docs/frameworks/) - [Список инструментов для разработчиков с использованием консенсуса](https://github.com/ConsenSys/ethereum-developer-tools-list) - [Стандарты токенов](/developers/docs/standards/tokens/) -- [Biastek: инструменты для Ethereum](https://biastek.com/ethereum-tools/) - [CryptoDevHub: инструменты для EVM](https://cryptodevhub.io/wiki/ethereum-virtual-machine-tools) #### Новейшие исследования {#recent-research-17} diff --git a/public/content/translations/ru/community/support/index.md b/public/content/translations/ru/community/support/index.md index 55433b8d926..5e0de3f54bd 100644 --- a/public/content/translations/ru/community/support/index.md +++ b/public/content/translations/ru/community/support/index.md @@ -39,7 +39,7 @@ _Это не полный список. Нужна помощь в поиске Этот процесс может быть сложным. Вот несколько ориентированных на разработку ресурсов с опытными разработчиками Ethereum, которые будут рады помочь. - [Университет Alchemy](https://university.alchemy.com/#starter_code) -- [CryptoDevs на платформе Discord](https://discord.gg/Z9TA39m8Yu) +- [CryptoDevs на платформе Discord](https://discord.com/invite/5W5tVb3) - [Ethereum StackExchange](https://ethereum.stackexchange.com/) - [StackOverflow](https://stackoverflow.com/questions/tagged/web3) - [Университет Web3](https://www.web3.university/) @@ -53,7 +53,7 @@ _Это не полный список. Нужна помощь в поиске Вот примеры нескольких популярных. -- [Solidity](https://gitter.im/ethereum/solidity) +- [Solidity](https://gitter.im/ethereum/solidity/) - [ethers.js](https://discord.gg/6jyGVDK6Jx) - [web3.js](https://discord.gg/GsABYQu4sC) - [Hardhat](https://discord.gg/xtrMGhmbfZ) @@ -65,7 +65,7 @@ _Это не полный список. Нужна помощь в поиске Если вы запускаете узел или валидатора, вот несколько сообществ, призванных помочь вам начать работу. -- [EthStaker на платформе Discord](https://discord.io/ethstaker) +- [EthStaker на платформе Discord](https://discord.gg/ethstaker) - [EthStaker на платформе Reddit](https://www.reddit.com/r/ethstaker) У большинства команд, разрабатывающих клиентов Ethereum, также есть специальные открытые площадки, где вы можете получить поддержку и задать вопросы. diff --git a/public/content/translations/ru/developers/docs/blocks/index.md b/public/content/translations/ru/developers/docs/blocks/index.md index b4556c44b50..336b353a754 100644 --- a/public/content/translations/ru/developers/docs/blocks/index.md +++ b/public/content/translations/ru/developers/docs/blocks/index.md @@ -1,6 +1,6 @@ --- title: Блоки -description: "Обзор блоков в блокчейне Ethereum: их структура данных, почему они необходимы и как сделаны." +description: 'Обзор блоков в блокчейне Ethereum: их структура данных, почему они необходимы и как сделаны.' lang: ru --- @@ -40,7 +40,7 @@ lang: ru В блоке содержится много разной информации. На самом высоком уровне блок содержит следующие поля: | Поле | Описание | -| :--------------- | :------------------------------------------------- | +|:---------------- |:-------------------------------------------------- | | `ячейка` | слот, к которому относится блок | | `proposer_index` | ID валидатора, который предлагает блок | | `parent_root` | хэш предыдущего блока | @@ -50,7 +50,7 @@ lang: ru Блок `body` содержит в себе несколько собственных полей: | Поле | Описание | -| :------------------- | :-------------------------------------------------------------- | +|:-------------------- |:--------------------------------------------------------------- | | `randao_reveal` | значение, используемое для выбора следующего предлагающего блок | | `eth1_data` | информация о депозитном контракте | | `граффити` | случайные данные, используемые для пометки блоков | @@ -65,7 +65,7 @@ lang: ru Поле `attestations` содержит список всех свидетельств в блоке. У свидетельств есть собственный тип данных, который содержит несколько частичек данных. Каждое свидетельство содержит следующее: | Поле | Описание | -| :----------------- | :-------------------------------------------------------- | +|:------------------ |:--------------------------------------------------------- | | `aggregation_bits` | список валидаторов, участвовавших в этом свидетельстве | | `данные` | контейнер с несколькими подполями | | `подпись` | агрегированная подпись всех свидетельствующих валидаторов | @@ -73,7 +73,7 @@ lang: ru Поле `data` в свидетельстве `attestation` содержит следующие данные: | Поле | Описание | -| :------------------ | :---------------------------------------------------------- | +|:------------------- |:----------------------------------------------------------- | | `ячейка` | слот, к которому относится свидетельство | | `index` | индексы свидетельствующих валидаторов | | `beacon_block_root` | корневой хэш блока Beacon, в котором содержится этот объект | @@ -85,7 +85,7 @@ lang: ru `execution_payload_header` содержит следующие поля: | Поле | Описание | -| :------------------ | :---------------------------------------------------------------------- | +|:------------------- |:----------------------------------------------------------------------- | | `parent_hash` | хэш родительского блока | | `fee_recipient` | адрес аккаунта для оплаты комиссий за транзакции | | `state_root` | корневой хэш глобального состояния после внесения изменений в этот блок | @@ -105,7 +105,7 @@ lang: ru Сама по себе проверочная строка `execution_payload` содержит следующие данные (заметьте, что она идентична заголовку, если не учитывать, что, в отличие корневого хэша транзакций, она включает текущий список транзакций и информации о выводах): | Поле | Описание | -| :------------------ | :---------------------------------------------------------------------- | +|:------------------- |:----------------------------------------------------------------------- | | `parent_hash` | хэш родительского блока | | `fee_recipient` | адрес аккаунта для оплаты комиссий за транзакции | | `state_root` | корневой хэш глобального состояния после внесения изменений в этот блок | @@ -125,7 +125,7 @@ lang: ru Список `withdrawals` содержит объекты вывода `withdrawal`, структурированные следующим образом: | Поле | Описание | -| :--------------- | :-------------------------------------------- | +|:---------------- |:--------------------------------------------- | | `address` | адрес аккаунта, с которого производится вывод | | `amount` | сумма вывода | | `index` | значение индекса вывода | diff --git a/public/content/translations/ru/developers/docs/evm/index.md b/public/content/translations/ru/developers/docs/evm/index.md index 6532ffc2f12..ab5ecf8dd52 100644 --- a/public/content/translations/ru/developers/docs/evm/index.md +++ b/public/content/translations/ru/developers/docs/evm/index.md @@ -10,7 +10,7 @@ lang: ru ## Прежде чем начать {#prerequisites} -Некоторые базовые знания в информатике, например термины [байт](https://wikipedia.org/wiki/Byte), [память](https://wikipedia.org/wiki/Computer_memory) и [стек](), необходимы для понимания работы EVM. Также было бы полезно ознакомиться с такими понятиями криптографии и блокчейна, как [хэш-функции](https://wikipedia.org/wiki/Cryptographic_hash_function) и [дерево Меркла](https://wikipedia.org/wiki/Merkle_tree). +Некоторые базовые знания в информатике, например термины [байт](https://wikipedia.org/wiki/Byte), [память](https://wikipedia.org/wiki/Computer_memory) и [стек](https://wikipedia.org/wiki/Stack_(abstract_data_type)), необходимы для понимания работы EVM. Также было бы полезно ознакомиться с такими понятиями криптографии и блокчейна, как [хэш-функции](https://wikipedia.org/wiki/Cryptographic_hash_function) и [дерево Меркла](https://wikipedia.org/wiki/Merkle_tree). ## От реестра к машине состояний {#from-ledger-to-state-machine} @@ -64,6 +64,7 @@ EVM работает как [стековая машина](https://wikipedia.or - [evmone](https://github.com/ethereum/evmone) — _C++_ - [ethereumjs-vm](https://github.com/ethereumjs/ethereumjs-vm) — _JavaScript_ - [eEVM](https://github.com/microsoft/eevm) — _C++_ +- [revm](https://github.com/bluealloy/revm) - _Rust_ ## Дополнительные ресурсы {#further-reading} diff --git a/public/content/translations/ru/developers/docs/evm/opcodes/index.md b/public/content/translations/ru/developers/docs/evm/opcodes/index.md index f71a5a63b99..363213979c7 100644 --- a/public/content/translations/ru/developers/docs/evm/opcodes/index.md +++ b/public/content/translations/ru/developers/docs/evm/opcodes/index.md @@ -14,157 +14,157 @@ lang: ru 💡 Небольшой совет: чтобы посмотреть строки целиком, используйте `[shift] + scroll` для горизонтальной прокрутки экрана. -| Стек | Имя | Газ | Исходный стек | Итоговый стек | Память/хранилище | Примечания | -| :---: | :------------- | :---------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------- | :------------------------------ | :---------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| 00 | STOP | 0 | | | | halt execution | -| 01 | ADD | 3 | `a, b` | `a + b` | | (u)int256 addition modulo 2\*\*256 | -| 02 | MUL | 5 | `a, b` | `a * b` | | (u)int256 multiplication modulo 2\*\*256 | -| 03 | SUB | 3 | `a, b` | `a - b` | | (u)int256 addition modulo 2\*\*256 | -| 04 | DIV | 5 | `a, b` | `a // b` | | uint256 division | -| 05 | SDIV | 5 | `a, b` | `a // b` | | int256 division | -| 06 | MOD | 5 | `a, b` | `a % b` | | uint256 modulus | -| 07 | SMOD | 5 | `a, b` | `a % b` | | int256 modulus | -| 08 | ADDMOD | 8 | `a, b, N` | `(a + b) % N` | | (u)int256 addition modulo N | -| 09 | MULMOD | 8 | `a, b, N` | `(a * b) % N` | | (u)int256 multiplication modulo N | -| 0A | EXP | [A1](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a1-exp) | `a, b` | `a ** b` | | uint256 exponentiation modulo 2\*\*256 | -| 0B | SIGNEXTEND | 5 | `b, x` | `SIGNEXTEND(x, b)` | | [sign extend](https://wikipedia.org/wiki/Sign_extension) `x` from `(b+1)` bytes to 32 bytes | -| 0C-0F | _invalid_ | | | | | | -| 10 | LT | 3 | `a, b` | `a < b` | | uint256 less-than | -| 11 | GT | 3 | `a, b` | `a > b` | | uint256 greater-than | -| 12 | SLT | 3 | `a, b` | `a < b` | | int256 less-than | -| 13 | SGT | 3 | `a, b` | `a > b` | | int256 greater-than | -| 14 | EQ | 3 | `a, b` | `a == b` | | (u)int256 equality | -| 15 | ISZERO | 3 | `a` | `a == 0` | | (u)int256 iszero | -| 16 | AND | 3 | `a, b` | `a && b` | | bitwise AND | -| 17 | OR | 3 | `a, b` | `a \|\| b` | | bitwise OR | -| 18 | XOR | 3 | `a, b` | `a ^ b` | | bitwise XOR | -| 19 | NOT | 3 | `a` | `~a` | | bitwise NOT | -| 1A | BYTE | 3 | `i, x` | `(x >> (248 - i * 8)) && 0xFF` | | `i`th byte of (u)int256 `x`, from the left | -| 1B | SHL | 3 | `shift, val` | `val << shift` | | shift left | -| 1C | SHR | 3 | `shift, val` | `val >> shift` | | logical shift right | -| 1D | SAR | 3 | `shift, val` | `val >> shift` | | arithmetic shift right | -| 1E-1F | _invalid_ | | | | | | -| 20 | KECCAK256 | [A2](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a2-sha3) | `ost, len` | `keccak256(mem[ost:ost+len-1])` | | keccak256 | -| 21-2F | _invalid_ | | | | | | -| 30 | ADDRESS | 2 | `.` | `address(this)` | | address of executing contract | -| 31 | BALANCE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `addr.balance` | | balance, in wei | -| 32 | ORIGIN | 2 | `.` | `tx.origin` | | address that originated the tx | -| 33 | CALLER | 2 | `.` | `msg.sender` | | address of msg sender | -| 34 | CALLVALUE | 2 | `.` | `msg.value` | | msg value, in wei | -| 35 | CALLDATALOAD | 3 | `idx` | `msg.data[idx:idx+32]` | | read word from msg data at index `idx` | -| 36 | CALLDATASIZE | 2 | `.` | `len(msg.data)` | | length of msg data, in bytes | -| 37 | CALLDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | copy msg data | -| 38 | CODESIZE | 2 | `.` | `len(this.code)` | | length of executing contract's code, in bytes | -| 39 | CODECOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | copy executing contract's bytecode | -| 3A | GASPRICE | 2 | `.` | `tx.gasprice` | | gas price of tx, in wei per unit gas [\*\*](https://eips.ethereum.org/EIPS/eip-1559#gasprice) | -| 3B | EXTCODESIZE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `len(addr.code)` | | size of code at addr, in bytes | -| 3C | EXTCODECOPY | [A4](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a4-extcodecopy) | `addr, dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | copy code from `addr` | -| 3D | RETURNDATASIZE | 2 | `.` | `size` | | size of returned data from last external call, in bytes | -| 3E | RETURNDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | copy returned data from last external call | -| 3F | EXTCODEHASH | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `хэш` | | hash = addr.exists ? keccak256(addr.code) : 0 | -| 40 | BLOCKHASH | 20 | `blockNum` | `blockHash(blockNum)` | | | -| 41 | COINBASE | 2 | `.` | `block.coinbase` | | address of miner of current block | -| 42 | TIMESTAMP | 2 | `.` | `block.timestamp` | | timestamp of current block | -| 43 | NUMBER | 2 | `.` | `block.number` | | number of current block | -| 44 | PREVRANDAO | 2 | `.` | `randomness beacon` | | randomness beacon | -| 45 | GASLIMIT | 2 | `.` | `block.gaslimit` | | gas limit of current block | -| 46 | CHAINID | 2 | `.` | `chain_id` | | push current [chain id](https://eips.ethereum.org/EIPS/eip-155) onto stack | -| 47 | SELFBALANCE | 5 | `.` | `address(this).balance` | | balance of executing contract, in wei | -| 48 | BASEFEE | 2 | `.` | `block.basefee` | | base fee of current block | -| 49-4F | _invalid_ | | | | | | -| 50 | POP | 2 | `_anon` | `.` | | remove item from top of stack and discard it | -| 51 | MLOAD | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost` | `mem[ost:ost+32]` | | read word from memory at offset `ost` | -| 52 | MSTORE | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost:ost+32] := val | write a word to memory | -| 53 | MSTORE8 | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost] := val && 0xFF | write a single byte to memory | -| 54 | SLOAD | [A6](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a6-sload) | `key` | `storage[key]` | | read word from storage | -| 55 | SSTORE | [A7](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a7-sstore) | `key, val` | `.` | storage[key] := val | write word to storage | -| 56 | JUMP | 8 | `dst` | `.` | | `$pc := dst` mark that `pc` is only assigned if `dst` is a valid jumpdest | -| 57 | JUMPI | 10 | `dst, condition` | `.` | | `$pc := condition ? dst : $pc + 1` | -| 58 | PC | 2 | `.` | `$pc` | | program counter | -| 59 | MSIZE | 2 | `.` | `len(mem)` | | size of memory in current execution context, in bytes | -| 5A | GAS | 2 | `.` | `gasRemaining` | | | -| 5B | JUMPDEST | 1 | | | mark valid jump destination | a valid jump destination for example a jump destination not inside the push data | -| 5C-5E | _invalid_ | | | | | | -| 5F | PUSH0 | 2 | `.` | `uint8` | | добавить постоянное значение 0 в стек | -| 60 | PUSH1 | 3 | `.` | `uint8` | | push 1-byte value onto stack | -| 61 | PUSH2 | 3 | `.` | `uint16` | | push 2-byte value onto stack | -| 62 | PUSH3 | 3 | `.` | `uint24` | | push 3-byte value onto stack | -| 63 | PUSH4 | 3 | `.` | `uint32` | | push 4-byte value onto stack | -| 64 | PUSH5 | 3 | `.` | `uint40` | | push 5-byte value onto stack | -| 65 | PUSH6 | 3 | `.` | `uint48` | | push 6-byte value onto stack | -| 66 | PUSH7 | 3 | `.` | `uint56` | | push 7-byte value onto stack | -| 67 | PUSH8 | 3 | `.` | `uint64` | | push 8-byte value onto stack | -| 68 | PUSH9 | 3 | `.` | `uint72` | | push 9-byte value onto stack | -| 69 | PUSH10 | 3 | `.` | `uint80` | | push 10-byte value onto stack | -| 6A | PUSH11 | 3 | `.` | `uint88` | | push 11-byte value onto stack | -| 6B | PUSH12 | 3 | `.` | `uint96` | | push 12-byte value onto stack | -| 6C | PUSH13 | 3 | `.` | `uint104` | | push 13-byte value onto stack | -| 6D | PUSH14 | 3 | `.` | `uint112` | | push 14-byte value onto stack | -| 6E | PUSH15 | 3 | `.` | `uint120` | | push 15-byte value onto stack | -| 6F | PUSH16 | 3 | `.` | `uint128` | | push 16-byte value onto stack | -| 70 | PUSH17 | 3 | `.` | `uint136` | | push 17-byte value onto stack | -| 71 | PUSH18 | 3 | `.` | `uint144` | | push 18-byte value onto stack | -| 72 | PUSH19 | 3 | `.` | `uint152` | | push 19-byte value onto stack | -| 73 | PUSH20 | 3 | `.` | `uint160` | | push 20-byte value onto stack | -| 74 | PUSH21 | 3 | `.` | `uint168` | | push 21-byte value onto stack | -| 75 | PUSH22 | 3 | `.` | `uint176` | | push 22-byte value onto stack | -| 76 | PUSH23 | 3 | `.` | `uint184` | | push 23-byte value onto stack | -| 77 | PUSH24 | 3 | `.` | `uint192` | | push 24-byte value onto stack | -| 78 | PUSH25 | 3 | `.` | `uint200` | | push 25-byte value onto stack | -| 79 | PUSH26 | 3 | `.` | `uint208` | | push 26-byte value onto stack | -| 7A | PUSH27 | 3 | `.` | `uint216` | | push 27-byte value onto stack | -| 7B | PUSH28 | 3 | `.` | `uint224` | | push 28-byte value onto stack | -| 7C | PUSH29 | 3 | `.` | `uint232` | | push 29-byte value onto stack | -| 7D | PUSH30 | 3 | `.` | `uint240` | | push 30-byte value onto stack | -| 7E | PUSH31 | 3 | `.` | `uint248` | | push 31-byte value onto stack | -| 7F | PUSH32 | 3 | `.` | `uint256` | | push 32-byte value onto stack | -| 80 | DUP1 | 3 | `a` | `a, a` | | clone 1st value on stack | -| 81 | DUP2 | 3 | `_, a` | `a, _, a` | | clone 2nd value on stack | -| 82 | DUP3 | 3 | `_, _, a` | `a, _, _, a` | | clone 3rd value on stack | -| 83 | DUP4 | 3 | `_, _, _, a` | `a, _, _, _, a` | | clone 4th value on stack | -| 84 | DUP5 | 3 | `..., a` | `a, ..., a` | | clone 5th value on stack | -| 85 | DUP6 | 3 | `..., a` | `a, ..., a` | | clone 6th value on stack | -| 86 | DUP7 | 3 | `..., a` | `a, ..., a` | | clone 7th value on stack | -| 87 | DUP8 | 3 | `..., a` | `a, ..., a` | | clone 8th value on stack | -| 88 | DUP9 | 3 | `..., a` | `a, ..., a` | | clone 9th value on stack | -| 89 | DUP10 | 3 | `..., a` | `a, ..., a` | | clone 10th value on stack | -| 8A | DUP11 | 3 | `..., a` | `a, ..., a` | | clone 11th value on stack | -| 8B | DUP12 | 3 | `..., a` | `a, ..., a` | | clone 12th value on stack | -| 8C | DUP13 | 3 | `..., a` | `a, ..., a` | | clone 13th value on stack | -| 8D | DUP14 | 3 | `..., a` | `a, ..., a` | | clone 14th value on stack | -| 8E | DUP15 | 3 | `..., a` | `a, ..., a` | | clone 15th value on stack | -| 8F | DUP16 | 3 | `..., a` | `a, ..., a` | | clone 16th value on stack | -| 90 | SWAP1 | 3 | `a, b` | `b, a` | | | -| 91 | SWAP2 | 3 | `a, _, b` | `b, _, a` | | | -| 92 | SWAP3 | 3 | `a, _, _, b` | `b, _, _, a` | | | -| 93 | SWAP4 | 3 | `a, _, _, _, b` | `b, _, _, _, a` | | | -| 94 | SWAP5 | 3 | `a, ..., b` | `b, ..., a` | | | -| 95 | SWAP6 | 3 | `a, ..., b` | `b, ..., a` | | | -| 96 | SWAP7 | 3 | `a, ..., b` | `b, ..., a` | | | -| 97 | SWAP8 | 3 | `a, ..., b` | `b, ..., a` | | | -| 98 | SWAP9 | 3 | `a, ..., b` | `b, ..., a` | | | -| 99 | SWAP10 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9A | SWAP11 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9B | SWAP12 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9C | SWAP13 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9D | SWAP14 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9E | SWAP15 | 3 | `a, ..., b` | `b, ..., a` | | | -| 9F | SWAP16 | 3 | `a, ..., b` | `b, ..., a` | | | -| A0 | LOG0 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len` | `.` | | LOG0(memory[ost:ost+len-1]) | -| A1 | LOG1 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0` | `.` | | LOG1(memory[ost:ost+len-1], topic0) | -| A2 | LOG2 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1) | -| A3 | LOG3 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2) | -| A4 | LOG4 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2, topic3` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2, topic3) | -| A5-EF | _invalid_ | | | | | | -| F0 | CREATE | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len` | `addr` | | addr = keccak256(rlp([address(this), this.nonce])) | -| F1 | CALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | gas, addr, val, argOst, argLen, retOst, retLen | `success` | mem[retOst:retOst+retLen-1] := returndata | | -| F2 | CALLCODE | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, val, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] = returndata | same as DELEGATECALL, but does not propagate original msg.sender and msg.value | -| F3 | RETURN | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | return mem[ost:ost+len-1] | -| F4 | DELEGATECALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | -| F5 | CREATE2 | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len, salt` | `addr` | | addr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] | -| F6-F9 | _invalid_ | | | | | | -| FA | STATICCALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | -| FB-FC | _invalid_ | | | | | | -| FD | REVERT | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | revert(mem[ost:ost+len-1]) | -| FE | INVALID | [AF](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#af-invalid) | | | designated invalid opcode - [EIP-141](https://eips.ethereum.org/EIPS/eip-141) | | -| FF | SELFDESTRUCT | [AB](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#ab-selfdestruct) | `addr` | `.` | | | destroy contract and sends all funds to `addr` | +| Стек | Имя | Газ | Исходный стек | Итоговый стек | Память/хранилище | Примечания | +|:-----:|:-------------- |:-----------------------------------------------------------------------------------------------:|:------------------------------------------------ |:-------------------------------------------- |:----------------------------------------------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 00 | STOP | 0 | | | | halt execution | +| 01 | ADD | 3 | `a, b` | `a + b` | | (u)int256 addition modulo 2\*\*256 | +| 02 | MUL | 5 | `a, b` | `a * b` | | (u)int256 multiplication modulo 2\*\*256 | +| 03 | SUB | 3 | `a, b` | `a - b` | | (u)int256 addition modulo 2\*\*256 | +| 04 | DIV | 5 | `a, b` | `a // b` | | uint256 division | +| 05 | SDIV | 5 | `a, b` | `a // b` | | int256 division | +| 06 | MOD | 5 | `a, b` | `a % b` | | uint256 modulus | +| 07 | SMOD | 5 | `a, b` | `a % b` | | int256 modulus | +| 08 | ADDMOD | 8 | `a, b, N` | `(a + b) % N` | | (u)int256 addition modulo N | +| 09 | MULMOD | 8 | `a, b, N` | `(a * b) % N` | | (u)int256 multiplication modulo N | +| 0A | EXP | [A1](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a1-exp) | `a, b` | `a ** b` | | uint256 exponentiation modulo 2\*\*256 | +| 0B | SIGNEXTEND | 5 | `b, x` | `SIGNEXTEND(x, b)` | | [sign extend](https://wikipedia.org/wiki/Sign_extension) `x` from `(b+1)` bytes to 32 bytes | +| 0C-0F | _invalid_ | | | | | | +| 10 | LT | 3 | `a, b` | `a < b` | | uint256 less-than | +| 11 | GT | 3 | `a, b` | `a > b` | | uint256 greater-than | +| 12 | SLT | 3 | `a, b` | `a < b` | | int256 less-than | +| 13 | SGT | 3 | `a, b` | `a > b` | | int256 greater-than | +| 14 | EQ | 3 | `a, b` | `a == b` | | (u)int256 equality | +| 15 | ISZERO | 3 | `a` | `a == 0` | | (u)int256 iszero | +| 16 | AND | 3 | `a, b` | `a && b` | | bitwise AND | +| 17 | OR | 3 | `a, b` | `a \|\| b` | | bitwise OR | +| 18 | XOR | 3 | `a, b` | `a ^ b` | | bitwise XOR | +| 19 | NOT | 3 | `a` | `~a` | | bitwise NOT | +| 1A | BYTE | 3 | `i, x` | `(x >> (248 - i * 8)) && 0xFF` | | `i`th byte of (u)int256 `x`, from the left | +| 1B | SHL | 3 | `shift, val` | `val << shift` | | shift left | +| 1C | SHR | 3 | `shift, val` | `val >> shift` | | logical shift right | +| 1D | SAR | 3 | `shift, val` | `val >> shift` | | arithmetic shift right | +| 1E-1F | _invalid_ | | | | | | +| 20 | KECCAK256 | [A2](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a2-sha3) | `ost, len` | `keccak256(mem[ost:ost+len-1])` | | keccak256 | +| 21-2F | _invalid_ | | | | | | +| 30 | ADDRESS | 2 | `.` | `address(this)` | | address of executing contract | +| 31 | BALANCE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `addr.balance` | | balance, in wei | +| 32 | ORIGIN | 2 | `.` | `tx.origin` | | address that originated the tx | +| 33 | CALLER | 2 | `.` | `msg.sender` | | address of msg sender | +| 34 | CALLVALUE | 2 | `.` | `msg.value` | | msg value, in wei | +| 35 | CALLDATALOAD | 3 | `idx` | `msg.data[idx:idx+32]` | | read word from msg data at index `idx` | +| 36 | CALLDATASIZE | 2 | `.` | `len(msg.data)` | | length of msg data, in bytes | +| 37 | CALLDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | copy msg data | +| 38 | CODESIZE | 2 | `.` | `len(this.code)` | | length of executing contract's code, in bytes | +| 39 | CODECOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | copy executing contract's bytecode | +| 3A | GASPRICE | 2 | `.` | `tx.gasprice` | | gas price of tx, in wei per unit gas [\*\*](https://eips.ethereum.org/EIPS/eip-1559#gasprice) | +| 3B | EXTCODESIZE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `len(addr.code)` | | size of code at addr, in bytes | +| 3C | EXTCODECOPY | [A4](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a4-extcodecopy) | `addr, dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | copy code from `addr` | +| 3D | RETURNDATASIZE | 2 | `.` | `size` | | size of returned data from last external call, in bytes | +| 3E | RETURNDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | copy returned data from last external call | +| 3F | EXTCODEHASH | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `хэш` | | hash = addr.exists ? keccak256(addr.code) : 0 | +| 40 | BLOCKHASH | 20 | `blockNum` | `blockHash(blockNum)` | | | +| 41 | COINBASE | 2 | `.` | `block.coinbase` | | address of miner of current block | +| 42 | TIMESTAMP | 2 | `.` | `block.timestamp` | | timestamp of current block | +| 43 | NUMBER | 2 | `.` | `block.number` | | number of current block | +| 44 | PREVRANDAO | 2 | `.` | `randomness beacon` | | randomness beacon | +| 45 | GASLIMIT | 2 | `.` | `block.gaslimit` | | gas limit of current block | +| 46 | CHAINID | 2 | `.` | `chain_id` | | push current [chain id](https://eips.ethereum.org/EIPS/eip-155) onto stack | +| 47 | SELFBALANCE | 5 | `.` | `address(this).balance` | | balance of executing contract, in wei | +| 48 | BASEFEE | 2 | `.` | `block.basefee` | | base fee of current block | +| 49-4F | _invalid_ | | | | | | +| 50 | POP | 2 | `_anon` | `.` | | remove item from top of stack and discard it | +| 51 | MLOAD | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost` | `mem[ost:ost+32]` | | read word from memory at offset `ost` | +| 52 | MSTORE | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost:ost+32] := val | write a word to memory | +| 53 | MSTORE8 | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost] := val && 0xFF | write a single byte to memory | +| 54 | SLOAD | [A6](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a6-sload) | `key` | `storage[key]` | | read word from storage | +| 55 | SSTORE | [A7](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a7-sstore) | `key, val` | `.` | storage[key] := val | write word to storage | +| 56 | JUMP | 8 | `dst` | `.` | | `$pc := dst` mark that `pc` is only assigned if `dst` is a valid jumpdest | +| 57 | JUMPI | 10 | `dst, condition` | `.` | | `$pc := condition ? dst : $pc + 1` | +| 58 | PC | 2 | `.` | `$pc` | | program counter | +| 59 | MSIZE | 2 | `.` | `len(mem)` | | size of memory in current execution context, in bytes | +| 5A | GAS | 2 | `.` | `gasRemaining` | | | +| 5B | JUMPDEST | 1 | | | mark valid jump destination | a valid jump destination for example a jump destination not inside the push data | +| 5C-5E | _invalid_ | | | | | | +| 5F | PUSH0 | 2 | `.` | `uint8` | | добавить постоянное значение 0 в стек | +| 60 | PUSH1 | 3 | `.` | `uint8` | | push 1-byte value onto stack | +| 61 | PUSH2 | 3 | `.` | `uint16` | | push 2-byte value onto stack | +| 62 | PUSH3 | 3 | `.` | `uint24` | | push 3-byte value onto stack | +| 63 | PUSH4 | 3 | `.` | `uint32` | | push 4-byte value onto stack | +| 64 | PUSH5 | 3 | `.` | `uint40` | | push 5-byte value onto stack | +| 65 | PUSH6 | 3 | `.` | `uint48` | | push 6-byte value onto stack | +| 66 | PUSH7 | 3 | `.` | `uint56` | | push 7-byte value onto stack | +| 67 | PUSH8 | 3 | `.` | `uint64` | | push 8-byte value onto stack | +| 68 | PUSH9 | 3 | `.` | `uint72` | | push 9-byte value onto stack | +| 69 | PUSH10 | 3 | `.` | `uint80` | | push 10-byte value onto stack | +| 6A | PUSH11 | 3 | `.` | `uint88` | | push 11-byte value onto stack | +| 6B | PUSH12 | 3 | `.` | `uint96` | | push 12-byte value onto stack | +| 6C | PUSH13 | 3 | `.` | `uint104` | | push 13-byte value onto stack | +| 6D | PUSH14 | 3 | `.` | `uint112` | | push 14-byte value onto stack | +| 6E | PUSH15 | 3 | `.` | `uint120` | | push 15-byte value onto stack | +| 6F | PUSH16 | 3 | `.` | `uint128` | | push 16-byte value onto stack | +| 70 | PUSH17 | 3 | `.` | `uint136` | | push 17-byte value onto stack | +| 71 | PUSH18 | 3 | `.` | `uint144` | | push 18-byte value onto stack | +| 72 | PUSH19 | 3 | `.` | `uint152` | | push 19-byte value onto stack | +| 73 | PUSH20 | 3 | `.` | `uint160` | | push 20-byte value onto stack | +| 74 | PUSH21 | 3 | `.` | `uint168` | | push 21-byte value onto stack | +| 75 | PUSH22 | 3 | `.` | `uint176` | | push 22-byte value onto stack | +| 76 | PUSH23 | 3 | `.` | `uint184` | | push 23-byte value onto stack | +| 77 | PUSH24 | 3 | `.` | `uint192` | | push 24-byte value onto stack | +| 78 | PUSH25 | 3 | `.` | `uint200` | | push 25-byte value onto stack | +| 79 | PUSH26 | 3 | `.` | `uint208` | | push 26-byte value onto stack | +| 7A | PUSH27 | 3 | `.` | `uint216` | | push 27-byte value onto stack | +| 7B | PUSH28 | 3 | `.` | `uint224` | | push 28-byte value onto stack | +| 7C | PUSH29 | 3 | `.` | `uint232` | | push 29-byte value onto stack | +| 7D | PUSH30 | 3 | `.` | `uint240` | | push 30-byte value onto stack | +| 7E | PUSH31 | 3 | `.` | `uint248` | | push 31-byte value onto stack | +| 7F | PUSH32 | 3 | `.` | `uint256` | | push 32-byte value onto stack | +| 80 | DUP1 | 3 | `a` | `a, a` | | clone 1st value on stack | +| 81 | DUP2 | 3 | `_, a` | `a, _, a` | | clone 2nd value on stack | +| 82 | DUP3 | 3 | `_, _, a` | `a, _, _, a` | | clone 3rd value on stack | +| 83 | DUP4 | 3 | `_, _, _, a` | `a, _, _, _, a` | | clone 4th value on stack | +| 84 | DUP5 | 3 | `..., a` | `a, ..., a` | | clone 5th value on stack | +| 85 | DUP6 | 3 | `..., a` | `a, ..., a` | | clone 6th value on stack | +| 86 | DUP7 | 3 | `..., a` | `a, ..., a` | | clone 7th value on stack | +| 87 | DUP8 | 3 | `..., a` | `a, ..., a` | | clone 8th value on stack | +| 88 | DUP9 | 3 | `..., a` | `a, ..., a` | | clone 9th value on stack | +| 89 | DUP10 | 3 | `..., a` | `a, ..., a` | | clone 10th value on stack | +| 8A | DUP11 | 3 | `..., a` | `a, ..., a` | | clone 11th value on stack | +| 8B | DUP12 | 3 | `..., a` | `a, ..., a` | | clone 12th value on stack | +| 8C | DUP13 | 3 | `..., a` | `a, ..., a` | | clone 13th value on stack | +| 8D | DUP14 | 3 | `..., a` | `a, ..., a` | | clone 14th value on stack | +| 8E | DUP15 | 3 | `..., a` | `a, ..., a` | | clone 15th value on stack | +| 8F | DUP16 | 3 | `..., a` | `a, ..., a` | | clone 16th value on stack | +| 90 | SWAP1 | 3 | `a, b` | `b, a` | | | +| 91 | SWAP2 | 3 | `a, _, b` | `b, _, a` | | | +| 92 | SWAP3 | 3 | `a, _, _, b` | `b, _, _, a` | | | +| 93 | SWAP4 | 3 | `a, _, _, _, b` | `b, _, _, _, a` | | | +| 94 | SWAP5 | 3 | `a, ..., b` | `b, ..., a` | | | +| 95 | SWAP6 | 3 | `a, ..., b` | `b, ..., a` | | | +| 96 | SWAP7 | 3 | `a, ..., b` | `b, ..., a` | | | +| 97 | SWAP8 | 3 | `a, ..., b` | `b, ..., a` | | | +| 98 | SWAP9 | 3 | `a, ..., b` | `b, ..., a` | | | +| 99 | SWAP10 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9A | SWAP11 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9B | SWAP12 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9C | SWAP13 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9D | SWAP14 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9E | SWAP15 | 3 | `a, ..., b` | `b, ..., a` | | | +| 9F | SWAP16 | 3 | `a, ..., b` | `b, ..., a` | | | +| A0 | LOG0 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len` | `.` | | LOG0(memory[ost:ost+len-1]) | +| A1 | LOG1 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0` | `.` | | LOG1(memory[ost:ost+len-1], topic0) | +| A2 | LOG2 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1) | +| A3 | LOG3 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2) | +| A4 | LOG4 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2, topic3` | `.` | | LOG1(memory[ost:ost+len-1], topic0, topic1, topic2, topic3) | +| A5-EF | _invalid_ | | | | | | +| F0 | CREATE | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len` | `addr` | | addr = keccak256(rlp([address(this), this.nonce])) | +| F1 | CALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | gas, addr, val, argOst, argLen, retOst, retLen | `success` | mem[retOst:retOst+retLen-1] := returndata | | +| F2 | CALLCODE | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, val, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] = returndata | same as DELEGATECALL, but does not propagate original msg.sender and msg.value | +| F3 | RETURN | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | return mem[ost:ost+len-1] | +| F4 | DELEGATECALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | +| F5 | CREATE2 | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len, salt` | `addr` | | addr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] | +| F6-F9 | _invalid_ | | | | | | +| FA | STATICCALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | +| FB-FC | _invalid_ | | | | | | +| FD | REVERT | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | revert(mem[ost:ost+len-1]) | +| FE | INVALID | [AF](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#af-invalid) | | | designated invalid opcode - [EIP-141](https://eips.ethereum.org/EIPS/eip-141) | | +| FF | SELFDESTRUCT | [AB](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#ab-selfdestruct) | `addr` | `.` | | | destroy contract and sends all funds to `addr` | diff --git a/public/content/translations/ru/developers/docs/gas/index.md b/public/content/translations/ru/developers/docs/gas/index.md index c0ef820186d..4c1aeaad058 100644 --- a/public/content/translations/ru/developers/docs/gas/index.md +++ b/public/content/translations/ru/developers/docs/gas/index.md @@ -55,7 +55,7 @@ lang: ru Базовая комиссия рассчитывается по формуле, которая сравнивает размер предыдущего блока (количество газа, использованного для всех транзакций) с целевым размером. Базовая комиссия увеличится максимум на 12,5 % за блок, если размер целевого блока превышен. Этот экспоненциальный рост делает экономически нецелесообразным, чтобы размер блока оставался высоким на неопределенный срок. | Номер блока | Включенный газ | Увеличение комиссии | Текущая базовая комиссия | -| ----------- | -------------: | ------------------: | -----------------------: | +| ----------- | --------------:| -------------------:| ------------------------:| | 1 | 15 млн | 0 % | 100 gwei | | 2 | 30 млн | 0 % | 100 gwei | | 3 | 30 млн | 12,5 % | 112,5 gwei | @@ -70,7 +70,7 @@ lang: ru Также важно отметить, что сильные всплески серий полных блоков маловероятны из-за скорости, с которой базовая комиссия увеличивается перед полным блоком. | Номер блока | Включенный газ | Увеличение комиссии | Текущая базовая комиссия | -| ----------- | -------------: | ------------------: | -----------------------: | +| ----------- | --------------:| -------------------:| ------------------------:| | 30 | 30 млн | 12,5 % | 2705,6 gwei | | ... | ... | 12,5 % | ... | | 50 | 30 млн | 12,5 % | 28531,3 gwei | diff --git a/public/content/translations/ru/developers/docs/networks/index.md b/public/content/translations/ru/developers/docs/networks/index.md index 3aa643e2e57..bad5b4e680d 100644 --- a/public/content/translations/ru/developers/docs/networks/index.md +++ b/public/content/translations/ru/developers/docs/networks/index.md @@ -56,10 +56,11 @@ lang: ru - [Кран QuickNode Sepolia](https://faucet.quicknode.com/drip) - [Grabteeth](https://grabteeth.xyz/) - [Кран PoW](https://sepolia-faucet.pk910.de/) -- [Кран кошелька Coinbase Wallet | Sepolia](https://coinbase.com/faucets/ethereum-sepolia-faucet) +- [Кран кошелька Coinbase | Sepolia](https://coinbase.com/faucets/ethereum-sepolia-faucet) - [Кран Alchemy Sepolia](https://sepoliafaucet.com/) - [Кран Infura Sepolia](https://www.infura.io/faucet) - [Кран Chainstack Sepolia](https://faucet.chainstack.com/sepolia-faucet) +- [Кран тестовой сети | Sepolia](https://testnet-faucet.com/sepolia/) #### Goerli _(долгосрочная поддержка)_ {#goerli} @@ -111,28 +112,36 @@ Goerli — тестовая сеть для проверки валидации - [Кран Paradigm](https://faucet.paradigm.xyz/) - [Кран Coinbase Wallet | Optimism Goerli](https://coinbase.com/faucets/optimism-goerli-faucet) +#### Starknet Goerli {#starknet-goerli} + +Тестовая сеть для [Starknet](https://www.starknet.io). + +##### Краны + +- [Кран Starknet](https://faucet.goerli.starknet.io) + ## Частные сети {#private-networks} -Сеть Ethereum представляет собой частную сеть, если ее узлы не подключены к публичной сети (т. е. к основной или тестовой сети). В этом контексте «частная» означает только «зарезервированная» или «изолированная», а не «защищенная» или «безопасная». +Сеть Ethereum представляет собой частную сеть, если ее узлы не подключены к общедоступной сети (т. е. к основной или тестовой сети). В этом контексте «частная» означает только «зарезервированная» или «изолированная», а не «защищенная» или «безопасная». ### Сети разработки {#development-networks} -Чтобы разработать приложение Ethereum, вам нужно запустить его в частной сети и увидеть, как оно работает, прежде чем развертывать. Подобно тому, как вы создаете локальный сервер на своем компьютере для веб-разработки, вы можете создать локальный экземпляр блокчейна для тестирования своего децентрализованного приложения. Это позволяет выполнять итерацию намного быстрее, чем в публичной тестовой сети. +При разработке приложения Ethereum вам нужно запустить его в частной сети и увидеть, как оно работает, прежде чем развертывать. Подобно тому, как вы создаете локальный сервер на своем компьютере для веб-разработки, вы можете создать локальный экземпляр блокчейна для тестирования своего децентрализованного приложения. Это позволяет повторять итерации намного быстрее, чем в общедоступной тестовой сети. -Существуют проекты и инструменты, которые могут помочь в этом. Подробнее о [сетях для разработки](/developers/docs/development-networks/). +Существуют проекты и инструменты, которые могут помочь в этом. Узнайте больше о [сетях для разработки](/developers/docs/development-networks/). ### Сети консорциума {#consortium-networks} -Процесс консенсуса контролируется заранее определенным набором узлов, которым доверяют. Например, частная сеть известных академических учреждений, каждое из которых управляет одним узлом, а блоки проверяются пороговым числом подписантов внутри сети. +Процесс консенсуса контролируется заранее определенным набором доверенных узлов. Например, частная сеть известных академических учреждений, каждое из которых управляет одним узлом, а блоки проверяются пороговым числом подписантов внутри сети. -Если общедоступная сеть Ethereum похожа на общедоступный Интернет, то сеть консорциума похожа на частный интранет. +Если общедоступная сеть Ethereum похожа на общедоступный интернет, то сеть консорциума похожа на частный интранет. ## Связанные инструменты {#related-tools} -- [Chainlist](https://chainlist.org/) — _список сетей EVM для подключения кошельков и поставщиков к соответствующему ID цепочки и ID сети_ -- [Цепочки на основе EVM](https://github.com/ethereum-lists/chains) — _репозиторий GitHub с метаданными цепочки, на которых основан Chainlist_ +- [Chainlist](https://chainlist.org/) — _список сетей EVM для подключения кошельков и поставщиков услуг к соответствующим идентификаторам цепочки и сети._ +- [Цепочки на основе EVM](https://github.com/ethereum-lists/chains) — _репозиторий GitHub с метаданными цепочки, на которых основан Chainlist._ ## Дополнительные ресурсы {#further-reading} -- [Предложение: предсказуемый жизненный цикл тестовых Ethereum](https://ethereum-magicians.org/t/proposal-predictable-ethereum-testnet-lifecycle/11575/17) +- [Предложение: предсказуемый жизненный цикл тестовых сетей Ethereum](https://ethereum-magicians.org/t/proposal-predictable-ethereum-testnet-lifecycle/11575/17) - [Эволюция тестовых сетей Ethereum](https://etherworld.co/2022/08/19/the-evolution-of-ethereum-testnet/) diff --git a/public/content/translations/ru/developers/docs/transactions/index.md b/public/content/translations/ru/developers/docs/transactions/index.md index e2bbd6d470d..ebfc54e4a8f 100644 --- a/public/content/translations/ru/developers/docs/transactions/index.md +++ b/public/content/translations/ru/developers/docs/transactions/index.md @@ -1,6 +1,6 @@ --- title: Транзакции -description: "Обзор транзакций Ethereum: как они работают, их структура данных и как их отправлять через приложение." +description: 'Обзор транзакций Ethereum: как они работают, их структура данных и как их отправлять через приложение.' lang: ru --- diff --git a/public/content/translations/ru/guides/how-to-create-an-ethereum-account/index.md b/public/content/translations/ru/guides/how-to-create-an-ethereum-account/index.md index 1d5b1f97fe8..1c9747c0943 100644 --- a/public/content/translations/ru/guides/how-to-create-an-ethereum-account/index.md +++ b/public/content/translations/ru/guides/how-to-create-an-ethereum-account/index.md @@ -20,7 +20,7 @@ lang: ru Если вы новичок, то можете выбрать фильтр «Новичок в криптовалютах» на странице «найти кошелек», чтобы определить кошельки, которые должны включать все необходимые функции, подходящие для начинающих. -![выбор фильтра на странице «найти кошелек»](./wallet-box.png) +![Выбор фильтра на странице поиска кошелька](./wallet-box.png) Существуют также другие фильтры профиля, позволяющие учесть ваши потребности. Это примеры часто используемых кошельков. Вам нужно самостоятельно изучить ситуацию, прежде чем доверять какому-либо программному обеспечению. diff --git a/public/content/translations/ru/guides/how-to-swap-tokens/index.md b/public/content/translations/ru/guides/how-to-swap-tokens/index.md index 53eb4c759d2..a01ca0220e0 100644 --- a/public/content/translations/ru/guides/how-to-swap-tokens/index.md +++ b/public/content/translations/ru/guides/how-to-swap-tokens/index.md @@ -12,12 +12,12 @@ lang: ru **Необходимо соблюдать следующие предварительные условия:** -- иметь криптовалютный кошелек. Вы можете ознакомиться с этим руководством: [Как зарегистрировать учетную запись Ethereum](/guides/how-to-register-an-ethereum-account/); +- иметь криптовалютный кошелек (вы можете воспользоваться следующим руководством: [Как зарегистрировать учетную запись Ethereum](/guides/how-to-create-an-ethereum-account/)); - добавить средства на свой кошелек. ## 1. Подключите свой кошелек к децентрализованной бирже (DEX) по выбору -Вот некоторые популярные биржи. +Вот некоторые популярные биржи: - [Uniswap](https://app.uniswap.org/#/swap) - [Sushiswap](https://www.sushi.com/swap) diff --git a/public/content/translations/ru/guides/how-to-use-a-bridge/index.md b/public/content/translations/ru/guides/how-to-use-a-bridge/index.md index 5617eee7e04..5c07132896e 100644 --- a/public/content/translations/ru/guides/how-to-use-a-bridge/index.md +++ b/public/content/translations/ru/guides/how-to-use-a-bridge/index.md @@ -10,7 +10,7 @@ lang: ru **Необходимо соблюдать следующие предварительные условия:** -- иметь криптовалютный кошелек. Вы можете ознакомиться с этим руководством: [Как зарегистрировать учетную запись Ethereum](/guides/how-to-register-an-ethereum-account/); +- иметь криптовалютный кошелек (вы можете воспользоваться следующим руководством: [Как зарегистрировать учетную запись Ethereum](/guides/how-to-create-an-ethereum-account/)); - добавить средства на свой кошелек. ## 1. Определите, какую сеть второго уровня вы хотите использовать diff --git a/public/content/translations/ru/guides/how-to-use-a-wallet/index.md b/public/content/translations/ru/guides/how-to-use-a-wallet/index.md index 46fc7f43bb1..1ab60e11a47 100644 --- a/public/content/translations/ru/guides/how-to-use-a-wallet/index.md +++ b/public/content/translations/ru/guides/how-to-use-a-wallet/index.md @@ -51,7 +51,7 @@ lang: ru 1. Посетите сайт любого проекта. 2. Если целевая страница проекта является просто его статичным описанием, у вас должна быть возможность нажать кнопку «Открыть приложение» (Open the App) в меню, после чего вы перейдете к соответствующему веб-приложению. -3. После того как вы зайдете в приложение, нажмите кнопку «Подключиться» (Connect). +3. Войдя в приложение, нажмите кнопку Connect (Подключиться). ![Кнопка, позволяющая пользователю подключаться к сайту с помощью кошелька](./connect1.png) diff --git a/public/dapps/skiff.png b/public/dapps/skiff.png deleted file mode 100644 index 0adada597f7..00000000000 Binary files a/public/dapps/skiff.png and /dev/null differ diff --git a/public/layer-2/base.png b/public/layer-2/base.png new file mode 100644 index 00000000000..8293da7a78f Binary files /dev/null and b/public/layer-2/base.png differ diff --git a/public/layer-2/growthepie.png b/public/layer-2/growthepie.png new file mode 100644 index 00000000000..39f5291602e Binary files /dev/null and b/public/layer-2/growthepie.png differ diff --git a/public/wallets/aurox.png b/public/wallets/aurox.png new file mode 100644 index 00000000000..4caeaadc529 Binary files /dev/null and b/public/wallets/aurox.png differ diff --git a/src/components/BannerGrid/index.tsx b/src/components/BannerGrid/index.tsx index 31dcdf3886f..5e2adb460ee 100644 --- a/src/components/BannerGrid/index.tsx +++ b/src/components/BannerGrid/index.tsx @@ -1,11 +1,9 @@ import React from "react" import { Box, Flex, Grid, useToken } from "@chakra-ui/react" -export type Props = { - children: React.ReactNode -} +import { ChildOnlyProp } from "@/lib/types" -export const Banner: React.FC = ({ children }) => { +export const Banner = ({ children }: ChildOnlyProp) => { return ( = ({ children }) => { ) } -export const BannerBody: React.FC = ({ children }) => { +export const BannerBody = ({ children }: ChildOnlyProp) => { return ( {children} @@ -34,7 +32,7 @@ export const BannerBody: React.FC = ({ children }) => { ) } -export const BannerImage: React.FC = ({ children }) => { +export const BannerImage = ({ children }: ChildOnlyProp) => { return ( {children} @@ -42,7 +40,7 @@ export const BannerImage: React.FC = ({ children }) => { ) } -export const BannerGrid: React.FC = ({ children }) => { +export const BannerGrid = ({ children }: ChildOnlyProp) => { return ( = ({ children }) => { ) } -export const BannerGridCell: React.FC = ({ children }) => { +export const BannerGridCell = ({ children }: ChildOnlyProp) => { const [medBp, lgBp] = useToken("breakpoints", ["md", "lg"]) return ( diff --git a/src/components/BannerNotification/index.tsx b/src/components/BannerNotification/index.tsx index 550599796de..70f0e14ac3d 100644 --- a/src/components/BannerNotification/index.tsx +++ b/src/components/BannerNotification/index.tsx @@ -3,15 +3,15 @@ import { Center, FlexProps, useMediaQuery } from "@chakra-ui/react" import { lightTheme as oldTheme } from "../../theme" -export interface IProps extends FlexProps { +export type BannerNotificationProps = FlexProps & { shouldShow?: boolean } -const BannerNotification: React.FC = ({ +const BannerNotification = ({ children, shouldShow = false, ...props -}) => { +}: BannerNotificationProps) => { const [isLGScreen] = useMediaQuery(`min-width: ${oldTheme.breakpoints.l}`) return ( <> diff --git a/src/components/Banners/BugBountyBanner.tsx b/src/components/Banners/BugBountyBanner.tsx index ddc7019c457..46ce6703bcf 100644 --- a/src/components/Banners/BugBountyBanner.tsx +++ b/src/components/Banners/BugBountyBanner.tsx @@ -5,7 +5,7 @@ import { Center, Text } from "@chakra-ui/react" // Components import BannerNotification from "../BannerNotification" -const BugBountyBanner: React.FC = () => ( +const BugBountyBanner = () => (
      diff --git a/src/components/Banners/DismissableBanner.tsx b/src/components/Banners/DismissableBanner.tsx index 5b49f94d425..748c83fdc7e 100644 --- a/src/components/Banners/DismissableBanner.tsx +++ b/src/components/Banners/DismissableBanner.tsx @@ -6,12 +6,15 @@ import { Center, CloseButton } from "@chakra-ui/react" import BannerNotification from "../BannerNotification" // Interface -export interface IProps { +export type DismissableBannerProps = { children: JSX.Element storageKey: string } -const DismissableBanner: React.FC = ({ children, storageKey }) => { +const DismissableBanner = ({ + children, + storageKey, +}: DismissableBannerProps) => { const [show, setShow] = useState(false) useEffect(() => { diff --git a/src/components/Banners/PostMergeBanner.tsx b/src/components/Banners/PostMergeBanner.tsx index 2d79778e466..3184c52e3f5 100644 --- a/src/components/Banners/PostMergeBanner.tsx +++ b/src/components/Banners/PostMergeBanner.tsx @@ -6,11 +6,11 @@ import type { TranslationKey } from "@/lib/types" import BannerNotification from "../BannerNotification" import Translation from "../Translation" -export interface IProps { +export type PostMergeBannerProps = { translationString: TranslationKey } -const PostMergeBanner: React.FC = ({ translationString }) => ( +const PostMergeBanner = ({ translationString }: PostMergeBannerProps) => ( = ({ children }) => ( +const H3 = ({ children }: ChildOnlyProp) => ( = ({ children }) => ( ) -const BeaconChainActions: React.FC = () => { +const BeaconChainActions = () => { const { t } = useTranslation(["page-upgrades-index", "page-upgrades"]) const datapoints: CardListItem[] = [ diff --git a/src/components/BoxGrid.tsx b/src/components/BoxGrid.tsx index 9e65187403b..b39a3a1617f 100644 --- a/src/components/BoxGrid.tsx +++ b/src/components/BoxGrid.tsx @@ -7,15 +7,15 @@ import Emoji from "./Emoji" import OldHeading from "./OldHeading" import Text from "./OldText" -export interface IBoxItem { +export interface BoxItem { emoji: string title: string description: string matomo: MatomoEventOptions } -export interface IProps { - items: Array +export type BoxGridProps = { + items: Array } // Represent string as 32-bit integer @@ -40,7 +40,7 @@ const colors = [ "gridPurple", ] -const BoxGrid: React.FC = ({ items }) => { +const BoxGrid = ({ items }: BoxGridProps) => { const [indexOpen, setOpenIndex] = useState(0) return ( diff --git a/src/components/ButtonDropdown.tsx b/src/components/ButtonDropdown.tsx index fe9dada13df..49b2859b5bc 100644 --- a/src/components/ButtonDropdown.tsx +++ b/src/components/ButtonDropdown.tsx @@ -33,11 +33,11 @@ export interface List { items: Array } -export interface IProps extends ButtonProps { +export type ButtonDropdownProps = ButtonProps & { list: List } -const ButtonDropdown: React.FC = ({ list, ...rest }) => { +const ButtonDropdown = ({ list, ...rest }: ButtonDropdownProps) => { const { t } = useTranslation("common") const handleClick = ( e: MouseEvent, diff --git a/src/components/CallToContribute.tsx b/src/components/CallToContribute.tsx index 8f1ac96448f..821c8b40920 100644 --- a/src/components/CallToContribute.tsx +++ b/src/components/CallToContribute.tsx @@ -2,20 +2,18 @@ import React, { ReactNode } from "react" import { FaGithub } from "react-icons/fa" import { Flex, FlexProps, Icon, useToken } from "@chakra-ui/react" +import { ChildOnlyProp } from "@/lib/types" + import { ButtonLink } from "./Buttons" import InlineLink from "./Link" import OldHeading from "./OldHeading" import Text from "./OldText" import Translation from "./Translation" -export interface IProps { +export type CallToContributeProps = { editPath: string } -export type ChildOnlyType = { - children: ReactNode -} - const ContentColumn = (props: { children: ReactNode hideBelow?: FlexProps["hideBelow"] @@ -32,13 +30,13 @@ const ContentColumn = (props: { /> ) -const DescriptionParagraph = ({ children }: ChildOnlyType) => ( +const DescriptionParagraph = ({ children }: ChildOnlyProp) => ( {children} ) -const CallToContribute: React.FC = ({ editPath }) => { +const CallToContribute = ({ editPath }: CallToContributeProps) => { /** * TODO: After completion of the UI migration, * Remove this and pass the token value directly diff --git a/src/components/Callout.tsx b/src/components/Callout.tsx index 376e10cf8a9..821767ce052 100644 --- a/src/components/Callout.tsx +++ b/src/components/Callout.tsx @@ -8,7 +8,7 @@ import { Image, type ImageProps } from "@/components/Image" import OldHeading from "@/components/OldHeading" import Text from "@/components/OldText" -export interface IProps extends FlexProps { +export type CalloutProps = FlexProps & { children?: React.ReactNode image?: ImageProps["src"] emoji?: string @@ -18,7 +18,7 @@ export interface IProps extends FlexProps { className?: string } -const Callout: React.FC = ({ +const Callout = ({ image, emoji, alt, @@ -27,7 +27,7 @@ const Callout: React.FC = ({ children, className, ...rest -}) => { +}: CalloutProps) => { const { t } = useTranslation("common") return ( diff --git a/src/components/Card/Card.stories.tsx b/src/components/Card/Card.stories.tsx index 270f8ae0cf7..5adf8532429 100644 --- a/src/components/Card/Card.stories.tsx +++ b/src/components/Card/Card.stories.tsx @@ -4,7 +4,7 @@ import { Meta, StoryFn } from "@storybook/react" import { Button } from "@/components/Buttons" -import Card, { IProps } from "." +import Card, { CardProps } from "." export default { component: Card, @@ -20,7 +20,7 @@ export default { export const Default: StoryFn = (args) => { const { t } = useTranslation("page-developers-index") - const defaultProps: IProps = { + const defaultProps: CardProps = { emoji: ":woman_student:", title: t("page-developers-learn"), description: t("page-developers-learn-desc"), diff --git a/src/components/Card/index.tsx b/src/components/Card/index.tsx index d693f966371..513abf5a8b8 100644 --- a/src/components/Card/index.tsx +++ b/src/components/Card/index.tsx @@ -3,20 +3,14 @@ import { Heading, Stack, StackProps, Text } from "@chakra-ui/react" import Emoji from "@/components/Emoji" -export interface IProps extends Omit { +export type CardProps = Omit & { children?: ReactNode emoji?: string title?: ReactNode description?: ReactNode } -const Card: React.FC = ({ - emoji, - title, - description, - children, - ...props -}) => ( +const Card = ({ emoji, title, description, children, ...props }: CardProps) => ( { diff --git a/src/components/Codeblock.tsx b/src/components/Codeblock.tsx index 2bf02c780c4..0ba46da941d 100644 --- a/src/components/Codeblock.tsx +++ b/src/components/Codeblock.tsx @@ -204,19 +204,19 @@ const getValidChildrenForCodeblock = (child) => { } } -export interface IProps { +export type CodeblockProps = { allowCollapse?: boolean codeLanguage: string fromHomepage?: boolean children: React.ReactNode } -const Codeblock: React.FC = ({ +const Codeblock = ({ children, allowCollapse = true, codeLanguage, fromHomepage = false, -}) => { +}: CodeblockProps) => { const { t } = useTranslation("common") const selectedTheme = useColorModeValue(codeTheme.light, codeTheme.dark) diff --git a/src/components/CopyToClipboard.tsx b/src/components/CopyToClipboard.tsx index 74da841a4cc..9aa4c41ee60 100644 --- a/src/components/CopyToClipboard.tsx +++ b/src/components/CopyToClipboard.tsx @@ -2,17 +2,17 @@ import { useEffect, useRef, useState } from "react" import ClipboardJS from "clipboard" import { Box } from "@chakra-ui/react" -export interface IProps { +export type CopyToClipboardProps = { text: string inline?: boolean children: (isCopied: boolean) => React.ReactNode } -const CopyToClipboard: React.FC = ({ +const CopyToClipboard = ({ children, text, inline = false, -}) => { +}: CopyToClipboardProps) => { const [isCopied, setIsCopied] = useState(false) const targetEl = useRef(null) const timer = useRef(0) diff --git a/src/components/DataProductCard.tsx b/src/components/DataProductCard.tsx index c40e1c71222..2582ef5f704 100644 --- a/src/components/DataProductCard.tsx +++ b/src/components/DataProductCard.tsx @@ -19,7 +19,7 @@ export interface DataRow { apy: string } -export interface IProps { +export type DataProductCardProps = { url: string background: string image: StaticImageData @@ -30,7 +30,7 @@ export interface IProps { data?: Array } -const DataProductCard: React.FC = ({ +const DataProductCard = ({ url, background, image, @@ -39,7 +39,7 @@ const DataProductCard: React.FC = ({ name, description, data, -}) => { +}: DataProductCardProps) => { const boxShadow = useColorModeValue("tableBox.light", "tableBox.dark") return ( diff --git a/src/components/DeveloperDocsLinks.tsx b/src/components/DeveloperDocsLinks.tsx index 2640d65faea..43dbe08852d 100644 --- a/src/components/DeveloperDocsLinks.tsx +++ b/src/components/DeveloperDocsLinks.tsx @@ -6,11 +6,11 @@ import Translation from "@/components/Translation" import docLinks from "@/data/developer-docs-links.yaml" -export interface IProps { +export type DeveloperDocsLinksProps = { headerId: string } -const DeveloperDocsLinks: React.FC = ({ headerId }) => ( +const DeveloperDocsLinks = ({ headerId }: DeveloperDocsLinksProps) => ( {docLinks .filter(({ id }) => id.includes(headerId)) diff --git a/src/components/DocLink.tsx b/src/components/DocLink.tsx index 26939d5973c..7036fd133e0 100644 --- a/src/components/DocLink.tsx +++ b/src/components/DocLink.tsx @@ -14,13 +14,13 @@ import Text from "./OldText" import { useRtlFlip } from "@/hooks/useRtlFlip" -export interface IProps { +export type DocLinkProps = { children?: React.ReactNode to: string isExternal?: boolean } -const DocLink: React.FC = ({ to, children, isExternal = false }) => { +const DocLink = ({ to, children, isExternal = false }: DocLinkProps) => { const linkBoxShadowColor = useToken("colors", "primary.base") const { flipForRtl } = useRtlFlip() diff --git a/src/components/DocsNav.tsx b/src/components/DocsNav.tsx index 87d98113990..bdd11c5d1af 100644 --- a/src/components/DocsNav.tsx +++ b/src/components/DocsNav.tsx @@ -22,7 +22,7 @@ import docLinks from "@/data/developer-docs-links.yaml" import { useRtlFlip } from "@/hooks/useRtlFlip" -const TextDiv: React.FC = ({ children, ...props }) => ( +const TextDiv = ({ children, ...props }: FlexProps) => ( { // Find index that matches current page let currentIndex = 0 for (let i = 0; i < docsArray.length; i++) { - if (asPath.indexOf(docsArray[i].to) > -1) { + if ( + asPath.indexOf(docsArray[i].to) >= 0 && + asPath.length === docsArray[i].to.length + ) { currentIndex = i } } // Extract previous and next doc based on current index +/- 1 - const previousDoc = currentIndex - 1 > 0 ? docsArray[currentIndex - 1] : null + const previousDoc = currentIndex - 1 >= 0 ? docsArray[currentIndex - 1] : null const nextDoc = currentIndex + 1 < docsArray.length ? docsArray[currentIndex + 1] : null diff --git a/src/components/EnergyConsumptionChart.tsx b/src/components/EnergyConsumptionChart.tsx index 0f9cb70799c..e1c6ce2606c 100644 --- a/src/components/EnergyConsumptionChart.tsx +++ b/src/components/EnergyConsumptionChart.tsx @@ -23,7 +23,7 @@ import type { Lang } from "@/lib/types" import { isLangRightToLeft } from "@/lib/utils/translations" -interface ITickProps { +type CustomTickProps = { x: number y: number payload: { value: number | string } @@ -55,7 +55,7 @@ const RechartText = chakra(Text, { }, }) -const CustomTick: React.FC = ({ x, y, payload }) => { +const CustomTick = ({ x, y, payload }: CustomTickProps) => { return ( = ({ x, y, payload }) => { ) } -const EnergyConsumptionChart: React.FC = () => { +const EnergyConsumptionChart = () => { const { t } = useTranslation("page-what-is-ethereum") const textColor = useToken("colors", "text") const { locale } = useRouter() diff --git a/src/components/EnvWarningBanner.tsx b/src/components/EnvWarningBanner.tsx index 73e1a8d8d56..6a67d95fb3b 100644 --- a/src/components/EnvWarningBanner.tsx +++ b/src/components/EnvWarningBanner.tsx @@ -4,7 +4,7 @@ import { FlexProps } from "@chakra-ui/react" import InfoBanner from "./InfoBanner" import Translation from "./Translation" -const EnvWarningBanner: React.FC = ({ ...flexProps }) => ( +const EnvWarningBanner = ({ ...flexProps }: FlexProps) => ( diff --git a/src/components/EventCard.tsx b/src/components/EventCard.tsx index 470485afa7b..a40c430b54b 100644 --- a/src/components/EventCard.tsx +++ b/src/components/EventCard.tsx @@ -12,7 +12,7 @@ const clearStyles = { clear: "both", } -export interface IProps { +export type EventCardProps = { title: string to: string date: string @@ -22,7 +22,7 @@ export interface IProps { isEven: boolean } -const EventCard: React.FC = ({ +const EventCard = ({ title, to, date, @@ -30,7 +30,7 @@ const EventCard: React.FC = ({ className, location, isEven, -}) => ( +}: EventCardProps) => ( { + const { t } = useTranslation("common") const size = "3rem" return ( - ) : ( + {/* Body: */} + {feedbackSubmitted && ( <> - - + {t("feedback-widget-thank-you-timing")} + )} - + + + {feedbackSubmitted ? ( + + ) : ( + <> + + + + )} + + diff --git a/src/components/FileContributors.tsx b/src/components/FileContributors.tsx index 9bd17cc5554..0d6dff23f33 100644 --- a/src/components/FileContributors.tsx +++ b/src/components/FileContributors.tsx @@ -69,7 +69,7 @@ const Contributor = ({ contributor }: { contributor: Author }) => { ) } -export interface FileContributorsProps extends FlexProps { +export type FileContributorsProps = FlexProps & { editPath?: string contributors: Author[] loading: boolean @@ -77,13 +77,13 @@ export interface FileContributorsProps extends FlexProps { lastEdit: string } -const FileContributors: React.FC = ({ +const FileContributors = ({ contributors, loading, error, lastEdit, ...props -}) => { +}: FileContributorsProps) => { const [isModalOpen, setModalOpen] = useState(false) const { locale } = useRouter() diff --git a/src/components/FindWallet/WalletFilterSidebar/WalletFilterFeature/index.tsx b/src/components/FindWallet/WalletFilterSidebar/WalletFilterFeature/index.tsx index 6c51919ac65..605b7824e2b 100644 --- a/src/components/FindWallet/WalletFilterSidebar/WalletFilterFeature/index.tsx +++ b/src/components/FindWallet/WalletFilterSidebar/WalletFilterFeature/index.tsx @@ -45,17 +45,17 @@ const FilterToggle = ({ ) -export interface WalletFilterFeatureProps { +export type WalletFilterFeatureProps = { resetWalletFilter: MutableRefObject<() => void> filters: Record updateFilterOption: (key: any) => void updateFilterOptions: (key: any, value: any) => void } -const WalletFilterFeature: React.FC = ({ +const WalletFilterFeature = ({ updateFilterOption, ...restProps -}) => { +}: WalletFilterFeatureProps) => { const { filterOptions, setShowOptions } = useWalletFilterFeature(restProps) const filterPanelBg = useColorModeValue("chakra-subtle-bg", "black400") diff --git a/src/components/FindWallet/WalletFilterSidebar/index.tsx b/src/components/FindWallet/WalletFilterSidebar/index.tsx index 19d679a7d33..e8498091512 100644 --- a/src/components/FindWallet/WalletFilterSidebar/index.tsx +++ b/src/components/FindWallet/WalletFilterSidebar/index.tsx @@ -49,7 +49,7 @@ const FilterTab = ({ /> ) -interface WalletFilterSidebarProps extends Omit { +type WalletFilterSidebarProps = Omit & { filters: FiltersType resetWalletFilter: React.MutableRefObject<() => void> resetFilters: () => void @@ -60,7 +60,7 @@ interface WalletFilterSidebarProps extends Omit { updateFilterOptions: (keys: any, value: any) => void } -const WalletFilterSidebar: React.FC = ({ +const WalletFilterSidebar = ({ filters, resetWalletFilter, resetFilters, @@ -71,7 +71,7 @@ const WalletFilterSidebar: React.FC = ({ updateFilterOptions, top, ...tabsProps -}) => { +}: WalletFilterSidebarProps) => { const theme = useTheme() const { t } = useTranslation("page-wallets-find-wallet") diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 25904b46cb1..0dd81c711dd 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -50,11 +50,11 @@ export interface LinkSection { }> } -export interface IProps { +export type FooterProps = { lastDeployDate: string } -const Footer: React.FC = ({ lastDeployDate }) => { +const Footer = ({ lastDeployDate }: FooterProps) => { const { locale } = useRouter() const { t } = useTranslation("common") diff --git a/src/components/GhostCard.tsx b/src/components/GhostCard.tsx index a425993acb0..2104fd14d13 100644 --- a/src/components/GhostCard.tsx +++ b/src/components/GhostCard.tsx @@ -1,12 +1,10 @@ import React from "react" import { Box, BoxProps } from "@chakra-ui/react" -export interface IProps extends BoxProps { - className?: string -} +export type GhostCardProps = BoxProps -const GhostCard: React.FC = ({ children, className, ...rest }) => ( - +const GhostCard = ({ children, ...rest }: GhostCardProps) => ( + = ({ +const GitHubContributors = ({ relativePath, lastUpdatedDate, -}) => { +}: GitHubContributors) => { const state = useClientSideGitHubContributors(relativePath) return ( diff --git a/src/components/Glossary/GlossaryDefinition/index.tsx b/src/components/Glossary/GlossaryDefinition/index.tsx index 3cfb10ce68e..757a3cf76d6 100644 --- a/src/components/Glossary/GlossaryDefinition/index.tsx +++ b/src/components/Glossary/GlossaryDefinition/index.tsx @@ -3,12 +3,12 @@ import { Box, Text } from "@chakra-ui/react" import OldHeading from "@/components/OldHeading" import Translation from "@/components/Translation" -interface IProps { +interface GlossaryDefinitionProps { term: string size?: "md" | "sm" } -const GlossaryDefinition: React.FC = ({ term, size = "md" }) => { +const GlossaryDefinition = ({ term, size = "md" }: GlossaryDefinitionProps) => { const headingStyles = size === "sm" ? { fontSize: "md", mt: 0, mb: 2 } diff --git a/src/components/Glossary/GlossaryTooltip/index.tsx b/src/components/Glossary/GlossaryTooltip/index.tsx index dd42d634243..52cfb4a8ede 100644 --- a/src/components/Glossary/GlossaryTooltip/index.tsx +++ b/src/components/Glossary/GlossaryTooltip/index.tsx @@ -4,12 +4,12 @@ import { Text, useBreakpointValue } from "@chakra-ui/react" import GlossaryDefinition from "@/components/Glossary/GlossaryDefinition" import Tooltip from "@/components/Tooltip" -interface IProps { +type GlossaryTooltipProps = { children: ReactNode termKey: string } -const GlossaryTooltip: React.FC = ({ children, termKey }) => { +const GlossaryTooltip = ({ children, termKey }: GlossaryTooltipProps) => { const isLargeScreen = useBreakpointValue({ base: false, lg: true }) return isLargeScreen ? ( diff --git a/src/components/History/NetworkUpgradeSummary.tsx b/src/components/History/NetworkUpgradeSummary.tsx index ca56118da8f..cfd95209f3f 100644 --- a/src/components/History/NetworkUpgradeSummary.tsx +++ b/src/components/History/NetworkUpgradeSummary.tsx @@ -11,11 +11,11 @@ import NetworkUpgradeSummaryData from "../../data/NetworkUpgradeSummaryData" import Emoji from "../Emoji" import InlineLink from "../Link" -interface IProps { +type NetworkUpgradeSummaryProps = { name: string } -const NetworkUpgradeSummary: React.FC = ({ name }) => { +const NetworkUpgradeSummary = ({ name }: NetworkUpgradeSummaryProps) => { const [formattedUTC, setFormattedUTC] = useState("") const { locale } = useRouter() const localeForStatsBoxNumbers = getLocaleForNumberFormat(locale as Lang) @@ -48,11 +48,11 @@ const NetworkUpgradeSummary: React.FC = ({ name }) => { const blockTypeTranslation = (translationKey, explorerUrl, number) => { return ( - + {t(translationKey)}:{" "} - {new Intl.NumberFormat(localeForStatsBoxNumbers).format(number)} + {new Intl.NumberFormat(localeForStatsBoxNumbers).format(number)} ) diff --git a/src/components/HorizontalCard.tsx b/src/components/HorizontalCard.tsx index ffec58e3039..bfef6a30485 100644 --- a/src/components/HorizontalCard.tsx +++ b/src/components/HorizontalCard.tsx @@ -4,21 +4,21 @@ import { Box, Flex, FlexProps } from "@chakra-ui/react" import Emoji from "./Emoji" import Text from "./OldText" -export interface IProps extends Omit { +export type HorizontalCardProps = Omit & { emoji: string title?: ReactNode description: ReactNode emojiSize?: number } -const HorizontalCard: React.FC = ({ +const HorizontalCard = ({ emoji, title, description, children, emojiSize, ...rest -}) => ( +}: HorizontalCardProps) => ( diff --git a/src/components/LanguagePicker/MenuItem.tsx b/src/components/LanguagePicker/MenuItem.tsx new file mode 100644 index 00000000000..e1ec58213e3 --- /dev/null +++ b/src/components/LanguagePicker/MenuItem.tsx @@ -0,0 +1,133 @@ +import { useRouter } from "next/router" +import { useTranslation } from "next-i18next" +import { BsCheck } from "react-icons/bs" +import { + Badge, + Box, + Flex, + forwardRef, + Icon, + MenuItem as ChakraMenuItem, + type MenuItemProps as ChakraMenuItemProps, + Text, +} from "@chakra-ui/react" + +import type { LocaleDisplayInfo } from "@/lib/types" + +import { BaseLink } from "@/components/Link" + +import ProgressBar from "./ProgressBar" + +type ItemProps = ChakraMenuItemProps & { + displayInfo: LocaleDisplayInfo +} + +const MenuItem = forwardRef(({ displayInfo, ...props }: ItemProps, ref) => { + const { + localeOption, + sourceName, + targetName, + approvalProgress, + wordsApproved, + isBrowserDefault, + } = displayInfo + const { t } = useTranslation("page-languages") + const { asPath, locale } = useRouter() + const isCurrent = localeOption === locale + + const getProgressInfo = (approvalProgress: number, wordsApproved: number) => { + const percentage = new Intl.NumberFormat(locale!, { + style: "percent", + }).format(approvalProgress / 100) + const progress = + approvalProgress === 0 ? "<" + percentage.replace("0", "1") : percentage + const words = new Intl.NumberFormat(locale!).format(wordsApproved) + return { progress, words } + } + + const { progress, words } = getProgressInfo(approvalProgress, wordsApproved) + + return ( + { + e.target.scrollIntoView({ block: "nearest" }) + }} + scrollMarginY="8" + _hover={{ + bg: "primary.lowContrast", + textDecoration: "none", + "p.language-name": { color: "primary.base" }, + }} + _focus={{ bg: "primary.lowContrast" }} + sx={{ + p: { + textDecoration: "none", + overflow: "hidden", + textOverflow: "ellipsis", + whiteSpace: "nowrap", + }, + }} + href={asPath} + locale={localeOption} + {...props} + > + + + + + {targetName} + + {isBrowserDefault && ( + + {t("page-languages-browser-default")} + + )} + + + {sourceName} + + + {isCurrent && ( + + )} + + + {progress} {t("page-languages-translated")} • {words}{" "} + {t("page-languages-words")} + + + + ) +}) + +export default MenuItem diff --git a/src/components/LanguagePicker/NoResultsCallout.tsx b/src/components/LanguagePicker/NoResultsCallout.tsx new file mode 100644 index 00000000000..e45916839de --- /dev/null +++ b/src/components/LanguagePicker/NoResultsCallout.tsx @@ -0,0 +1,33 @@ +import { useTranslation } from "next-i18next" +import { FormHelperText, forwardRef, Text } from "@chakra-ui/react" + +import { BaseLink } from "@/components/Link" + +import MenuItem from "./MenuItem" + +type NoResultsCalloutProps = { onClose: () => void } + +const NoResultsCallout = forwardRef( + ({ onClose }: NoResultsCalloutProps, ref) => { + const { t } = useTranslation("page-languages") + return ( + + + {t("page-languages-want-more-header")} + + {t("page-languages-want-more-paragraph")}{" "} + + {t("page-languages-want-more-link")} + + + ) + } +) + +export default NoResultsCallout diff --git a/src/components/LanguagePicker/ProgressBar.tsx b/src/components/LanguagePicker/ProgressBar.tsx new file mode 100644 index 00000000000..06bb008923f --- /dev/null +++ b/src/components/LanguagePicker/ProgressBar.tsx @@ -0,0 +1,19 @@ +import { Progress, ProgressProps } from "@chakra-ui/react" + +type ProgressBarProps = Pick + +const ProgressBar = ({ value }: ProgressBarProps) => ( + +) + +export default ProgressBar diff --git a/src/components/LanguagePicker/index.tsx b/src/components/LanguagePicker/index.tsx new file mode 100644 index 00000000000..367d9a488be --- /dev/null +++ b/src/components/LanguagePicker/index.tsx @@ -0,0 +1,226 @@ +import { + Box, + Flex, + FormControl, + FormLabel, + Input, + InputGroup, + InputRightElement, + Kbd, + Menu, + MenuList, + type MenuListProps, + type MenuProps, + Text, + type UseDisclosureReturn, + useEventListener, +} from "@chakra-ui/react" + +import { Button } from "@/components/Buttons" +import { BaseLink } from "@/components/Link" + +import MenuItem from "./MenuItem" +import NoResultsCallout from "./NoResultsCallout" +import { useLanguagePicker } from "./useLanguagePicker" + +type LanguagePickerProps = Omit & { + children: React.ReactNode + placement?: MenuProps["placement"] + handleClose?: () => void + menuState?: UseDisclosureReturn +} + +const LanguagePicker = ({ + children, + placement, + handleClose, + menuState, + ...props +}: LanguagePickerProps) => { + const { t, refs, disclosure, filterValue, setFilterValue, filteredNames } = + useLanguagePicker(handleClose, menuState) + const { inputRef, firstItemRef, noResultsRef, footerRef } = refs + const { onClose } = disclosure + + /** + * Adds a keydown event listener to focus filter input (\). + * @param {string} event - The keydown event. + */ + useEventListener("keydown", (e) => { + if (e.key !== "\\") return + e.preventDefault() + inputRef.current?.focus() + }) + + return ( + + {children} + { + if (e.key === "Tab" || e.key === "\\") { + e.preventDefault() + ;(e.shiftKey ? inputRef : footerRef).current?.focus() + } + }} + {...props} + > + {/* Mobile Close bar */} + + + + + {/* Main Language selection menu */} + + + + {t("page-languages-filter-label")}{" "} + + ({filteredNames.length} {t("common:languages")}) + + + + setFilterValue(e.target.value)} + onBlur={(e) => { + if (e.relatedTarget?.tagName.toLowerCase() === "div") { + e.currentTarget.focus() + } + }} + ref={inputRef} + h="8" + mt="1" + mb="2" + bg="background.base" + color="body.base" + onKeyDown={(e) => { + // Navigate to first result on enter + if (e.key === "Enter") { + e.preventDefault() + firstItemRef.current?.click() + } + // If Tab/ArrowDown, focus on first item if available, NoResults link otherwise + if (e.key === "Tab" || e.key === "ArrowDown") { + e.preventDefault() + ;(filteredNames.length === 0 + ? noResultsRef + : firstItemRef + ).current?.focus() + e.stopPropagation() + } + }} + /> + + + \ + + + + + {filteredNames.map((displayInfo, index) => ( + { + if (e.key !== "\\") return + e.preventDefault() + inputRef.current?.focus() + }} + onClick={() => + onClose({ + eventAction: "Locale chosen", + eventName: displayInfo.localeOption, + }) + } + /> + ))} + + {filteredNames.length === 0 && ( + + onClose({ + eventAction: "Translation program link (no results)", + eventName: "/contributing/translation-program", + }) + } + /> + )} + + + + {/* Footer callout */} + + + {t("page-languages-recruit-community")}{" "} + + onClose({ + eventAction: "Translation program link (menu footer)", + eventName: "/contributing/translation-program", + }) + } + > + {t("common:learn-more")} + + + + + + ) +} + +export default LanguagePicker diff --git a/src/components/LanguagePicker/useLanguagePicker.tsx b/src/components/LanguagePicker/useLanguagePicker.tsx new file mode 100644 index 00000000000..c5336e5d55e --- /dev/null +++ b/src/components/LanguagePicker/useLanguagePicker.tsx @@ -0,0 +1,191 @@ +import { useEffect, useRef, useState } from "react" +import { useRouter } from "next/router" +import { useTranslation } from "next-i18next" +import { useDisclosure, type UseDisclosureReturn } from "@chakra-ui/react" + +import type { + I18nLocale, + Lang, + LocaleDisplayInfo, + ProjectProgressData, +} from "@/lib/types" + +import { MatomoEventOptions, trackCustomEvent } from "@/lib/utils/matomo" +import { languages } from "@/lib/utils/translations" + +import progressDataJson from "@/data/translationProgress.json" + +import { DEFAULT_LOCALE } from "@/lib/constants" + +const progressData = progressDataJson satisfies ProjectProgressData[] + +export const useLanguagePicker = ( + handleClose?: () => void, + menuState?: UseDisclosureReturn +) => { + const { t } = useTranslation("page-languages") + const { locale, locales } = useRouter() + const refs = { + inputRef: useRef(null), + firstItemRef: useRef(null), + noResultsRef: useRef(null), + footerRef: useRef(null), + } + const [filterValue, setFilterValue] = useState("") + + const [filteredNames, setFilteredNames] = useState([]) + + // perform all the filtering and mapping when the filter value change + useEffect(() => { + // Get the preferred languages for the users browser + const navLangs = typeof navigator !== "undefined" ? navigator.languages : [] + + // For each browser preference, reduce to the most specific match found in `locales` array + const allBrowserLocales: Lang[] = navLangs + .map( + (navLang) => + locales?.reduce((acc, cur) => { + if (cur.toLowerCase() === navLang.toLowerCase()) return cur + if ( + navLang.toLowerCase().startsWith(cur.toLowerCase()) && + acc !== navLang + ) + return cur + return acc + }, "") as Lang + ) + .filter((i) => !!i) // Remove those without matches + + // Remove duplicate matches + const browserLocales = Array.from(new Set(allBrowserLocales)) + + const localeToDisplayInfo = (localeOption: Lang): LocaleDisplayInfo => { + const i18nItem: I18nLocale = languages[localeOption] + const englishName = i18nItem.name + + // Get "source" display name (Language choice displayed in language of current locale) + const intlSource = new Intl.DisplayNames([locale!], { + type: "language", + }).of(localeOption) + // For languages that do not have an Intl display name, use English name as fallback + const fallbackSource = + intlSource !== localeOption ? intlSource : englishName + const i18nKey = "language-" + localeOption.toLowerCase() + const i18nSource = t(i18nKey) + const sourceName = i18nSource === i18nKey ? fallbackSource : i18nSource + + // Get "target" display name (Language choice displayed in that language) + const fallbackTarget = new Intl.DisplayNames([localeOption], { + type: "language", + }).of(localeOption) + const i18nConfigTarget = i18nItem.localName + const targetName = i18nConfigTarget || fallbackTarget + + if (!sourceName || !targetName) { + throw new Error( + "Missing language display name, locale: " + localeOption + ) + } + + // English will not have a dataItem + const dataItem = progressData.find( + ({ languageId }) => + i18nItem.crowdinCode.toLowerCase() === languageId.toLowerCase() + ) + + const approvalProgress = + localeOption === DEFAULT_LOCALE + ? 100 + : Math.floor( + (dataItem!.words.approved / dataItem!.words.total) * 100 + ) || 0 + + if (progressData.length === 0) + throw new Error( + "Missing translation progress data; check GitHub action" + ) + + const totalWords = progressData[0].words.total + + const wordsApproved = + localeOption === DEFAULT_LOCALE + ? totalWords || 0 + : dataItem?.words.approved || 0 + + const isBrowserDefault = browserLocales.includes(localeOption) + + return { + localeOption, + approvalProgress, + sourceName, + targetName, + englishName, + wordsApproved, + isBrowserDefault, + } + } + + const displayNames: LocaleDisplayInfo[] = + (locales as Lang[])?.map(localeToDisplayInfo).sort((a, b) => { + const indexA = browserLocales.indexOf(a.localeOption as Lang) + const indexB = browserLocales.indexOf(b.localeOption as Lang) + if (indexA >= 0 && indexB >= 0) return indexA - indexB + if (indexA >= 0) return -1 + if (indexB >= 0) return 1 + return b.approvalProgress - a.approvalProgress + }) || [] + + setFilteredNames( + displayNames.filter( + ({ localeOption, sourceName, targetName, englishName }) => + (localeOption + sourceName + targetName + englishName) + .toLowerCase() + .includes(filterValue.toLowerCase()) + ) + ) + }, [filterValue, locale, locales, t]) + + const { isOpen, ...menu } = useDisclosure() + + const eventBase: Pick = { + eventCategory: `Language picker`, + eventAction: "Open or close language picker", + } + + const onOpen = () => { + menu.onOpen() + menuState?.onOpen() + trackCustomEvent({ + ...eventBase, + eventName: "Opened", + } as MatomoEventOptions) + } + + /** + * When closing the menu, track whether this is following a link, or simply closing the menu + * @param customMatomoEvent Optional custom event property overrides + */ + const onClose = ( + customMatomoEvent?: Required> & + Partial + ): void => { + setFilterValue("") + handleClose && handleClose() + menu.onClose() + menuState?.onClose() + trackCustomEvent( + (customMatomoEvent + ? { ...eventBase, ...customMatomoEvent } + : { ...eventBase, eventName: "Closed" }) satisfies MatomoEventOptions + ) + } + + return { + t, + refs, + disclosure: { isOpen, onOpen, onClose }, + filterValue, + setFilterValue, + filteredNames, + } +} diff --git a/src/components/Layer2/Layer2Onboard.tsx b/src/components/Layer2/Layer2Onboard.tsx index 828b8c49ec2..1e03e062e56 100644 --- a/src/components/Layer2/Layer2Onboard.tsx +++ b/src/components/Layer2/Layer2Onboard.tsx @@ -112,17 +112,17 @@ interface CexOnboardOption extends Option { cexOnboard: CexOnboard } -export interface IProps { +export type Layer2OnboardProps = { layer2DataCombined: Array ethIcon: StaticImageData ethIconAlt: string } -const Layer2Onboard: React.FC = ({ +const Layer2Onboard = ({ layer2DataCombined, ethIcon, ethIconAlt, -}) => { +}: Layer2OnboardProps) => { const { t } = useTranslation("page-layer-2") const [selectedCexOnboard, setSelectedCexOnboard] = useState< diff --git a/src/components/Layer2ProductCard.tsx b/src/components/Layer2ProductCard.tsx index 55dc153c9f1..e50a2f4c5cd 100644 --- a/src/components/Layer2ProductCard.tsx +++ b/src/components/Layer2ProductCard.tsx @@ -8,7 +8,7 @@ import { Image } from "@/components/Image" import InlineLink from "@/components/Link" import Text from "@/components/OldText" -export interface IProps { +export type Layer2ProductCardProps = { children?: React.ReactNode url?: string background: string @@ -22,7 +22,7 @@ export interface IProps { ecosystemPortal?: string } -const Layer2ProductCard: React.FC = ({ +const Layer2ProductCard = ({ url, background, image, @@ -34,7 +34,7 @@ const Layer2ProductCard: React.FC = ({ bridge, tokenLists, ecosystemPortal, -}) => { +}: Layer2ProductCardProps) => { const { t } = useTranslation("page-layer-2") return ( diff --git a/src/components/LearningToolsCardGrid.tsx b/src/components/LearningToolsCardGrid.tsx index f8c59e0117d..28165f156bf 100644 --- a/src/components/LearningToolsCardGrid.tsx +++ b/src/components/LearningToolsCardGrid.tsx @@ -6,9 +6,7 @@ import { LearningToolsCardGridProps } from "@/lib/types" import ProductCard from "./ProductCard" import Translation from "./Translation" -const LearningToolsCardGrid: React.FC = ({ - category, -}) => { +const LearningToolsCardGrid = ({ category }: LearningToolsCardGridProps) => { return ( = ({ +const LeftNavBar = ({ dropdownLinks, maxDepth = 1, tocItems, ...props -}) => { +}: LeftNavBarProps) => { return ( + trackCustomEvent( + customEventOptions ?? { + eventCategory: `Link`, + eventAction: `Clicked`, + eventName: "Clicked on internal PDF", + eventValue: href, + } + ) + } + {...commonProps} + as={NextLink} + > + {children} + + ) + } + if (isHash) { return ( ({ ...headingPropsForAnchor(id), }) -const IdAnchor: React.FC<{ id?: string }> = ({ id }) => { +const IdAnchor = ({ id }: { id?: string }) => { if (!id) return null return ( => { // sort meetups by country and then by city const sortedMeetups: Array = sortBy(meetups, ["emoji", "location"]) -export interface IProps {} - // TODO create generalized CardList / TableCard // TODO prop if ordered list or unordered -const MeetupList: React.FC = () => { +const MeetupList = () => { const [searchField, setSearchField] = useState("") const { flipForRtl } = useRtlFlip() const filteredMeetups = filterMeetups(searchField) @@ -128,7 +126,12 @@ const MeetupList: React.FC = () => { me={4} flexWrap="wrap" > - + {meetup.location} diff --git a/src/components/MergeArticleList.tsx b/src/components/MergeArticleList.tsx index 6cd24e4c92d..7408c027615 100644 --- a/src/components/MergeArticleList.tsx +++ b/src/components/MergeArticleList.tsx @@ -3,9 +3,7 @@ import { Box } from "@chakra-ui/react" import CardList, { type CardListItem } from "@/components/CardList" -export interface IProps {} - -const MergeArticleList: React.FC = () => { +const MergeArticleList = () => { const { t } = useTranslation(["page-upgrades", "page-upgrades-index"]) const reads: CardListItem[] = [ diff --git a/src/components/MergeInfographic/index.tsx b/src/components/MergeInfographic/index.tsx index 2abc0a495a6..344dbbd7e75 100644 --- a/src/components/MergeInfographic/index.tsx +++ b/src/components/MergeInfographic/index.tsx @@ -12,9 +12,7 @@ const Text = chakra("text", { }, }) -export interface SvgProps {} - -const SvgText: React.FC = () => { +const SvgText = () => { const { t } = useTranslation(["page-upgrades-index"]) const [sm, lg] = ["7px", "8px"] @@ -49,16 +47,11 @@ const SvgText: React.FC = () => { ) } -export interface IProps { - className?: string -} - -const MergeInfographic: React.FC = ({ className }) => { +const MergeInfographic = () => { const { t } = useTranslation() return ( { - children?: React.ReactNode - isOpen: boolean - setIsOpen: (isOpen: boolean) => void -} +export type ModalProps = ModalContentProps & + Pick & { + children?: React.ReactNode + isOpen: boolean + setIsOpen: (isOpen: boolean) => void + } -const Modal: React.FC = ({ +const Modal = ({ children, isOpen, setIsOpen, size, ...restProps -}) => { +}: ModalProps) => { return ( ( /> ) -interface IDropdownContext { +type DropdownContext = { isOpen: boolean toggle: () => void close: () => void @@ -37,18 +37,14 @@ interface IDropdownContext { ) => void } -const DropdownContext = React.createContext(null) +const DropdownContext = React.createContext(null) -export interface IProps { +export type NavDropdownProps = { children?: React.ReactNode section: ISection } -const NavDropdown: React.FC & { - Item: typeof Item - Link: typeof BaseLink - Title: typeof Title -} = ({ children, section }) => { +const NavDropdown = ({ children, section }: NavDropdownProps) => { const [isOpen, setIsOpen] = useState(false) const ref = createRef() @@ -134,12 +130,12 @@ const NavDropdown: React.FC & { ) } -interface IItemProp { +type ItemProps = { children?: React.ReactNode isLast?: boolean } -const Item: React.FC = ({ children, isLast = false, ...rest }) => { +const Item = ({ children, isLast = false, ...rest }: ItemProps) => { const context = useContext(DropdownContext) return ( @@ -159,11 +155,11 @@ const Item: React.FC = ({ children, isLast = false, ...rest }) => { ) } -interface ITitleProps { +type TitleProps = { children?: React.ReactNode } -const Title: React.FC = (props) => { +const Title = (props: TitleProps) => { return ( = (props) => { ) } -NavDropdown.Item = Item -NavDropdown.Link = NavLink -NavDropdown.Title = Title - -export default NavDropdown +export default Object.assign(NavDropdown, { Link: NavLink, Item, Title }) diff --git a/src/components/Nav/Menu.tsx b/src/components/Nav/Menu.tsx index 983d3239782..6aedc52ad79 100644 --- a/src/components/Nav/Menu.tsx +++ b/src/components/Nav/Menu.tsx @@ -5,12 +5,12 @@ import NavDropdown from "./Dropdown" // import { Lang } from "../../utils/languages" import { ISections } from "./types" -export interface IProps extends FlexProps { +export type MenuProps = FlexProps & { path: string sections: ISections } -const Menu: React.FC = ({ path, sections, ...props }) => { +const Menu = ({ path, sections, ...props }: MenuProps) => { // const { locale } = useRouter() const direction = "ltr" // const direction = getDirection(language as Lang) diff --git a/src/components/Nav/Mobile.tsx b/src/components/Nav/Mobile.tsx index 2d32a8c43d3..48640de2515 100644 --- a/src/components/Nav/Mobile.tsx +++ b/src/components/Nav/Mobile.tsx @@ -1,22 +1,32 @@ import React, { Fragment, ReactNode, RefObject } from "react" import { motion } from "framer-motion" import { useTranslation } from "next-i18next" -import { MdBrightness2, MdLanguage, MdSearch, MdWbSunny } from "react-icons/md" +import { IconType } from "react-icons" +import { BsTranslate } from "react-icons/bs" +import { MdBrightness2, MdSearch, MdWbSunny } from "react-icons/md" import { Box, ButtonProps, Drawer, DrawerBody, + DrawerCloseButton, DrawerContent, DrawerFooter, DrawerOverlay, Flex, forwardRef, + Grid, Icon, + IconButton, List, ListItem, + MenuButton, + Text, + useColorModeValue, } from "@chakra-ui/react" +import LanguagePicker from "@/components/LanguagePicker" + import type { ChildOnlyProp } from "../../lib/types" import { Button } from "../Buttons" import { BaseLink } from "../Link" @@ -70,8 +80,25 @@ const FooterItem = forwardRef((props, ref) => ( /> )) +type FooterButtonProps = ButtonProps & { + icon: IconType +} + +const FooterButton = ({ icon, ...props }: FooterButtonProps) => ( + + } + {...props} + /> + ) +} + +type CloseButtonProps = ButtonProps & { + onToggle: () => void +} + +const CloseButton = ({ onToggle, ...props }: CloseButtonProps) => { + const { t } = useTranslation("common") + return ( + + + + + + + } + {...props} + /> + ) +} + +export type MobileNavMenuProps = ButtonProps & { + isMenuOpen: boolean + isDarkTheme: boolean + toggleMenu: () => void + toggleTheme: () => void + toggleSearch: () => void + linkSections: ISections + fromPageParameter: string + drawerContainerRef: RefObject +} + +const MobileNavMenu = ({ + isMenuOpen, + isDarkTheme, + toggleMenu: onToggle, + toggleTheme, + toggleSearch, + linkSections, + fromPageParameter, + drawerContainerRef, + ...props +}: MobileNavMenuProps) => { + const { t } = useTranslation("common") + + const ThemeIcon = useColorModeValue(MdBrightness2, MdWbSunny) + const themeLabelKey = useColorModeValue("dark-mode", "light-mode") + + return ( + <> + + + {t("close")} + {Object.keys(linkSections).map((sectionKey, idx) => { @@ -204,7 +276,7 @@ const MobileNavMenu: React.FC = ({ {item.text} {item.items.map((item, idx) => ( - + = ({ ))} ) : ( - + = ({ ) : ( - + = ({ py={0} mt="auto" > - { - // Workaround to ensure the input for the search modal can have focus - toggleMenu() - toggleSearch() - }} - > - - {t("search")} - - - - - {t(isDarkTheme ? "light-mode" : "dark-mode")} - - - - + { + // Workaround to ensure the input for the search modal can have focus + onToggle() + toggleSearch() }} > - - {t("languages")} - - + {t("search")} + + + {t(themeLabelKey)} + + + + {t("languages")} + + + diff --git a/src/components/Nav/index.tsx b/src/components/Nav/index.tsx index 5374671b252..99f23767f03 100644 --- a/src/components/Nav/index.tsx +++ b/src/components/Nav/index.tsx @@ -1,13 +1,25 @@ -import React, { FC, useRef } from "react" +import { FC, useRef } from "react" import { useRouter } from "next/router" import { useTranslation } from "next-i18next" -import { MdBrightness2, MdLanguage, MdWbSunny } from "react-icons/md" -import { Box, Flex, HStack, Icon, useDisclosure } from "@chakra-ui/react" +import { BsTranslate } from "react-icons/bs" +import { MdBrightness2, MdWbSunny } from "react-icons/md" +import { + Box, + Button, + Flex, + HStack, + Icon, + MenuButton, + Text, + useDisclosure, + useEventListener, +} from "@chakra-ui/react" -import { ButtonLink, IconButton } from "../Buttons" -import { EthHomeIcon } from "../icons" -import { BaseLink } from "../Link" -import Search from "../Search" +import { IconButton } from "@/components/Buttons" +import { EthHomeIcon } from "@/components/icons" +import LanguagePicker from "@/components/LanguagePicker" +import { BaseLink } from "@/components/Link" +import Search from "@/components/Search" import Menu from "./Menu" import MobileNavMenu from "./Mobile" @@ -21,7 +33,6 @@ export interface IProps { const Nav: FC = ({ path }) => { const { ednLinks, - fromPageParameter, isDarkTheme, shouldShowSubNav, toggleColorMode, @@ -32,6 +43,23 @@ const Nav: FC = ({ path }) => { const { t } = useTranslation("common") const searchModalDisclosure = useDisclosure() const navWrapperRef = useRef(null) + const languagePickerState = useDisclosure() + const languagePickerRef = useRef(null) + /** + * Adds a keydown event listener to toggle color mode (ctrl|cmd + \) + * or open the language picker (\). + * @param {string} event - The keydown event. + */ + useEventListener("keydown", (e) => { + if (e.key !== "\\") return + e.preventDefault() + if (e.metaKey || e.ctrlKey) { + toggleColorMode() + } else { + if (languagePickerState.isOpen) return + languagePickerRef.current?.click() + } + }) return ( @@ -82,6 +110,7 @@ const Nav: FC = ({ path }) => { toggleSearch={searchModalDisclosure.onOpen} drawerContainerRef={navWrapperRef} /> + {/* Desktop */} = ({ path }) => { color: "primary.hover", }} onClick={toggleColorMode} - > - } - variant="ghost" - isSecondary - px={1.5} - _hover={{ - color: "primary.hover", - "& svg": { - transform: "rotate(10deg)", - transition: "transform 0.5s", - }, - }} + /> + + {/* Locale-picker menu */} + - {t("languages")} {locale!.toUpperCase()} - + + + + {t("common:languages")}  + + {locale!.toUpperCase()} + + diff --git a/src/components/OrderedList.tsx b/src/components/OrderedList.tsx index 492700f9f05..a418f05670b 100644 --- a/src/components/OrderedList.tsx +++ b/src/components/OrderedList.tsx @@ -7,9 +7,8 @@ import { SystemStyleObject, } from "@chakra-ui/react" -export interface IProps { +export type OrderedListProps = { listData: Array - className?: string } /** @@ -31,9 +30,9 @@ const liCustomType: SystemStyleObject = { // `listData` should be a list of strings, or HTML components // ex: [

      string

      ] or ['string'] -const OrderedList: React.FC = ({ listData, className }) => { +const OrderedList = ({ listData }: OrderedListProps) => { return ( - + {buttons.map((button, idx) => { + const isSecondary = idx !== 0 if (isButtonLink(button)) { return ( @@ -112,6 +113,7 @@ const PageHero = ({ eventName: button.matomo.eventName, }) } + isSecondary={isSecondary} > {button.content} @@ -132,6 +134,7 @@ const PageHero = ({ eventName: button.matomo.eventName, }) } + isSecondary={isSecondary} > {button.content} diff --git a/src/components/PageMetadata.tsx b/src/components/PageMetadata.tsx index a129284a584..56ecb903c5c 100644 --- a/src/components/PageMetadata.tsx +++ b/src/components/PageMetadata.tsx @@ -18,7 +18,7 @@ type PropMeta = { export type Meta = NameMeta | PropMeta -export interface IProps { +export type PageMetadataProps = { title: string description: string image?: string @@ -26,13 +26,13 @@ export interface IProps { author?: string } -const PageMetadata: React.FC = ({ +const PageMetadata = ({ description, title, image, canonicalUrl, author, -}) => { +}: PageMetadataProps) => { const { locale, asPath } = useRouter() const { t } = useTranslation() @@ -51,7 +51,10 @@ const PageMetadata: React.FC = ({ * @example ethereum.org/about/ -> ethereum.org/about * @example ethereum.org/pt-br/web3/ -> ethereum.org/pt-br/web3 */ - const url = new URL(join(locale === DEFAULT_LOCALE ? "" : locale!, path), SITE_URL).href.replace(/\/$/, "") + const url = new URL( + join(locale === DEFAULT_LOCALE ? "" : locale!, path), + SITE_URL + ).href.replace(/\/$/, "") const canonical = canonicalUrl || url /* Set fallback ogImage based on path */ diff --git a/src/components/Pill.tsx b/src/components/Pill.tsx index d9cd3d7cb44..90cae84fce1 100644 --- a/src/components/Pill.tsx +++ b/src/components/Pill.tsx @@ -1,20 +1,20 @@ import React from "react" import { Flex, FlexProps } from "@chakra-ui/react" -export interface IProps extends FlexProps { +export type PillProps = FlexProps & { children?: React.ReactNode className?: string isSecondary?: boolean color?: string } -const Pill: React.FC = ({ +const Pill = ({ children, className, isSecondary, background, ...rest -}) => { +}: PillProps) => { return isSecondary ? ( = ({ subject, children }) => { +} + +const SubjectBadge = ({ subject, children }: SubjectBadgeProps) => { const backgroundProp = () => { switch (subject) { case "Solidity": @@ -52,7 +54,7 @@ const SubjectBadge: React.FC<{ ) } -export interface IProps { +export type ProductCardProps = { children?: React.ReactNode url: string background: string @@ -68,7 +70,7 @@ export interface IProps { hideStars?: boolean } -const ProductCard: React.FC = ({ +const ProductCard = ({ url, background: bgProp, image, @@ -82,7 +84,7 @@ const ProductCard: React.FC = ({ githubRepoStars = 0, githubRepoLanguages = [], hideStars = false, -}) => { +}: ProductCardProps) => { const DESCRIPTION_STYLES: TextProps = { opacity: 0.8, fontSize: "sm", diff --git a/src/components/Quiz/QuizWidget/AnswerIcon.tsx b/src/components/Quiz/QuizWidget/AnswerIcon.tsx index 0fddd91c92d..ec5acde8831 100644 --- a/src/components/Quiz/QuizWidget/AnswerIcon.tsx +++ b/src/components/Quiz/QuizWidget/AnswerIcon.tsx @@ -7,7 +7,7 @@ import { CorrectIcon, IncorrectIcon, TrophyIcon } from "../../icons/quiz" import { AnswerStatus } from "./useQuizWidget" -interface AnswerIconProps { +type AnswerIconProps = { answerStatus: AnswerStatus } diff --git a/src/components/Quiz/QuizWidget/QuizRadioGroup.tsx b/src/components/Quiz/QuizWidget/QuizRadioGroup.tsx index 5fecc167391..8bdb1bf6527 100644 --- a/src/components/Quiz/QuizWidget/QuizRadioGroup.tsx +++ b/src/components/Quiz/QuizWidget/QuizRadioGroup.tsx @@ -15,7 +15,7 @@ import { VisuallyHidden, } from "@chakra-ui/react" -import { TranslationKey } from "@/lib/types" +import type { AnswerKey, TranslationKey } from "@/lib/types" import { useQuizWidgetContext } from "./context" @@ -28,7 +28,7 @@ export const QuizRadioGroup = () => { } = useQuizWidgetContext() const { t } = useTranslation("learn-quizzes") - const handleSelection = (answerId: string) => { + const handleSelection = (answerId: AnswerKey) => { const isCorrect = answerId === questions[currentQuestionIndex].correctAnswerId setCurrentQuestionAnswerChoice({ answerId, isCorrect }) diff --git a/src/components/Quiz/QuizWidget/context.ts b/src/components/Quiz/QuizWidget/context.ts index 0f20d2dd9a4..a45423c77b2 100644 --- a/src/components/Quiz/QuizWidget/context.ts +++ b/src/components/Quiz/QuizWidget/context.ts @@ -1,7 +1,6 @@ import { createContext, Dispatch, SetStateAction, useContext } from "react" -import { QuizStatus, UserStats } from "@/lib/types" -import { AnswerChoice, Quiz } from "@/lib/interfaces" +import { AnswerChoice, Quiz, QuizKey, QuizStatus, UserStats } from "@/lib/types" import { AnswerStatus } from "./useQuizWidget" @@ -12,12 +11,12 @@ type QuizWidgetContextType = Quiz & { showResults: boolean currentQuestionAnswerChoice: AnswerChoice | null quizPageProps: - | { - currentHandler: (nextKey: string) => void - statusHandler: (status: QuizStatus) => void - nextQuiz: string | undefined - } - | false + | { + currentHandler: (nextKey: QuizKey) => void + statusHandler: (status: QuizStatus) => void + nextQuiz: QuizKey | undefined + } + | false numberOfCorrectAnswers: number quizScore: number ratioCorrect: number diff --git a/src/components/Quiz/QuizWidget/index.tsx b/src/components/Quiz/QuizWidget/index.tsx index 55cd2a78c96..f3a55b6b3cf 100644 --- a/src/components/Quiz/QuizWidget/index.tsx +++ b/src/components/Quiz/QuizWidget/index.tsx @@ -9,7 +9,7 @@ import { VStack, } from "@chakra-ui/react" -import { QuizStatus, UserStats } from "@/lib/types" +import type { QuizKey, QuizStatus, UserStats } from "@/lib/types" import Translation from "@/components/Translation" @@ -28,7 +28,7 @@ import { useQuizWidget } from "./useQuizWidget" import { useRtlFlip } from "@/hooks/useRtlFlip" type CommonProps = { - quizKey: string + quizKey: QuizKey updateUserStats: Dispatch> } @@ -39,7 +39,7 @@ type StandaloneQuizProps = CommonProps & { } type QuizPageProps = CommonProps & { - currentHandler: (nextKey: string) => void + currentHandler: (nextKey: QuizKey) => void statusHandler: (status: QuizStatus) => void isStandaloneQuiz?: false } @@ -76,7 +76,7 @@ const QuizWidget = ({ const quizPageProps = useRef< | (Required> & { - nextQuiz: string | undefined + nextQuiz: QuizKey | undefined }) | false >(false) diff --git a/src/components/Quiz/QuizWidget/useQuizWidget.tsx b/src/components/Quiz/QuizWidget/useQuizWidget.tsx index bd9393f3e6a..da4bc0d993b 100644 --- a/src/components/Quiz/QuizWidget/useQuizWidget.tsx +++ b/src/components/Quiz/QuizWidget/useQuizWidget.tsx @@ -1,14 +1,15 @@ -import { useEffect, useMemo, useRef, useState } from "react" +import { useEffect, useMemo, useState } from "react" import { shuffle } from "lodash" import { useTranslation } from "next-i18next" -import { +import type { AnswerChoice, Question, Quiz, + QuizKey, RawQuestion, RawQuiz, -} from "@/lib/interfaces" +} from "@/lib/types" import allQuizzesData from "@/data/quizzes" import questionBank from "@/data/quizzes/questionBank" @@ -28,11 +29,9 @@ export const useQuizWidget = ({ const { t } = useTranslation() const [quizData, setQuizData] = useState(null) - const [nextQuiz, setNextQuiz] = useState(undefined) - const [userQuizProgress, setUserQuizProgress] = useState>( - [] - ) - const [showAnswer, setShowAnswer] = useState(false) + const [nextQuiz, setNextQuiz] = useState(undefined) + const [userQuizProgress, setUserQuizProgress] = useState([]) + const [showAnswer, setShowAnswer] = useState(false) const [currentQuestionAnswerChoice, setCurrentQuestionAnswerChoice] = useState(null) @@ -46,18 +45,9 @@ export const useQuizWidget = ({ setUserQuizProgress([]) setShowAnswer(false) - const currentQuizKey = - quizKey || - Object.keys(allQuizzesData).filter((quizUri) => - window?.location.href.includes(quizUri) - )[0] || - null - - if (!currentQuizKey) return - // Get quiz data from key, shuffle, then truncate if necessary - const rawQuiz: RawQuiz = allQuizzesData[currentQuizKey] - const questions: Array = rawQuiz.questions.map((id) => { + const rawQuiz: RawQuiz = allQuizzesData[quizKey] + const questions: Question[] = rawQuiz.questions.map((id) => { const rawQuestion: RawQuestion = questionBank[id] return { id, ...rawQuestion } }) @@ -99,10 +89,7 @@ export const useQuizWidget = ({ const quizScore = Math.floor(ratioCorrect * 100) const isPassingScore = quizScore > PASSING_QUIZ_SCORE - const showConfetti = useMemo( - () => !!quizData && showResults && isPassingScore, - [quizData, showResults, isPassingScore] - ) + const showConfetti = !!quizData && showResults && isPassingScore useEffect(() => { if (!showResults) return diff --git a/src/components/Quiz/QuizzesList.tsx b/src/components/Quiz/QuizzesList.tsx index a9317c86e6f..28c21be4e9a 100644 --- a/src/components/Quiz/QuizzesList.tsx +++ b/src/components/Quiz/QuizzesList.tsx @@ -1,7 +1,7 @@ import React from "react" import { Heading, OrderedList, Stack, Text } from "@chakra-ui/react" -import type { QuizzesSection, UserStats } from "@/lib/types" +import type { QuizKey, QuizzesSection, UserStats } from "@/lib/types" import { trackCustomEvent } from "@/lib/utils/matomo" @@ -11,12 +11,12 @@ import Translation from "../Translation" import QuizItem from "./QuizItem" -export interface QuizzesListProps { +type QuizzesListProps = { userStats: UserStats - content: Array + content: QuizzesSection[] headingId: string descriptionId: string - quizHandler: (id: string) => void + quizHandler: (id: QuizKey) => void modalHandler: (isModalOpen: boolean) => void } diff --git a/src/components/Quiz/QuizzesModal.tsx b/src/components/Quiz/QuizzesModal.tsx index 47701c8e553..8966c21cb4c 100644 --- a/src/components/Quiz/QuizzesModal.tsx +++ b/src/components/Quiz/QuizzesModal.tsx @@ -10,12 +10,16 @@ import { import { QuizStatus } from "@/lib/types" -interface IProps extends Omit { +type QuizzesModalProps = Omit & { children: React.ReactNode quizStatus: QuizStatus } -const QuizzesModal: React.FC = ({ children, quizStatus, ...rest }) => { +const QuizzesModal = ({ + children, + quizStatus, + ...props +}: QuizzesModalProps) => { const getStatusColor = (): ModalContentProps["bg"] => { if (quizStatus === "neutral") { return "neutral" @@ -31,7 +35,7 @@ const QuizzesModal: React.FC = ({ children, quizStatus, ...rest }) => { isCentered size={{ base: "full", md: "xl" }} scrollBehavior="inside" - {...rest} + {...props} > diff --git a/src/components/Quiz/useLocalQuizData.ts b/src/components/Quiz/useLocalQuizData.ts index 733e030f857..e16091b084d 100644 --- a/src/components/Quiz/useLocalQuizData.ts +++ b/src/components/Quiz/useLocalQuizData.ts @@ -1,4 +1,4 @@ -import { UserStats } from "@/lib/types" +import type { CompletedQuizzes, UserStats } from "@/lib/types" import { USER_STATS_KEY } from "@/lib/constants" @@ -7,7 +7,7 @@ import { useLocalStorage } from "@/hooks/useLocalStorage" export const INITIAL_USER_STATS: UserStats = { score: 0, average: [], - completed: {}, + completed: {} as CompletedQuizzes, } export const useLocalQuizData = () => { diff --git a/src/components/RandomAppList.tsx b/src/components/RandomAppList.tsx index 739311e226f..16080304bfd 100644 --- a/src/components/RandomAppList.tsx +++ b/src/components/RandomAppList.tsx @@ -50,9 +50,7 @@ const appList: Array = [ }, ] -export interface IProps {} - -const RandomAppList: React.FC = () => { +const RandomAppList = () => { const [randomAppList, setRandomAppList] = useState>([]) useEffect(() => { diff --git a/src/components/Roadmap/RoadmapActionCard.tsx b/src/components/Roadmap/RoadmapActionCard.tsx index c38f3d6be78..8243426cc5d 100644 --- a/src/components/Roadmap/RoadmapActionCard.tsx +++ b/src/components/Roadmap/RoadmapActionCard.tsx @@ -15,7 +15,7 @@ import security from "@/public/roadmap/roadmap-security.png" import scaling from "@/public/roadmap/roadmap-transactions.png" import userExperience from "@/public/roadmap/roadmap-ux.png" -interface IProps { +type RoadmapActionCardProps = { to: string alt: string image: string @@ -24,14 +24,14 @@ interface IProps { buttonText: string } -const RoadmapActionCard: React.FC = ({ +const RoadmapActionCard = ({ to, alt, image, title, description, buttonText, -}) => { +}: RoadmapActionCardProps) => { const images = { futureProofing, scaling, diff --git a/src/components/Roadmap/RoadmapImageContent.tsx b/src/components/Roadmap/RoadmapImageContent.tsx index ce56274819f..16bc85250f3 100644 --- a/src/components/Roadmap/RoadmapImageContent.tsx +++ b/src/components/Roadmap/RoadmapImageContent.tsx @@ -4,12 +4,12 @@ import { Image } from "@/components/Image" import wallet from "@/public/wallet.png" -export interface IProps { +export type RoadmapImageContentProps = { children: React.ReactNode title: String } -const RoadmapImageContent: React.FC = ({ children, title }) => ( +const RoadmapImageContent = ({ children, title }: RoadmapImageContentProps) => ( {title} diff --git a/src/components/RollupProductDevDoc.tsx b/src/components/RollupProductDevDoc.tsx index a38145afc7c..e329e97d6f2 100644 --- a/src/components/RollupProductDevDoc.tsx +++ b/src/components/RollupProductDevDoc.tsx @@ -9,11 +9,11 @@ import Translation from "./Translation" const rollups = layer2Data as Rollups -export interface IProps { +export type RollupProductDevDocProps = { rollupType: RollupType } -const RollupProductDevDoc: React.FC = ({ rollupType }) => { +const RollupProductDevDoc = ({ rollupType }: RollupProductDevDocProps) => { return ( {rollups[rollupType].map( diff --git a/src/components/Search/SearchModal.tsx b/src/components/Search/SearchModal.tsx index b8bf2b03a82..5b4923b5913 100644 --- a/src/components/Search/SearchModal.tsx +++ b/src/components/Search/SearchModal.tsx @@ -9,9 +9,10 @@ type ModalPropsNoScroll = Omit const DocSearchModalWithChakra = chakra( (props: ModalPropsNoScroll & { className?: string }) => { const { className, ...docModalProps } = props + const windowScrollY = typeof window === "undefined" ? 0 : window.scrollY return (

      - +
      ) } diff --git a/src/components/Search/utils.ts b/src/components/Search/utils.ts index e883735df91..1496b3dcb37 100644 --- a/src/components/Search/utils.ts +++ b/src/components/Search/utils.ts @@ -74,6 +74,11 @@ export const getSearchModalStyles = (): SystemStyleObject => ({ "--docsearch-modal-width": "650px", "--docsearch-hit-height": "fit-content", + ".DocSearch.DocSearch-Container": { + position: "fixed", + inset: 0, + }, + ".DocSearch-SearchBar": { p: { base: 4, md: 8 }, pb: 4, @@ -103,10 +108,9 @@ export const getSearchModalStyles = (): SystemStyleObject => ({ }, }, - ".DocSearch-Container--Stalled .DocSearch-MagnifierLabel, .DocSearch-Container--Stalled .DocSearch-LoadingIndicator": - { - color: "primary.highContrast", - }, + ".DocSearch-Container--Stalled .DocSearch-MagnifierLabel, .DocSearch-Container--Stalled .DocSearch-LoadingIndicator": { + color: "primary.highContrast", + }, ".DocSearch-Dropdown": { ps: { base: 4, md: 8 }, diff --git a/src/components/SideNav.tsx b/src/components/SideNav.tsx index 76701a69703..d9103d3651b 100644 --- a/src/components/SideNav.tsx +++ b/src/components/SideNav.tsx @@ -4,6 +4,7 @@ import { useTranslation } from "next-i18next" import { MdExpandMore } from "react-icons/md" import { Box, HStack, Icon } from "@chakra-ui/react" +import { ChildOnlyProp } from "@/lib/types" import { DeveloperDocsLink } from "@/lib/interfaces" import { BaseLink, LinkProps } from "@/components/Link" @@ -32,7 +33,7 @@ const innerLinksVariants = { }, } -const LinkContainer: React.FC<{ children: ReactNode }> = ({ children }) => { +const LinkContainer = ({ children }: ChildOnlyProp) => { return ( { ) } -export interface IPropsNavLink { +export type NavLinkProps = { item: DeveloperDocsLink path: string isTopLevel?: boolean } -const NavLink: React.FC = ({ item, path, isTopLevel }) => { +const NavLink = ({ item, path, isTopLevel }: NavLinkProps) => { const { t } = useTranslation("page-developers-docs") const isLinkInPath = isTopLevel || path.includes(item.to) || path.includes(item.path) diff --git a/src/components/SideNavMobile.tsx b/src/components/SideNavMobile.tsx index 98081d07179..9d52736da20 100644 --- a/src/components/SideNavMobile.tsx +++ b/src/components/SideNavMobile.tsx @@ -1,10 +1,10 @@ -import React, { ReactNode, useState } from "react" +import React, { useState } from "react" import { AnimatePresence, motion } from "framer-motion" import { useTranslation } from "next-i18next" import { MdExpandMore } from "react-icons/md" import { Box, Center, HStack, Icon } from "@chakra-ui/react" -import type { TranslationKey } from "@/lib/types" +import type { ChildOnlyProp, TranslationKey } from "@/lib/types" import { DeveloperDocsLink } from "@/lib/interfaces" import { BaseLink, LinkProps } from "@/components/Link" @@ -13,7 +13,7 @@ import docLinks from "@/data/developer-docs-links.yaml" import { dropdownIconContainerVariant, - IPropsNavLink as INavLinkProps, + type NavLinkProps as SideNavLinkProps, } from "./SideNav" // Traverse all links to find page id @@ -46,7 +46,7 @@ const innerLinksVariants = { }, } -const LinkContainer: React.FC<{ children: ReactNode }> = ({ children }) => { +const LinkContainer = ({ children }: ChildOnlyProp) => { return ( { ) } -export interface IPropsNavLink extends INavLinkProps { +export type NavLinkProps = SideNavLinkProps & { toggle: () => void } -const NavLink: React.FC = ({ item, path, toggle }) => { +const NavLink = ({ item, path, toggle }: NavLinkProps) => { const { t } = useTranslation("page-developers-docs") const [isOpen, setIsOpen] = useState(false) @@ -144,12 +144,12 @@ const NavLink: React.FC = ({ item, path, toggle }) => { ) } -export interface IProps { +export type SideNavMobileProps = { path: string } // TODO consolidate into SideNav -const SideNavMobile: React.FC = ({ path }) => { +const SideNavMobile = ({ path }: SideNavMobileProps) => { const { t } = useTranslation("page-developers-docs") const [isOpen, setIsOpen] = useState(false) diff --git a/src/components/Simulator/ClickAnimation.tsx b/src/components/Simulator/ClickAnimation.tsx index 28701290bd4..aee27fa0108 100644 --- a/src/components/Simulator/ClickAnimation.tsx +++ b/src/components/Simulator/ClickAnimation.tsx @@ -15,15 +15,15 @@ const DownArrowLong = motion( }) ) -interface IProps extends Pick { +type ClickAnimationProps = Pick & { below?: boolean delay?: number } -export const ClickAnimation: React.FC = ({ +export const ClickAnimation = ({ below, delay = 5000, children, -}) => { +}: ClickAnimationProps) => { const [visible, setVisible] = useState(false) useEffect(() => { const timeout = setTimeout(() => setVisible(true), delay) diff --git a/src/components/Simulator/Explanation.tsx b/src/components/Simulator/Explanation.tsx index 603c113f480..6ad20a3c7b0 100644 --- a/src/components/Simulator/Explanation.tsx +++ b/src/components/Simulator/Explanation.tsx @@ -3,19 +3,20 @@ import { motion } from "framer-motion" import { MdArrowBack } from "react-icons/md" import { Box, Flex, Grid, Heading, Text } from "@chakra-ui/react" +import type { SimulatorNavProps } from "@/lib/types" + import { Button, ButtonLink } from "../Buttons" import type { LabelHref, SimulatorExplanation, - SimulatorNavProps, SimulatorPathSummary, } from "./interfaces" import { MoreInfoPopover } from "./MoreInfoPopover" import { PathButton } from "./PathButton" import type { PathId } from "./types" -interface ExplanationProps extends SimulatorNavProps { +type ExplanationProps = SimulatorNavProps & { explanation: SimulatorExplanation nextPathSummary: SimulatorPathSummary | null nextPathId: PathId | null @@ -23,7 +24,7 @@ interface ExplanationProps extends SimulatorNavProps { openPath?: (pathId: PathId) => void logFinalCta?: () => void } -export const Explanation: React.FC = ({ +export const Explanation = ({ nav, explanation, nextPathSummary, @@ -31,7 +32,7 @@ export const Explanation: React.FC = ({ finalCtaLink, openPath, logFinalCta, -}) => { +}: ExplanationProps) => { const { regressStepper, step, totalSteps } = nav const { header, description } = explanation diff --git a/src/components/Simulator/MoreInfoPopover.tsx b/src/components/Simulator/MoreInfoPopover.tsx index 40b6eed9960..7d4dc13fdd4 100644 --- a/src/components/Simulator/MoreInfoPopover.tsx +++ b/src/components/Simulator/MoreInfoPopover.tsx @@ -18,13 +18,10 @@ import { PulseAnimation } from "./PulseAnimation" const MotionButton = motion(Button) -interface IProps extends Pick { +type MoreInfoPopover = Pick & { isFirstStep: boolean } -export const MoreInfoPopover: React.FC = ({ - isFirstStep, - children, -}) => { +export const MoreInfoPopover = ({ isFirstStep, children }: MoreInfoPopover) => { const [clicked, setClicked] = useState(false) return ( diff --git a/src/components/Simulator/NotificationPopover.tsx b/src/components/Simulator/NotificationPopover.tsx index aa2601f55ff..4cc081722de 100644 --- a/src/components/Simulator/NotificationPopover.tsx +++ b/src/components/Simulator/NotificationPopover.tsx @@ -12,18 +12,17 @@ import { Portal, } from "@chakra-ui/react" -interface IProps - extends Omit, - Pick { - children: ReactNode -} -export const NotificationPopover: React.FC = ({ +type NotificationPopoverProps = Omit & + Pick & { + children: ReactNode + } +export const NotificationPopover = ({ placement, children, content, title, ...restProps -}) => { +}: NotificationPopoverProps) => { return ( {children} diff --git a/src/components/Simulator/PathButton.tsx b/src/components/Simulator/PathButton.tsx index 3d5f82f6d16..e1c7aa72dac 100644 --- a/src/components/Simulator/PathButton.tsx +++ b/src/components/Simulator/PathButton.tsx @@ -3,11 +3,11 @@ import { Button, Flex, Text } from "@chakra-ui/react" import type { SimulatorPathSummary } from "./interfaces" -interface IProps { +type PathButtonProps = { pathSummary: SimulatorPathSummary handleClick: () => void } -export const PathButton: React.FC = ({ pathSummary, handleClick }) => { +export const PathButton = ({ pathSummary, handleClick }: PathButtonProps) => { const { primaryText, secondaryText, Icon } = pathSummary return (