* feat(data): implement Viem lib alternative to Ethers for @semaphore-protocol/data package class
This adds a Viem-based alternative to SemaphoreEthers, allowing
developers to choose their preferred Ethereum library.
Closes#343
* chore(data): update yarn.lock for viem dependency
* chore(data): improve test coverage for SemaphoreViem class
* chore(data): improve test coverage for SemaphoreViem class
* chore: update semaphore contract address
re #978
* feat: add ethereum as a supported network
re #977
* feat: add ethereum subgraph and deploy subgraphs
re #978, #977
Update ethers version to resolve ws security issue (CVE-2024-37890).
Move contract address check outside of branch statement so Typescript can see.
Add build instructions to setup to resolve 'Cannot find module '@semaphore-protocol/...' when
running tests for the first time.
re #920
* feat(cli): remove @semaphore-protocol/cli prepublish script
The idea is to remove the prepublish script from the scripts object of the package.json file of
every cli template when the template is downloaded using the CLI.
BREAKING CHANGE: n
* refactor(cli): add comment
* refactor(cli): create seperate file for removePrePublishScript function
* refactor(cli): using updatedPackageJsonContent var instead of calling readFileSync again
* fix(subgraph): clean node_modules before building subgraph
* refactor(subgraph): fix: test typo
* refactor(subgraph): refactor: remove nohoist
* refactor(subgraph): refactor: workspaces structure
* chore(contracts): remove sub() from gas() in staticcall at SemaphoreVerifier
re #871
* refactor(contracts): using fixed gas cost on precompile calls
re #871
* refactor(contracts): increease fixed gas cost with safety buffer
* feat(cli): remove @semaphore-protocol/cli prepublish script
The idea is to remove the prepublish script from the scripts object of the package.json file of
every cli template when the template is downloaded using the CLI.
BREAKING CHANGE: n
* refactor(cli): add comment
* refactor(cli): create seperate file for removePrePublishScript function
* refactor(cli): using updatedPackageJsonContent var instead of calling readFileSync again
* refactor(scripts): added a script to convert bigint to hex
* refactor(contracts): split SemaphoreVerifier verification key points into a separate library (#330)
* chore(contracts): yarn format & lint
* refactor(contracts): update SemaphoreVerifierKeyPts library to be internal
re #330
* chore(contracts): update spacing
* chore(contracts): updated per peer review and added invariant check for VerifierKeyPts lib
* chore(contracts): update invariant check to revert with custom error
This static method is particularly useful after signature verification, as it allows retrieval of
the corresponding commitment associated with the public key.
re #873
* chore(contracts): deploy semaphore contracts on base
re #865
* chore(contracts): deploy semaphore contracts on linea
re #865
* refactor(data): add types for new networks
re #865
* chore(contracts): deploy contracts on arbitrum
re #859
* chore(contracts): deploy contracts on polygon
re #859
* chore(contracts): deploy contracts on optimism
re #859
* chore: define separate version.ts script
* chore: include publishing to soldeer in script
* fix(contracts): push to soldeer
re 800
* ci: fetch latest contract version from soldeer
* refactor: do not use execa in scripts
* fix: do not exit process in script
* chore: remove comments
* refactor: use shebang in ts scripts
* chore(contracts): add soldeerignore
* chore: inherit stdio in scripts
* chore: remove dry run flag
* chore: uncomment
* chore: fix typo in comment
The public signal of proof related to the Merkle root could obviously be different from what is
expected to be the root of the group. Therefore, for the proof to be valid, it is necessary that the
group root passed as a parameter matches the proof/circuit root output.
re #842
refactor(cli): create an empty yarn.lock file when generating a semaphore project with the cli
Now devs will be able to install dependencies successfully right after creating a project with the
CLI.
re #827
* ci(contracts): a script that moves the abi.json file created to utils folder
A script could be run immediately after compilation to copy the file
artifacts/contracts/Semaphore.sol/Semaphore.json to packages/utils/src/semaphore-abi.json. Then all
packages/apps that need the interface can import it from @semaphore-protocol/utils.
re #817
* refactor(utils): allows packages to import abi from @semaphore-protocol/utils
re #817
* refactor(cli-template-monorepo-ethers): installs ncp and exports Semaphore Abi byte code
re #817
* refactor(contracts): added a script that automates movement of semaphore-abi.json
* chore(cli): changed the dependency and moved to ncp for copying semaphore abi
Changed the importation of abi in utils to _interface and moved the ncp to a dev depency
* chore(utils): changed ab to _interface and update to package.json
* chore(cli): deleted Cli-template file and made a document change
delted some cli-template file, changed yarn commit to git commit and fixed the yarn compile script
* chore: parallelize build scripts
* chore: run tests concurrently
* chore: group test log outputs
* chore: execute lint and format scripts concurrently
* refactor: do no use wildcard for test script`
* fix(identity)!: update type of private key
The new types support buffers and text, so that there is less ambiguity on strings.
* refactor(identity): use base64 as encoding for exported priv keys
re #799
* Update packages/identity/src/index.ts
Co-authored-by: Andrew Twyman <artwyman@users.noreply.github.com>
* test(identity): add more tests
re #799
---------
Co-authored-by: Andrew Twyman <artwyman@users.noreply.github.com>
* chore(website): add trusted setup ceremony on the website
* docs(docs): add trusted setup ceremony instructions on documentation
* chore(docs): add candidate plan for prod ceremony
re n
* fix(docs): rename file to avoid mismatching hyphens
* style(website): follow style guide for hover
* fix(website): wrong link to ceremony
* fix(docs): switch emoji
* chore: shorten `docs` scripts
`githubPages` is true by default
https://rb.gy/hzopfn
* docs: update README.md
* chore: trigger docs workflow only on changes in relevant files
* refactor: provide `cname` typedoc option via config file
* chore: remove heyauthn from exclude typedoc list
* chore: update @zk-kit/baby-jubjub and @zk-kit/eddsa-poseidon dependencies
re #786
* chore(group): use the new @zk-kit/lean-imt library
re #786
* chore: update @zk-kit/utils version
re #786
* chore(contracts): use the new @zk-kit/lean-imt.sol library in contracts
re #786
* feat: support more tree depth
Now Semaphore v4 will support tree depth from 2 to 32.
re #778
* test(proof): update tests to support circuit changes and tree depth 2 - 32
re #778
* fix(contracts): update verifier VK_POINTS
re #778
* test(proof): make tests more atomic
* chore: support tree depth 1
re #778
Through Github rulesets and the definition of code owners, it is possible to automate the review
process without additional workflows. It also makes responsibilities within the project clearer. The
current CODEOWNERS file is very simple but more complex rules can be introduced in the future.
re #783
* test: add missing tests
Now all lines of js libraries are 100% covered.
re #484
* test(proof): update message type
re #484
* test(proof): update constant
re #484
* test(proof): update number constant
re #484
* chore: update lint-staged config
* chore: use czg instead of cz + cz-git
re #738
* chore: use cat instead of vim editor to write commits
re #738
* chore: use secrets.GITHUB_TOKEN instead of secrets.GH_TOKEN
re #738
* style: add a space at the end of the pre-commit file
* chore(docs): format `mdx` files with `remark`
`prettier` doesn't not have proper support for MDX v3.
Docusaurus recommends using `remark` instead.
https://docusaurus.io/docs/markdown-features/react
re #503
* chore(docs): add remark lint plugins
* chore: bump yarn.lock
* chore: add `quiet` option to remark
The ZK-Kit EdDSA Poseidon package only supports the following private key types: text, buffer. The
Semaphore identity supports text and hexadecimal strings. If the identity private key is an
hexadicimal string it needs to be converted before being passed to any ZK-Kit function.
re #733
Targeting ES2020 looks like it's generally fine today. It's widely supported across modern browsers
and environments and it would allow Semaphore bundles to use new ES features natively, like arrow
functions, promises, and classes, which can improve code readability and efficiency.
re #688
Former-commit-id: 9f49d91197
The best practice to update a group admin is through a two-step update. The existing admin assigns
the new potential admin, and the new admin accepts in a separate transaction. This prevents existing
admins from making mistakes and assigning wrong addresses.
re #690
Former-commit-id: 255bccf2eb
overrides only works with NPM and both overrides and resolutions works if they are in the project
root package.json. So they don't solve #713.
re #713
Former-commit-id: b77feebdea
Adding the 'resolutions' field with the static version of web-worker solves the problem described in
issue #713. To be regarded as a temporary solution.
re #713
Former-commit-id: ca36ed5488
The utils package will no longer provide errors and types utilities as those functions have been
moved to zk-kit. The utils package now provides a list of supported networks and a function to
decode messages instead.
re #642, #641
Former-commit-id: d2ce1070f0
The type of the identities' private key will always be a string type, either text or hexadecimal
strings. This will allow devs to store private keys more easily and avoid confusion with types.
re #700
Former-commit-id: eead04e45d
since the group ids are created incrementally internally in the contracts, there's no need to check
whether the group id has already been taken.
re #708
Former-commit-id: e205bf6ad7
The Semaphore V4 CLI templates don't support npm and pnpm yet. The documentation should reflect this
aspect. It will be updated as soon as those templates support more package managers.
re #676
Former-commit-id: e6198cfdbf
The commit adds more documentation to the Identity class and update the TypeDoc link. It also
removes the class method to verify signatures as the static method can be used instead.
re #483
Former-commit-id: b4c2887cf1
This commit add more documentation to the Semaphore circuits, with the aim of providing an overview
of the code used and to refer to other resources for futher information.
re #483
Former-commit-id: de12d471c0
This new package allows devs to fetch on-chain data by using a Semaphore subgraph or the Ethers
library.
BREAKING CHANGE: The code of the old `@semaphore-protocol/subgraph` package has been moved to the
`@semaphore-protocol/data` package.
re #256
Former-commit-id: fc2f648acc
<!-- Please refer to our contributing documentation for any questions on submitting a pull request -->
<!--- Provide a general summary of your changes in the Title above -->
<!-- Please refer to our CONTRIBUTING documentation for any questions on submitting a pull request. -->
<!-- Provide a general summary of your changes in the Title above. -->
## Description
<!--- Describe your changes in detail -->
<!-- Describe your changes in detail. -->
<!-- You may want to answer some of the following questions: -->
<!-- What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) -->
<!-- What is the current behavior?** (You can also link to an open issue here) -->
<!-- What is the new behavior (if this is a feature change)? -->
<!-- Does this PR introduce a breaking change?** (What changes might users need to make in their application due to this PR?) -->
## Related Issue
## Related Issue(s)
<!--- This project accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->
<!-- This project accepts pull requests related to open issues. -->
<!-- If suggesting a new feature or change, please discuss it in an issue first. -->
<!-- If fixing a bug, there should be an issue describing it with steps to reproduce. -->
<!-- Please link to the issue(s) here -->
## Does this introduce a breaking change?
- [ ] Yes
- [ ] No
<!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. -->
<!-- Closes # -->
<!-- Fixes # -->
## Other information
<!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. -->
<!-- Feel free to remove this section if you will not use it. -->
## Checklist
<!-- Please check if the PR fulfills these requirements. -->
- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] My changes generate no new warnings
- [ ] I have run `yarn format` and `yarn lint` without getting any errors
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
> [!IMPORTANT]
> We do not accept minor grammatical fixes (e.g., correcting typos, rewording sentences) unless they significantly improve clarity in technical documentation. These contributions, while appreciated, are not a priority for merging. If there is a grammatical error feel free to message the team.
@@ -22,13 +22,16 @@ Pull requests are great if you want to add a feature or fix a bug. Here's a quic
3. Add a test for your change. Only refactoring and documentation changes require no new tests.
4. Make sure to check out the [Style Guide](/CONTRIBUTING#style-guide) and ensure that your code complies with the rules.
4. Make sure to check out the [Style Guide](/CONTRIBUTING.md#style-guide) and ensure that your code complies with the rules.
5. Make the test pass.
6. Commit your changes.
7. Push to your fork and submit a pull request on our `dev` branch. Please provide us with some explanation of why you made the changes you made. For new features make sure to explain a standard use case to us.
7. Push to your fork and submit a pull request on our `main` branch. Please provide us with some explanation of why you made the changes you made. For new features make sure to explain a standard use case to us.
> [!IMPORTANT]
> We do not accept minor grammatical fixes (e.g., correcting typos, rewording sentences) unless they significantly improve clarity in technical documentation. These contributions, while appreciated, are not a priority for merging. If there is a grammatical error feel free to message the team.
## CI (Github Actions) Tests
@@ -42,11 +45,11 @@ When you submit your PR (or later change that code), a CI build will automatical
We always use ESLint and Prettier. To check that your code follows the rules, simply run the npm script `yarn lint`.
### Commits rules
### Commit rules
For commits it is recommended to use [Conventional Commits](https://www.conventionalcommits.org).
Don't worry if it looks complicated, in our repositories, after `git add`, you can usually run the npm script `yarn commit` to make many of these steps interactive.
Don't worry if it looks complicated, in our repositories, `git commit` opens an interactive app to create your conventional commit.
Each commit message consists of a **header**, a **body** and a **footer**. The **header** has a special format that includes a **type**, a **scope** and a **subject**:
@@ -93,7 +96,6 @@ Just as in the subject, use the imperative, present tense: "change" not "changed
### Branch rules
- There must be a `main` branch, used only for the releases.
- There must be a `dev` branch, used to merge all the branches under it.
- Avoid long descriptive names for long-lived branches.
- Use kebab-case (no CamelCase).
- Use grouping tokens (words) at the beginning of your branch names (in a similar way to the `type` of commit).
| Semaphore is a protocol, designed to be a simple and generic privacy layer for Ethereum DApps. Using zeroknowledge, Ethereum users can prove their membership of a group and send signals such as votes or endorsements without revealing their original identity. |
| Semaphore is a generic privacy layer. Leveraging zero-knowledge technology, users can prove their membership in groups and send messages (extending from votes to endorsements) off-chain or across EVM-compatible blockchains, all without revealing their personal identity. |
The core of the Semaphore protocol is in the [circuit logic](/packages/circuits/scheme.png). However Semaphore also provides [Solidity contracts](/packages/contracts) (NPM: `@semaphore-protocol/contracts`) and JavaScript libraries to make the steps for offchain proof creation and onchain verification easier. To learn more about Semaphore visit [semaphore.appliedzkp.org](https://semaphore.appliedzkp.org).
The core of the Semaphore protocol is in the [circuit logic](/packages/circuits/scheme.png). However, Semaphore also provides [Solidity contracts](/packages/contracts) and JavaScript libraries to make the steps for offchain proof creation and onchain/offchain verification easier. To learn more about Semaphore visit [semaphore.pse.dev](https://semaphore.pse.dev).
You can find Semaphore V1 on [`version/1.0.0`](https://github.com/semaphore-protocol/semaphore/tree/version/1.0.0).
---
> [!IMPORTANT]
> Help Semaphore prosper by sharing your ideas with the PSE [acceleration program](https://github.com/privacy-scaling-explorations/acceleration-program).
## 📦 Packages
@@ -70,6 +78,25 @@ You can find Semaphore V1 on [`version/1.0.0`](https://github.com/semaphore-prot
Run [Prettier](https://prettier.io/) to check formatting rules:
```bash
yarn prettier
yarn format
```
Or to automatically format the code:
```bash
yarn prettier:write
yarn format:write
```
### Conventional commits
@@ -249,19 +322,11 @@ yarn prettier:write
Semaphore uses [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/). A [command line utility](https://github.com/commitizen/cz-cli) to commit using the correct syntax can be used by running:
```bash
yarn commit
git commit
```
It will also automatically check that the modified files comply with ESLint and Prettier rules.
### Snark artifacts
Download the Semaphore snark artifacts needed to generate and verify proofs:
```bash
yarn download:snark-artifacts
```
### Testing
Run [Jest](https://jestjs.io/) to test the JS libraries:
@@ -284,10 +349,10 @@ yarn test
### Build libraries & compile contracts
Run [Rollup](https://www.rollupjs.org) to build all the packages:
Run [Rollup](https://www.rollupjs.org) and [TheGraph](https://www.npmjs.com/package/@graphprotocol/graph-cli) to build all the packages and the subgraph:
```bash
yarn build:libraries
yarn build
```
Compile the smart contracts with [Hardhat](https://hardhat.org/):
@@ -305,3 +370,31 @@ yarn docs
```
The output will be placed on the `docs` folder.
### Releases
Steps:
1. Bump a new version with:
```bash
yarn version:bump <version>
# e.g. yarn version:bump 2.0.0
```
This step creates a commit and a git tag.
2. Push the changes to main:
```bash
git push origin main
```
3. Push the new git tag:
```bash
git push origin <version>
# e.g. git push origin v2.0.0
```
After pushing the new git tag, a workflow will be triggered to publish the Semaphore packages on [npm](https://www.npmjs.com/) and release a new version on GitHub with its changelogs automatically.
| This repository contains the code for the Semaphore documentation published at [docs.semaphore.pse.dev](https://docs.semaphore.pse.dev). It uses Markdown syntax and the [Docusaurus](https://docusaurus.io/) site generator. |
'<b><a href="https://github.com/semaphore-protocol/semaphore/releases/tag/v4.0.0" target="_blank">Semaphore V4</a> is out 🎉 <a href="/getting-started">Try it out</a> and let us know if you have any feedback on <a href="https://semaphore.pse.dev/telegram" target="_blank">Telegram</a> or <a href="https://github.com/orgs/semaphore-protocol/discussions" target="_blank">Github</a>!</b>',
backgroundColor:"#dde6fc",
textColor:"#000000"
},
// Social media card
image:"img/social-media.png",
navbar:{
logo:{
alt:"Semaphore Logo",
src:"img/semaphore-logo.svg"
},
items:[
{
type:"docsVersionDropdown",
position:"left",
dropdownActiveClassDisabled: true
},
{
label:"Whitepaper",
to:"https://semaphore.pse.dev/whitepaper-v1.pdf",
position:"left",
className:"whitepaper-v1"
},
{
label:"Github",
href:"https://github.com/semaphore-protocol",
position:"right"
},
{
label:"Website",
href:"https://semaphore.pse.dev",
position:"right"
},
{
type:"localeDropdown",
position:"right"
}
]
},
colorMode:{
defaultMode:"light",
// Should we use the prefers-color-scheme media-query,
// using user system preferences, instead of the hardcoded defaultMode
"message":"Using zero knowledge, Semaphore allows Ethereum users to prove their membership of a group and send signals such as votes or endorsements without revealing their original identity."
},
"quick-setup.button":{
"message":"Quick setup"
},
"boilerplate.button":{
"message":"Boilerplate"
},
"components.description":{
"message":"Building an Ethereum dApp? Semaphore components make it simple to add a privacy layer!"
},
"components.button.solidity":{
"message":"Solidity contract"
},
"components.button.circuits":{
"message":"zkSNARK circuits"
},
"components.button.libraries":{
"message":"JavaScript libraries"
},
"section.identities.title":{
"message":"Semaphore identities"
},
"section.identities.description":{
"message":"Given to all Semaphore group members, it is comprised of three parts: identity commitment, trapdoor, and nullifier."
},
"section.identities.link":{
"message":"Create Semaphore identities"
},
"section.identities.box1.title":{
"message":"Private values"
},
"section.identities.box1.description":{
"message":"Trapdoor and nullifier values are the private values of the Semaphore identity. To avoid fraud, the owner must keep both values secret."
},
"section.identities.box2.title":{
"message":"Public values"
},
"section.identities.box2.description":{
"message":"Semaphore uses the Poseidon hash function to create the identity commitment from the identity private values. Identity commitments can be made public, similarly to Ethereum addresses."
},
"section.identities.box3.title":{
"message":"Generate identities"
},
"section.identities.box3.description":{
"message":"Semaphore identities can be generated deterministically or randomly. Deterministic identities can be generated from the hash of a secret message."
},
"section.groups.title":{
"message":"Semaphore groups"
},
"section.groups.description":{
"message":"Semaphore groups are binary incremental Merkle trees that store the public identity commitment of each member."
},
"section.groups.link":{
"message":"Curate Semaphore groups"
},
"section.groups.box1.title":{
"message":"Merkle trees"
},
"section.groups.box1.description":{
"message":"Each leaf contains an identity commitment for a user. The identity commitment proves that the user is a group member without revealing the private identity of the user."
},
"section.groups.box2.title":{
"message":"Types of groups"
},
"section.groups.box2.description":{
"message":"Groups can be created and managed in a decentralized fashion with Semaphore contracts or off-chain with our JavaScript libraries."
},
"section.groups.box3.title":{
"message":"Group management"
},
"section.groups.box3.description":{
"message":"Users can join and leave groups by themselves, or an admin can add and remove them. Admins can be centralized authorities, Ethereum accounts, multi-sig wallets or smart contracts."
},
"section.proofs.title":{
"message":"Semaphore proofs"
},
"section.proofs.description":{
"message":"Semaphore group members can anonymously prove that they are part of a group and that they are generating their own proofs and signals."
},
"section.proofs.link":{
"message":"Generate Semaphore proofs"
},
"section.proofs.box1.title":{
"message":"Membership"
},
"section.proofs.box1.description":{
"message":"Only users who are part of a group can generate a valid proof for that group."
},
"section.proofs.box2.title":{
"message":"Signals"
},
"section.proofs.box2.description":{
"message":"Group users can anonymously broadcast signals such as votes or endorsements without revealing their original identity."
},
"section.proofs.box3.title":{
"message":"Verifiers"
},
"section.proofs.box3.description":{
"message":"Semaphore proofs can be verified with Semaphore contracts on-chain or with our JavaScript libraries off-chain."
},
"theme.ErrorPageContent.title":{
"message":"This page crashed.",
"description":"The title of the fallback page when the page crashed"
},
"theme.ErrorPageContent.tryAgain":{
"message":"Try again",
"description":"The label of the button to try again when the page crashed"
},
"theme.NotFound.title":{
"message":"Page Not Found",
"description":"The title of the 404 page"
},
"theme.NotFound.p1":{
"message":"We could not find what you were looking for.",
"description":"The first paragraph of the 404 page"
},
"theme.NotFound.p2":{
"message":"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.",
"description":"The 2nd paragraph of the 404 page"
},
"theme.admonition.note":{
"message":"note",
"description":"The default label used for the Note admonition (:::note)"
},
"theme.admonition.tip":{
"message":"tip",
"description":"The default label used for the Tip admonition (:::tip)"
},
"theme.admonition.danger":{
"message":"danger",
"description":"The default label used for the Danger admonition (:::danger)"
},
"theme.admonition.info":{
"message":"info",
"description":"The default label used for the Info admonition (:::info)"
},
"theme.admonition.caution":{
"message":"caution",
"description":"The default label used for the Caution admonition (:::caution)"
},
"theme.BackToTopButton.buttonAriaLabel":{
"message":"Scroll back to top",
"description":"The ARIA label for the back to top button"
},
"theme.blog.archive.title":{
"message":"Archive",
"description":"The page & hero title of the blog archive page"
},
"theme.blog.archive.description":{
"message":"Archive",
"description":"The page & hero description of the blog archive page"
},
"theme.blog.paginator.navAriaLabel":{
"message":"Blog list page navigation",
"description":"The ARIA label for the blog pagination"
},
"theme.blog.paginator.newerEntries":{
"message":"Newer Entries",
"description":"The label used to navigate to the newer blog posts page (previous page)"
},
"theme.blog.paginator.olderEntries":{
"message":"Older Entries",
"description":"The label used to navigate to the older blog posts page (next page)"
},
"theme.blog.post.paginator.navAriaLabel":{
"message":"Blog post page navigation",
"description":"The ARIA label for the blog posts pagination"
},
"theme.blog.post.paginator.newerPost":{
"message":"Newer Post",
"description":"The blog post button label to navigate to the newer/previous post"
},
"theme.blog.post.paginator.olderPost":{
"message":"Older Post",
"description":"The blog post button label to navigate to the older/next post"
},
"theme.blog.post.plurals":{
"message":"One post|{count} posts",
"description":"Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.blog.tagTitle":{
"message":"{nPosts} tagged with \"{tagName}\"",
"description":"The title of the page for a blog tag"
},
"theme.tags.tagsPageLink":{
"message":"View All Tags",
"description":"The label of the link targeting the tag list page"
},
"theme.colorToggle.ariaLabel":{
"message":"Switch between dark and light mode (currently {mode})",
"description":"The ARIA label for the navbar color mode toggle"
},
"theme.colorToggle.ariaLabel.mode.dark":{
"message":"dark mode",
"description":"The name for the dark color mode"
},
"theme.colorToggle.ariaLabel.mode.light":{
"message":"light mode",
"description":"The name for the light color mode"
},
"theme.docs.breadcrumbs.home":{
"message":"Home page",
"description":"The ARIA label for the home page in the breadcrumbs"
},
"theme.docs.breadcrumbs.navAriaLabel":{
"message":"Breadcrumbs",
"description":"The ARIA label for the breadcrumbs"
},
"theme.docs.DocCard.categoryDescription":{
"message":"{count} items",
"description":"The default description for a category card in the generated index about how many items this category includes"
},
"theme.docs.paginator.navAriaLabel":{
"message":"Docs pages navigation",
"description":"The ARIA label for the docs pagination"
},
"theme.docs.paginator.previous":{
"message":"Previous",
"description":"The label used to navigate to the previous doc"
},
"theme.docs.paginator.next":{
"message":"Next",
"description":"The label used to navigate to the next doc"
},
"theme.docs.tagDocListPageTitle.nDocsTagged":{
"message":"One doc tagged|{count} docs tagged",
"description":"Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.docs.tagDocListPageTitle":{
"message":"{nDocsTagged} with \"{tagName}\"",
"description":"The title of the page for a docs tag"
},
"theme.docs.versionBadge.label":{
"message":"Version: {versionLabel}"
},
"theme.docs.versions.unreleasedVersionLabel":{
"message":"This is unreleased documentation for {siteTitle} {versionLabel} version.",
"description":"The label used to tell the user that he's browsing an unreleased doc version"
},
"theme.docs.versions.unmaintainedVersionLabel":{
"message":"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.",
"description":"The label used to tell the user that he's browsing an unmaintained doc version"
"message":"Toggle the collapsible sidebar category '{label}'",
"description":"The ARIA label to toggle the collapsible sidebar category"
},
"theme.navbar.mobileLanguageDropdown.label":{
"message":"Languages",
"description":"The label for the mobile language switcher dropdown"
},
"theme.TOCCollapsible.toggleButtonLabel":{
"message":"On this page",
"description":"The label used by the button on the collapsible TOC component"
},
"theme.blog.post.readMore":{
"message":"Read More",
"description":"The label used in blog post item excerpts to link to full blog posts"
},
"theme.blog.post.readMoreLabel":{
"message":"Read more about {title}",
"description":"The ARIA label for the link to full blog posts from excerpts"
},
"theme.blog.post.readingTime.plurals":{
"message":"One min read|{readingTime} min read",
"description":"Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.docs.sidebar.collapseButtonTitle":{
"message":"Collapse sidebar",
"description":"The title attribute for collapse button of doc sidebar"
},
"theme.docs.sidebar.collapseButtonAriaLabel":{
"message":"Collapse sidebar",
"description":"The title attribute for collapse button of doc sidebar"
"description":"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"
"description":"The ARIA label for hamburger menu button of mobile navigation"
},
"theme.docs.sidebar.expandButtonTitle":{
"message":"Expand sidebar",
"description":"The ARIA label and title attribute for expand button of doc sidebar"
},
"theme.docs.sidebar.expandButtonAriaLabel":{
"message":"Expand sidebar",
"description":"The ARIA label and title attribute for expand button of doc sidebar"
},
"theme.common.skipToMainContent":{
"message":"Skip to main content",
"description":"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation"
},
"theme.tags.tagsPageTitle":{
"message":"Tags",
"description":"The title of the tag list page"
},
"footer.left.title":{
"message":"About"
},
"footer.left.description":{
"message":"Semaphore is part of Privacy & Scaling Explorations (PSE), a multidisciplinary team supported by the Ethereum Foundation. PSE explores new use cases for zero knowledge proofs and other cryptographic primitives."
"message":"Utilizando zero knowledge (conocimiento cero), Semaphore permite a los usuarios de Ethereum demostrar su membresía en un grupo y enviar señales como votos o reconocimientos sin revelar su identidad original."
},
"quick-setup.button":{
"message":"Configuración rápida"
},
"boilerplate.button":{
"message":"Boilerplate"
},
"components.description":{
"message":"¿Está desarrollando una dApp en Ethereum? ¡Los componentes Semaphore permiten agregar una capa de privacidad de forma sencilla!"
},
"components.button.solidity":{
"message":"Contrato en Solidity"
},
"components.button.circuits":{
"message":"Circuitos zkSNARK"
},
"components.button.libraries":{
"message":"Librerías JavaScript"
},
"section.identities.title":{
"message":"Identidades Semaphore"
},
"section.identities.description":{
"message":"Otorgada a todos los miembros de un grupo Semaphore, está compuesta por tres partes: identity commitment (compromiso de identidad), trapdoor, y nullifier."
},
"section.identities.link":{
"message":"Crear identidades Semaphore"
},
"section.identities.box1.title":{
"message":"Valores privados"
},
"section.identities.box1.description":{
"message":"Los valores trapdoor y nullifier son los valores privados de una identidad Semaphore. Para evitar fraude, la persona dueña debe mantener ambos valores en secreto."
},
"section.identities.box2.title":{
"message":"Valores públicos"
},
"section.identities.box2.description":{
"message":"Semaphore utiliza la función hash Poseidon para crear el identity commitment a partir de los valores privados. Los identity commitments se pueden compartir públicamente, de forma similar a las direcciones Ethereum."
},
"section.identities.box3.title":{
"message":"Generar identidades"
},
"section.identities.box3.description":{
"message":"Las identidades Semaphore pueden generarse de forma determinística o aleatoria. Las identidades determinísticas se pueden generar a partir del hash de un mensaje secreto."
},
"section.groups.title":{
"message":"Grupos Semaphore"
},
"section.groups.description":{
"message":"Los grupos Semaphore son árboles de Merkle binarios e incrementales que almacenan el identity commitment público de cada miembro."
},
"section.groups.link":{
"message":"Curaduría de grupos Semaphore"
},
"section.groups.box1.title":{
"message":"Árboles de Merkle"
},
"section.groups.box1.description":{
"message":"Cada hoja contiene el identity commitment de un usuario. El identity commitment demuestra que el usuario es miembro de un grupo sin revelar la identidad privada del usuario."
},
"section.groups.box2.title":{
"message":"Tipos de grupos"
},
"section.groups.box2.description":{
"message":"Los grupos pueden crearse y administrarse de forma descentralizada con contratos Semaphore o off-chain (fuera de la cadena) con nuestras librerías en JavaScript."
},
"section.groups.box3.title":{
"message":"Administración de grupos"
},
"section.groups.box3.description":{
"message":"Los usuarios pueden unirse y abandonar un grupo por si solos, o un administrador puede agregarles o removerles. Los administradores pueden ser autoridades centralizadas, cuentas Ethereum, carteras multi-sig o smart contracts (contratos inteligentes)."
},
"section.proofs.title":{
"message":"Pruebas Semaphore"
},
"section.proofs.description":{
"message":"Los miembros de un grupo Semaphore pueden demostrar de forma anónima que pertenecen a un grupo y que ellos están generando sus propias pruebas y señales."
},
"section.proofs.link":{
"message":"Generar pruebas Semaphore"
},
"section.proofs.box1.title":{
"message":"Membresía"
},
"section.proofs.box1.description":{
"message":"Únicamente los usuarios que forman parte de un grupo pueden generar una prueba válida para ese grupo."
},
"section.proofs.box2.title":{
"message":"Señales"
},
"section.proofs.box2.description":{
"message":"Los usuarios del grupo pueden transmitir señales anónimamente, como votos o reconocimientos, sin revelar su identidad original."
},
"section.proofs.box3.title":{
"message":"Verificadores"
},
"section.proofs.box3.description":{
"message":"Las pruebas Semaphore pueden verificarse on-chain (dentro de la cadena) con contratos en Solidity o off-chain con nuestras librerías en JavaScript."
},
"theme.ErrorPageContent.title":{
"message":"Esta página no está funcionando.",
"description":"The title of the fallback page when the page crashed"
},
"theme.ErrorPageContent.tryAgain":{
"message":"Intente de nuevo",
"description":"The label of the button to try again when the page crashed"
},
"theme.NotFound.title":{
"message":"Página No Encontrada",
"description":"The title of the 404 page"
},
"theme.NotFound.p1":{
"message":"No pudimos encontrar lo que buscaba.",
"description":"The first paragraph of the 404 page"
},
"theme.NotFound.p2":{
"message":"Comuníquese con el dueño del sitio que lo vinculó a la URL original y hágale saber que su vínculo está roto.",
"description":"The 2nd paragraph of the 404 page"
},
"theme.admonition.note":{
"message":"nota",
"description":"The default label used for the Note admonition (:::note)"
},
"theme.admonition.tip":{
"message":"tip",
"description":"The default label used for the Tip admonition (:::tip)"
},
"theme.admonition.danger":{
"message":"peligro",
"description":"The default label used for the Danger admonition (:::danger)"
},
"theme.admonition.info":{
"message":"información",
"description":"The default label used for the Info admonition (:::info)"
},
"theme.admonition.caution":{
"message":"precaución",
"description":"The default label used for the Caution admonition (:::caution)"
},
"theme.BackToTopButton.buttonAriaLabel":{
"message":"Volver al principio",
"description":"The ARIA label for the back to top button"
},
"theme.blog.archive.title":{
"message":"Archivo",
"description":"The page & hero title of the blog archive page"
},
"theme.blog.archive.description":{
"message":"Archivo",
"description":"The page & hero description of the blog archive page"
},
"theme.blog.paginator.navAriaLabel":{
"message":"Navegación por la página de la lista de blogs ",
"description":"The ARIA label for the blog pagination"
},
"theme.blog.paginator.newerEntries":{
"message":"Entradas más recientes",
"description":"The label used to navigate to the newer blog posts page (previous page)"
},
"theme.blog.paginator.olderEntries":{
"message":"Entradas más antiguas",
"description":"The label used to navigate to the older blog posts page (next page)"
},
"theme.blog.post.paginator.navAriaLabel":{
"message":"Barra de paginación de publicaciones del blog",
"description":"The ARIA label for the blog posts pagination"
},
"theme.blog.post.paginator.newerPost":{
"message":"Publicación más reciente",
"description":"The blog post button label to navigate to the newer/previous post"
},
"theme.blog.post.paginator.olderPost":{
"message":"Publicación más antigua",
"description":"The blog post button label to navigate to the older/next post"
"description":"Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.blog.tagTitle":{
"message":"{nPosts} etiquetados con \"{tagName}\"",
"description":"The title of the page for a blog tag"
},
"theme.tags.tagsPageLink":{
"message":"Ver todas las etiquetas",
"description":"The label of the link targeting the tag list page"
},
"theme.colorToggle.ariaLabel":{
"message":"Cambiar entre el modo día y noche (actualmente en {mode})",
"description":"The ARIA label for the navbar color mode toggle"
},
"theme.colorToggle.ariaLabel.mode.dark":{
"message":"modo noche",
"description":"The name for the dark color mode"
},
"theme.colorToggle.ariaLabel.mode.light":{
"message":"modo día",
"description":"The name for the light color mode"
},
"theme.docs.breadcrumbs.home":{
"message":"Página de inicio",
"description":"The ARIA label for the home page in the breadcrumbs"
},
"theme.docs.breadcrumbs.navAriaLabel":{
"message":"Breadcrumbs",
"description":"The ARIA label for the breadcrumbs"
},
"theme.docs.DocCard.categoryDescription":{
"message":"{count} items",
"description":"The default description for a category card in the generated index about how many items this category includes"
},
"theme.docs.paginator.navAriaLabel":{
"message":"Navegación de páginas de documentos",
"description":"The ARIA label for the docs pagination"
},
"theme.docs.paginator.previous":{
"message":"Anterior",
"description":"The label used to navigate to the previous doc"
},
"theme.docs.paginator.next":{
"message":"Siguiente",
"description":"The label used to navigate to the next doc"
"description":"Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.docs.tagDocListPageTitle":{
"message":"{nDocsTagged} con \"{tagName}\"",
"description":"The title of the page for a docs tag"
},
"theme.docs.versionBadge.label":{
"message":"Versión: {versionLabel}"
},
"theme.docs.versions.unreleasedVersionLabel":{
"message":"Esta es documentación sin liberar para {siteTitle} {versionLabel} versión.",
"description":"The label used to tell the user that he's browsing an unreleased doc version"
},
"theme.docs.versions.unmaintainedVersionLabel":{
"message":"Esta es documentación para {siteTitle} {versionLabel}, que ya no se mantiene activamente.",
"description":"The label used to tell the user that he's browsing an unmaintained doc version"
"message":"Toggle the collapsible sidebar category '{label}'",
"description":"The ARIA label to toggle the collapsible sidebar category"
},
"theme.navbar.mobileLanguageDropdown.label":{
"message":"Idiomas",
"description":"The label for the mobile language switcher dropdown"
},
"theme.TOCCollapsible.toggleButtonLabel":{
"message":"En esta página",
"description":"The label used by the button on the collapsible TOC component"
},
"theme.blog.post.readMore":{
"message":"Leer Más",
"description":"The label used in blog post item excerpts to link to full blog posts"
},
"theme.blog.post.readMoreLabel":{
"message":"Lea más de {title}",
"description":"The ARIA label for the link to full blog posts from excerpts"
},
"theme.blog.post.readingTime.plurals":{
"message":"Lectura de un minuto|{readingTime} min de lectura",
"description":"Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.docs.sidebar.collapseButtonTitle":{
"message":"Colapsar barra lateral",
"description":"The title attribute for collapse button of doc sidebar"
},
"theme.docs.sidebar.collapseButtonAriaLabel":{
"message":"Colapsar barra lateral",
"description":"The title attribute for collapse button of doc sidebar"
"description":"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"
"description":"The ARIA label for hamburger menu button of mobile navigation"
},
"theme.docs.sidebar.expandButtonTitle":{
"message":"Expandir barra lateral",
"description":"The ARIA label and title attribute for expand button of doc sidebar"
},
"theme.docs.sidebar.expandButtonAriaLabel":{
"message":"Expandir barra lateral",
"description":"The ARIA label and title attribute for expand button of doc sidebar"
},
"theme.common.skipToMainContent":{
"message":"Saltar al contenido principal",
"description":"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation"
},
"theme.tags.tagsPageTitle":{
"message":"Etiquetas",
"description":"The title of the tag list page"
},
"footer.left.title":{
"message":"Acerca de"
},
"footer.left.description":{
"message":"Semaphore es parte de Privacy & Scaling Explorations (PSE), un equipo multidisciplinario apoyado por la Fundación Ethereum. PSE explora nuevos casos de uso para pruebas de conocimiento cero (ZKPs) y otras bases criptográficas."
[To Mixers and Beyond: presenting Semaphore, a privacy gadget built on Ethereum](https://medium.com/coinmonks/to-mixers-and-beyond-presenting-semaphore-a-privacy-gadget-built-on-ethereum-4c8b00857c9b) - Koh Wei Jie
[Privacy in Ethereum](https://www.youtube.com/watch?v=maDHYyj30kg) - Barry WhiteHat at the Taipei Ethereum Meetup
[Snarks for mixing, signaling and scaling by](https://www.youtube.com/watch?v=lv6iK9qezBY) - Barry WhiteHat at Devcon 4
[Privacy in Ethereum](https://www.youtube.com/watch?v=zBUo7G95wYE) - Barry WhiteHat at Devcon 5
[A trustless Ethereum mixer using zero-knowledge signalling](https://www.youtube.com/watch?v=GzVT16lFOHU) - Koh Wei Jie and Barry WhiteHat at Devcon 5
[Hands-on Applications of Zero-Knowledge Signalling](https://www.youtube.com/watch?v=7wd2aAN2jXI) - Koh Wei Jie at Devcon 5
Semaphore V2 is the work of several people, for a complete list of contributors you can visit our [Github pages](https://github.com/semaphore-protocol/semaphore/graphs/contributors).
- [Identity commitment](#identity-commitment): the public value.
- Identity trapdoor and identity nullifier: secret values known only by the user.
## Semaphore group
A group is a binary incremental [Merkle tree](#merkle-tree) in which each leaf contains an [identity commitment](#identity-commitment) for a user.
The identity commitment proves that the user is a group member without revealing the Semaphore identity of the user.
Semaphore uses the **Poseidon** hash function to create Merkle trees.
For more information, see the [Poseidon website](https://www.poseidon-hash.info/).
## Identity commitment
The public [Semaphore identity](#semaphore-identity) value used in [Semaphore groups](#semaphore-group).
Semaphore uses the **Poseidon** hash function to create the identity commitment from the Semaphore identity secret values.
For more information, see the [Poseidon website](https://www.poseidon-hash.info/).
## Merkle tree
A tree in which every leaf (i.e., a node that doesn't have children) is labelled with the cryptographic hash of a data block,
and every node that isn't a leaf is labelled with the cryptographic hash of its child node labels.
In zero-knowledge protocols, Merkle trees can be used to efficiently summarize and validate large data sets.
To validate that a tree contains a specific leaf, a verifier only needs a portion of the complete data structure.
For more information, see [Merkle tree in Wikipedia](https://en.wikipedia.org/wiki/Merkle_tree).
## Nullifier
A value used to prevent double entry or double signalling.
See [Circuit nullifier hash](/V2/technical-reference/circuits/#nullifier-hash).
## Relay
A third-party who receives a fee for including relayed transactions in the blockchain (McMenamin, Daza, and Fitz. https://eprint.iacr.org/2022/155.pdf, p.3).
To preserve the anonymity of the user broadcasting a signal with Semaphore, an application may use a relayer to post the signal transaction to Ethereum on behalf of the user.
Applications may provide rewards for relayers and implement front-running prevention mechanisms, such as requiring the signals to include the relayer’s address, binding the
signal to that specific address (https://semaphore.pse.dev/whitepaper-v1.pdf, p.6).
## Trusted setup files
The secure, verifiable parameters generated by Semaphore's trusted setup ceremony.
Semaphore uses the trusted setup files to generate and verify valid zero-knowledge proofs.
To generate or verify valid zero-knowledge proofs with Semaphore, applications must include the following Semaphore _trusted setup_ files:
- semaphore.zkey
- semaphore.wasm
- semaphore.json
For a complete list of ready-to-use files, see [trusted-setup-pse.org](https://www.trusted-setup-pse.org).
To learn more, see the [trusted setup ceremony](https://storage.googleapis.com/trustedsetup-a86f4.appspot.com/semaphore/semaphore_top_index.html).
Use Semaphore in your application or smart contract to create off-chain and on-chain groups.
A [Semaphore group](/V2/glossary/#semaphore-group) contains [identity commitments](/V2/glossary/#identity-commitment) of group members.
Example uses of groups include the following:
- Poll question that attendees join to rate an event.
- Ballot that members join to vote on a proposal.
- Whistleblowers who are verified employees of an organization.
A Semaphore group is an [incremental Merkle tree](/V2/glossary/#merkle-tree), and group members (i.e., identity commitments) are tree leaves.
Semaphore groups set the following two parameters:
-**Tree depth**: the maximum number of members a group can contain (`max size = 2 ^ tree depth`).
-**Zero value**: the value used to calculate the zero nodes of the incremental Merkle tree.
Learn how to work with groups.
- [**Off-chain groups**](#off-chain-groups)
- [**On-chain groups**](#on-chain-groups)
## Off-chain groups
- [Create a group](#create-a-group)
- [Add members](#add-members)
- [Remove or update members](#remove-or-update-members)
### Create a group
Use the [`@semaphore-protocol/group`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/group) library `Group` class to create an off-chain group.
#### Options
-**Tree depth**: (_default `20`_) the maximum number of members a group can contain (`max size = 2 ^ tree depth`).
-**Zero value**: (_default `BigInt(0)`_) the value for a tree node that doesn't have a member assigned.
To create a group with default _`treeDepth`_ and _`zeroValue`_, call the `Group` constructor without parameters--for example:
To remove members from a group, pass the member index to the `Group removeMember` function--for example:
```ts
group.removeMember(0)
```
To update members in a group, pass the member index and the new value to the `Group updateMember` function--for example:
```ts
group.updateMember(0,2)
```
:::caution
Removing a member from a group sets the node value to `zeroValue`.
Given that the node isn't removed, and the length of the `group.members` array doesn't change.
:::
## On-chain groups
The [`SemaphoreGroups`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/contracts/base/SemaphoreGroups.sol) contract uses the [`IncrementalBinaryTree`](https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/incremental-merkle-tree.sol/contracts/IncrementalBinaryTree.sol) library and provides methods to create and manage groups.
:::info
You can import `SemaphoreGroups` and other Semaphore contracts from the [`@semaphore-protocol/contracts`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts) NPM module.
:::
Alternatively, you can use an already deployed [`Semaphore`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/contracts/Semaphore.sol) contract and use its group external functions.
In order to join a [Semaphore group](/V2/glossary#semaphore-group), a user must first create a [Semaphore identity](/V2/glossary#semaphore-identity).
A Semaphore identity contains two values generated with the identity:
- Identity trapdoor
- identity nullifier
To use and verify the identity, the identity owner (user) must know the trapdoor and nullifier values.
To prevent fraud, the owner should keep both values secret.
## Create identities
In your code, use the [`@semaphore-protocol/identity`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/identity) library to create a Semaphore identity _deterministically_ (from the hash of a message) or _randomly_.
- [**Create random identities**](#create-random-identities)
Learn how to use Semaphore to generate and verify zero-knowledge proofs.
Once a user joins their [Semaphore identity](/V2/glossary#semaphore-identity) to a [Semaphore group](/V2/glossary#semaphore-group), the user can signal anonymously with a zero-knowledge proof that proves the following:
- The user is a member of the group.
- The same user created the signal and the proof.
Developers can use Semaphore for the following:
- [**Generate a proof off-chain**](#generate-a-proof-off-chain)
- [**Verify a proof off-chain**](#verify-a-proof-off-chain)
- [**Verify a proof on-chain**](#verify-a-proof-on-chain)
## Generate a proof off-chain
Use the [`@semaphore-protocol/proof`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/proof) library to generate an off-chain proof.
To generate a proof, pass the following properties to the `generateProof` function:
-`identity`: The Semaphore identity of the user broadcasting the signal and generating the proof.
-`group`: The group to which the user belongs.
-`externalNullifier`: The value that prevents double-signaling.
-`signal`: The signal the user wants to send anonymously.
-`snarkArtifacts`: The `zkey` and `wasm` [trusted setup files](/V2/glossary/#trusted-setup-files).
In the voting system use case, once all the voters have joined their [identities](/V2/guides/identities#create-identities) to the ballot [group](/V2/guides/groups),
a voter can generate a proof to vote for a proposal.
In the call to `generateProof`, the voting system passes the unique ballot ID (the [Merkle tree](/V2/glossary#merkle-tree) root of the group) as the
`externalNullifier` to prevent the voter signaling more than once for the ballot.
The following code sample shows how to use `generateProof` to generate the voting proof:
Use the [`@semaphore-protocol/proof`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/proof) library to verify a Semaphore proof off-chain.
To verify a proof, pass the following to the `verifyProof` function:
-_`proof`_: the Semaphore proof.
-_`verificationKey`_: the JavaScript object in the `semaphore.json` [trusted setup file](/V2/glossary/#trusted-setup-files).
The following code sample shows how to parse the verification key object from `semaphore.json`
awaitverifyProof(verificationKey,fullProof)// true or false.
```
`verifyProof` returns a Promise that resolves to `true` or `false`.
## Verify a proof on-chain
Use the [`SemaphoreCore`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/contracts/base/SemaphoreCore.sol) contract to verify proofs on-chain. It uses a verifier deployed to Ethereum and provides methods hash the signal and verify a proof.
:::info
You can import `SemaphoreCore` and other Semaphore contracts from the [`@semaphore-protocol/contracts`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts) NPM module.
:::
To verify Semaphore proofs in your contract, import `SemaphoreCore` and pass the following to the `_verifyProof` internal method:
-_`signal`_: The Semaphore signal to prove.
-_`root`_: The root of the Merkle tree.
-_`nullifierHash`_: a [nullifier hash](#retrieve-a-nullifier-hash).
-_`externalNullifier`_: The external nullifier.
-_`proof`_: A [_Solidity-compatible_ Semaphore proof](#generate-a-solidity-compatible-proof).
-_`verifier`_: The verifier address.
Remember to save the `nullifierHash` on-chain to avoid double-signaling.
Alternatively, you can use an already deployed [`Semaphore`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/Semaphore.sol) contract and use its `verifiyProof` external function.
### Generate a Solidity-compatible proof
To transform a proof to be compatible with Solidity contracts, pass the proof to the `packToSolidityProof` utility function--for example:
[Semaphore V2 is Live!](https://medium.com/privacy-scaling-explorations/semaphore-v2-is-live-f263e9372579) - Privacy and Scaling Explorations
[To Mixers and Beyond: presenting Semaphore, a privacy gadget built on Ethereum](https://medium.com/coinmonks/to-mixers-and-beyond-presenting-semaphore-a-privacy-gadget-built-on-ethereum-4c8b00857c9b) - Koh Wei Jie
[Privacy in Ethereum](https://www.youtube.com/watch?v=maDHYyj30kg) - Barry WhiteHat at the Taipei Ethereum Meetup
[Snarks for mixing, signaling and scaling by](https://www.youtube.com/watch?v=lv6iK9qezBY) - Barry WhiteHat at Devcon 4
[Privacy in Ethereum](https://www.youtube.com/watch?v=zBUo7G95wYE) - Barry WhiteHat at Devcon 5
[A trustless Ethereum mixer using zero-knowledge signalling](https://www.youtube.com/watch?v=GzVT16lFOHU) - Koh Wei Jie and Barry WhiteHat at Devcon 5
[Hands-on Applications of Zero-Knowledge Signalling](https://www.youtube.com/watch?v=7wd2aAN2jXI) - Koh Wei Jie at Devcon 5
[The Graph](https://thegraph.com/) is a protocol for indexing networks like Ethereum and IPFS.
Site owners publish _subgraphs_ that expose site data for anyone to query.
Semaphore's subgraph allows you to retrieve data from the [`Semaphore.sol`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/Semaphore.sol) smart contract.
:::tip
The Graph protocol uses the [GraphQL](https://graphql.org/) query lanaguage. For examples, see the [GraphQL API documentation](https://thegraph.com/docs/developer/graphql-api). Visit the [subgraph repository](https://github.com/semaphore-protocol/subgraph) to see the list of Semaphore subgraphs.
:::
## Schema
### MerkleTree
-`id`: unique identifier among all MerkleTree entities,
-`depth`: Merkle tree depth,
-`root`: Merkle tree root,
-`zeroValue`: Merkle tree zero value,
-`numberOfLeaves`: total number of tree leaves,
-`group`: link to the Group entity.
### Group
-`id`: unique identifier among all Group entities,
-`merkleTree`: link to the MerkleTree entity,
-`timestamp`: block timestamp,
-`admin`: admin of the group,
-`members`: list of group members.
-`verifiedProofs`: list of group proofs.
### Member
-`id`: unique identifier among all Member entities,
The [Semaphore circuit](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/circuits) is the heart of the protocol and consists of three parts:
- [**Proof of membership**](/V2/technical-reference/circuits#proof-of-membership)
The diagram above shows how the input signals are used in the Semaphore circuit and how the outputs are calculated.
## Proof of membership
The circuit hashes the hash of the identity nullifier with the identity trapdoor to generate an identity commitment. Then, it verifies the proof of membership against the Merkle root and the identity commitment.
**Private inputs:**
-`treeSiblings[nLevels]`: the values along the Merkle path to the user's identity commitment,
-`treePathIndices[nLevels]`: the direction (0/1) per tree level corresponding to the Merkle path to the user's identity commitment,
-`identityNullifier`: the 32-byte identity secret used as nullifier,
-`identityTrapdoor`: the 32-byte identity secret used as trapdoor.
**Public outputs:**
-`root`: The Merkle root of the tree.
## Nullifier hash
The circuit hashes the identity nullifier with the external nullifier and then checks that the result matches the provided nullifier hash.
Nullifier hashes saved in a Semaphore smart contract allow the contract to reject a proof that contains a used nullifier hash.
**Private inputs:**
-`identityNullifier`: the 32-byte identity secret used as a nullifier.
**Public inputs:**
-`externalNullifier`: the 32-byte external nullifier.
**Public outputs:**
-`nullifierHash`: the hash of the identity nullifier and the external nullifier; used to prevent double-signaling.
**Procedure:**
## Signal
The circuit calculates a dummy square of the signal hash to prevent any tampering with the proof.
To use Semaphore contracts and interfaces in your project,
install the [`@semaphore-protocol/contracts`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts) NPM package.
:::
## Base contracts
Semaphore provides the following base contracts:
- [`SemaphoreCore.sol`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/base/SemaphoreCore.sol): contains the functions to verify Semaphore proofs;
- [`SemaphoreGroups.sol`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/base/SemaphoreGroups.sol): contains the functions to create groups and add/remove members.
These contracts are closely related to the protocol.
You can inherit them in your contract or you can use [`Semaphore.sol`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/Semaphore.sol), which inherits them for you.
See our [deployed contracts](/V2/deployed-contracts#semaphore) to find the addresses for your network.
:::info
While some dApps may use on-chain groups, others may prefer to use off-chain groups, saving only their tree roots in the contract.
:::
## Extension contracts
- [`SemaphoreVoting.sol`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/extensions/SemaphoreVoting.sol): voting contract that contains the essential functions to create polls, add voters, and anonymously cast votes.
- [`SemaphoreWhistleblowing.sol`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/extensions/SemaphoreWhistleblowing.sol): whistleblowing contract that contains the essential functions to create entities (for example: non-profit organizations), add whistleblowers, and anonymously publish leaks.
These contracts extend the protocol to provide application logic for specific use-cases.
More extensions will be added in the future.
## Verifiers
To verify Semaphore proofs, the [`SemaphoreCore.sol`](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/base/SemaphoreCore.sol) contract requires the address of a deployed verifier contract.
You can choose to manually deploy the [verifier](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/contracts/verifiers) you prefer or you can use one of our [deployed verifiers](/V2/deployed-contracts#verifiers).
Each verifier name indicates the tree depth that it can verify.
For example, given a Semaphore proof generated with a tree depth `20`:
- The `Verifier20.sol` contract can verify the proof.
- The [group](/guides/groups) used for the proof can have a maximum `2^20=1048576` members.
The private voting use case describes how Semaphore interacts with your users and Ethereum to allow users to cast private votes in your application.
Learn how Semaphore enables applications to do the following:
- Register members as voters.
- Allow members to vote anonymously.
- Prove voter membership.
- Record and prove votes.
- Prevent double-voting.
## Roles
-**[Developer or community admin](#developer-or-community-admin)**
-**[Community member (dApp user)](#community-member)**
-**[Relay](#relay)**
### Developer or community admin
As a developer or community admin, you deploy the following:
-**Smart contract on Ethereum**: implements the Semaphore **base contract** to create a poll (Semaphore **group** that members join to vote), post transactions, and verify proofs on Ethereum.
-**Decentralized application (dApp)**: your application that provides a user interface (UI) where members join a poll and vote on a proposal.
### Community member
Community members connect their wallets to the dApp to take the following actions:
1. Verify ownership of the community token.
2. Generate an anonymous ID.
3. Cast a vote.
### Relay
To preserve anonymity and avoid disclosing the member's wallet address, the dApp may use a [relay](/V2/glossary/#relay) to broadcast the vote.
The relay calls the **contract** function that then posts the member's vote transaction to Ethereum.
## Private voting
Consider a scenario where your community issues a token that users can mint.
The token might be a Proof of Attendance (POAP), NFT, or social token that your users can mint to receive membership and vote in your community.
The voting scenario has the following steps:
1. [Create a poll](#create-a-poll): Coordinator creates a poll, or _group_, in which members can vote on a proposal.
2. [Register voters](#register-voters): Members join the poll to vote.
3. [Record votes](#record-votes): Once the poll opens, members may cast one vote, or _signal_, on the topic.
### Create a poll
A community coordinator or dApp administrator uses the deployed smart contract to create an on-chain (Ethereum) poll, a [Semaphore group](/V2/guides/groups/) that members can join and cast votes to.
In the following sample code, the voting contract declares a `createPoll` function that uses the Semaphore base `_createGroup` function:
Next, learn how to [register voters](#register-voters) for the poll.
### Register voters
Before a user can register to vote, the dApp needs to verify membership by checking the user's wallet for the NFT.
To grant access to the wallet, the user clicks a `Connect wallet` button in the dApp and allows the dApp to check for the NFT.
Once a member is verified, the dApp provides the following member interactions:
1. [Generate a private identity](#generate-a-private-identity).
2. [Join a poll](#join-a-poll).
:::info
To learn how to connect to Ethereum wallets, visit the [ethers.js Getting Started documentation]((https://docs.ethers.io/v5/getting-started).
:::
#### Generate a private identity
To generate a private identity, the member completes a form in the dApp UI.
With the form values and the `@semaphore-protocol/identity` library, the dApp prompts the member to sign a wallet message and then generates the signed private identity.
The private identity is known only to the member and can be used in future interactions with the dApp.
Next, learn how members [join a poll](#join-a-poll).
#### Join a poll
Once the member has a private identity for the dApp, the member may select a poll to vote in.
When the member selects a poll, the dApp does the following:
1. Uses the `@semaphore-protocol/identity` library to generate an anonymous Semaphore ID, or _identity commitment_, from the private identity.
2. Calls a contract function that adds the new Semaphore ID to the on-chain poll.
With a member registered for a poll, learn how the dApp [records votes](#record-votes).
### Record votes
Once members have joined a poll, the coordinator starts the poll to allow voting.
When a member votes (for example, by selecting a radio button), then the dApp takes the following actions:
1. Uses the `@semaphore-protocol/proof` library to create a proof of the vote, the poll identifier, the Semaphore ID, and a [nullifier](/V2/glossary/#nullifier) that prevents double-voting.
2. Sends the vote proof to the [relay](#relay).
### Related
- To get started developing with Semaphore, see the [Quick setup](/V2/quick-setup/) guide.
- For an example app that you can use to start your own project, see [Semaphore boilerplate](https://github.com/semaphore-protocol/boilerplate).
[Semaphore](https://github.com/semaphore-protocol/semaphore) is a [zero-knowledge](https://z.cash/technology/zksnarks) protocol that allows you to cast a signal (for example, a vote or endorsement) as a provable group member without revealing your identity.
Additionally, it provides a simple mechanism to prevent double-signaling.
Use cases include private voting, whistleblowing, anonymous DAOs and mixers.
## Features
With Semaphore, you can allow your users to do the following:
1. [Create a Semaphore identity](/V2/guides/identities/).
2. [Add their Semaphore identity to a group (i.e. _Merkle tree_)](/V2/guides/groups/).
3. [Send a verifiable, anonymous signal (e.g a vote or endorsement)](/V2/guides/proofs/).
When a user broadcasts a signal (for example: a vote), Semaphore zero-knowledge
proofs can ensure that the user has joined the group and hasn't already cast a signal with their nullifier.
Semaphore uses on-chain Solidity contracts and off-chain JavaScript libraries that work in tandem.
- Off chain, JavaScript libraries can be used to create identities, manage groups and generate proofs.
- On chain, Solidity contracts can be used to manage groups and verify proofs.
## Developer benefits
Semaphore is designed to be a simple and generic _privacy layer_ for decentralized applications (dApps) on Ethereum. It encourages modular application design, allowing dApp developers to choose and customize the on-chain and off-chain components they need.
## About the code
The core of the protocol is the [circuit logic](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1/packages/circuits/scheme.png).
and [JavaScript libraries](https://github.com/semaphore-protocol/semaphore/tree/v2.6.1#-packages) that allow developers to generate zero-knowledge proofs and verify them with minimal effort.
Semaphore es el esfuerzo de varias personas, para ver una lista completa de contribuidores puede visitar nuestras [páginas en Github](https://github.com/semaphore-protocol/semaphore/graphs/contributors).
Semaphore es un protocolo de conocimiento cero (zero-knowledge) que permite a los usuarios demostrar su pertenencia a un grupo y enviar señales como votos, comentarios o mensajes de texto sin revelar la identidad del usuario.
Esto significa que las señales no tienen conexión con las identidades.
También proporciona un mecanismo simple para evitar la doble señalización, lo que significa que no puede verificar la misma prueba dos veces.
## ¿Dónde puedo hacer preguntas sobre Semaphore?
Puede hacer preguntas sobre Semaphore en [Telegram](https://semaphore.pse.dev/telegram) o abriendo un [Semaphore Discussion](https://github.com/semaphore-protocol/semaphore/discussions).
## ¿Por qué las identidades requieren tanto `identity trapdoor` como `identity nullifier`?
Tener dos valores privados proporciona una capa de seguridad adicional. Si alguien rompe el hash del nullifier (imagínese que existe cierta maleabilidad de que la preimagen de Poseidón es fácil de encontrar cuando se aplica un hash con un valor específico X, que es el external nullifier elegido por los desarrolladores), el atacante puede encontrar todos los mensajes que envió la misma persona, pero no puede encontrar a quién, porque también está el trapdoor, que podría ser más difícil de romper.
## ¿Cuál es la diferencia entre `identity nullifier`, `external nullifier` y `nullifier hash`?
El identity nullifier (anulador de identidad) es uno de los valores secretos del usuario, mientras que el external nullifier (anulador externo) se puede utilizar como un tema sobre el que los usuarios pueden generar una prueba válida (por ejemplo, enviar votos anónimos) un número limitado de veces.
Tanto el identity nullifier como el external nullifier se utilizan para evitar que la misma prueba se verifique dos veces, lo que significa que si un usuario genera la misma prueba (con la misma identidad y el mismo external nullifier) dos veces, la segunda no será válida.
Finalmente, el nullifier hash (hash del anulador) es solo el hash del identity nullifier y el external nullifier que se utiliza para comprobar si ya se ha generado la misma prueba.
En el caso de una aplicación de votación, si tiene un grupo y desea que todos los miembros de este grupo voten solo una vez, puede usar la identificación del grupo como external nullifier. Cuando un usuario vota por primera vez, puede guardar el hash de su identity nullifier y la identificación del grupo (es decir, el nullifier hash) y evitar la doble votación comprobando si ese hash ya existe.
Vea los [circuitos de Semaphore](https://docs.semaphore.pse.dev/technical-reference/circuits) para más información técnica, o el [Semaphore boilerplate](https://github.com/semaphore-protocol/boilerplate) para un caso de uso real.
## ¿Por qué debo evitar que las pruebas se verifiquen dos veces?
Dado que las pruebas de conocimiento cero son completamente anónimas, es importante evitar que las generadas por identidades elegibles sean reutilizadas por una parte malintencionada.
En una aplicación de voto anónimo, por ejemplo, sin chequeos, se podría reutilizar una prueba válida para volver a votar.
## ¿Dónde puedo encontrar ejemplos de aplicaciones que utilicen Semaphore?
Puede encontrar algunas aplicaciones que usan Semaphore en [este blog post](https://mirror.xyz/privacy-scaling-explorations.eth/Yi4muh-vzDZmIqJIcM9Mawu2e7jw8MRnwxvhFcyfns8).
## ¿Cómo puedo iniciar un proyecto usando Semaphore?
Hay tres formas de comenzar a usar Semaphore en su proyecto: usando la [Semaphore CLI](https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli), usando el [Semaphore boilerplate](https://github.com/semaphore-protocol/boilerplate) como una plantilla o bifurcándolo, o instalando los paquetes de Semaphore manualmente.
### Semaphore CLI
Para crear un nuevo proyecto podrías usar `npx` o instalar la [Semaphore CLI](https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli) globalmente usando `npm` y entonces crear un nuevo proyecto usando el comando `semaphore create`. Vea [Configuración Rápida](https://docs.semaphore.pse.dev/quick-setup) para más información.
Hay tres plantillas soportadas en este momento: `contracts-hardhat`, `monorepo-ethers` y `monorepo-subgraph`.
-`contracts-hardhat`: Contiene un caso de uso básico de Semaphore. Viene con un contrato de muestra, una prueba (test) para ese contrato y una tarea (task) de muestra que implementa (deploys) ese contrato.
-`monorepo-ethers`: Es una aplicación completa que demuestra un caso de uso básico de Semaphore. Viene con un contrato de muestra, una prueba para ese contrato y una tarea de muestra que implementa ese contrato. También contiene una interfaz para usar el contrato. Esta plantilla usa [Ethers](https://github.com/ethers-io/ethers.js/) por detrás para obtener datos on-chain.
-`monorepo-subgraph`: Es lo mismo que la plantilla `monorepo-ethers`, pero usa [The Graph protocol](https://thegraph.com/) por detrás para obtener datos on-chain.
La Semaphore CLI también se puede usar para obtener datos de grupo de una red soportada. Hay comandos como: `get-groups`, `get-group`, `get-members`, `get-proofs`:
-`get-groups`: Muestra la lista de grupos de una red soportada.
-`get-group`: Muestra los datos de un grupo de una red soportada.
-`get-members`: Muestra los miembros de un grupo de una red soportada.
-`get-proofs`: Muestra las pruebas de un grupo de una red soportada.
### Semaphore boilerplate
Para crear un proyecto, también puede utilizar el [Semaphore boilerplate](https://github.com/semaphore-protocol/boilerplate). Puede bifurcarlo o usarlo como plantilla.
Las plantillas de la Semaphore CLI y el Semaphore boilerplate contienen el mismo código, que es una aplicación de feedback en la que puede crear una identidad, unirse a un grupo, y enviar su feedback de forma anónima. Son casi lo mismo, la única diferencia es que las plantillas usan CSS para que pueda decidir el framework de CSS o librería que desea usar y el boilerplate usa [ChakraUI](https://chakra-ui.com/) por defecto.
También puede probar la aplicación Semaphore boilerplate en vivo aquí: https://demo.semaphore.pse.dev.
### Instalación manual
Alternativamente, también puede instalar todos los paquetes manualmente usando npm o yarn siguiendo la [documentación de Semaphore](https://docs.semaphore.pse.dev).
## ¿Cómo puedo contribuir al protocolo?
Hay varias formas de contribuir al protocolo, puede encontrar más información al respecto aquí: https://github.com/semaphore-protocol#ways-to-contribute.
La identidad de un usuario en el protocolo Semaphore.
Una identidad contiene los tres valores que se mencionan a continuación:
- [Compromiso de identidad](#compromiso-de-identidad-identity-commitment) (identity commitment): el valor público.
- Identidad trampilla (identity trapdoor) y anulador de identidad (identity nullifier): valores secretos que únicamente son del conocimiento del usuario.
## Compromiso de identidad (Identity commitment)
El valor público de la [identidad Semaphore](#identidad-semaphore) utilizado en los [grupos Semaphore](#grupo-semaphore).
Semaphore utiliza la función hash [Poseidon](https://www.poseidon-hash.info/) para crear un compromiso de identidad a partir de los valores secretos de la identidad Semaphore.
## Grupo Semaphore
Un grupo es un [árbol de Merkle](#árbol-de-merkle-merkle-tree) binario e incremental en el que cada hoja contiene un [compromiso de identidad](#compromiso-de-identidad-identity-commitment) para un usuario.
El compromiso de identidad comprueba que un usuario es un miembro del grupo sin revelar la identidad Semaphore del usuario.
Semaphore utiliza la función hash **Poseidon** para crear árboles de Merkle.
Para mayor información, vea el [sitio web de Poseidon](https://www.poseidon-hash.info/).
## Árbol de Merkle (Merkle tree)
Un árbol en el que cada hoja (es decir, un nodo que no tiene hijos) es etiquetado con el hash criptográfico de un bloque de datos,
y cada nodo, que no es una hoja, es etiquetado con el hash criptográfico de las etiquetas de sus nodos hijos.
En los protocolos de conocimiento zero (ZK), los árboles de Merkle pueden ser utilizados para resumir y validar de forma eficiente grandes conjuntos de datos.
Para validar que un árbol contiene una hoja en específico, un verificador sólo necesita una porción de la estructura completa de datos.
Para más información, vea [árbol de Merkle en Wikipedia](https://es.wikipedia.org/wiki/%C3%81rbol_de_Merkle).
## Anulador (Nullifier)
Un valor utilizado para prevenir registros dobles o dos señales emitidas por el mismo usuario.
Ver [hash de circuito nullifier](/V3/technical-reference/circuits#hash-anulador-nullifier-hash).
## Retransmisor (Relayer)
Un tercero que recibe una comisión por incluir transacciones retransmitidas en la blockchain (McMenamin, Daza, and Fitz. https://eprint.iacr.org/2022/155.pdf, p.3).
Para preservar la anonimidad del usuario emitiendo una señal con Semaphore, una aplicación puede utilizar un retransmisor para publicar la transacción de la señal en Ethereum en nombre del usuario.
Las aplicaciones pueden ofrecer recompensas a los retransmisores e implementar mecanismos para prevenir ventajas maliciosas, como requerir que las señales incluyan la dirección del retransmisor, vinculando así la señal a esa dirección en específico (https://semaphore.pse.dev/whitepaper-v1.pdf, p.6).
## Archivos confiables de configuración (Trusted setup files)
Los parámetros verificables y seguros generados por la ceremonia de configuración de confianza de Semaphore.
Semaphore utiliza los archivos confiables de configuración para generar y verificar pruebas válidas de conocimiento cero.
Para generar o verificar pruebas válidas de conocimiento cero con Semaphore, las aplicaciones deben incluir los siguientes archivos _confiables de configuración_ de Semaphore.
- semaphore.zkey
- semaphore.wasm
- semaphore.json
Para ver una lista completa de archivos listos para utilizarse, vea [trusted-setup-pse.org](https://www.trusted-setup-pse.org).
Para aprender más, vea la [ceremonia de configuración de confianza](https://storage.googleapis.com/trustedsetup-a86f4.appspot.com/semaphore/semaphore_top_index.html) (trusted setup ceremony).
## Señales (Signals)
El término "señales" en Semaphore se refiere a los valores que el usuario transmite al votar, confirmar, enviar un mensaje, etc. Por otro lado, "[señales](https://docs.circom.io/circom-language/signals/)" en Circom se refiere a datos que contienen elementos dentro del campo de Z/pZ. En Circom, las "señales" se pueden definir como entrada o salida y, de lo contrario, se consideran señales intermedias.
Para obtener datos on-chain del contrato [Semaphore.sol](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/contracts/Semaphore.sol), puedes usar la librería [@semaphore-protocol/data](https://github.com/semaphore-protocol/semaphore/tree/main/packages/data).
Hay dos formas para hacer esto, usando [`SemaphoreSubgraph`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/data/src/subgraph.ts) o [`SemaphoreEthers`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/data/src/ethers.ts). La clase `SemaphoreSubgraph` usa el [subgrafo de Semaphore](https://github.com/semaphore-protocol/subgraph), el cual usa [The Graph Protocol](https://thegraph.com/) detrás del telón, y la clase `SemaphoreEthers` usa [Ethers](https://github.com/ethers-io/ethers.js/).
- [**Obtener datos usando SemaphoreSubgraph**](#obtener-datos-usando-semaphoresubgraph)
- [**Obtener datos usando SemaphoreEthers**](#obtener-datos-usando-semaphoreethers)
## Instalar librería
<Tabs
defaultValue="npm"
groupId="package-managers"
values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
<TabItem value="npm">
```bash
npm install @semaphore-protocol/data@^3
```
</TabItem>
<TabItem value="yarn">
```bash
yarn add @semaphore-protocol/data@^3
```
</TabItem>
<TabItem value="pnpm">
```bash
pnpm add @semaphore-protocol/data@^3
```
</TabItem>
</Tabs>
## Obtener datos usando SemaphoreSubgraph
Para obtener datos usando el subgrafo de Semaphore puedes usar la clase [`SemaphoreSubgraph`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/data/src/subgraph.ts) del paquete [@semaphore-protocol/data](https://github.com/semaphore-protocol/semaphore/tree/main/packages/data).
```typescript
import { SemaphoreSubgraph } from "@semaphore-protocol/data"
const semaphoreSubgraph = new SemaphoreSubgraph()
// or:
const semaphoreSubgraph = new SemaphoreSubgraph("arbitrum")
Para obtener datos usando Ethers puedes usar la clase [`SemaphoreEthers`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/data/src/ethers.ts) del paquete [@semaphore-protocol/data](https://github.com/semaphore-protocol/semaphore/tree/main/packages/data).
```typescript
import { SemaphoreEthers } from "@semaphore-protocol/data"
const semaphoreEthers = new SemaphoreEthers()
// or:
const semaphoreEthers = new SemaphoreEthers("homestead", {
address: "semaphore-address",
startBlock: 0
})
// or:
const semaphoreEthers = new SemaphoreEthers("http://localhost:8545", {
Un [grupo Semaphore](/V3/glossary/#grupo-semaphore) contiene los [identity commitments](/V3/glossary/#compromiso-de-identidad-identity-commitment) (compromisos de identidad) de miembros del grupo.
Estos son algunos ejemplos de uso de los grupos:
- Encuesta con preguntas a la que se unen las personas que acudieron a un evento para calificarlo,
- votación a la que se unen los miembros para votar por una propuesta,
- Denunciantes que están verificados como empleados de una organización.
Un grupo Semaphore es un [árbol de Merkle incremental](/V3/glossary/#árbol-de-merkle-merkle-tree), y los miembros del grupo (por ejemplo, [identity commitments](/V3/glossary/#compromiso-de-identidad-identity-commitment)) son las hojas del árbol.
Los grupos Semaphore determinan los siguientes tres parámetro:
- **Group id**: un identificador único para el grupo;
- **Tree depth**: el número máximo de miembros que puede contener un grupo (`max size = 2 ^ tree depth`);
- **Members** la lista de miembros para inicializar el grupo.
- [Remover o actualizar miembros](#remover-o-actualizar-miembros)
### Crear un grupo
Utilice la clase `Group` de la librería [`@semaphore-protocol/group`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/group) para crear un grupo off-chain con los siguientes parámetros:
- `Group id`: un identificar único para el grupo;
- `Tree depth`: (*default `20`*) el número máximo de usuarios que puede contener un grupo, el valor por defecto es 20 (`max size = 2 ^ tree depth`).
- `Members`: (*default `[]`*) la lista de miembros para inicializar el grupo.
#### Instalar librería:
<Tabs
defaultValue="npm"
groupId="package-managers"
values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
<TabItem value="npm">
```bash
npm install @semaphore-protocol/group@^3
```
</TabItem>
<TabItem value="yarn">
```bash
yarn add @semaphore-protocol/group@^3
```
</TabItem>
<TabItem value="pnpm">
```bash
pnpm add @semaphore-protocol/group@^3
```
</TabItem>
</Tabs>
Para crear un grupo con el número de usuarios que aparece por defecto (20) *`treeDepth`*, llame la función para construir un `Group` sin el segundo parámetro. Por ejemplo:
```ts
import { Group } from "@semaphore-protocol/group"
const group = new Group(1)
```
El siguiente código de ejemplo pasa por *`treeDepth`* para crear un grupo para `2 ^ 30 = 1073741824` miembros:
```ts
import { Group } from "@semaphore-protocol/group"
const group = new Group(1, 30)
```
También puede inicializar un grupo con varios miembros pasando la lista de identity commitments (miembros) como tercer parámetro al crear el grupo:
Cuando utiliza la misma identidad Semaphore en varios grupos, si un atacante toma control de esa identidad, todos los grupos de los que forma parte estarán comprometidos. Considere utilizar identidades diferentes para cada grupo.
:::
### Remover o actualizar miembros
Para remover miembros de un equipo, pasa el índice del miembro por la función `Group removeMember`. Por ejemplo:
```ts
group.removeMember(0)
```
Para actualizar los miembros dentro de un grupo, pasa el índice del miembro y el nuevo valor por la función `Group updateMember`. Por ejemplo:
```ts
group.updateMember(0, 2)
```
:::caution
Remover a un miembro de un grupo configura el valor del nodo a un valor especial (ejemplo, `zeroValue`).
Dado que ese nodo no se remueve y el largo de la selección de `group.members` no cambia.
:::
## Grupos on-chain
El contrato [`SemaphoreGroups`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/contracts/base/SemaphoreGroups.sol) utiliza la librería del [`IncrementalBinaryTree`](https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/incremental-merkle-tree.sol/contracts/IncrementalBinaryTree.sol) (árbol binario incremental) y provee métodos para crear y administrar grupos.
:::información
puede importar el contrato `SemaphoreGroups.sol` y otros contratos Semaphore del módulo NPM [`@semaphore-protocol/contracts`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/contracts).
:::
Alternativamente, puede utilizar un contrato [`Semaphore.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/contracts/Semaphore.sol) ya desplegado y utilizar sus funciones externas para grupos.
:::caution
`Semaphore.sol` no revisa si un miembro con un identity commitment en específico ya existe en un grupo. Esta revisión se debe realizar off-chain.
:::
:::caution
`Semaphore.sol` incluye un mecanismo para verificar pruebas Semaphore creadas con raíces de árboles de Merkle antiguas. La duración de este mecanismo puede ser definido por el admin en la función `createGroup`. Por lo tanto, los miembros de un grupo pueden continuar generando pruebas válidas incluso después de ser removidos. Para más información ver el issue [#98](https://github.com/semaphore-protocol/semaphore/issues/98).
Para unirse a un [grupo Semaphore](/V3/glossary#grupo-semaphore), un usuario primero deberá crear una [identidad Semaphore](/V3/glossary#identidad-semaphore).
Una identidad Semaphore contiene dos valores generados junto con la identidad:
- Identity trapdoor (Identidad trampilla)
- Identity nullifier (Anulador de identidad)
Para utilizar y verificar su identidad, la persona dueña de la identidad (usuario) debe conocer los valores trapdoor y nullifier.
Para prevenir fraudes, la persona dueña debe conservar de forma secreta ambos valores.
## Crear identidades
En su código, utilice la librería [`@semaphore-protocol/identity`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/identity) para crear una identidad Semaphore *de forma determinística* (del hash de un mensaje) o *de forma aleatoria*.
Para crear una identidad aleatoria, represente `Identity` sin algún parámetro. Por ejemplo:
```ts
import { Identity } from "@semaphore-protocol/identity"
const { trapdoor, nullifier, commitment } = new Identity()
```
La nueva identidad contiene dos valores aleatorios secretos: `trapdoor` y `nullifier`, y un valor público: `commitment`.
El hash Poseidon del identity nullifier y trapdoor se conoce como *identity secret* (el secreto de identidad),
y su hash es el *identity commitment* (compromiso de identidad).
Un identity commitment (compromiso de identidad), de forma similar a las direcciones Ethereum, es un valor público que se utiliza en los grupos Semaphore para representar la
identidad de un miembro del grupo. Los valores secretos son similares a las llaves privadas
Ethereum y se utilizan para generar pruebas de conocimiento cero (ZKP) Semaphore y autenticar señales.
### Crear identidades determinísticas
Si transmite un mensaje como un parámetro, Semaphore genera `trapdoor` y `nullifier`
del hash *SHA256* del mensaje.
El mensaje puede ser una contraseña o un mensaje que el usuario firma de forma criptográfica con una llave privada.
Al utilizar identidades determinísticas siempre deberá mantener secreto el mensaje.
Dado que el hash es determinístico, cualquier persona con el mismo mensaje puede recrear la misma identidad.
```ts
const identity = new Identity("secret-message")
```
:::tip
Crear un sistema que guarde o recupere valores secretos de identidades Semaphore no es trivial.
Puede elegir delegar este tipo de funcionalidad a carteras existente como Metamask. Por ejemplo:
1. En Metamask, un usuario firma un mensaje con la llave privada de su cuenta Ethereum.
2. En la aplicación que usted ofrece, el usuario crea una identidad determinística con el mensaje firmado.
3. Ahora el usuario puede recrear su identidad Semaphore cuando quiera al firmar el mismo mensaje con su cuenta Ethereum en Metamask.
:::
## Guarde sus identidades
Puede generar una identidad como una cadena de caractéres JSON que puede guardar y reutilizar más tarde.
El método `Identity.toString()` genera una matriz JSON a partir de una identidad. Por ejemplo:
```ts
console.log(identity.toString()) // Ver la identidad trampilla y anulador.
// '["8255d...", "62c41..."]'
```
La matriz contiene la trapdoor y el nullifier.
Para reutilizar la identidad guardada, transforme la cadena JSON al constructor `Identity()`.
```ts
const identity2 = new Identity(identity.toString())
Una vez que un usuario liga su [identidad Semaphore](/V3/glossary#identidad-semaphore) a un [grupo Semaphore](/V3/glossary#grupo-semaphore), el usuario puede emitir una señal anónima con una prueba de conocimiento cero (ZKP) que demuestre lo siguiente:
- el usuario es un miembro del grupo,
- el mismo usuario creo tanto la señal como la prueba.
Las y los desarrolladores pueden utilizar Semaphore para realizar las siguientes acciones:
- [**Generar una prueba externa a la cadena (off-chain)**](#generar-una-prueba-off-chain)
- [**Verificar una prueba externa a la cadena (off-chain)**](#verificar-una-prueba-off-chain)
- [**Verificar una prueba interna a la cadena (on-chain)**](#verificar-una-prueba-on-chain)
## Generar una prueba off-chain
Utilice la librería [`@semaphore-protocol/proof`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/proof) para generar una prueba off-chain.
Para generar una prueba, transforme los siguientes parámetros con la función `generateProof`:
- `identity`: la identidad Semaphore del usuario emitiendo la señal y generando la prueba;
- `group`: el grupo al cual pertenece el usuario;
- `externalNullifier`: el valor que impide la emisión de dos señales por el mismo usuario;
- `signal`: la señal que el usuario quiere enviar de forma anónima;
- `snarkArtifacts`: la `zkey` y `wasm` de los [archivos confiables de configuración](/V3/glossary/#archivos-confiables-de-configuración-trusted-setup-files).
#### Instalar librería:
<Tabs
defaultValue="npm"
groupId="package-managers"
values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
<TabItem value="npm">
```bash
npm install @semaphore-protocol/proof@^3
```
</TabItem>
<TabItem value="yarn">
```bash
yarn add @semaphore-protocol/proof@^3
```
</TabItem>
<TabItem value="pnpm">
```bash
pnpm add @semaphore-protocol/proof@^3
```
</TabItem>
</Tabs>
En el caso de uso de un sistema de votación, una vez que todos los votantes hayan ligado sus [identidades](/V3/guides/identities#crear-identidades) al [grupo](/V3/guides/groups) de la votación,
un votante puede generar una prueba para votar por una propuesta.
En el llamado para `generateProof`(generar la prueba), el sistema de votación envía el ID único de la votación (la raíz del [árbol de Merkle](/V3/glossary/#árbol-de-merkle-merkle-tree) del grupo) como el
`externalNullifier` para impedir que el votante emita más de una señal para esta votación.
La siguiente muestra de código demuestra cómo utilizar `generateProof` para generar una prueba de votación:
```ts
import { generateProof } from "@semaphore-protocol/proof"
Utilice la librería [`@semaphore-protocol/proof`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/proof) para verificar una prueba Semaphore off-chain.
Para verificar una prueba, transforme los siguientes parámetros con la función `verifyProof`:
- `fullProof`: la prueba Semaphore;
- `treeDepth`: la profundidad del árbol de Merkle.
La siguiente muestra de código demuestra cómo verificar la prueba generada previamente:
```ts
import { verifyProof } from "@semaphore-protocol/proof"
await verifyProof(fullProof, 20) // verdadero o falso.
```
`verifyProof` devolverá una Promesa que determina uno de los dos valores `verdadero` o `falso`.
## Verificar una prueba on-chain
Utilice el contrato [`Semaphore.sol`](/V3/technical-reference/contracts#semaphoresol) para verificar pruebas on-chain.
:::info
Vea nuestros [contratos desplegados](/V3/deployed-contracts) para encontrar las direcciones adecuadas para su red.
::::
Para verificar las pruebas Semaphore en su contrato, importe `ISemaphore.sol`, transfórmelo a la dirección `Semaphore.sol` y llame el método `verifyProof` con los siguientes parámetros:
- `groupId`: el identificador del grupo;
- `merkleTreeRoot`: la raíz del árbol de Merkle;
- `signal`: la señal que el usuario quiere enviar de forma anónima ;
- `nullifierHash`: un nullifier hash (hash anulador);
- `externalNullifier`: el valor que impide la emisión de dos señales por el mismo usuario;
- `proof`: una prueba Semaphore que es compatible con Solidity.
:::info
Puede importar `ISemaphore.sol` y otros contratos Semaphore del módulo NPM [`@semaphore-protocol/contracts`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/contracts).
Los templates soportados son: [`contracts-hardhat`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli-template-contracts-hardhat), [`monorepo-ethers`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli-template-monorepo-ethers), [`monorepo-subgraph`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli-template-monorepo-subgraph)
:::
:::info
El CLI [`semaphore`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli) también se puede utilizar para obtener información de los grupos que existen dentro de las redes soportadas por Semaphore (por ejemplo: `semaphore get-groups --network goerli`).
:::
Para comenzar a trabajar en su proyecto, instale las siguientes dependencias:
<Tabs
defaultValue="npm"
groupId="package-managers"
values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
<TabItem value="npm">
```bash
cd my-app
npm i
```
</TabItem>
<TabItem value="yarn">
```bash
cd my-app
yarn
```
</TabItem>
<TabItem value="pnpm">
```bash
cd my-app
pnpm install
```
</TabItem>
</Tabs>
## Output
El comando `create` creará un directorio con el nombre my-app (o cualquier nombre que usted escoja) dentro de la carpeta actual. Ese directorio contendrá la estructura inicial del proyecto, que incluye un contrato simple (contract), una tarea (task) para desplegar lo, algunas pruebas (test) y una aplicación de Next.js (la carpeta web-app) para interactuar con el contrato.
```
my-app
├── .yarn
├── apps
│ └── contracts
│ │ └── contracts
| │ │ └── Feedback.sol
│ │ └── scripts
| │ │ └── download-snark-artifacts.ts
│ │ └── tasks
| │ │ └── deploy.ts
│ │ └── test
| │ │ └── Feedback.ts
│ │ └── hardhat.config.ts
│ │ └── package.json
│ │ └── tsconfig.json
│ └── web-app
├── scripts
│ └── copy-contracts-artifacts.ts
├── .editorconfig
├── .env
├── .env.example
├── .eslintignore
├── .eslintrc.json
├── .gitignore
├── .prettierignore
├── .prettierrc.json
├── .yarnrc.yml
├── package.json
├── README.md
└── tsconfig.json
```
El contrato `Feedback.sol` crea un grupo Semaphore, permite que los usuarios se unan a ese grupo con su identidad Semaphore, y, finalmente, permite que los miembros de ese grupo envíen un feedback anónimo.
## Uso
### Compilar contratos
Vaya a la carpeta `contracts`:
```bash
cd apps/contracts
```
Y compile sus contratos al correr:
<Tabs
defaultValue="npm"
groupId="package-managers"
values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
<TabItem value="npm">
```bash
npm run compile
```
</TabItem>
<TabItem value="yarn">
```bash
yarn compile
```
</TabItem>
<TabItem value="pnpm">
```bash
pnpm compile
```
</TabItem>
</Tabs>
### Pruebe los contratos
Pruebe sus contratos al correr:
<Tabs
defaultValue="npm"
groupId="package-managers"
values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
<TabItem value="npm">
```bash
npm test
```
</TabItem>
<TabItem value="yarn">
```bash
yarn test
```
</TabItem>
<TabItem value="pnpm">
```bash
pnpm test
```
</TabItem>
</Tabs>
Genere un reporte de la prueba de cobertura:
<Tabs
defaultValue="npm"
groupId="package-managers"
values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
<TabItem value="npm">
```bash
npm run test:coverage
```
</TabItem>
<TabItem value="yarn">
```bash
yarn test:coverage
```
</TabItem>
<TabItem value="pnpm">
```bash
pnpm test:coverage
```
</TabItem>
</Tabs>
O un reporte de la prueba de gas:
<Tabs
defaultValue="npm"
groupId="package-managers"
values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
<TabItem value="npm">
```bash
npm run test:report-gas
```
</TabItem>
<TabItem value="yarn">
```bash
yarn test:report-gas
```
</TabItem>
<TabItem value="pnpm">
```bash
pnpm test:report-gas
```
</TabItem>
</Tabs>
### Desplegar contratos
Siga las instrucciones a continuación para desplegar sus contratos:
En la carpeta raíz del proyecto:
1. Agregue sus variables de entorno en el archivo `.env`.
:::note
Deberá por lo menos configurar un URL válido en Ethereum (ejemplo: Infura) y una llave privada con algunos ethers.
:::
2. Vaya a la carpeta `apps/contracts` y desplegue su contrato.
<Tabs
defaultValue="npm"
groupId="package-managers"
values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
<TabItem value="npm">
```bash
npm run deploy -- --semaphore <semaphore-address> --group <group-id> --network goerli
[Propuesta de la comunidad: Semaphore: Señalización de conocimiento cero (ZK) en Ethereum (v1 Whitepaper)](https://semaphore.pse.dev/whitepaper-v1.pdf) - Kobi Gurkan, Koh Wei Jie y Barry WhiteHat
[Para Mezcladores y más allá: presentando Semaphore, una herramienta de privacidad construida en Ethereum](https://medium.com/coinmonks/to-mixers-and-beyond-presenting-semaphore-a-privacy-gadget-built-on-ethereum-4c8b00857c9b) - Koh Wei Jie
[¡La versión 2 de Semaphore está lista!](https://medium.com/privacy-scaling-explorations/semaphore-v2-is-live-f263e9372579) - Privacy and Scaling Explorations
## Videos
[Privacidad en Ethereum](https://www.youtube.com/watch?v=maDHYyj30kg) - Barry WhiteHat en el Meetup de Ethereum en Taipei
[Snarks para mezclar, enviar señales y escalabilidad](https://www.youtube.com/watch?v=lv6iK9qezBY) - Barry WhiteHat en Devcon 4
[Privacidad en Ethereum](https://www.youtube.com/watch?v=zBUo7G95wYE) - Barry WhiteHat en Devcon 5
[Un mezclador de Ethereum trustless utilizando señalizaciones de conocimiento cero (ZK)](https://www.youtube.com/watch?v=GzVT16lFOHU) - Koh Wei Jie y Barry WhiteHat en Devcon 5
[Implementación de aplicaciones de señalizaciones de conocimiento cero (ZK)](https://www.youtube.com/watch?v=7wd2aAN2jXI) - Koh Wei Jie en Devcon 5
[Roadmap para Semaphore en Ethereum](https://www.youtube.com/watch?v=gOub903iWFs) - Barry WhiteHat en Zcon1
[Pruebas concisas en Ethereum](https://www.youtube.com/watch?v=TtsDNneTDDY) - Barry WhiteHat en el 2ndo ZKProof Workshop
[Propuesta: Semaphore - Señalización de conocimiento cero (ZK) en Ethereum](https://www.youtube.com/watch?v=y5uV9eRb3-w) - Kobi Gurkan y Koh Wei Jie en el ZKProof Home Edition
[Señalizaciones anónimas en Ethereum](https://www.youtube.com/watch?v=dxAfL91Sbw4) - Cedoor en Devcon 6 Bogotá
[The Graph](https://thegraph.com/) es un protocolo para indexar redes como Ethererum o IPFS.
Las personas dueñas de los sitios publica _subgrafos_ que exponen los datos del sitio para que cualquiera los pueda consultar.
El subgrafo de Semaphore le permite obtener datos del contrato inteligente [`Semaphore.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/Semaphore.sol).
:::tip
El protocolo The Graph utiliza el lenguaje de consulta [GraphQL](https://graphql.org/). Para ver ejemplos visite [GraphQL API documentation](https://thegraph.com/docs/developer/graphql-api). Para ver la lista de subgrafos de Semaphore visite el [repositorio de subgrafos](https://github.com/semaphore-protocol/subgraph).
:::
## Esquema
### Árbol de Merkle
-`id`: identificador único entre todas las entidades de árboles de Merkle,
-`depth`: profundidad del árbol de Merkle,
-`root`: raíz del árbol de Merkle,
-`zeroValue`: valor cero del árbol de Merkle,
-`numberOfLeaves`: número total de hojas en el árbol,
-`group`: link a la entidad del grupo.
### Grupo
-`id`: identificador único entre todas las entidades del grupo,
-`merkleTree`: link a la entidad del árbol de Merkle,
-`timestamp`: timestamp (registro de tiempo) del bloque,
-`admin`: administrador del grupo,
-`members`: lista de los miembros del grupo,
-`verifiedProofs`: lista de las pruebas del grupo.
### Miembro
-`id`: identificador único entre todos los miembros,
-`identityCommitment`: compromiso de identidad Semaphore,
-`timestamp`: timestamp del bloque,
-`index`: índice de la hoja del árbol,
-`group`: link a la entidad del grupo.
### PruebaVerificada
-`id`: identificador único entre todas las entidades con una prueba verificada (VerifiedProof),
El [circuito Semaphore](https://github.com/semaphore-protocol/semaphore/tree/main/packages/circuits) es el corazón del protocolo y está compuesto por tres partes:
El diagrama anterior muestra cómo se utilizan las señales de entrada en el circuito Semaphore y cómo se calculan los resultados.
## Prueba de membresía
El circuito resume criptográficamente (hashes) el nullifier hash de la identidad utilizando la identity trapdoor (identidad trampilla) para generar el compromiso de identidad. Después de esto, el circuito verifica la prueba de membresía contra la raíz de Merkle y el compromiso de identidad.
**Insumos (inputs) privados:**
-`treeSiblings[nLevels]`: los valores a lo largo del camino de Merkle rumbo al compromiso de identidad del usuario,
-`treePathIndices[nLevels]`: la dirección (0/1) por nivel del árbol correspondiente al camino de Merkle rumbo al compromiso de identidad del usuario,
-`identityNullifier`: la identidad secreta de 32-bits utilizada como anulador,
-`identityTrapdoor`: la identidad secreta de 32-bits utilizada como trampilla.
**Resultados (outputs) públicos:**
-`root`: La raíz de Merkle del árbol.
## Hash anulador (Nullifier hash)
El circuito resume criptográficamente (hashes) el identity nullifier con el nullifier externo y después revisa que el resultado coincida con el nullifier hash provisto.
Los nullifier hashes guardados en un contrato inteligente Semaphore permiten que el contrato rechace las pruebas que contengan un nullifier hash ya utilizado.
**Insumos (inputs) privados:**
-`identityNullifier`: el identity secret (secreto de identidad) de 32 bits que se utiliza como nullifier.
**Insumos (inputs) públicos:**
-`externalNullifier`: el nullifier externo de 32 bits.
**Resultados (outputs) públicos:**
-`nullifierHash`: el hash del identity nullifier y del nullifier externo; se utiliza para prevenir que el mismo usuario emita dos señales.
**Procedimiento:**
## Señal
El circuito calcula un cuadrado ficticio del hash de la señal para prevenir que se altere la prueba.
- [**Contratos para la extensión**](#contratos-para-la-extensión)
así como [**Semaphore.sol**](#semaphoresol), el principal contrato desplegado en las redes soportadas por Semaphore.
:::info
Para utilizar los contratos e interfaces Semaphore en su proyecto, instale el paquete NPM [`@semaphore-protocol/contracts`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/contracts).
:::
## Contratos base
Semaphore ofrece los siguientes contratos base:
- [`SemaphoreVerifier.sol`](https://github.com/semaphore-protocol/semaphore/blob/v3.15.2/packages/contracts/contracts/base/SemaphoreVerifier.sol): contiene una función para verificar pruebas Semaphore;
- [`SemaphoreGroups.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/base/SemaphoreGroups.sol): contiene las funciones para crear grupos y añadir/remover/actualizar miembros.
Los contratos base están relacionados de forma muy cercana al protocolo.
Puede utilizarlos en su contrato o puede utilizar [**Semaphore.sol**](/V3/technical-reference/contracts#semaphoresol) que ya los tiene integrados.
:::info
Si bien algunas dApps pueden utilizar grupos internos a la cadena, otros puede que prefieran utilizar grupos externos a la cadena, por lo que únicamente guardarán las raíces de sus árboles en el contrato.
:::
## Contratos para la extensión
- [`SemaphoreVoting.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/extensions/SemaphoreVoting.sol): contrato para votaciones que contiene las funciones esenciales para crear encuestas, añadir electores, y emitir votos de forma anónima;
- [`SemaphoreWhistleblowing.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/extensions/SemaphoreWhistleblowing.sol): contrato para denuncias que contiene las funciones esenciales para crear entidades (por ejemplo: organizaciones sin fines de lucro), añade denunciantes, y filtraciones publicadas de forma anónima.
Estos contratos extienden las capacidades del protocolo y proveen una aplicación lógica para casos de uso específicos.
En un futuro se incluirán más extensiones.
## Semaphore.sol
[`Semaphore.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/contracts/Semaphore.sol) utiliza los contratos base como punto de partida, los integra y de forma adicional brinda:
- un sistema que solamente permite que administradores (ej. cuentas de Ethereum o contratos inteligentes) controlen grupos;
- un mecanismo que guarda los [hashes anuladores](/V3/technical-reference/circuits#hash-anulador-nullifier-hash) (nullifier hashes) de cada grupo y evita que el mismo miembro emita dos señales;
- un mecanismo que permite que pruebas Semaphore generadas con raíces de Merkle antiguas sean verificadas por un periodo de tiempo determinado por el administrador del grupo.
:::info
Visitando [contratos desplegados](/V3/deployed-contracts) puede encontrar las direcciones correspondientes a su red.
Si estas sugerencias no funcionan, no dude en preguntar en las [Semaphore Discussions](https://github.com/semaphore-protocol/semaphore/discussions) o en el canal [Semaphore Telegram](https://semaphore.pse.dev/telegram).
## Usando Semaphore en the frontend
Semaphore funciona con cualquier framework de JavaScript, pero el paquete [`@semaphore-protocol/proof`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/proof) está usando [snarkjs](https://github.com/iden3/snarkjs), que usa módulos Node.js que no son compatibles con los frameworks de frontend y hay algunos cambios que debemos hacer para que funcione en el lado del cliente.
### Semaphore con Nextjs
Verá un error como este:
```
Module not found: Can't resolve 'fs'
```
Para resolver esto, en su archivo `next.config.js`, dentro del objeto `nextConfig`, agregue:
```javascript
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.fallback = {
fs: false
}
}
return config
}
```
Su fichero `next.config.js` sería algo como esto:
```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.fallback = {
fs: false
}
}
return config
}
}
module.exports = nextConfig
```
### Semaphore con React + Vite o Vuejs + Vite
Verá un error como este:
```bash
readman.js:43 Uncaught ReferenceError: process is not defined
at stringToBase64 (threadman.js:43:5)
at threadman.js:50:22
```
Para resolver eso:
1- Instale `@esbuild-plugins/node-globals-polyfill` y `@esbuild-plugins/node-modules-polyfill`
En caso de React con Vite, si ve un subrayado ondulado rojo en cada módulo Semaphore que dice `Could not find a declaration file for module ...`, cambie el `moduleResolution` de `bundler` a `Node` en el fichero `tsconfig.json` dentro de `compilerOptions`.
Cuando crea un grupo y se revierte la transacción, asegúrese de que la identificación del grupo que está utilizando no existe en la red que está utilizando.
Para comprobarlo, puede utilizar la [Semaphore CLI](https://github.com/semaphore-protocol/semaphore/tree/main/packages/cli) con el comando `get-groups` y la red que está utilizando y luego, asegúrese de que su id de grupo no sea parte de esa lista. También puede utilizar el [Semaphore explorer](https://explorer.semaphore.pse.dev/).
## Semaphore Proofs
### Transacción revertida al usar el mismo external nullifier
Cuando genera una prueba usando el mismo external nullifier que usó para verificar una prueba antes, la transacción se revertirá porque ese external nullifier ya se usó. Si desea enviar y verificar varias pruebas de la misma identidad, debe usar un external nullifier diferente cada vez que genere una prueba.
[Semaphore](https://github.com/semaphore-protocol/semaphore) es un protocolo que utiliza [conocimiento cero (zero-knowledge)](https://z.cash/technology/zksnarks) y permite emitir una señal (por ejemplo: un voto o una aprobación) como una persona probablemente miembro de un grupo sin revelar su identidad.
Además, proporciona un mecanismo sencillo para impedir que un mismo usuario emita dos señales.
Algunos de los potenciales casos de uso son: votaciones, denuncias, DAOs anónimas y mezcladores.
## Características
Con Semaphore puede permitir que sus usuarios realicen las siguientes acciones:
1. [Crear una identidad Semaphore](/V3/guides/identities/).
2. [Agregar su identidad Semaphore a un grupo (es decir: _Árbol de Merkle_)](/V3/guides/groups/).
3. [Enviar una señal anónima, verificable (ej. un voto o una aprobación)](/V3/guides/proofs/).
Cuando un usuario emite una señal (por ejemplo: un voto), las pruebas de conocimiento cero (ZKP) pueden asegurar que el usuario se ha incorporado al grupo y aún no ha emitido una señal con su nullifier (anulador).
Semaphore utiliza contratos internos a la cadena en Solidity y librerías de JavaScript externas a la cadena que funcionan de forma conjunta.
- Externos a la cadena (off-chain), se pueden utilizar librerías de Javascript para crear identidades, organizar grupos y generar pruebas.
- Internos a la cadena (on-chain), se pueden utilizar contratos en Solidity para organizar grupos y verificar pruebas.
## Beneficios para desarrolladores
Semaphore está diseñado para ser un _componente de privacidad_ simple y genérico para aplicaciones descentralizadas (dApps) en Ethereum. Promueve el diseño modular de las aplicaciones, lo que permite que los desarrolladores de las dApps escojan y personalicen los componentes que necesitan externos e internos a la cadena.
## Respecto al código
La base del protocolo es la [lógica de circuitos](https://github.com/semaphore-protocol/semaphore/tree/main/packages/circuits/scheme.png) (circuit logic).
Además de los circuitos,
Semaphore ofrece [contratos en Solidity](https://github.com/semaphore-protocol/semaphore/tree/main/packages/contracts)
y [librerías en JavaScript](https://github.com/semaphore-protocol/semaphore#-packages) que permiten que los desarrolladores generen pruebas de conocimiento cero (ZKP) y las verifiquen con un esfuerzo mínimo.
### Ceremonia de configuración de confianza (Trusted Setup Ceremony)
Los [parámetros seguros](/V3/glossary#archivos-confiables-de-configuración-trusted-setup-files) para generar pruebas válidas con los circuitos Semaphore fueron generados en una [ceremonia de configuración de confianza](https://storage.googleapis.com/trustedsetup-a86f4.appspot.com/semaphore/semaphore_top_index.html) que se completó con más de 300 participantes el [29 de Marzo de 2022](https://etherscan.io/tx/0xec6dbe68883c7593c2bea82f55af18b3aeb5cc146e026d0083a9b3faa9aa0b65#eventlog).
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.