diff --git a/.github/workflows/docs-style.yml b/.github/workflows/docs-style.yml new file mode 100644 index 0000000..ce76740 --- /dev/null +++ b/.github/workflows/docs-style.yml @@ -0,0 +1,124 @@ +name: docs style + +# Enforces the mechanical rules in STYLEGUIDE.md on the en source pages +# (frontmatter, diataxis/folder match, description length, code-fence language +# tags, no em dashes). en is the source of truth; generated cn/ko are not checked. + +on: + pull_request: + paths: + - 'docs/pages/en/**' + - 'docs/lib/verify-style.mjs' + workflow_dispatch: + +permissions: + contents: read + pull-requests: write + +jobs: + style: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: npm + - run: npm ci + - name: Check styleguide compliance + id: style + # Capture the exit code so we can still post the comment on failure; + # the job is failed explicitly in the final step. + run: | + set +e + npm run style:check + echo "exit_code=$?" >> "$GITHUB_OUTPUT" + env: + STYLE_REPORT: ${{ runner.temp }}/style-report.md + STYLE_SUGGESTIONS: ${{ runner.temp }}/style-suggestions.json + # Blob base for the PR head commit; makes report paths clickable + # links pinned to the exact reviewed revision. + STYLE_REPO_URL: ${{ github.server_url }}/${{ github.repository }}/blob/${{ github.event.pull_request.head.sha }} + - name: Comment styleguide report + if: always() && github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = `${process.env.RUNNER_TEMP}/style-report.md`; + if (!fs.existsSync(path)) return; + const marker = ''; + const body = `${marker}\n${fs.readFileSync(path, 'utf8')}`; + const { owner, repo } = context.repo; + const issue_number = context.issue.number; + const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number }); + const existing = comments.find(c => c.body && c.body.includes(marker)); + if (existing) { + await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body }); + } else { + await github.rest.issues.createComment({ owner, repo, issue_number, body }); + } + - name: Suggest fixes inline + if: always() && github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = `${process.env.RUNNER_TEMP}/style-suggestions.json`; + if (!fs.existsSync(path)) return; + const suggestions = JSON.parse(fs.readFileSync(path, 'utf8')); + if (!suggestions.length) return; + + const { owner, repo } = context.repo; + const pull_number = context.issue.number; + const commit_id = context.payload.pull_request.head.sha; + const MARK = ''; + + // Map each changed file to the set of new-side line numbers the PR + // adds. GitHub only accepts suggestions on lines in the diff. + const files = await github.paginate(github.rest.pulls.listFiles, { owner, repo, pull_number }); + const addedLines = new Map(); + for (const f of files) { + if (!f.patch) continue; + const set = new Set(); + let newLine = 0; + for (const ln of f.patch.split('\n')) { + const h = ln.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/); + if (h) { newLine = parseInt(h[1], 10); continue; } + if (ln.startsWith('+') && !ln.startsWith('+++')) { set.add(newLine); newLine++; } + else if (ln.startsWith('-') && !ln.startsWith('---')) { /* old side only */ } + else { newLine++; } + } + addedLines.set(f.filename, set); + } + + // Clear our previous suggestion comments so reruns don't pile up. + const prior = await github.paginate(github.rest.pulls.listReviewComments, { owner, repo, pull_number }); + for (const c of prior) { + if (c.body && c.body.includes(MARK)) { + await github.rest.pulls.deleteReviewComment({ owner, repo, comment_id: c.id }); + } + } + + let posted = 0, skipped = 0; + for (const s of suggestions) { + const filename = `docs/pages/en/${s.rel}`; + if (!addedLines.get(filename)?.has(s.line)) { skipped++; continue; } + const body = `${MARK}\n${s.reason}\n\n\`\`\`suggestion\n${s.fixed}\n\`\`\``; + try { + await github.rest.pulls.createReviewComment({ + owner, repo, pull_number, commit_id, path: filename, line: s.line, side: 'RIGHT', body, + }); + posted++; + } catch (e) { + core.warning(`Could not suggest on ${filename}:${s.line} — ${e.message}`); + skipped++; + } + } + core.info(`Inline suggestions posted: ${posted}, skipped (not in diff): ${skipped}`); + + - name: Fail on blocking issues + if: steps.style.outputs.exit_code != '0' + run: | + echo "Styleguide check found blocking issues. See the PR comment for details." + exit 1 diff --git a/.github/workflows/i18n-translate.yml b/.github/workflows/i18n-translate.yml index c64fe28..b202dc9 100644 --- a/.github/workflows/i18n-translate.yml +++ b/.github/workflows/i18n-translate.yml @@ -87,7 +87,11 @@ jobs: - name: Translate changed pages into cn + ko if: steps.guard.outputs.skip != 'true' && steps.changed.outputs.pages != '' env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + # Provider/model are swappable here without touching the scripts. + LLM_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + TRANSLATE_MODEL: google/gemini-2.5-flash + MAX_OUTPUT_TOKENS: 32000 # 2.5-flash supports a large output window + # REVIEW_MODEL: google/gemini-2.5-flash # set to enable the QA pass run: | pages=$(echo "${{ steps.changed.outputs.pages }}" | tr '\n' ' ') node docs/lib/i18n-translate.mjs cn $pages @@ -98,7 +102,9 @@ jobs: - name: Regenerate localized sidebars if: steps.guard.outputs.skip != 'true' && steps.sidebar.outputs.changed == 'true' env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + LLM_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + TRANSLATE_MODEL: google/gemini-2.5-flash + MAX_OUTPUT_TOKENS: 32000 run: | node docs/lib/i18n-sidebar.mjs cn node docs/lib/i18n-sidebar.mjs ko diff --git a/.gitignore b/.gitignore index 015f70e..80d3805 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ docs/dist/ *.log .DS_Store .env + +# Generated by `vocs build` from the tracked .ttf sources +docs/public/fonts/*.woff2 diff --git a/ADRs/DR002_i18n_Sync_Pipeline.md b/ADRs/DR002_i18n_Sync_Pipeline.md index c9a51df..fa066ff 100644 --- a/ADRs/DR002_i18n_Sync_Pipeline.md +++ b/ADRs/DR002_i18n_Sync_Pipeline.md @@ -105,6 +105,15 @@ stale.** ### 5. Translation engine (`docs/lib/i18n-translate.mjs`) +> **Superseded by [DR004](./DR004_Translation_LLM_Provider.md).** The provider/ +> model below (Anthropic SDK, `claude-opus-4-8`, `ANTHROPIC_API_KEY`) was +> replaced by a swappable OpenAI-compatible seam (`docs/lib/llm.mjs`) defaulting +> to OpenRouter + a cheap model, with an optional review pass and structural +> validation. Use `LLM_API_KEY` and see DR004 for current usage. The discovery +> behavior also changed: explicit paths now skip in-sync pages (drift is always +> checked), with `--force` to override. The rest of this section is retained as +> the original record. + ``` ANTHROPIC_API_KEY=... node docs/lib/i18n-translate.mjs [--stale] [--limit N] [page ...] ``` @@ -120,6 +129,11 @@ itself, or takes explicit paths. ### 6. Sidebars (`docs/lib/i18n-sidebar.mjs`) +> **Engine superseded by [DR004](./DR004_Translation_LLM_Provider.md):** the +> "batched Opus call" is now the provider-agnostic `complete()` seam (cheap model +> by default, optional review). The structure/regeneration logic below is +> unchanged. + `en` is the source of truth for sidebar *structure* too: only the `/en` section of `docs/sidebar.json` is hand-maintained. `i18n-sidebar.mjs ` regenerates the `/cn` and `/ko` sections from `/en` — it deep-clones the tree, swaps each @@ -165,6 +179,10 @@ report `0 missing`. ### Step 2 — Translate the missing pages +> The `ANTHROPIC_API_KEY` invocations below are superseded by +> [DR004](./DR004_Translation_LLM_Provider.md) — use `LLM_API_KEY` (the engine +> now calls an OpenAI-compatible provider, OpenRouter by default). + ```bash ANTHROPIC_API_KEY=... node docs/lib/i18n-translate.mjs cn ANTHROPIC_API_KEY=... node docs/lib/i18n-translate.mjs ko diff --git a/ADRs/DR003_Page_Filename_Index_Constraint.md b/ADRs/DR003_Page_Filename_Index_Constraint.md index cd453e2..e98da4c 100644 --- a/ADRs/DR003_Page_Filename_Index_Constraint.md +++ b/ADRs/DR003_Page_Filename_Index_Constraint.md @@ -70,7 +70,8 @@ end in `index` (e.g. `-guides`, `-overview`). Do not reach for `-index` as a this record plus `docs:build` link-checking: a `sidebar.json` link to the intended `/foo-index` fails the build, surfacing the mistake. (A lint rule rejecting non-`index.mdx` files ending in `index` would make this active - rather than incidental — an open follow-up if it recurs.) + rather than incidental — an open follow-up if it recurs. The natural home is + now the styleguide checker, [DR005](./DR005_Styleguide_Enforcement.md).) ## Related diff --git a/ADRs/DR004_Translation_LLM_Provider.md b/ADRs/DR004_Translation_LLM_Provider.md new file mode 100644 index 0000000..7ff6fe1 --- /dev/null +++ b/ADRs/DR004_Translation_LLM_Provider.md @@ -0,0 +1,136 @@ +# DR004: Translation LLM provider — swappable seam, cheap model + review + +> Supersedes [DR002](./DR002_i18n_Sync_Pipeline.md) §5 (translation engine) and +> §6 (sidebar) **internals only**. DR002's contract — `en` as source of truth, +> the parity checker, the CI gates, block-on-missing/warn-on-stale, the page +> mapping and re-homing — is unchanged and still authoritative. This record +> covers *which model answers and how the call is made*. + +## Context + +DR002 built the translation engine on `@anthropic-ai/sdk` + **`claude-opus-4-8`** +with adaptive thinking. On a working PR this surfaced three problems: + +- **Cost / overkill.** Opus is `$5/$25` per MTok and adaptive thinking bills + thinking tokens — for a *translation* task that needs neither frontier + reasoning nor deep thinking. The work is structure-preserving rewriting, which + mid-tier and cheap models do well. +- **Reliability.** The Opus-backed job hit rate-limit / "credit balance too low" + failures that blocked the whole `i18n-translate` workflow (the entire batch + failed once credits ran out mid-run). +- **No swappability.** Provider, model, and key were hard-coded across two + scripts; trying a cheaper model meant editing code in several places. + +A separate, compounding bug was also found and fixed (see Decision §5): the +engine re-translated **every** changed page unconditionally when given explicit +paths, ignoring the `source_sha` freshness check — so each push re-ran the full +changeset through Opus. + +The user's decision: move to **OpenRouter** with a cheap model, keep quality +with a **review pass**, and make the LLM **replaceable by configuration, not +code**. + +## Decision + +### 1. One provider-agnostic seam — `docs/lib/llm.mjs` + +All LLM access goes through a single `complete({ model, system, user, maxTokens })` +helper (~30 lines). The two scripts import only this; they never construct a +client or know the wire format. + +- **Transport: native `fetch` against the OpenAI Chat Completions format.** No + SDK. The OpenAI `/chat/completions` shape is the lingua franca every major + gateway speaks (OpenRouter, OpenAI, Together, Groq, local vLLM/Ollama), so one + function is portable across all of them. **`@anthropic-ai/sdk` was removed** + from `package.json` (no remaining importers). +- A small retry (2×, backoff) on `429`/`5xx`/network replaces the SDK's + auto-retry. Non-streaming for simplicity (cheap models return in seconds; Node + `fetch` has no client timeout). + +### 2. Everything is env-configurable + +| Env var | Default | Purpose | +| --- | --- | --- | +| `LLM_API_KEY` | — (falls back to `OPENROUTER_API_KEY`) | Bearer key (required) | +| `LLM_BASE_URL` | `https://openrouter.ai/api/v1` | Any OpenAI-compatible endpoint | +| `TRANSLATE_MODEL` | `google/gemini-2.5-flash` | Translation-pass model | +| `REVIEW_MODEL` | *(unset → no review)* | Optional QA-pass model | +| `MAX_OUTPUT_TOKENS` | `8000` | Per-call output cap (must fit the model) | + +Swapping provider or model is a workflow `env:` change or a shell var — **zero +code edits**. `.github/workflows/i18n-translate.yml` wires the repo secret +`OPENROUTER_API_KEY` into `LLM_API_KEY` and pins `TRANSLATE_MODEL` + +`MAX_OUTPUT_TOKENS: 32000` (gemini-2.5-flash has a large output window). + +### 3. Translate → optional review pipeline + +`translateOne()` calls `complete()` with `TRANSLATE_MODEL`; if `REVIEW_MODEL` is +set, it makes a second `complete()` call that hands the model the English source ++ the draft and asks it to correct mistranslations and structural drift. Same +helper, called twice — no pipeline framework. The review pass is the cost/quality +dial: off by default, on by setting one env var. + +### 4. Deterministic guards (the real safety net) + +Cheap models will occasionally damage structure, so output is validated **before +it is written**: + +- **Structural validation** — frontmatter block present, fenced-code-block count + matches the source, no stray ```` ``` ```` wrapping the file. On failure the + page throws and is skipped (surfaced in the run) rather than written. +- **Robust link normalization** — `localizeLinks` no longer only rewrites + `](/en/`. Models "localize" hrefs themselves (emitting `/zh-CN/`, `/ko-KR/`, or + a duplicated section), so it now rewrites **any** locale/lang prefix + (`en|cn|ko|zh|zh-cn|ko-kr`) to the target slug and collapses a duplicated + section segment — touching only the locale prefix, leaving `/images/...` and + external links alone. This fixed 65 deadlinks that failed the build on the + first cheap-model run. The no-API `--relink` pass applies the same fix to + already-generated files. + +### 5. Mismatch-only translation (bug fix) + +`discover()` previously returned explicit paths verbatim, bypassing the +`source_sha` freshness gate — so CI (which passes every changed en page +explicitly) re-translated the whole PR changeset on every push. Now explicit +paths flow through the same missing-or-drifted check used by a full sweep +(drift is always checked for explicit paths; gated behind `--stale` for a sweep), +with `--force` to re-translate regardless. An in-sync page is now a no-op. + +## Consequences + +- **~50× cheaper per token** (gemini-2.5-flash ≈ `$0.10/$0.40` vs Opus `$5/$25`) + and no billed thinking tokens, even with the review pass on. +- **Provider/model are config.** Proven in practice: the first model id 404'd on + OpenRouter and the fix was a one-line env change, no code. +- **Quality is guarded by deterministic checks + an optional second model**, not + by the translator's raw fidelity — necessary, because the cheap model did + mangle link hrefs on the first run (caught and fixed). +- **Lost the SDK's auto-retry**; replaced by the small retry in `complete()` plus + the existing per-page try/catch and mismatch-only reruns. +- A first full run still costs real (small) money and time (88 pages × 2 locales, + ~13 min on gemini-2.5-flash) — it is CI-triggered on en changes, drafting only + the deltas, exactly as in DR002. + +## Verification + +```bash +# Single page (provider/model from env; --force ignores the freshness skip) +LLM_API_KEY=… TRANSLATE_MODEL=google/gemini-2.5-flash \ + node docs/lib/i18n-translate.mjs cn how-to/use-faucet --force +``` + +- Inspect the output: frontmatter + `source_sha` intact, code untouched, links + re-prefixed to `/cn/`, prose translated. +- Swappability: re-run with a different `TRANSLATE_MODEL` / `LLM_BASE_URL` — works + with no code change. In-sync page → `translating 0 page(s)`. +- Enable review: set `REVIEW_MODEL` and confirm the corrected output. +- `npm run i18n:check` → `0 missing`; `npm run docs:build` → 0 deadlinks. + +### What "passing" looks like + +| Check | Pass condition | +| --- | --- | +| single-page run | valid MDX, structure preserved, links `//`, `source_sha` stamped | +| in-sync page | `translating 0 page(s)` (no API call) | +| `docs:build` | 0 deadlinks across en/cn/ko | +| model/provider swap | env-only, no code change | diff --git a/ADRs/DR005_Styleguide_Enforcement.md b/ADRs/DR005_Styleguide_Enforcement.md new file mode 100644 index 0000000..f925d6a --- /dev/null +++ b/ADRs/DR005_Styleguide_Enforcement.md @@ -0,0 +1,118 @@ +# DR005: Styleguide enforcement + +## Context + +The docs had a written [`STYLEGUIDE.md`](../STYLEGUIDE.md) (voice, frontmatter +rules, headings, callouts, code blocks) but **nothing enforced any of it**. +Prose conventions drift, and the mechanical rules (frontmatter presence, +`diataxis` values, description length, code-fence language tags, em dashes, +marketing adjectives) are exactly the kind a machine should catch on every PR +instead of a reviewer doing it by hand. + +Two design tensions shaped the decision: + +- **Most of a styleguide can't be linted.** Voice, tone, "lead with the outcome," + when to use a callout — these are judgment, not regex. Only a small slice is + mechanically decidable. +- **Duplication drifts.** The mechanical rules' specifics (the length cap, the + banned-word list, the `diataxis` enum) risk living in two places — the checker + code *and* the prose — so editing one silently diverges from the other. + +## Decision + +Split the styleguide into two layers, each with exactly one home, and enforce +only the mechanical layer in CI — surfaced to contributors as PR comments and +applyable suggestions. + +### 1. Mechanical checker — `docs/lib/verify-style.mjs` + +Wired as `npm run style:check`. Scans `en/**/*.mdx` only (`en` is source of +truth; generated `cn`/`ko` may legitimately differ in punctuation). It is +**Vocs-aware**: it ignores directive markers (`:::note`, `::::steps`, +`:badge[...]`) and treats the first token after a code fence as the language +(allowing trailing meta like `ts twoslash`). + +- **Blocking** (non-zero exit): missing `title`/`description`/`diataxis` + frontmatter, invalid `diataxis`, folder ≠ `diataxis`, over-long `description`, + a code fence with no language, an em dash in prose. +- **Warning** (advisory): marketing adjectives with no technical meaning. + +### 2. Single source of truth for rule values — the `RULES` block + +All tunable specifics (valid `diataxis` values, exempt folders, the description +cap, the marketing-word list) live in **one labeled `RULES` block** in +`verify-style.mjs`. `STYLEGUIDE.md` does **not** restate them — it links to the +checker. `npm run style:check -- --rules` prints the enforced rules, so the prose +references a live source instead of a copy that drifts. + +This gives a clean update process, documented in STYLEGUIDE.md's "Updating the +styleguide" section: + +| To change… | Edit | +| --- | --- | +| a **mechanical** rule (ban a word, change the cap, add a diataxis type) | the `RULES` block — one place; CI + `--rules` pick it up | +| a **judgment** rule (voice, tone, structure) | the prose in `STYLEGUIDE.md` | + +If a rule can't be a value or a small regex, it stays in the prose, not the +checker. + +### 3. PR surfacing — `.github/workflows/docs-style.yml` + +The findings are made actionable on the PR, not buried in a log: + +- **Sticky summary comment** of every finding, grouped by file, each path a + clickable link to the file **at the PR head commit** with `#L` line anchors. + Marker-based find-or-update, so re-runs edit one comment instead of stacking. +- **Inline applyable suggestions** for fixes with a safe mechanical correction + (currently em dash → colon). These are GitHub "suggested changes" the author + commits with one click. A constraint drives the design: GitHub only allows a + suggestion on a line **in the PR diff**, so the workflow maps diff hunks to + added line numbers and posts only those; findings on untouched lines remain in + the summary comment. Prior bot suggestions are deleted before re-posting. +- **Enforcement is preserved**: the job still exits non-zero on blocking issues + (the comment is informational, not a replacement for the gate). Marketing-word + warnings never block. + +The checker writes the comment markdown (`STYLE_REPORT`) and the suggestion JSON +(`STYLE_SUGGESTIONS`) only when those env vars are set, so local runs are +unaffected. + +## Consequences + +- **Mechanical rules are enforced uniformly**; reviewers stop hand-catching em + dashes and missing frontmatter. +- **Changing an enforced value is a one-place edit** with no prose drift. +- **Suggestions are diff-scoped** — a finding on a line the PR didn't touch can't + carry an applyable suggestion (GitHub limitation); it shows in the summary + only. The log reports posted-vs-skipped counts so this isn't silent. +- **Only em dashes auto-suggest today.** Marketing-word fixes are intentionally + *not* auto-suggested — deleting an adjective often mangles the sentence — so + they stay advisory. +- **The judgment layer is still unenforced by design.** It relies on review (and, + optionally, the LLM review pass). A richer prose linter (**Vale** — declarative + YAML rules, editor + CI integration) is the natural next step if the team wants + to enforce sentence length, passive voice, etc.; it would complement, not + replace, the repo-specific checks (diataxis↔folder, frontmatter, Vocs-aware + fences) this checker does. See also the `*-index.mdx` lint-rule follow-up + flagged in [DR003](./DR003_Page_Filename_Index_Constraint.md) — `verify-style.mjs` + is the natural home for it. + +## Verification + +```bash +npm run style:check # check pages (non-zero exit on blocking issues) +npm run style:check -- --rules # print the enforced rules +``` + +- Introduce an em dash in an `en` page → blocking failure; `connect.mdx`-style + list separators must be colons. +- On a PR, confirm the sticky summary comment appears with line-anchored links + and an inline suggestion on a changed line carrying an em dash. + +### What "passing" looks like + +| Check | Pass condition | +| --- | --- | +| `style:check` | `0 blocking` (warnings allowed) | +| `--rules` | prints the current enforced rules from `RULES` | +| `docs-style.yml` | comments findings; fails only on blocking issues | diff --git a/ADRs/README.md b/ADRs/README.md index 8d13125..a5988b6 100644 --- a/ADRs/README.md +++ b/ADRs/README.md @@ -29,4 +29,6 @@ Each ADR should follow this general structure: - [DR001: Structured Data (JSON-LD) Strategy](./DR001_SEO_Structured_Data.md) — central JSON-LD / SEO `` injection via the Vocs `head` option - [DR002: i18n Parity & Translation Pipeline](./DR002_i18n_Sync_Pipeline.md) — en as source of truth; checker + CI gate + auto-draft translation engine to keep cn/ko in sync -- [DR003: Page filenames must not end in `index`](./DR003_Page_Filename_Index_Constraint.md) — Vocs strips a trailing `index` from any filename; `*-index.mdx` pages 404. Use `index.mdx` or a non-`index` suffix. \ No newline at end of file +- [DR003: Page filenames must not end in `index`](./DR003_Page_Filename_Index_Constraint.md) — Vocs strips a trailing `index` from any filename; `*-index.mdx` pages 404. Use `index.mdx` or a non-`index` suffix. +- [DR004: Translation LLM provider](./DR004_Translation_LLM_Provider.md) — swappable OpenAI-compatible seam (`llm.mjs`) defaulting to OpenRouter + a cheap model, optional review pass, structural + link guards; supersedes DR002 §5–6 internals. +- [DR005: Styleguide enforcement](./DR005_Styleguide_Enforcement.md) — mechanical rules in a single `RULES` source enforced by `verify-style.mjs`, surfaced on PRs as a sticky comment + inline applyable suggestions; judgment rules stay prose. \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index 7ac1191..a59c29f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,8 +19,8 @@ the Diátaxis structure: `explanation/`, `how-to/`, `reference/`, `tutorial/`, `/ko` sections are **generated** from `/en` (links re-prefixed, labels translated) — never hand-edit them. Regenerate after editing `/en`: ```bash - ANTHROPIC_API_KEY=… node docs/lib/i18n-sidebar.mjs cn - ANTHROPIC_API_KEY=… node docs/lib/i18n-sidebar.mjs ko + LLM_API_KEY=… node docs/lib/i18n-sidebar.mjs cn + LLM_API_KEY=… node docs/lib/i18n-sidebar.mjs ko ``` - **Internal links** are absolute and locale-prefixed (`/en/...` in source). The translation pipeline rewrites them to the target locale automatically; never @@ -30,14 +30,27 @@ the Diátaxis structure: `explanation/`, `how-to/`, `reference/`, `tutorial/`, - **Generate/refresh translations locally** (e.g. when CI can't, or for a freshness pass): ```bash - ANTHROPIC_API_KEY=… node docs/lib/i18n-translate.mjs cn [--stale] [pages…] - ANTHROPIC_API_KEY=… node docs/lib/i18n-translate.mjs ko [--stale] [pages…] + LLM_API_KEY=… node docs/lib/i18n-translate.mjs cn [--stale] [pages…] + LLM_API_KEY=… node docs/lib/i18n-translate.mjs ko [--stale] [pages…] ``` +- **LLM provider/model are env-swappable** (one seam, [`docs/lib/llm.mjs`](./docs/lib/llm.mjs)). + `LLM_API_KEY` (or `OPENROUTER_API_KEY`) is required; `LLM_BASE_URL` defaults to + OpenRouter; `TRANSLATE_MODEL` picks the translator and an optional `REVIEW_MODEL` + enables a second QA pass; `MAX_OUTPUT_TOKENS` (default 8000) must fit the chosen + model's output cap. Changing provider or model is config, never a code edit. - **Verify** before finishing: `npm run i18n:check` (expect `0 missing`) and `npm run docs:build`. Full rationale: [`ADRs/DR002_i18n_Sync_Pipeline.md`](./ADRs/DR002_i18n_Sync_Pipeline.md). +## Writing style + +Before editing or adding a page, read [`STYLEGUIDE.md`](./STYLEGUIDE.md). It is the +authority on voice, frontmatter (`title` / `description` / `diataxis`), file/folder +rules, callout directives, code blocks, and the Vocs authoring features to use. The +mechanical rules are enforced on every PR by `npm run style:check` +([`docs/lib/verify-style.mjs`](./docs/lib/verify-style.mjs)) — run it before finishing. + ## Build Node `>=22`. `npm run docs:dev` / `docs:build` / `docs:preview`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3940f3e..b302cf6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,9 @@ auto-generated translation, you're off-process. 1. **Edit English only.** New page → create it under the right Diátaxis folder in `docs/pages/en/` (`explanation/`, `how-to/`, `reference/`, `tutorial/`, - `resources/`) with `title` / `description` / `diataxis` frontmatter. + `resources/`) with `title` / `description` / `diataxis` frontmatter. Follow + [`STYLEGUIDE.md`](./STYLEGUIDE.md) for voice, structure, frontmatter, callouts, and + code-block conventions; `npm run style:check` enforces the mechanical rules in CI. 2. **Update the sidebar if pages were added/moved/renamed.** Edit the `/en` section of `docs/sidebar.json` only; the `/cn` and `/ko` sections are generated from it (links re-prefixed, labels translated) — never hand-edit them. diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md new file mode 100644 index 0000000..06e4a2b --- /dev/null +++ b/STYLEGUIDE.md @@ -0,0 +1,327 @@ +# Stable docs styleguide + +Rules for writing and reviewing documentation in this repo. The bar is Stripe, Cloudflare, and the best developer docs in the industry. + +When making corrections, preserve the original meaning and technical accuracy. + +This repo is built with [Vocs](https://vocs.dev). English is the source of truth: write and edit content in `docs/pages/en/` only. The `cn` and `ko` trees are generated by the translation pipeline. See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the workflow and [`CLAUDE.md`](./CLAUDE.md) for the agent version. + +## The four-question self-check + +Before returning any page, read it back and answer these four questions. Fix anything that fails: + +1. Could a developer who just landed here know what to do next within 10 seconds? +2. Is there any sentence that sells instead of explains? +3. Is there any concept introduced without a concrete example or link to one? +4. Does every code block have an expected output? + +## Voice and tone + +- Write in **second person**. Address the reader as "you" directly ("You connect by…", "Deploy the contract with…"). +- Use **third person** only when describing what a system does, not what the reader does ("The contract returns…", "Stable uses…"). Never narrate the reader in third person ("users can…", "one must…"). +- Use **contractions** where they feel natural (you're, you'll, it's, here's). +- Prefer **active voice**. Passive only when the actor is irrelevant or unknown. +- Keep sentences under **30 words** where possible. Treat 30 as a signal to review. Short sentences over long multi-clause ones. +- Don't make a case for the product. Assume the reader has already decided to use it. +- Be direct. If a sentence can be cut without losing information, cut it. +- **No marketing adjectives** without technical meaning (*robust*, *seamless*, *powerful*, and the like). The checker flags an enforced list of these — run `npm run style:check -- --rules` to see it. + +## What to remove + +- **No "Why [Product]" sections** on overview or landing pages. That content belongs in marketing, not docs. +- **No problem/solution framing** ("Before X, developers struggled with…"). Get straight to how things work. +- **No filler transitions** ("This section covers…", "In this guide, you will…", "This page consolidates…"). Start with the content. +- **No generic hero filler** ("Unlock the power of…", "Empowering your journey", "All-in-one solution", "Welcome to Stable"). +- **No vague CTA labels** like "Learn more". Name the destination. + +## Technical writing standards + +- **Define, then show.** Introduce a concept in one sentence, then show it in code or a concrete example immediately after. +- **Spell out what something does before naming what it is.** "Stable reserves a portion of each block for enterprise workloads. This is called guaranteed blockspace." +- Don't use em dashes. Write like a human: split into two sentences, use a comma, or use parentheses when an aside is truly parenthetical. In link and next-step lists, the separator is a colon, never an em dash (see [Where to go next](#where-to-go-next)). + +## Terminology + +| Use | When | Do not use | +| :--- | :--- | :--- | +| Stable | Referring to the network (capital S) | stable, STABLE (when meaning the network) | +| STABLE | Referring to the token (all caps) | Stable (when meaning the token), stable | +| StableChain | Referring to the underlying settlement layer / protocol (capital S and C) | Stablechain, Stable chain, stablechain | +| Stablechain | Only in the introductory definition ("Stable is the first Stablechain") | | +| USDT | Referring to the asset | Tether (unless referring to the company) | + +- Use the product or protocol name exactly as branded (e.g., "LayerZero", "RedStone", "USDT0"). + +### UI and keyboard actions + +- `select`: all mouse/touch interactions with buttons, dropdowns, checkboxes, and tabs. +- `press`: keyboard keys (e.g., "Press Enter"). +- `go to`: navigating to a URL (e.g., "Go to https://faucet.stable.xyz"). +- Never mix click, press, choose, or tap for the same type of action. + +## Headings + +- Use **sentence case**: capitalize only the first word and proper nouns (e.g., "Gas pricing", "USDT-specific features"). +- Do not use title case (e.g., ~~"Gas Pricing And Fees"~~). +- Vocs builds the right-side outline from your headings, so keep them short and scannable. + +## Frontmatter + +Every page must include these three fields, in this order: + +```yaml +--- +title: "Page title" +description: "Outcome-framed, one-sentence summary. What can the reader do after reading this?" +diataxis: "reference" +--- +``` + +- `title`: required. Sentence case. +- `description`: required. One sentence, kept short (the checker enforces a hard length cap — run `npm run style:check -- --rules` for the current value). **Frame it as an outcome**, not a topic description. Vocs renders this as the page subtitle and uses it for SEO and social cards, so it's the first thing the reader sees. + - Good: "Send your first transaction on Stable Testnet: connect, fund a wallet, and submit." + - Bad: "This page covers connecting to Stable and sending a transaction." +- `diataxis`: required. One of: + - `tutorial`: learning-oriented, step-by-step lessons + - `how-to`: goal-oriented, practical guides for a specific task + - `reference`: information-oriented, technical descriptions (APIs, addresses, tables, specs) + - `explanation`: understanding-oriented, conceptual discussions + +`diataxis` is a project-specific field. The JSON-LD / SEO engine reads it to pick the schema.org page type (see [`ADRs/DR001_SEO_Structured_Data.md`](./ADRs/DR001_SEO_Structured_Data.md)), so it must be present and accurate on every en page. + +### Other Vocs frontmatter fields + +Vocs supports more page fields (`layout: "minimal" | "blank"`, `outline: false | `, `showSidebar`, `showTopNav`, and others). Use them only for genuinely special pages (a landing page, a wide reference table), and use them consistently. Do not set `lang` per page: locale routing handles language. + +### Mixing Diataxis types + +Each page has one `diataxis` value. If you find yourself writing step-by-step instructions on a reference page, or defining concepts inside a how-to, split the content or link out instead. A reference page lists what exists. A how-to page shows what to do. They are not the same page. + +## File structure + +Content lives under `docs/pages/en/`, organized by Diataxis content type, not by sidebar location. A page's folder must match its `diataxis` frontmatter value: + +| `diataxis` | Folder | +| :--- | :--- | +| `explanation` | `docs/pages/en/explanation/` | +| `tutorial` | `docs/pages/en/tutorial/` | +| `how-to` | `docs/pages/en/how-to/` | +| `reference` | `docs/pages/en/reference/` | + +Supplementary content (brand assets and similar) lives in `docs/pages/en/resources/`. + +Do not name a page `*-index.mdx`. Vocs strips a trailing `index` from filenames, which makes such a page unreachable (404). Use `index.mdx` for a section root, or any non-`index` suffix. See [`ADRs/DR003_Page_Filename_Index_Constraint.md`](./ADRs/DR003_Page_Filename_Index_Constraint.md). + +Sidebar grouping lives in `docs/sidebar.json` and is independent of the filesystem. A conceptual page about a use case and a conceptual page about consensus both live in `en/explanation/`, even though they appear under different sidebar groups. Do not create parallel folders that mirror the sidebar (e.g., `en/learn/` or `en/explanation/use-cases/`). When moving a page between Diataxis types, move the file and update the link references that point to it. + +### One page, one sidebar home + +Every page has exactly one home in the sidebar. Edit only the `/en` section of `docs/sidebar.json`; the `/cn` and `/ko` sections are generated from it. There is no soft alias that renders the same page under two groups without a jump. + +When a concept is relevant to multiple sections (e.g., a Learn concept that readers also need mid-task in Build), keep it in its canonical section and surface it from the others through **content**, not navigation. Link to it from the relevant overview page inline. Concepts live in one place; task-oriented sections point at them. + +## Page structure + +Follow this general pattern: + +1. **Frontmatter** (title, outcome-framed description, diataxis). +2. **Opening paragraph**: start directly with content. No filler transitions. If a concept is being introduced, define it in one sentence, then show a concrete example or code snippet immediately after. +3. **Overview table** (Integrate pages only): columns: **Provider**, **Category**, **Docs / Get Started**, **Notes**. +4. **Sections**: organized under `##` headings, each covering one provider, feature, or concept. +5. **Capabilities lists** (Integrate pages): bold `**Capabilities**` label followed by a bullet list under each provider/feature. +6. **Callout boxes** (`:::note`, `:::warning`): use for any behavior that would surprise a developer coming from Ethereum or a similar environment. Do not bury gotchas in prose. +7. **Contact CTA** (Integrate pages): closing line inviting providers to reach out, linking to `bizdev@stable.xyz`. +8. **Where to go next**: every page ends with 2–4 links with one-line descriptions. The reader should never hit a dead end. No vague labels like "Learn more". Name the destination. + +Not every page needs all of these. Architecture and explanation pages may skip the overview table and Integrate CTA. **The opening subtitle and Where to go next apply to every page.** + +## Opening paragraph + +The first body paragraph must stand alone. If someone reads only this paragraph, they should understand what the page covers and what they will be able to do. Do not start with a transition sentence. Do not restate the title. Start with the content. + +## Callout box usage + +Vocs renders callouts from directive blocks. Available types: `:::note`, `:::info`, `:::tip`, `:::warning`, `:::danger`, `:::success`. You can also use the generic `:::callout[Custom title]` or give any type a custom title, e.g. `:::warning[Breaking change]`. + +```md +:::warning +`maxPriorityFeePerGas` is ignored by Stable and must be set to `0`. +::: +``` + +- `:::warning` (or `:::danger` for destructive actions): use when a wrong assumption causes broken code, data loss, or a failed transaction. Ethereum migration gotchas always get a warning. +- `:::note` / `:::info` / `:::tip`: use for clarifications that help but are not blocking: planned features, alternative approaches, non-obvious defaults. +- Do not use callouts for information that belongs in the main prose. + +## Card and link descriptions + +- Link descriptions are **sentences**, not noun lists. +- Pattern: `[action verb] [thing] [with/using/so that context]`. +- Bad: "System requirements, installation, configuration, snapshots, and monitoring." +- Good: "Install and configure a full or archive node, with snapshot-based sync to get online faster." + +### Inline links + +- Use **descriptive anchor text**: `[Get started with Alchemy](https://...)`, not `click [here](https://...)`. +- Internal links are absolute and locale-prefixed (`/en/...`). The translation pipeline rewrites them to the target locale; never point an en page at `/cn/...` or `/ko/...`. +- When the URL itself is the primary information (tables, reference sections), display the full URL as both text and link: `[https://docs.example.com](https://docs.example.com)`. + +## Where to go next + +End every page with a `## Where to go next` section listing 2–4 links. Each gets a one-line description following the link description pattern: [action verb] [thing] [context]. Separate the link from its description with a **colon**, never an em dash: + +```md +## Where to go next + +- [**Deploy a smart contract**](/en/tutorial/smart-contract): Scaffold a Foundry project and deploy to Stable testnet. +- [**Build a payment app**](/en/how-to/build-p2p-payments): Create a wallet, send, receive, and query payment history. +``` + +Do not use "Learn more", "Read more", or "See also" as anchor text. Name the destination. + +## Tables + +- Left-align all columns using `:---` syntax. +- Bold column headers. +- For overview tables on Integrate pages, use columns: **Provider**, **Category**, **Docs / Get Started**, **Notes**. + +## Code blocks + +- Always include a language tag (e.g., ` ```solidity `, ` ```bash `, ` ```yaml `). +- Use inline code (backticks) for contract names, function names, addresses, and config values within prose. +- **Every code block is followed by its expected output** in a matching `text` block (or equivalent), so the reader knows what success looks like: + + ````markdown + ```bash + cast chain-id --rpc-url https://rpc.stable.xyz + ``` + + ```text + 988 + ``` + ```` + +- For Solidity / contract-pattern examples that don't produce runtime output, annotate with a `// SAFE` or `// UNSAFE on Stable` comment so the reader can scan which pattern to use. + +## Vocs authoring features + +Use these framework features where they make a page clearer. They are tools, not requirements. + +### Code groups + +Show the same task across languages or runtimes (ethers vs viem, npm vs pnpm) with `:::code-group` instead of stacking separate prose blocks. Each inner fence still carries its own language tag and its own expected-output block. + +````md +:::code-group +```ts [ethers] +const tx = await wallet.sendTransaction({ to, value }); +``` + +```ts [viem] +const hash = await walletClient.sendTransaction({ to, value }); +``` +::: +```` + +### Twoslash + +For TypeScript examples where inferred types matter, enable Twoslash to render compiler-checked types and inline hints. Twoslash demonstrates types; it does not replace the expected-output rule for runnable commands. + +````md +```ts twoslash +import { wallet } from "./config"; + +const address = wallet.address; +// ^? +``` +```` + +Use `// @errors: ` to show an expected compiler error and `// @noErrors` to suppress checking when the snippet is intentionally incomplete. + +### Code annotations + +Vocs supports inline markers inside code blocks: + +- Title: ` ```ts [title] ` or ` ```ts filename="client.ts" ` +- Highlight a line: `// [!code highlight]` +- Focus a line (dims the rest): `// [!code focus]` +- Diff: `// [!code ++]` (added) and `// [!code --]` (removed) +- Highlight a word: `// [!code word:term]` + +### Steps + +For ordered procedures you can use the `::::steps` directive with `#####` sub-headings. **Caveat:** the SEO engine derives schema.org HowTo steps from `##` (H2) headings (see [`ADRs/DR001_SEO_Structured_Data.md`](./ADRs/DR001_SEO_Structured_Data.md)). Keep tutorial and how-to procedures as numbered `##` step headings (the current convention) unless DR001's extraction is confirmed to handle `::::steps`. + +### Badges + +Use inline badges for status labels (planned or beta features) as an alternative to a `:::note`: + +```md +:badge[Beta]{warning} +:badge[Stable]{success} +``` + +## Images and diagrams + +Every image must have descriptive alt text that conveys the content, not just the filename. Describe what the diagram shows, not what type of file it is. + +## i18n: edit English only + +English is the source of truth. Edit only `docs/pages/en/`; the `cn` and `ko` pages are generated by the translation pipeline and must never be hand-edited. When you add, move, rename, or delete a page, mirror the change per [`CONTRIBUTING.md`](./CONTRIBUTING.md) and update the `/en` section of `docs/sidebar.json`. + +## What not to change + +- Do not alter technical content, code samples, contract addresses, or API references when fixing style. +- If you are unsure whether something is a style issue or intentional, leave it as-is. + +## Automated checks + +The **mechanical** rules are enforced on every PR by `npm run style:check` +([`docs/lib/verify-style.mjs`](./docs/lib/verify-style.mjs)), which scans the `en` +source pages only. Run it locally before pushing. + +The exact enforced rules — which `diataxis` values are valid, the `description` +length cap, the banned marketing words, etc. — are defined once, in the `RULES` +block of `verify-style.mjs` (the single source of truth). This guide does not +restate those values. To see the current rules, run: + +```bash +npm run style:check -- --rules +``` + +Some are **blocking** (fail CI); the marketing-word list is **advisory** +(warnings, never block). The everything-else of this styleguide — voice, tone, +structure — is human judgment a linter can't check; it lives in the prose above. + +On a PR, the `docs style` workflow surfaces results two ways: + +- **A summary comment** listing every finding, grouped by file. Each path is a + link to the file at the PR's head commit, and line-locatable findings carry a + `#L` anchor so you can jump straight to the line. The comment is sticky — it is + updated in place on each push, not duplicated. +- **Inline suggested changes** for fixes that have a safe mechanical correction + (currently em dashes → colon). These appear as GitHub suggestions you can apply + with **Commit suggestion**, or edit first (a comma or two sentences may read + better). Suggestions can only attach to lines your PR changed; findings on + untouched lines appear in the summary comment only. Re-running replaces prior + suggestions rather than stacking them. + +A suggestion is a starting point, not a mandate — apply it, edit it, or fix the +line by hand. CI passes once no blocking issues remain. + +## Updating the styleguide + +There are two kinds of rule, with two different homes — change the one that fits, +not both: + +- **A mechanical rule** (a new banned word, a different length cap, another + `diataxis` type or exempt folder): edit the `RULES` block in + [`docs/lib/verify-style.mjs`](./docs/lib/verify-style.mjs). That's the only + place the value lives — CI and `--rules` pick it up automatically. No prose + change needed. (Adding a brand-new *kind* of check — not just a new value — + also means a few lines of checker logic next to `RULES`.) +- **A judgment rule** (voice, tone, structure, when to use a callout): edit the + prose in this file. Nothing mechanical to touch. + +If a rule can't be expressed as a value or a small regex, it belongs in the prose, +not the checker — keep the checker to things it can decide unambiguously. diff --git a/docs/lib/i18n-sidebar.mjs b/docs/lib/i18n-sidebar.mjs index 4e0dd40..b7a9f98 100644 --- a/docs/lib/i18n-sidebar.mjs +++ b/docs/lib/i18n-sidebar.mjs @@ -10,14 +10,15 @@ * The `/en` section is hand-maintained; the localized sections are generated — * do not hand-edit them. Re-run after editing the `/en` sidebar. * - * ANTHROPIC_API_KEY=... node docs/lib/i18n-sidebar.mjs + * LLM_API_KEY=... node docs/lib/i18n-sidebar.mjs * * cn | ko (required) * - * Labels are translated in a single batched request (deduped). Model: opus. + * Labels are translated in a single batched request (deduped). Provider/model + * are env-configurable via docs/lib/llm.mjs (TRANSLATE_MODEL, REVIEW_MODEL). */ -import Anthropic from '@anthropic-ai/sdk' +import { complete, TRANSLATE_MODEL, REVIEW_MODEL, MAX_OUTPUT_TOKENS } from './llm.mjs' import { readFileSync, writeFileSync } from 'node:fs' const SIDEBAR = 'docs/sidebar.json' @@ -54,7 +55,15 @@ Rules: - Preserve any surrounding punctuation/brackets exactly (e.g. "[Agents]" keeps its square brackets). - Return ONLY a JSON array of the translated strings, in the same order and with the same length as the input. No commentary, no code fence.` -const client = new Anthropic() +const REVIEW_SYSTEM = `You are reviewing ${LANGUAGE[locale]} translations of navigation-sidebar labels for the Stable blockchain developer docs. You are given the original English JSON array and a draft translated array. Return a corrected JSON array. + +- Same order and length as the input. +- Fix mistranslations and over-long labels; keep them short. +- DO NOT translate product/protocol identifiers and acronyms (Stable, SDK, USDT0, EVM, RPC, JSON-RPC, API, x402, MPP, EIP-7702, ERC-3009, P2P, MCP, viem, wagmi); preserve surrounding punctuation/brackets exactly. +- Return ONLY the JSON array, no commentary, no code fence.` + +// Strip a ```/```json wrapper a model may add around the JSON array. +const unfence = (s) => s.trim().replace(/^```(?:json)?\n?|\n?```$/g, '') // Rewrite an en link prefix to the target locale (same token as i18n-translate). const localizeLink = (link) => @@ -73,22 +82,26 @@ function localizeTree(items, dict) { }) } -const stream = client.messages.stream({ - model: 'claude-opus-4-8', - max_tokens: 8000, - thinking: { type: 'adaptive' }, +const input = JSON.stringify(labels, null, 2) + +let raw = await complete({ + model: TRANSLATE_MODEL, system: SYSTEM, - messages: [{ role: 'user', content: JSON.stringify(labels, null, 2) }], + user: input, + maxTokens: MAX_OUTPUT_TOKENS, }) -const final = await stream.finalMessage() -const raw = final.content - .filter((b) => b.type === 'text') - .map((b) => b.text) - .join('') - .trim() - .replace(/^```(?:json)?\n?|\n?```$/g, '') - -const translated = JSON.parse(raw) + +// Optional second pass: a (usually stronger) model corrects the draft labels. +if (REVIEW_MODEL) { + raw = await complete({ + model: REVIEW_MODEL, + system: REVIEW_SYSTEM, + user: `English labels:\n\n${input}\n\n---\n\nDraft translation to review and correct:\n\n${unfence(raw)}`, + maxTokens: MAX_OUTPUT_TOKENS, + }) +} + +const translated = JSON.parse(unfence(raw)) if (!Array.isArray(translated) || translated.length !== labels.length) { console.error( `Translation count mismatch: expected ${labels.length}, got ${Array.isArray(translated) ? translated.length : 'non-array'}`, diff --git a/docs/lib/i18n-translate.mjs b/docs/lib/i18n-translate.mjs index 1939127..3036e61 100644 --- a/docs/lib/i18n-translate.mjs +++ b/docs/lib/i18n-translate.mjs @@ -9,17 +9,21 @@ * Used by both the auto-draft CI workflow (.github/workflows/i18n-translate.yml) * and one-off local backfills. * - * ANTHROPIC_API_KEY=... node docs/lib/i18n-translate.mjs [--stale] [--limit N] [page ...] + * LLM_API_KEY=... node docs/lib/i18n-translate.mjs [--stale] [--force] [--limit N] [page ...] * * cn | ko (required) - * --stale also re-translate pages whose source_sha drifted (default: missing only) + * --stale in a full sweep, also re-translate pages whose source_sha drifted (default: missing only) + * --force re-translate every candidate even if its translation is in sync * --limit N translate at most N pages this run (default: all) - * page ... explicit en-relative paths to translate (overrides discovery) + * page ... explicit en-relative paths to consider; in-sync ones are still + * skipped (drift is always checked) unless --force is given * - * Model: claude-opus-4-8, adaptive thinking, streamed (pages can be long). + * Provider/model are env-configurable via docs/lib/llm.mjs (LLM_BASE_URL, + * LLM_API_KEY, TRANSLATE_MODEL, REVIEW_MODEL). When REVIEW_MODEL is set, a + * second model reviews and corrects each draft before it's written. */ -import Anthropic from '@anthropic-ai/sdk' +import { complete, TRANSLATE_MODEL, REVIEW_MODEL, MAX_OUTPUT_TOKENS } from './llm.mjs' import { execFileSync } from 'node:child_process' import { readdirSync, readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs' import { join, relative, dirname } from 'node:path' @@ -31,10 +35,11 @@ const LANGUAGE = { cn: 'Simplified Chinese (zh-CN)', ko: 'Korean (ko-KR)' } const [locale, ...rest] = process.argv.slice(2) if (!LANGUAGE[locale]) { - console.error('Usage: node docs/lib/i18n-translate.mjs [--stale] [--limit N] [page ...]') + console.error('Usage: LLM_API_KEY=... node docs/lib/i18n-translate.mjs [--stale] [--force] [--limit N] [page ...]') process.exit(2) } const includeStale = rest.includes('--stale') +const force = rest.includes('--force') const relinkOnly = rest.includes('--relink') const limitIdx = rest.indexOf('--limit') const limit = limitIdx !== -1 ? Number(rest[limitIdx + 1]) : Infinity @@ -63,23 +68,43 @@ function frontmatterSha(file) { const blobSha = (file) => execFileSync('git', ['hash-object', file], { encoding: 'utf8' }).trim() -// en source links are absolute `/en/...`. Rewrite the markdown-link token -// `](/en/` to the target locale so a translated page navigates within its own -// language tree. External URLs that merely contain `/en/` start with `](http` -// and are intentionally left alone. Idempotent. -const localizeLinks = (body, locale) => body.replaceAll('](/en/', `](/${locale}/`) - -// Discover which en pages this locale needs. +// Normalize internal markdown-link hrefs to the target locale tree. en source +// links are `](/en/...)`, but translation models often "localize" the path +// themselves — emitting the language tag (`/zh-CN/`, `/ko-KR/`), the wrong +// locale slug, or a duplicated section. This rewrites the locale prefix of any +// `](//...)` link to `](//...)` and collapses a duplicated section +// segment. Only the locale prefix is touched, so asset paths like `/images/...` +// and external `](http...)` links are left alone. Idempotent. +const LOCALE_TOKENS = 'en|cn|ko|zh|zh-cn|ko-kr' +const SECTIONS = 'tutorial|how-to|reference|explanation|resources' +const localizeLinks = (body, locale) => + body + .replace(new RegExp(`\\]\\(/(?:${LOCALE_TOKENS})/`, 'gi'), `](/${locale}/`) + .replace(new RegExp(`\\]\\(/${locale}/(${SECTIONS})/\\1/`, 'g'), `](/${locale}/$1/`) + +// Discover which en pages this locale actually needs translating. +// +// Candidates are the explicit paths if given, else every en page. A candidate +// is only translated when its target is missing or its source drifted — so a +// page whose translation already matches the current en `source_sha` is skipped +// (no wasted API call). `--force` re-translates every candidate regardless. +// +// Drift is always checked for explicit paths: the caller named them because +// they changed, so an in-sync one is genuinely nothing to do. For a full sweep +// drift is gated behind `--stale` (otherwise the default is missing-only). function discover() { - if (explicit.length) return explicit - const enFiles = walk(join(PAGES, SOURCE)) - .map((p) => relative(join(PAGES, SOURCE), p)) - .sort() + const candidates = explicit.length + ? explicit + : walk(join(PAGES, SOURCE)) + .map((p) => relative(join(PAGES, SOURCE), p)) + .sort() + if (force) return candidates + const checkDrift = explicit.length > 0 || includeStale const needed = [] - for (const rel of enFiles) { + for (const rel of candidates) { const target = join(PAGES, locale, rel) if (!existsSync(target)) needed.push(rel) - else if (includeStale && frontmatterSha(target) !== blobSha(join(PAGES, SOURCE, rel))) + else if (checkDrift && frontmatterSha(target) !== blobSha(join(PAGES, SOURCE, rel))) needed.push(rel) } return needed @@ -91,29 +116,62 @@ Rules: - Translate prose, headings, the frontmatter "title" and "description" values, alt text, and table cell text. - DO NOT translate: code blocks, inline code, command output, URLs, file paths, frontmatter keys, MDX/JSX component names and props, HTML tags, or identifiers like USDT0, EVM, RPC, JSON-RPC, chain IDs, hex values, env var names. - Preserve the exact MDX structure: frontmatter fences, import statements, JSX components, links (translate link text, keep the href), and whitespace/indentation. +- Internal links use \`/en/...\` paths. Keep the href EXACTLY as \`/en/...\` — do not change the \`/en/\` prefix to a language tag or locale, and do not alter the path. - Keep the frontmatter "diataxis" value unchanged if present. - Output ONLY the translated MDX file content, with no commentary, no markdown code fence around the whole file.` -const client = new Anthropic() +const REVIEW_SYSTEM = `You are a senior reviewer for ${LANGUAGE[locale]} translations of the Stable blockchain developer docs. You are given the English source MDX and a draft translation. Return a corrected version of the translation. + +Fix: +- Any untranslated prose, mistranslations, or awkward phrasing. +- Any structural drift from the source: the draft MUST keep the same frontmatter keys, the same number and content of fenced code blocks, the same inline code, URLs, file paths, JSX/MDX components and props, HTML tags, and identifiers (USDT0, EVM, RPC, etc.) — all unchanged from the English. +- Keep the frontmatter "diataxis" value unchanged. Translate frontmatter "title"/"description" values only. + +Output ONLY the corrected MDX file content — no commentary, no markdown code fence around the whole file. If the draft is already correct, output it unchanged.` + +// Count top-level fenced code blocks (``` or ~~~) in MDX prose. Used as a cheap +// structural check: a faithful translation keeps every code block intact. +const fenceCount = (text) => (text.match(/^\s*(`{3,}|~{3,})/gm) || []).length + +// Reject a generation that lost structure rather than writing corrupt output. +// Throwing here skips the page and surfaces it in the run (per-page try/catch). +function validateStructure(rel, source, out) { + if (!out) throw new Error('empty translation') + if (/^\s*```/.test(out)) throw new Error('translation is wrapped in a markdown code fence') + if (source.startsWith('---\n') && !out.startsWith('---\n')) + throw new Error('translation dropped the frontmatter block') + const want = fenceCount(source) + const got = fenceCount(out) + if (got !== want) throw new Error(`code-fence count drifted (source ${want}, translation ${got})`) +} async function translateOne(rel) { const srcPath = join(PAGES, SOURCE, rel) const sha = blobSha(srcPath) const source = readFileSync(srcPath, 'utf8') - const stream = client.messages.stream({ - model: 'claude-opus-4-8', - max_tokens: 64000, - thinking: { type: 'adaptive' }, - system: SYSTEM, - messages: [{ role: 'user', content: `Translate this MDX file:\n\n${source}` }], - }) - const final = await stream.finalMessage() - let body = final.content - .filter((b) => b.type === 'text') - .map((b) => b.text) - .join('') - .trim() + let body = ( + await complete({ + model: TRANSLATE_MODEL, + system: SYSTEM, + user: `Translate this MDX file:\n\n${source}`, + maxTokens: MAX_OUTPUT_TOKENS, + }) + ).trim() + + // Optional second pass: a (usually stronger) model corrects the draft. + if (REVIEW_MODEL) { + body = ( + await complete({ + model: REVIEW_MODEL, + system: REVIEW_SYSTEM, + user: `English source MDX:\n\n${source}\n\n---\n\nDraft translation to review and correct:\n\n${body}`, + maxTokens: MAX_OUTPUT_TOKENS, + }) + ).trim() + } + + validateStructure(rel, source, body) // Inject source tracking into the translated frontmatter so verify-i18n can // detect drift later. Assumes the model preserved the leading `---` fence. diff --git a/docs/lib/llm.mjs b/docs/lib/llm.mjs new file mode 100644 index 0000000..f724191 --- /dev/null +++ b/docs/lib/llm.mjs @@ -0,0 +1,76 @@ +/** + * The single LLM seam for the i18n tooling. + * + * The translation/sidebar scripts call `complete()` and nothing else — they + * never know the provider, the wire format, or the endpoint. Swapping provider, + * gateway, or model is therefore pure configuration (env vars), not a code edit. + * + * We speak the OpenAI Chat Completions format over plain `fetch` because every + * major gateway (OpenRouter, OpenAI, Together, Groq, local vLLM/Ollama, …) speaks + * it, so one tiny function covers all of them with no SDK dependency. + * + * Config: + * LLM_BASE_URL API base (default https://openrouter.ai/api/v1) + * LLM_API_KEY bearer key (OPENROUTER_API_KEY accepted as a fallback) + * TRANSLATE_MODEL model for the translation pass (see callers for defaults) + * REVIEW_MODEL optional second-pass QA model; unset = no review + */ + +const BASE = (process.env.LLM_BASE_URL || 'https://openrouter.ai/api/v1').replace(/\/$/, '') +const KEY = process.env.LLM_API_KEY || process.env.OPENROUTER_API_KEY + +export const TRANSLATE_MODEL = process.env.TRANSLATE_MODEL || 'google/gemini-2.5-flash' +// Unset → callers skip the review pass entirely. +export const REVIEW_MODEL = process.env.REVIEW_MODEL || null +// Output-token ceiling per call. Keep this within the chosen model's max output +// (e.g. Gemini 2.0 Flash ≈ 8192); raise it via env when using a bigger-output +// model so long pages aren't truncated. Over-requesting can make some providers +// reject the call outright, so the default stays conservative. +export const MAX_OUTPUT_TOKENS = Number(process.env.MAX_OUTPUT_TOKENS) || 8000 + +const sleep = (ms) => new Promise((r) => setTimeout(r, ms)) + +/** + * One chat completion: system + user → assistant text. Retries transient + * failures (429 / 5xx / network) a couple of times with backoff, replacing the + * auto-retry the SDK used to provide. + */ +export async function complete({ model, system, user, maxTokens }) { + if (!KEY) throw new Error('LLM_API_KEY (or OPENROUTER_API_KEY) is not set') + + const body = JSON.stringify({ + model, + max_tokens: maxTokens, + messages: [ + { role: 'system', content: system }, + { role: 'user', content: user }, + ], + }) + + let lastErr + for (let attempt = 0; attempt < 3; attempt++) { + if (attempt) await sleep(1000 * 2 ** (attempt - 1)) + let res + try { + res = await fetch(`${BASE}/chat/completions`, { + method: 'POST', + headers: { authorization: `Bearer ${KEY}`, 'content-type': 'application/json' }, + body, + }) + } catch (e) { + lastErr = e // network error — retry + continue + } + if (res.status === 429 || res.status >= 500) { + lastErr = new Error(`${res.status} ${(await res.text()).slice(0, 200)}`) + continue // transient — retry + } + if (!res.ok) throw new Error(`${res.status} ${(await res.text()).slice(0, 500)}`) + + const data = await res.json() + const text = data.choices?.[0]?.message?.content + if (typeof text !== 'string') throw new Error(`unexpected response shape: ${JSON.stringify(data).slice(0, 300)}`) + return text + } + throw lastErr +} diff --git a/docs/lib/verify-style.mjs b/docs/lib/verify-style.mjs new file mode 100644 index 0000000..4986c71 --- /dev/null +++ b/docs/lib/verify-style.mjs @@ -0,0 +1,265 @@ +/** + * Styleguide lint for the en source pages. + * + * Enforces the mechanical styleguide rules on every `en/**​/*.mdx` page. `en` is + * the source of truth, so the generated `cn`/`ko` trees are NOT checked + * (translation may legitimately differ in punctuation and wording). + * + * The enforced rules live in the `RULES` block below — the single source of + * truth. STYLEGUIDE.md is the human narrative and links here rather than + * restating values. Print the current rules with: + * npm run style:check -- --rules + * + * The checker is Vocs-aware: it ignores directive markers (`:::note`, + * `:::code-group`, `::::steps`, `:badge[...]`) and treats the first token after a + * code fence as the language, allowing trailing meta (`ts twoslash`, `bash [x]`, + * `ts filename="y"`). + * + * Run from the repo root: + * npm run style:check # check pages + * npm run style:check -- --rules # print the enforced rules + */ + +import { readdirSync, readFileSync, writeFileSync } from 'node:fs' +import { join, relative } from 'node:path' + +const PAGES = 'docs/pages' +const SOURCE = 'en' + +// ───────────────────────────────────────────────────────────────────────────── +// RULES — the single source of truth for the mechanically-enforced styleguide. +// +// To change what CI enforces, edit THIS block. STYLEGUIDE.md does not restate +// these values; it links here. Print the current rules with: +// npm run style:check -- --rules +// ───────────────────────────────────────────────────────────────────────────── +const RULES = { + // Valid `diataxis` frontmatter values; a page must also live in the matching + // folder (e.g. a `how-to` page under `how-to/`). + diataxis: ['tutorial', 'how-to', 'reference', 'explanation'], + // Folders that hold pages but are not Diataxis types (skip the folder match). + exemptFolders: ['resources'], + // Max length (chars) of the frontmatter `description`. + maxDescription: 160, + // Marketing adjectives with no technical meaning — advisory warnings only. + marketingWords: [ + 'comprehensive', 'robust', 'meticulously', 'powerful', 'seamless', + 'seamlessly', 'cutting-edge', 'world-class', 'unparalleled', 'revolutionary', + 'game-changing', 'state-of-the-art', 'best-in-class', 'effortless', + ], +} + +// `--rules`: print the enforced rules and exit (so docs/contributors can read +// the source of truth instead of a copy that drifts). +if (process.argv.includes('--rules')) { + console.log(`Styleguide rules enforced by docs/lib/verify-style.mjs: + +Blocking (fail CI): + - frontmatter present: title, description, diataxis + - diataxis is one of: ${RULES.diataxis.join(' | ')} + - page folder matches its diataxis (exempt: ${RULES.exemptFolders.join(', ')}) + - description ≤ ${RULES.maxDescription} characters + - every fenced code block declares a language + - no em dash (—) in prose + +Warnings (advisory): + - marketing words: ${RULES.marketingWords.join(', ')}`) + process.exit(0) +} + +function walk(dir) { + const out = [] + for (const e of readdirSync(dir, { withFileTypes: true })) { + const p = join(dir, e.name) + if (e.isDirectory()) out.push(...walk(p)) + else if (e.name.endsWith('.mdx')) out.push(p) + } + return out +} + +/** Parse the `key: value` pairs from a leading `---` frontmatter block. */ +function frontmatter(text) { + const m = text.match(/^---\n([\s\S]*?)\n---/) + if (!m) return {} + const fm = {} + for (const line of m[1].split('\n')) { + const kv = line.match(/^([A-Za-z0-9_]+):\s*(.*)$/) + if (kv) fm[kv[1]] = kv[2].trim().replace(/^["']|["']$/g, '') + } + return fm +} + +/** Strip the frontmatter block from the page body. */ +function body(text) { + return text.replace(/^---\n[\s\S]*?\n---\n?/, '') +} + +/** + * Split a body into prose lines and fenced code blocks. Returns `prose` (the + * body with code-block interiors removed) and `fences` (the opening fence info + * strings, e.g. `ts twoslash`). Vocs `:::code-group` wrappers are directives, not + * fences, so their inner ``` fences are still seen here. + */ +function partition(text, offset = 0) { + const lines = text.split('\n') + const proseLines = [] + const fences = [] + let inFence = false + for (let i = 0; i < lines.length; i++) { + const line = lines[i] + const fence = line.match(/^(\s*)(`{3,}|~{3,})(.*)$/) + if (fence) { + if (!inFence) { + inFence = true + // 1-based line number in the original file. + fences.push({ info: fence[3].trim(), line: offset + i + 1 }) + } else { + inFence = false + } + continue + } + // Keep prose lines paired with their original 1-based line number so + // findings can be anchored to an exact line. + if (!inFence) proseLines.push({ text: line, line: offset + i + 1 }) + } + return { proseLines, prose: proseLines.map((l) => l.text).join('\n'), fences } +} + +const enRoot = join(PAGES, SOURCE) +const files = walk(enRoot).sort() + +let blocking = 0 +let warnings = 0 +const issues = [] +// Applyable fixes for rules with a safe mechanical correction. CI turns these +// into inline GitHub "suggested changes" on lines that are part of the PR diff. +const suggestions = [] + +for (const file of files) { + const rel = relative(enRoot, file) + const parts = rel.split('/') + // Root-level pages (e.g. en/index.mdx) have no folder to match against. + const topFolder = parts.length > 1 ? parts[0] : null + const text = readFileSync(file, 'utf8') + const fm = frontmatter(text) + // Offset = lines consumed by the stripped frontmatter block, so prose/fence + // line numbers map back to the original file. + const fmMatch = text.match(/^---\n[\s\S]*?\n---\n?/) + const offset = fmMatch ? fmMatch[0].split('\n').length - 1 : 0 + const { proseLines, prose, fences } = partition(body(text), offset) + + const err = (msg, line) => { blocking++; issues.push({ rel, level: '✗', msg, line }) } + const warn = (msg, line) => { warnings++; issues.push({ rel, level: '⚠', msg, line }) } + // First prose line (1-based, original file) matching a regex, or undefined. + const proseLine = (re) => proseLines.find((l) => re.test(l.text))?.line + + // Frontmatter presence. + if (!fm.title) err('missing frontmatter: title') + if (!fm.description) err('missing frontmatter: description') + if (!fm.diataxis) err('missing frontmatter: diataxis') + + // Diataxis value + folder match. + if (fm.diataxis && !RULES.diataxis.includes(fm.diataxis)) { + err(`invalid diataxis "${fm.diataxis}" (expected one of ${RULES.diataxis.join(', ')})`) + } else if (fm.diataxis && topFolder && !RULES.exemptFolders.includes(topFolder) && topFolder !== fm.diataxis) { + err(`diataxis "${fm.diataxis}" but file is under "${topFolder}/" (move it to "${fm.diataxis}/")`) + } + + // Description length. + if (fm.description && fm.description.length > RULES.maxDescription) { + err(`description is ${fm.description.length} chars (max ${RULES.maxDescription})`) + } + + // Code fences must declare a language (first token of the info string). + for (const { info, line } of fences) { + const lang = info.split(/[\s[]/)[0] + if (!lang) err('code block has no language tag', line) + } + + // Em dashes in prose only. + if (prose.includes('—')) { + const n = (prose.match(/—/g) || []).length + err(`${n} em dash${n > 1 ? 'es' : ''} in prose (use a colon, comma, or two sentences)`, proseLine(/—/)) + // Offer a colon replacement per offending line. The colon is the + // styleguide's first-listed fix; the author can edit before committing. + for (const l of proseLines) { + if (!l.text.includes('—')) continue + const fixed = l.text.replace(/\s*—\s*/g, ': ') + if (fixed !== l.text) { + suggestions.push({ rel, line: l.line, fixed, reason: 'Replace the em dash with a colon (or edit to a comma / two sentences).' }) + } + } + } + + // Marketing adjectives (advisory). + for (const word of RULES.marketingWords) { + const re = new RegExp(`\\b${word}\\b`, 'i') + if (re.test(prose)) warn(`marketing word "${word}"`, proseLine(re)) + } +} + +for (const { rel, level, msg, line } of issues) { + console.log(` ${level} ${rel}${line ? `:${line}` : ''}: ${msg}`) +} + +const summary = + `${blocking === 0 ? '✓' : '✗'} ${files.length} en pages — ` + + `${blocking} blocking, ${warnings} warning${warnings === 1 ? '' : 's'}` + +console.log(`\n${summary}`) + +// Optional Markdown report for CI to post as a PR comment. Writing it never +// changes the exit code — blocking issues still fail the job. +if (process.env.STYLE_REPORT) { + writeFileSync(process.env.STYLE_REPORT, renderReport()) +} + +// Optional JSON of applyable fixes for CI to post as inline suggestions. +if (process.env.STYLE_SUGGESTIONS) { + writeFileSync(process.env.STYLE_SUGGESTIONS, JSON.stringify(suggestions, null, 2)) +} + +function renderReport() { + // STYLE_REPO_URL is the blob base for the PR head commit, e.g. + // https://github.com/owner/repo/blob/. When set, file paths become + // clickable links (with #L line anchors); otherwise they stay plain text. + const base = process.env.STYLE_REPO_URL?.replace(/\/$/, '') + const fileUrl = (rel, line) => + base ? `${base}/docs/pages/en/${rel}${line ? `#L${line}` : ''}` : null + + const lines = ['## Styleguide check', '', `**${summary}**`, ''] + if (issues.length === 0) { + lines.push('No styleguide issues found. ✨') + return lines.join('\n') + } + // Group issues by file, preserving discovery order. + const byFile = new Map() + for (const it of issues) { + if (!byFile.has(it.rel)) byFile.set(it.rel, []) + byFile.get(it.rel).push(it) + } + if (blocking > 0) { + lines.push('Blocking issues must be fixed before merge; warnings are advisory.', '') + } + for (const [rel, list] of byFile) { + const url = fileUrl(rel) + lines.push(url ? `### [docs/pages/en/${rel}](${url})` : `### \`docs/pages/en/${rel}\``) + for (const { level, msg, line } of list) { + const label = level === '✗' ? '**✗ blocking**' : '⚠ warning' + const loc = line + ? base + ? ` ([L${line}](${fileUrl(rel, line)}))` + : ` (line ${line})` + : '' + lines.push(`- ${label}: ${msg}${loc}`) + } + lines.push('') + } + const guide = base + ? `[STYLEGUIDE.md](${base}/STYLEGUIDE.md)` + : '[STYLEGUIDE.md](../blob/HEAD/STYLEGUIDE.md)' + lines.push(`Enforced by \`npm run style:check\` — see ${guide}.`) + return lines.join('\n') +} + +process.exit(blocking === 0 ? 0 : 1) diff --git a/docs/pages/cn/explanation/accounts-guides.mdx b/docs/pages/cn/explanation/accounts-guides.mdx index 3d14757..4eddc65 100644 --- a/docs/pages/cn/explanation/accounts-guides.mdx +++ b/docs/pages/cn/explanation/accounts-guides.mdx @@ -1,26 +1,26 @@ --- source_path: explanation/accounts-guides.mdx -source_sha: cf8f431a04b9629b56f347af8835b979316da7ae +source_sha: a227a6651c1f8c559681e3e818155c67e39d3f7b title: "账户指南" -description: "所有账户指南、概念和参考集中于一页:钱包创建、EIP-7702 委托、代理钱包以及相关的 API 接口。" +description: "所有账户指南、概念和参考资料都在一个页面:钱包创建、EIP-7702 委托、代理钱包以及相关的 API 接口。" diataxis: "explanation" --- # 账户指南 -账户标签下的每个指南、概念和参考,按你想要完成的任务进行分组。 +“账户”选项卡下的所有指南、概念和参考资料,按您要执行的操作分组。 ## 设置钱包 -- [**创建钱包**](/cn/how-to/create-wallet) — 使用 ethers.js 或 Tether WDK 生成新的密钥对或从助记词恢复。 -- [**代理钱包**](/cn/reference/agentic-wallets) — 用于 AI 代理的自托管钱包——它们与用户钱包的区别。 +- [**创建钱包**](/cn/how-to/create-wallet):使用 ethers.js 或 Tether WDK 生成新密钥对或从助记词恢复。 +- [**代理钱包**](/cn/reference/agentic-wallets):AI 代理的自托管钱包(它们与用户钱包有何不同)。 ## 委托账户(EIP-7702) -- [**EIP-7702 概念**](/cn/explanation/eip-7702) — EIP-7702 在 Stable 上实现的功能及其安全模型。 -- [**账户抽象操作指南**](/cn/how-to/account-abstraction) — 将 EIP-7702 应用于批量支付、消费限额和会话密钥。 +- [**EIP-7702 概念**](/cn/explanation/eip-7702):EIP-7702 在 Stable 上实现的功能和安全模型。 +- [**账户抽象操作指南**](/cn/how-to/account-abstraction):将 EIP-7702 应用于批量支付、消费限额和会话密钥。 ## 参考 -- [**EIP-7702 API**](/cn/reference/eip-7702-api) — Type-4 交易格式和授权列表。 -- [**订阅与收款**](/cn/how-to/subscribe-and-collect) — 将 EIP-7702 委托应用于订阅支付流程(交叉列出)。 +- [**EIP-7702 API**](/cn/reference/eip-7702-api):Type-4 交易格式和授权列表。 +- [**订阅和收款**](/cn/how-to/subscribe-and-collect):将 EIP-7702 委托应用于订阅支付流程(交叉列出)。 diff --git a/docs/pages/cn/explanation/accounts-overview.mdx b/docs/pages/cn/explanation/accounts-overview.mdx index 1ca60ed..ab52be4 100644 --- a/docs/pages/cn/explanation/accounts-overview.mdx +++ b/docs/pages/cn/explanation/accounts-overview.mdx @@ -1,37 +1,37 @@ --- source_path: explanation/accounts-overview.mdx -source_sha: e216ff05dc7df6363bf8c91d905bf03ed4436e50 +source_sha: a61b4059ba015ad3e32ff09134ed6df69381096e title: "Stable 上的账户" -description: "Stable 上用户和代理账户的钱包、EIP-7702 委托、会话密钥和支出限额。" +description: "Stable 上的用户和代理账户的钱包、EIP-7702 委托、会话密钥和支出限额。" diataxis: "explanation" --- # Stable 上的账户 -Stable 上的账户是标准的以太坊 EOA,可以通过 [EIP-7702 委托](/cn/explanation/eip-7702)选择性地执行智能合约逻辑。用户在钱包、批量支付、定期订阅和会话密钥中始终保持一个地址和一个私钥。代理使用相同的账户模型运行,无需任何托管中间件。 +Stable 上的账户是一个标准的以太坊 EOA,它可以通过 [EIP-7702 委托](/cn/explanation/eip-7702) 可选择地执行智能合约逻辑。用户在钱包、批处理支付、循环订阅和会话密钥中保留一个地址和一个私钥。代理运行相同的账户模型,无需任何托管中间件。 -## 你可以构建什么 +## 您可以构建什么 -- **钱包**:从助记词创建,支持原生 USDT0 余额查询和签名交易。 -- **批量支付**:通过委托的 EOA 在一笔原子交易中执行多次转账。 -- **支出限额**:通过委托逻辑在 EOA 本身上强制实施每笔交易或每日上限。 -- **会话密钥**:向 dApp 授予一个范围受限、时间受限、预算受限的密钥,使用户无需为每个操作重新签名。 -- **代理钱包**:用自托管密钥为 AI 代理注资,让其自主支付 x402 服务费用。有关提供商和集成模式,请参阅[代理钱包](/cn/reference/agentic-wallets)。 +- **钱包**:通过助记词,进行原生的 USDT0 余额查询和签名交易。 +- **批处理支付**:通过委托型 EOA 在一个原子交易中执行多笔转账。 +- **支出限额**:通过委托逻辑在 EOA 本身强制执行每笔交易或每日上限。 +- **会话密钥**:授予 dApp 一个有范围、有时间限制、有预算限制的密钥,以便用户无需重新签署每个操作。 +- **代理钱包**:为 AI 代理提供自托管密钥,并让它自主支付 x402 服务。有关提供商和集成模式,请参阅[代理钱包](/cn/reference/agentic-wallets)。 ## Stable 的不同之处 -- **一个地址搞定一切。** 无需账户迁移即可解锁智能合约功能。EIP-7702 将代码委托*到*现有 EOA 上。 -- **仅用 USDT0 支付 Gas。** 用户无需单独的原生代币。新账户用 USDT0 注资后即可立即交易。 -- **多功能委托模式。** 单个委托可以组合批量、支出限额、会话密钥和订阅功能,因此一次委托即可覆盖你交付的所有功能。 +- **一个地址,包罗万象。** 无需账户迁移即可解锁智能合约功能。EIP-7702 将代码委托给现有的 EOA。 +- **仅限 USDT0 Gas。** 用户不需要单独的原生代币。新账户用 USDT0 充值后即可立即交易。 +- **多功能委托模式。** 一个委托可以结合批处理、支出限额、会话密钥和订阅,因此一个委托涵盖您提供的所有功能。 ## 从这里开始 -- [**创建钱包**](/cn/how-to/create-wallet) — 使用 ethers.js 或 Tether WDK 生成或恢复钱包。 -- [**使用 EIP-7702 委托**](/cn/how-to/account-abstraction) — 将批量支付、支出限额和会话密钥应用于现有 EOA。 -- [**Stable SDK**](/cn/explanation/sdk-overview) — 使用类型化客户端从任何账户签名并发送交易。 +- [**创建钱包**](/cn/how-to/create-wallet):使用 ethers.js 或 Tether WDK 生成或恢复钱包。 +- [**使用 EIP-7702 进行委托**](/cn/how-to/account-abstraction):将批处理支付、支出限额和会话密钥应用于现有 EOA。 +- [**Stable SDK**](/cn/explanation/sdk-overview):使用类型化客户端从任何账户签名和发送交易。 -## 接下来推荐 +## 下一步建议 -- [**账户指南索引**](/cn/explanation/accounts-guides) — 跳转到账户指南和参考的完整列表。 -- [**EIP-7702 概念**](/cn/explanation/eip-7702) — 为什么委托无需账户迁移即可工作。 -- [**订阅与收款**](/cn/how-to/subscribe-and-collect) — 将账户模型应用于定期支付流程。 +- [**账户指南索引**](/cn/explanation/accounts-guides):跳转到账户指南和参考的完整列表。 +- [**EIP-7702 概念**](/cn/explanation/eip-7702):为什么委托无需账户迁移即可工作。 +- [**订阅和收款**](/cn/how-to/subscribe-and-collect):将账户模型应用于循环支付流程。 diff --git a/docs/pages/cn/explanation/agent-settlement.mdx b/docs/pages/cn/explanation/agent-settlement.mdx index 6c2b24f..6d2a0ec 100644 --- a/docs/pages/cn/explanation/agent-settlement.mdx +++ b/docs/pages/cn/explanation/agent-settlement.mdx @@ -1,57 +1,57 @@ --- source_path: explanation/agent-settlement.mdx -source_sha: 161a49c64c60ae1d96e433bc9f7348f9f0220133 +source_sha: 1cf4364b9675c77a3542fbe1cbd4ac6aacaaaf53 title: "代理结算" -description: "自主代理如何在 Stable 上以 USDT 持有、支付和结算,无需独立的 gas 代币,并具备亚秒级最终确认。" +description: "自主代理如何在 Stable 上持有、支付和结算 USDT,无需单独的 gas 代币,且具有亚秒级终结性。" diataxis: "explanation" --- # 代理结算 -代理结算是 Stable 面向机器支付的通道。代理持有 USDT0 余额,通过 HTTP 为某个资源付费,付款在同一请求周期内于链上结算。代理从同一个余额中同时支出付款和网络费用。无需独立的 gas 代币,无需注册,也无需轮换 API 密钥。 +代理结算是 Stable 针对机器支付的通道。代理持有 USDT0 余额,通过 HTTP 方式为资源付费,支付在同一请求周期内于链上结算。代理从一个余额中支出,用于支付和网络费用。无需单独的 gas 代币,无需注册,也无需 API 密钥轮换。 ## 这对代理为何重要 -代理的交易方式与人类不同。它们持续运行,进行大量小额付款,且无法完成注册流程或轮换 API 密钥。Stable 上的结算正契合这种工作负载: +代理与人类交易方式不同。它们持续运行,进行大量小额支付,并且无法完成注册流程或轮换 API 密钥。Stable 上的结算匹配了这种工作负载: -- **USDT0 既是 gas 代币也是支付代币。** 代理钱包持有单一资产,并用它同时支付费用和付款。 -- **亚美分、可预测的费用。** 费用以美元计价,因此代理可以为每个操作的成本做预算,而无需从波动的 gas 资产进行换算。 -- **亚秒级最终确认。** 已付费的 HTTP 调用在请求生命周期内完成结算(约 700 毫秒出块时间),这使高频机器流量成为可能。 -- **USDT 的分发覆盖。** USDT 是持有最广泛的稳定币;Stable 是专为它打造的场所。 +- **USDT0 既是 gas 代币也是支付代币。** 代理钱包持有单一资产,并将其用于支付费用和款项。 +- **亚美分级、可预测的费用。** 费用以美元计价,因此代理可以预算每次操作的成本,而无需从不稳定的 gas 资产中进行转换。 +- **亚秒级终结性。** 已支付的 HTTP 调用在请求生命周期内(约 700 毫秒区块时间)完成结算,这使得高频机器流量成为可能。 +- **USDT 分发。** USDT 是持有最广泛的稳定币;Stable 是专为此目的而构建的平台。 -## 各层级如何协作 +## 各层级如何协同 -两个层级承担不同的职责,互为补充而非相互替代: +两个层级各司其职,互为补充,而非替代: -- **x402** 是*支付标准*。它是一种 HTTP 原生协议,服务器以 `402 Payment Required` 响应,客户端签署授权,由 facilitator 提交。 -- **MPP(Machine Payments Protocol)** 是 IETF 标准化路线上的标准,它通过更广泛的意图和多通道支持取代 x402;x402 是 Stable 目前支持的向后兼容子集。参见 [MPP](/cn/explanation/mpp)。 -- **Stable** 是*结算层*。USDT0 的链上转账实际上在这里发生。 +- **x402** 是*支付标准*。它是一种 HTTP 原生协议,服务器响应 `402 Payment Required`,客户端签署授权,然后由协调器提交。 +- **MPP (Machine Payments Protocol)** 是 IETF 正在跟踪的标准,它以更广泛的意图和多通道支持取代了 x402;x402 是 Stable 目前支持的向后兼容子集。参见 [MPP](/cn/explanation/mpp)。 +- **Stable** 是*结算层*。这是 USDT0 链上转账实际发生的地方。 -**facilitator** 位于两者之间:它验证已签名的付款并提交链上调用,从而使开发者无需运行结算基础设施。请参见 [Facilitators](/cn/reference/agentic-facilitators),了解目前支持 Stable 的提供商。 +一个**协调器**位于两者之间:它验证已签名的支付并提交链上调用,因此开发者无需运行结算基础设施。请参阅[协调器](/cn/reference/agentic-facilitators)以了解目前支持 Stable 的提供商。 ```text -agent (client) ──HTTP──▶ resource server ──signed payment──▶ facilitator ──tx──▶ Stable - (returns 402) (verify + submit) (USDT0 settles) +代理(客户端)──HTTP──▶ 资源服务器 ──已签名支付──▶ 协调器 ──交易──▶ Stable + (返回 402) (验证 + 提交) (USDT0 结算) ``` -## 你可以构建什么 +## 您可以构建什么 -- **按调用付费的 API**,以 USDT0 按请求计价,通过 x402 或 MPP 结算。 -- **代理对代理的商业**,一个代理通过 HTTP 为另一个代理的服务付费。 -- **付费的 MCP 工具**,封装 x402 端点,使 AI 客户端可以通过提示词调用并为其付费。 -- **自主采购**,基于已编入预算的 USDT0 余额。 -- **基于用量的计费**,按每次请求结算而非按发票结算。 -- **代理钱包**,仅以 USDT0 充值,无需托管中间件。 +- **按次付费 API** 以 USDT0 按请求定价,通过 x402 或 MPP 结算。 +- **代理间商务**,即一个代理通过 HTTP 为另一个代理的服务付费。 +- **付费 MPC 工具**,将 x402 端点封装起来,以便 AI 客户端通过提示调用并支付。 +- **自主采购**,根据预算的 USDT0 余额进行。 +- **基于使用量的计费**,按请求而非按发票结算。 +- **代理钱包**仅用 USDT0 资助,无需托管中间件。 ## 从这里开始 -- [**构建按调用付费的 API**](/cn/how-to/build-pay-per-call) — 搭建一个 x402 门控的端点,并在请求中结算一笔真实的 USDT0 付款。 -- [**在 Stable 上构建 MPP 端点**](/cn/how-to/build-mpp-endpoint) — 为 USDT0 编写三个 MPP 自定义方法钩子,并在 Stable 上结算。 -- [**使用 AI 进行开发**](/cn/how-to/develop-with-ai) — 将 Docs MCP 和 Runtime MCP 接入你的 AI 编辑器,并粘贴 Stable 上下文块。 -- [**通过 MCP 服务器付费**](/cn/how-to/pay-with-mcp) — 将 x402 付费 API 暴露为 MCP 工具,使代理可以通过自然语言提示词调用它们。 +- [**构建按次付费 API**](/cn/how-to/build-pay-per-call):建立一个受 x402 保护的端点,并在请求中结算真实的 USDT0 支付。 +- [**在 Stable 上构建 MPP 端点**](/cn/how-to/build-mpp-endpoint): 为 USDT0 编写三个 MPP 自定义方法钩子并在 Stable 上结算。 +- [**使用 AI 进行开发**](/cn/how-to/develop-with-ai):将 Docs MCP 和 Runtime MCP 连接到您的 AI 编辑器,并粘贴 Stable 上下文块。 +- [**使用 MCP 服务器支付**](/cn/how-to/pay-with-mcp):将 x402 支付的 API 作为 MPC 工具暴露,代理可以通过自然语言提示调用。 -## 推荐的后续阅读 +## 接下来推荐 -- [**深入了解 x402**](/cn/explanation/x402) — 阅读 HTTP 支付协议在 Stable 上端到端的工作方式。 -- [**MPP**](/cn/explanation/mpp) — x402 所属的更广泛的 IETF 标准化路线标准。 -- [**Facilitators**](/cn/reference/agentic-facilitators) — 查看哪些 facilitator 已在 Stable 上结算 USDT0 付款。 +- [**x402 深度解析**](/cn/explanation/x402):阅读 HTTP 支付协议如何在 Stable 上端到端工作。 +- [**MPP**](/cn/explanation/mpp):x402 所属的更广泛的 IETF 跟踪标准。 +- [**协调器**](/cn/reference/agentic-facilitators):查看哪些协调器已经在 Stable 上结算 USDT0 支付。 diff --git a/docs/pages/cn/explanation/ai-agents-guides.mdx b/docs/pages/cn/explanation/ai-agents-guides.mdx index 902c290..d807629 100644 --- a/docs/pages/cn/explanation/ai-agents-guides.mdx +++ b/docs/pages/cn/explanation/ai-agents-guides.mdx @@ -1,32 +1,32 @@ --- source_path: explanation/ai-agents-guides.mdx -source_sha: feec6b3035c4245e42fd83f92982234e3394a59d -title: "AI 与智能体指南" -description: "所有智能体指南、概念和参考:MCP 设置、付费 MCP 工具、智能体钱包和智能体结算服务。" +source_sha: 0e678109f589a9e41c9f1a8bcb36c139cd0e5275 +title: "AI 和代理指南" +description: "所有代理指南、概念和参考资料:MCP 设置、付费 MCP 工具、代理钱包和代理协调器。" diataxis: "explanation" --- -# AI 与智能体指南 +# AI 和代理指南 -AI/智能体标签页下的所有指南、概念和参考,按你想要完成的任务分组。 +AI/代理选项卡下的所有指南、概念和参考资料,按您要执行的操作进行分组。 -## 配置 AI 编辑器 +## 装备 AI 编辑器 -- [**使用 AI 进行开发**](/cn/how-to/develop-with-ai) — 安装 Docs MCP、Runtime MCP、智能体技能,并粘贴 Stable 上下文块。 -- [**创建智能体钱包**](/cn/how-to/create-wallet) — 通过 WDK 自托管密钥——智能体支付的基础。 +- [**使用 AI 进行开发**](/cn/how-to/develop-with-ai):安装 Docs MCP、Runtime MCP、代理技能,并粘贴 Stable 上下文块。 +- [**创建代理钱包**](/cn/how-to/create-wallet):通过 WDK 自行保管密钥,这是代理支付的基础。 -## 服务变现与使用 +## 货币化和消费服务 -- [**构建按调用付费的 API**](/cn/how-to/build-pay-per-call) — 使用 x402 中间件,为任意 HTTP 端点按请求以 USDT0 定价。 -- [**通过 MCP 服务器付费**](/cn/how-to/pay-with-mcp) — 将 x402 付费 API 封装为 MCP 工具,使 AI 客户端可以调用并为其付费。 +- [**构建按次付费 API**](/cn/how-to/build-pay-per-call):使用 x402 中间件,以 USDT0 为单位按请求对任何 HTTP 端点进行定价。 +- [**使用 MCP 服务器支付**](/cn/how-to/pay-with-mcp):将 x402 付费 API 封装为 MCP 工具,以便 AI 客户端调用并支付。 ## 参考 -- [**智能体结算服务**](/cn/reference/agentic-facilitators) — Stable 上用于智能体间商务的结算服务。 -- [**智能体钱包**](/cn/reference/agentic-wallets) — 用于自主智能体的钱包规范。 +- [**代理协调器**](/cn/reference/agentic-facilitators):Stable 上代理对代理商业的结算服务。 +- [**代理钱包**](/cn/reference/agentic-wallets):自主代理使用的钱包规范。 ## 基础概念 -- [**x402(HTTP 原生支付)**](/cn/explanation/x402) — 智能体用于按请求付费的 HTTP 协议。 -- [**MPP**](/cn/explanation/mpp) — x402 所属的更广泛的 IETF 标准,支持会话和多通道。 -- [**ERC-3009**](/cn/explanation/erc-3009) — x402 通过其进行结算的签名授权标准。 +- [**x402(HTTP 原生支付)**](/cn/explanation/x402):代理用于按请求支付的 HTTP 协议。 +- [**MPP**](/cn/explanation/mpp):x402 所属的更广泛的 IETF 轨道标准,支持会话和多轨道。 +- [**ERC-3009**](/cn/explanation/erc-3009):x402 通过其进行结算的签名授权标准。 diff --git a/docs/pages/cn/explanation/autobahn.mdx b/docs/pages/cn/explanation/autobahn.mdx index 4175c44..bae8566 100755 --- a/docs/pages/cn/explanation/autobahn.mdx +++ b/docs/pages/cn/explanation/autobahn.mdx @@ -1,77 +1,83 @@ --- source_path: explanation/autobahn.mdx -source_sha: 166db38136cef9a5d17c1d38bc33bb434a5b1e51 +source_sha: ed268ab80c3a227b6989f1d9746eaf5f0410245c title: "Autobahn" -description: "在低延迟与网络故障恢复性之间取得平衡的 Autobahn DAG-BFT 共识协议。" +description: "Autobahn DAG-based BFT consensus protocol balancing low latency and fault tolerance for StableBFT." +diataxis: "explanation" --- # Autobahn -## BFT 协议的权衡:低延迟 vs. 高鲁棒性 +## BFT 中的权衡:延迟与鲁棒性 -现代拜占庭容错(BFT)共识协议通常运行在部分同步模型下,该模型假设在某个不确定的时间点后,网络最终会变得稳定,消息传递延迟会有上限。虽然这个模型在协议设计上是实用的,但现实部署中很少能享受长时间的持续稳定。相反,系统经常经历同步阶段后出现短暂中断,如延迟激增、节点宕机或恶意攻击。这些短暂中断被称为 **“突变(blips)”**。 +现代拜占庭容错 (BFT) 共识协议通常在部分同步模型下运行。该模型假设网络最终会稳定下来,并且消息延迟保持在一定范围内。虽然这对于协议设计来说是实用的,但实际部署很少能享受到长时间不间断的稳定性。相反,系统经常会经历一段同步期,随后出现短暂的中断,例如延迟高峰、节点中断或对抗性条件。这些短暂的中断被称为 “**小故障**”(blips)。 -在这种情况下,现有的共识协议通常被迫在 **网络稳定时的低延迟** 与 **故障状态下的高鲁棒性** 之间做出取舍: +在这种情况下,现有共识协议被迫在**稳定网络条件下的低延迟和存在故障时的鲁棒性之间做出选择**。 -- **传统的基于视图(view-based)的 BFT 协议**(如 PBFT 和 HotStuff)在网络良好时响应迅速,但一旦发生突变,其性能会迅速恶化。这种性能衰退称为“宿醉效应(hangover)”,即使网络恢复后仍会持续,因为积压的请求会延迟后续交易处理。 -- **基于 DAG 的 BFT 协议**(如 [Narwhal & Tusk](https://arxiv.org/pdf/2105.11827)/[Bullshark](https://arxiv.org/pdf/2201.05677))将数据传播(DAG)与共识(BFT)解耦,允许交易异步传播至各副本。这种设计支持高吞吐量,并可在网络中断时继续推进。然而,这些协议即使在网络良好时也会因异步排序机制的复杂性而导致高延迟。 +- **传统的基于视图的 BFT 协议**,如 PBFT 和 HotStuff,在网络稳定、状况良好时,针对响应性进行了优化。然而,当出现小故障时,它们的性能会下降。这种下降,被称为“滞后”(hangover),即使在网络恢复后也可能持续存在,因为积压的请求会累积并延迟后续事务。 +- **基于 DAG 的 BFT 协议**,如 [Narwhal & Tusk](https://arxiv.org/pdf/2105.11827)/[Bullshark](https://arxiv.com/pdf/2201.05677),将数据传播 (DAG) 从共识 (BFT) 中解耦,并异步地在副本之间传播事务。这种设计实现了高吞吐量,并允许系统在网络中断期间继续进行。然而,即使在状况良好期间,这些协议也往往会由于其异步排序机制的复杂性而产生高延迟。 -[**Autobahn**](https://arxiv.org/pdf/2401.10369) 引入了一种全新方法,融合了这两种设计理念的优势。它结合了 DAG 协议的高吞吐与对突变的容忍性,以及传统共识协议的低延迟性能。Autobahn 的核心是一个高度并行的数据传播层,无论共识进展如何,始终以网络速度传播提案。在此之上,Autobahn 运行一个低延迟的部分同步共识协议,通过引用数据层的轻量级快照来提交提案。 +[**Autobahn**](https://arxiv.org/pdf/2401.10369) 引入了一种新方法,弥合了这两种设计理念。它结合了基于 DAG 协议的高吞吐量和小故障容忍性,以及传统基于视图共识的低延迟性能。Autobahn 的核心是一个高度并行的 数据传播层,它以网络速度持续传播提案,无论共识进程如何。在此层之上,Autobahn 运行一个低延迟、部分同步的共识协议,通过引用数据层的轻量级快照来提交提案。 -Autobahn 的一个显著特点是其在突变后无性能退化的恢复能力,称为 **“无缝性(seamlessness)”**。这意味着系统在网络稳定后可立即恢复全速和低延迟运行,无需对积压交易进行代价高昂的重复处理。通过将数据可用性与排序清晰分离,并避免协议自身引起的同步延迟,Autobahn 为真实环境下的区块链共识提供了一个既有高鲁棒性又响应迅速的基础。 +Autobahn 的一个显著特点是它能够从小故障中恢复,而不会导致性能下降。这种特性被称为**无缝性**,它确保系统在网络稳定后立即恢复全吞吐量和低延迟。无需对积压的事务进行昂贵的重新处理。通过将数据可用性与排序清晰分离,并避免协议引起的同步延迟,Autobahn 为现实世界条件下的区块链共识提供了强大而响应迅速的基础。 -## Autobahn 架构概览 +## Autobahn 架构概述 -Autobahn 的架构围绕其两大核心层:**数据传播层** 和 **共识层**,职责分离明确。这种解耦借鉴了 Narwhal 等 DAG 系统的设计,但 Autobahn 对其进行了增强,以支持无缝性和更低延迟。 +Autobahn 的架构围绕着**数据传播层**和**共识层**这两个核心层之间的职责清晰分离。这种解耦的灵感来自于 Narwhal 等基于 DAG 的系统设计,但 Autobahn 增强了这种结构以支持无缝性并降低延迟。 -数据传播层负责以可扩展的异步方式广播客户端交易。每个副本维护一条独立的交易批处理通道,称为“车道(lane)”,这些车道可独立于共识状态进行传播和认证。即使共识过程暂停,车道仍持续增长,保证系统对客户端始终保持响应。 +数据传播层负责以可扩展的异步方式广播客户端事务。它允许每个副本维护自己的事务批次通道,这些批次可以独立于共识状态进行传播和认证。这些通道持续增长,即使在共识进程停滞时也是如此,确保系统始终对客户端保持响应。 -共识层运行一个基于 PBFT 风格的部分同步协议。但与传统共识需就每一批交易达成一致不同,Autobahn 共识协议的处理方式类似“车头快照(tip cut)”,即各条车道当前状态的精简摘要。这种设计允许 Autobahn 一次性提交任意规模的数据,减少突变带来的影响。 +在此之上,Autobahn 运行一个基于 PBFT 风格协议的部分同步共识层。然而,共识协议不是就单个事务批次达成协议,而是就“尖端切片”(tip cuts)达成协议,尖端切片是所有数据通道最新状态的紧凑摘要。这种设计允许 Autobahn 在单个步骤中提交任意大量数据,从而最大限度地减少小故障的影响。 -相较于 HotStuff(数据与共识紧耦合,领导者失败时易停滞)和 Bullshark(因 DAG 遍历和同步造成高延迟),Autobahn 提供了更平滑、更快速的共识体验。它继承了 DAG 的并行性,却规避了其延迟劣势。 +HotStuff 将数据和共识紧密耦合,导致领导者失败时停滞。Bullshark 由于 DAG 遍历和数据同步而导致高提交延迟。Autobahn 提供了更流畅、更快速的共识体验,继承了 DAG 的并行性,同时避免了其延迟陷阱。 -## **数据传播层:车道与车辆** +## 数据传播层:通道与“汽车” -![Autobahn:无缝高速 BFT](/images/autobahn-high-speed1.png) +![Autobahn:无缝高速BFT](/images/autobahn-high-speed1.png) *Autobahn:无缝高速 BFT* -在 Autobahn 中,每个副本在其独立推进的链中提出交易,称为一条 **车道(lane)**。每个数据提案都包含来自其他副本的确认集合,称为 **“车辆(car)”**(即可用请求认证,Certification of Available Request)。这些车辆作为数据可用性的证明(PoA),确保至少一个诚实副本持有数据,并在需要时可重新传输。 +在 Autobahn 中,每个副本都在一个独立推进的链中提出事务,该链被称为**通道**。通道中的每个数据提案都与来自其他副本的一组确认捆绑在一起,形成作者所称的“**汽车**”(Car,即 Certification of Available Request 的缩写)。这些汽车充当**可用性证明** (PoA),确保至少一个正确的副本持有该数据,并在需要时可以重新传输。 -车辆通过在每个新提案中引用前一个车辆构建出链式结构。这种结构保证了只需验证车道的车头即可确认整个车道历史数据的可用性。这种可传递的可用性证明使 Autobahn 能即时引用车头快照,避免了 DAG 遍历操作或额外的同步操作。 +通过在每个新提案中包含对前一个汽车的引用,汽车被连接在一起。这种结构保证了验证通道的尖端意味着整个通道历史的可用性。这种可传递的可用性证明是 Autobahn 即时引用的关键。共识层可以引用一个尖端切片(当前通道头的向量),并知道所有先前数据都是可检索的,而无需执行 DAG 遍历或额外的同步。 -与传统 DAG 协议不同,Autobahn 避免了强制全局可用性和防双重广播所需的高成本广播步骤。它使用尽可能少的操作,信任每个 PoA 至少有一个诚实数据副本,从而即使在负载变化或部分故障下也能实现高吞吐与低延迟。数据层独立于共识持续推进,确保在突变期间仍保持响应。 +与典型的 DAG 协议不同,Autobahn 避免了强制执行全局可用性和非不明确性的昂贵可靠广播步骤。相反,它使用最少的协调,并相信每份 PoA 至少有一个诚实的副本持有数据。这即使在不同负载或部分故障下也能实现高吞吐量和低尾部延迟。数据层独立于共识继续进行,确保在小故障期间的响应性。 -## **共识层:低延迟达成一致** +## 共识层:低延迟协议 -![Autobahn:无缝高速 BFT](/images/autobahn-high-speed2.png) +![Autobahn:无缝高速BFT](/images/autobahn-high-speed2.png) *Autobahn:无缝高速 BFT* -Autobahn 的共识层在经典 PBFT 原则基础上引入关键优化,降低延迟并支持无缝恢复。每个共识时隙的目标是提交一个 **“车头快照(tip cut)”**,该快照捕捉来自各副本车道的最新认证提案。共识领导者使用两阶段提交流程(Prepare 和 Confirm)提出该快照。 +Autobahn 中的共识层建立在经典的 PBFT 原则之上,但引入了关键优化以降低延迟并支持无缝恢复。每个共识槽都旨在提交一个“**尖端切片**”,该切片捕获每个副本通道的最新认证提案。共识领导者使用两阶段提交过程(准备和确认)来提出这个切片。 -在 Prepare 阶段,副本对提议的快照进行投票。如果领导者迅速收到足够投票(完整法定数),可进入快速路径(Fast Path),仅需 3 次消息延迟即可完成提交。否则,它将进入 Confirm 阶段,收集第二轮投票后在 6 次消息延迟内完成提交。 +在准备阶段,副本对提出的尖端切片进行投票。如果领导者迅速收到足够的投票(一个完整的法定人数),它可以进入快速路径并仅通过 3 次消息延迟立即提交。如果不能,它将进入确认阶段,在完成 6 次消息延迟的提交之前收集另一组确认的法定人数。 -一大创新在于将数据同步从共识投票中拆解出来。副本可仅依据认证车头进行投票,即便尚未接收完整提案数据。这是安全的,因为 PoA 保证了数据的可检索性。同步操作并行进行,并在执行阶段前完成,避免协议阻塞。如遇领导者故障或超时,系统通过超时证书触发视图变更,由新领导者继续推进。 +一个关键的创新是将数据同步从共识投票中解耦。副本可以仅根据经过认证的尖端进行投票,即使它们尚未收到完整的提案数据。这是安全的,因为可用性证明确保了可检索性。同步并行进行并在执行阶段之前完成,从而避免了协议停滞。在领导者失败或超时的情况下,使用超时证书触发视图更改,新领导者可以高效地恢复进展。 -## Autobahn 的核心特性 +## Autobahn 的主要特性 -Autobahn 满足 BFT 协议标准的 **安全性** 与 **活性** 保证。安全性确保不会有两个正确副本在同一时隙提交不同区块;活性确保在全局稳定时间(GST)后,若最终选出正确领导者,则系统必将前进。 +Autobahn 满足 BFT 协议所期望的标准**安全性**和**活性**保证。安全性确保在同一槽中,没有两个正确的副本提交不同的块。活性保证在全局稳定时间 (GST) 之后,只要最终选出正确的领导者,就会取得进展。 -更重要的是,Autobahn 实现了真正的 **无缝性(seamlessness)**。其共识层可在常数时间(Constant Time)内提交任意规模的历史数据,避免因协议机制而导致的“宿醉”。即便经历突变,只要同步恢复,所有已传播的提案可立即被提交。这种能力使 Autobahn 能在间歇性故障环境中流畅运行,其恢复时间与响应速度均优于传统 BFT 协议。 +更重要的是,Autobahn 实现了**无缝性**。它通过允许共识层以恒定时间提交任意大量积压数据来避免协议引起的滞后。即使在出现小故障之后,一旦同步恢复,所有成功传播的数据提案都可以立即提交。这使得 Autobahn 能够在存在间歇性故障的环境中顺利运行,在恢复时间和系统响应能力方面都优于传统的 BFT 协议。 -此外,该协议还具备 **横向扩展性**。每个副本通过其车道为系统贡献吞吐量,随着参与者增加,快照提交容量自然增长,使 Autobahn 非常适合需要高性能与高鲁棒性的规模化部署。 +此外,该协议**水平扩展**。每个副本都通过自身的通道为系统的吞吐量做出贡献,并且共识切片随着参与者数量的增加而自然增长。这使得 Autobahn 适用于需要高性能和鲁棒性的大规模部署。 -## **低延迟遇上高鲁棒性** +## 低延迟与高弹性相结合 -Autobahn 在理想和故障注入的测试条件下与主流 BFT 协议(尤其是 Bullshark 和 HotStuff)进行对比测试。结果表明,Autobahn 兼具两者之长:在处理能力上匹敌 Bullshark(每秒处理超过 23 万笔交易),而延迟则降低了 50% 以上。 +Autobahn 在理想和注入故障的条件下,与领先的 BFT 协议,特别是 Bullshark 和 HotStuff,进行了评估。结果表明,Autobahn 兼具两者的优点:它与 Bullshark 的吞吐量相匹配,每秒处理超过 230,000 笔交易,同时将其延迟降低了 50% 以上。 -在网络良好条件下,Autobahn 仅需 3 至 6 次消息延迟即可提交交易,而 Bullshark 需 12 次,这使其实际提交延迟低至 280 毫秒,而 Bullshark 超过 590 毫秒。不同于 HotStuff 在突变后因积压处理而产生的长时间宿醉,Autobahn 能在网络稳定后一次性提交全部积压内容。 +在良好的网络条件下,Autobahn 仅用 3 到 6 次消息延迟即可提交交易,而 Bullshark 则需要 12 次。这在实践中意味着提交延迟低至 280 毫秒,而 Bullshark 超过 590 毫秒。与 HotStuff 不同,HotStuff 由于积压处理延迟而在出现故障后遭受长时间滞后,Autobahn 在网络稳定后立即在一个步骤中提交其全部积压。 -在领导者失效或部分网络分叉(partial network partitions)等故障场景下,Autobahn 表现出无缝恢复能力。在故障期间持续传播数据,并在共识恢复后迅速提交已积累提案。这些性能优势使 Autobahn 成为区块链平台在追求低延迟响应与高吞吐容错性方面的理想选择。 +在涉及领导者故障或部分网络分区的场景中,Autobahn 展示了无缝恢复。它在故障期间继续传播数据,并在共识恢复后迅速提交累积的提案。这些性能优势使 Autobahn 成为寻求将低延迟响应性与高吞吐量和容错性相结合的区块链平台的理想选择。 ## 延伸阅读 -欲了解更多技术细节,请参考: +如需更多技术深入探讨和细节,请参阅: - [Autobahn: Seamless high speed BFT](https://arxiv.org/pdf/2401.10369) + +## 下一步推荐 + +- [**共识**](/cn/explanation/consensus):返回 StableBFT,Autobahn 演进的共识实现。 +- [**终局性**](/cn/explanation/finality):构建 RPC 时使用 Stable 的单槽终局性。 diff --git a/docs/pages/cn/explanation/bank-module.mdx b/docs/pages/cn/explanation/bank-module.mdx index 12d4171..a9c8470 100755 --- a/docs/pages/cn/explanation/bank-module.mdx +++ b/docs/pages/cn/explanation/bank-module.mdx @@ -1,301 +1,44 @@ --- source_path: explanation/bank-module.mdx -source_sha: 95cf49e645e5694b709ae0b2db08735a0b0fde3a -title: 银行模块 -description: "提供 ERC-20 兼容代币转账、授权与委托功能的 Bank 预编译合约。" +source_sha: c19264aa3a4aa590a16f97192b30d5ffe1d88b08 +title: "银行模块" +description: "银行预编译合约暴露了与 ERC-20 兼容的代币转账以及由 SDK x/bank 模块支持的铸造、销毁和授权方法。" +diataxis: "explanation" --- # 银行模块 -## 概述 +Stable SDK 中的 `x/bank` 模块处理代币余额、转账和供应。其 EVM 接口(**银行预编译合约**)封装了此模块,并添加了 ERC-20 语义以及一个用于特权铸币/销毁操作的授权层。需要在 Stable 上转移代币的合约可以直接调用预编译合约,而无需部署自己的代币实现。 -Stable SDK 中的 `x/bank` 模块仅提供基本的代币管理功能。 -每个代币都可以无限制地转移到任何账户,用户无法委托其他账户代为转移其代币到其他账户。 -因此,`bank` 预编译合约在 Stable SDK 现有的 `x/bank` 模块基础上提供了额外的授权和委托功能。 +## 它暴露了什么 -## 目录 +银行预编译合约提供了标准的 ERC-20 方法: -1. **[概念](#concepts)** -2. **[配置](#configuration)** -3. **[方法](#methods)** -4. **[事件](#events)** +- `transfer`、`balanceOf`、`totalSupply` +- `approve`、`transferFrom`、`allowance`、`revoke` -## 概念 +这些方法适用于任何调用者。无需注册。 -该预编译合约提供 ERC20 标准方法 - 如用于转账的 `transfer` 和 `balanceOf`,以及用于委托的 `transferFrom`、`approve` 和 `allowance`。这些方法可以直接调用,无需注册合约地址。 +它还提供了特权方法: -然而,`mint` 和 `burn` 方法需要合约地址被列入白名单,通过 `x/precompile` 模块注册。 +- `mint`: 铸造新代币并将其转移到账户。 +- `burn`: 销毁账户持有的代币。 +- `multiTransfer`: 通过单个调用将代币从一个发送方转移到多个接收方。 -```go -func (p *Precompile) mint( - ctx sdk.Context, - contract *vm.Contract, - denom string, - method *abi.Method, - stateDB vm.StateDB, - args []interface{}, -) ([]byte, error) { - // ... +铸币和销毁要求调用合约通过治理提案在 `x/precompile` 允许列表中注册。治理代币的铸造被完全阻止。这使得供应通胀只受授权合约的限制。 - // mint method is only allowed for the registered caller contract - if _, err := precompilecommon.CheckPermissions(ctx, p.precompileKeeper, contract.CallerAddress, CallerPermissions); err != nil { - return nil, err - } -``` +## 何时使用 -额外的验证过程可以保证调用此预编译合约的代币合约是经过授权的。 +- DeFi 合约需要代表用户转移 STABLE 或 USDT0:直接在预编译合约上调用 `transfer` 或 `transferFrom`。 +- 协议合约根据业务逻辑铸造或销毁代币:首先通过治理注册,然后调用 `mint` / `burn`。 +- 支付合约需要一对多支付:在单个交易中调用 `multiTransfer`,而不是循环转账。 -需要通过治理提案来注册代币合约地址及其denomination到 `x/precompile` 模块的白名单中。 +## 在哪里找到 ABI -## 配置 +完整的方法签名、事件负载和授权流程在[银行预编译合约参考](/cn/reference/bank-module-api)中。 -合约地址和gas费用已预定义。 +## 接下来推荐 -### 合约地址 - -- `0x0000000000000000000000000000000000001003` STABLE (用于治理代币) - -## 方法 - -### `mint` - -铸造请求数量的新代币并转移到账户。 -要铸造的代币数量必须大于零。 - -当代币成功铸造并转移到账户时,会发出 `PrecompiledBankMint` 事件。 - -注意: - -- 禁止铸造治理代币。 -- 调用铸造方法的合约必须在 x/precompile 模块中注册。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|to|address|接收铸造代币的地址| -|amount|uint256|要铸造的代币数量| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果代币成功铸造并转移到账户,则为true| - -### `burn` - -从账户中销毁请求数量的代币。 -要销毁的代币数量必须大于零。 - -当代币成功销毁时,会发出 `PrecompiledBankBurn` 事件。 - -注意: - -- 禁止销毁治理代币。 -- 调用铸造方法的合约必须在 x/precompile 模块中注册。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|from|address|销毁代币的地址| -|amount|uint256|要销毁的代币数量| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果代币成功销毁,则为true| - -### `transfer` - -将请求数量的代币从发送者转移给接收者。 -代币必须设置为可发送。要转移的代币数量必须大于零。 - -当代币成功转移时,会发出 `PrecompiledBankTransfer` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|to|address|接收代币的地址| -|amount|uint256|要转移的代币数量| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果代币成功转移,则为true| - -### `transferFrom` - -由授权的支出者在允许额度范围内将请求数量的代币从所有者转移给接收者。 -代币必须设置为可发送。 -要转移的代币数量必须大于零并且小于或等于当前允许额度。 - -当代币成功转移时,会发出 `PrecompiledBankTransfer` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|from|address|转出代币的地址| -|to|address|接收代币的地址| -|amount|uint256|要转移的代币数量| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果代币成功转移,则为true| - -### `multiTransfer` - -将代币从单个账户转移到多个账户。 -代币必须设置为可发送。 -转移给每个接收者的代币数量必须大于零。 - -当代币成功转移时,每个接收者都会发出 `PrecompiledBankTransfer` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|to|address[]|接收转移代币的地址数组| -|amount|uint256[]|转移给每个接收者的代币数量| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果代币成功转移给每个接收者,则为true| - -### `approve` - -授权支出者从所有者账户转移代币。 -要授权的代币数量必须大于零。 - -当授权成功设置时,会发出 `PrecompiledBankApproval` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|spender|address|要授权的地址| -|value|uint256|要授权的代币数量| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果授权成功设置,则为true| - -### `revoke` - -撤销支出者从所有者转移代币的授权。 - -当授权成功撤销时,会发出 `PrecompiledBankRevoke` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|spender|address|要撤销的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果授权成功撤销,则为true| - -### `balanceOf` - -返回账户的代币余额。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|account|address|要获取代币余额的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|balance|uint256|账户中的代币数量| - -### `totalSupply` - -返回代币的总供应量。 - -#### 输入参数 - -无 - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|totalSupply|uint256|代币的总数量| - -### `allowance` - -返回支出者仍可从所有者提取的金额。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|owner|address|所有者的地址| -|spender|address|支出者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|amount|uint256|授权的代币数量| - -## 事件 - -所有从此预编译合约发出的事件都以 `PrecompiledBank` 为前缀。 -为了避免歧义,调用此预编译合约的代币合约应避免使用相同前缀的事件名称。 - -### PrecompiledBankMint - -|名称|类型|索引|描述| -|---|---|---|---| -|from|address|Y|铸造代币的地址| -|to|address|Y|接收铸造代币的地址| -|amount|uint256|N|铸造的代币数量| - -### PrecompiledBankBurn - -|名称|类型|索引|描述| -|---|---|---|---| -|from|address|Y|销毁代币的地址| -|to|address|Y|此方法中未使用| -|amount|uint256|N|销毁的代币数量| - -### PrecompiledBankTransfer - -|名称|类型|索引|描述| -|---|---|---|---| -|from|address|Y|转移代币的地址| -|to|address|Y|接收转移代币的地址| -|amount|uint256|N|转移的代币数量| - -### PrecompiledBankApproval - -|名称|类型|索引|描述| -|---|---|---|---| -|owner|address|Y|授权代币的地址| -|spender|address|Y|被授权的地址| -|value|uint256|N|授权的代币数量| - -### PrecompiledBankRevoke - -|名称|类型|索引|描述| -|---|---|---|---| -|owner|address|Y|撤销代币授权的地址| -|spender|address|Y|被撤销的地址| -|value|uint256|N|授权的代币数量| \ No newline at end of file +- [**银行预编译合约参考**](/cn/reference/bank-module-api):调用 `transfer`、`approve`、`mint`、`burn` 并读取事件。 +- [**系统模块概览**](/cn/explanation/system-modules-overview):返回预编译合约暴露的模块完整列表。 +- [**USDT 作为 Gas**](/cn/explanation/usdt-as-gas-token):了解银行模块管理的双重资产模型。 diff --git a/docs/pages/cn/explanation/bridge-security.mdx b/docs/pages/cn/explanation/bridge-security.mdx index 64117d3..1cdec75 100644 --- a/docs/pages/cn/explanation/bridge-security.mdx +++ b/docs/pages/cn/explanation/bridge-security.mdx @@ -1,50 +1,50 @@ --- source_path: explanation/bridge-security.mdx -source_sha: f1e67d648ec59eb4f8972eedeef0e8cda8c943af -title: "桥接安全性与 DVN" -description: "了解 Stable 如何配置 LayerZero DVN 来验证跨链消息,以及为什么单个密钥泄露不会造成致命影响。" +source_sha: 1566bfa5dadef64d40a9d10ef7ece18b4384ca62 +title: "跨链桥安全性与DVN" +description: "了解Stable如何配置LayerZero DVN来验证跨链消息,以及单个密钥泄露为何不是致命的。" diataxis: "explanation" --- -# 桥接安全性与 DVN +# 跨链桥安全性与DVN -LayerZero 桥的安全性,完全取决于确认某条链上发送的消息确实在另一条链上发生的验证层。这个层就是去中心化验证者网络(Decentralized Verifier Network,DVN)。本页将解释 DVN 的作用、Stable 如何在其桥上配置 DVN,以及为什么任何单个 DVN 的泄露都不会使 Stable 面临风险。 +LayerZero 跨链桥的安全性取决于验证层,该验证层确认一条链上发送的消息是否在另一条链上发生。该层是一个去中心化验证网络(Decentralized Verifier Network,简称 DVN)。本页面解释了 DVN 的作用,Stable 如何在其跨链桥上配置它们,以及单个 DVN 的泄露为何不会使 Stable 处于风险之中。 -## DVN 如何工作 +## DVN 的工作原理 -当 LayerZero 消息从链 A 移动到链 B 时,目标合约不会立即执行它,直到一组配置好的 DVN 独立证明该消息是真实的。每个应用都选择自己的配置: +当 LayerZero 消息从链 A 传输到链 B 时,目标合约不会执行它,直到一组配置好的 DVN 独立证明该消息是真实的。每个应用程序选择自己的配置: -- **必需 DVN(Required DVNs)。** 每个必需 DVN 都必须签名后,消息才会被接受。 -- **带 N-of-M 阈值的可选 DVN(Optional DVNs)。** 可在必需集合之上额外添加一个可选池,设置类似 2-of-5 的阈值,在必需签名之外还必须满足该阈值。 -- **区块确认深度。** DVN 在签名前等待的源链确认数量。 +- **必需的 DVN。** 在消息被接受之前,每个必需的 DVN 都必须签名。 +- **可选的 DVN,带有 N-of-M 阈值。** 除了必需的 DVN 集之外,还可以添加一个可选池,其阈值例如 2-of-5,必须满足该阈值才能加上必需的签名。 +- **区块确认深度。** DVN 在签名之前等待的源链确认数量。 -桥的安全性完全由这个配置决定。如果采用 1/1 配置,仅由单个 DVN 作为唯一验证者,那么该 DVN 签名密钥的任何泄露都会让攻击者伪造跨链消息。而横跨三个独立运营商的 3/3 配置,则要求三者同时被攻破。这其中的差别,就是因单个被盗密钥而失去整座桥,与在针对某一运营商的定向攻击中幸存下来之间的差别。 +跨链桥的安全性完全取决于此配置。如果采用 1/1 设置,只有一个 DVN 作为唯一的验证者,那么该 DVN 签名密钥的任何泄露都将允许攻击者伪造跨链消息。在三个独立运营商之间采用 3/3 设置,则需要同时泄露所有三个密钥。这两者之间的区别在于,一个是因单个密钥被盗而丢失跨链桥,另一个是在一个运营商遭受针对性攻击后仍能幸存。 ## Stable 的配置 -Stable 的桥运行 **3/3 必需 DVN** 配置,由三个独立运营商组成:**LayerZero Labs**、**Canary** 和 **Horizen**。三者都必须对每条跨链消息签名后,目标合约才会执行它。这里没有带阈值的可选池;必需集合就是全部的验证面。 +Stable 的跨链桥采用 **3/3 必需 DVN** 配置,由三个独立的运营商组成: **LayerZero Labs**、**Canary** 和 **Horizen**。所有这三个运营商都必须签署每条跨链消息,然后目标合约才会执行它。没有带阈值的可选池;必需的 DVN 集是整个验证面。 -单个签名密钥被泄露(包括 LayerZero 自己的密钥)对这种安全态势毫无作用。伪造一条消息将需要同时攻破全部三个独立运营商。 +单个泄露的签名密钥,包括 LayerZero 自己的密钥,对这种态势没有任何影响。伪造消息需要同时泄露所有三个独立的运营商。 -关于 DVN 合约地址,请参阅 [桥:Stable 的 DVN 运营商](/cn/reference/bridges#stable-s-dvn-operators)。 +有关 DVN 合约地址,请参阅[跨链桥:Stable 的 DVN 运营商](/cn/reference/bridges#stable-s-dvn-operators)。 ## STABLE OFT 架构 -STABLE 代币使用 LayerZero 的全链同质化代币(Omnichain Fungible Token,OFT)标准桥接到其他链。部署了两种合约类型: +STABLE 代币使用 LayerZero 的 Omnichain Fungible Token (OFT) 标准桥接到其他链。部署了两种合约类型: -- **`StableOFTAdapter`** 部署在 Stable 上。当 STABLE 被跨链发送时,该适配器在主链上锁定 STABLE 并发出一条 LayerZero 消息。 -- **`StableOFTUpgradeable`** 部署在每条远程链上。当消息被配置的 DVN 验证后,该合约在目标链上铸造 STABLE,并在返回路径上销毁它,从而使主链供应量保持权威性。 +- **`StableOFTAdapter`** 在 Stable 上。此适配器锁定主链上的 STABLE,并在 STABLE 跨链发送时发出 LayerZero 消息。 +- **`StableOFTUpgradeable`** 在每个远程链上。当消息通过配置的 DVN 验证后,此合约在目标链上铸造 STABLE,并在返回路径上销毁 STABLE,以便主链上的供应保持规范。 -关于各链上的已部署地址,请参阅 [桥:STABLE OFT 合约](/cn/reference/bridges#stable-oft-contracts)。 +有关每个链上部署的地址,请参阅[跨链桥:STABLE OFT 合约](/cn/reference/bridges#stable-oft-contracts)。 -## 运营依赖 +## 运营依赖项 -Stable 自身的桥接安全性独立于上游协议,但当合作协议暂停其自身的桥时,通过 Stable 的跨链流动仍可能暂停。例如,当 USDT0 暂停跨链铸造和销毁时,USDT0 无法进出 Stable,直到 USDT0 恢复为止。Stable 内的资金仍可自由流动;仅特定的跨链操作不可用。 +Stable 自己的跨链桥安全性独立于上游协议,但流经 Stable 的跨链流仍可能在合作协议暂停其自己的跨链桥时暂停。例如,当 USDT0 暂停跨链铸造和销毁时,USDT0 无法与 Stable 之间转移,直到 USDT0 恢复。Stable 内的资金继续自由流动;只有特定的跨链操作不可用。 -通过合作桥进行路由的应用界面应清楚地传达这一点,以便用户理解其中的区别:他们的资金没有风险,只是某条特定的跨链路径暂时不可用。 +通过合作伙伴跨链桥路由的应用程序界面应清楚地传达这一点,以便用户理解其区别:他们的资金没有风险,只是特定的跨链路径暂时不可用。 -## 下一步推荐 +## 下一步建议 -- [**将 USDT0 桥接到 Stable**](/cn/explanation/usdt0-bridging) — 了解 USDT0 如何通过 OFT Mesh 和 Legacy Mesh 到达 Stable。 -- [**桥提供商与地址**](/cn/reference/bridges) — 参考合约地址、DVN 运营商和支持的桥提供商。 -- [**LayerZero DVN 文档**](https://docs.layerzero.network/v2/concepts/protocol/security-stack-dvns) — 阅读 LayerZero 关于必需和可选 DVN 验证的规范。 +- [**将 USDT0 桥接到 Stable**](/cn/explanation/usdt0-bridging):了解 USDT0 如何通过 OFT Mesh 和 Legacy Mesh 到达 Stable。 +- [**跨链桥提供商和地址**](/cn/reference/bridges):参考合约地址、DVN 运营商和支持的跨链桥提供商。 +- [**LayerZero DVN 文档**](https://docs.layerzero.network/v2/concepts/protocol/security-stack-dvns):阅读 LayerZero 关于必需和可选 DVN 验证的规范。 diff --git a/docs/pages/cn/explanation/build-overview.mdx b/docs/pages/cn/explanation/build-overview.mdx index 79b1138..f8e2648 100644 --- a/docs/pages/cn/explanation/build-overview.mdx +++ b/docs/pages/cn/explanation/build-overview.mdx @@ -1,25 +1,25 @@ --- source_path: explanation/build-overview.mdx -source_sha: 3a41b9e06dc843c2aa33c4b44ca5f37301b9e57f +source_sha: 4b19d1f913597181cd62426d9b82ef8e91c4fae3 title: "概览" -description: "在 Stable 上构建:钱包与账户、支付、智能合约和 AI 智能体。从快速开始入手,或直接跳转到你需要的功能。" +description: "在 Stable 上推出产品:钱包和账户、支付、智能合约和 AI 代理。从快速入门开始,或者直接跳转到您需要的功能。" diataxis: "explanation" --- # 概览 -初次接触 Stable?请先运行[快速开始](/cn/tutorial/quick-start)。只需五分钟即可发送一笔测试网交易,让本栏其余内容有可对接的基础。 +Stable 新手?请先运行[快速入门](/cn/tutorial/quick-start)。它只需五分钟,并会发送一笔测试网交易,以便标签页的其余部分可以连接到它。 ## 探索 -- [**账户**](/cn/explanation/accounts-overview) — 创建钱包、使用 EIP-7702 委托 EOA,并为用户和智能体限定会话密钥范围。 -- [**支付**](/cn/explanation/payments-overview) — 发送 USDT0、构建 P2P 和订阅流程、使用 ERC-3009 结算发票,并通过 x402 为 API 定价。 -- [**合约**](/cn/explanation/contracts-overview) — 部署、验证和索引 Solidity 合约,并调用 Bank / Distribution / Staking 预编译合约。 -- [**AI 与智能体**](/cn/explanation/agent-settlement) — 将 MCP 服务器接入 AI 客户端,并暴露智能体可通过提示词调用的 x402 付费工具。 +- [**账户**](/cn/explanation/accounts-overview):创建钱包,使用 EIP-7702 授权 EOA,并为用户和代理限定会话密钥。 +- [**支付**](/cn/explanation/payments-overview):发送 USDT0,构建 P2P 和订阅流程,使用 ERC-3009 结算发票,并使用 x402 为 API 定价。 +- [**合约**](/cn/explanation/contracts-overview):部署、验证和索引 Solidity 合约,并调用 Bank / Distribution / Staking 预编译。 +- [**AI 和代理**](/cn/explanation/agent-settlement):将 MCP 服务器连接到 AI 客户端,并公开代理可以通过提示调用的 x402 付费工具。 ## 从这里开始 -- [**快速开始**](/cn/tutorial/quick-start) — 连接测试网、为钱包充值,并发送你的第一笔 USDT0 交易。 -- [**发送你的第一笔 USDT0**](/cn/tutorial/send-usdt0) — 在同一余额上进行原生和 ERC-20 转账,附带 TypeScript 示例。 -- [**部署智能合约**](/cn/tutorial/smart-contract) — 搭建 Foundry、配置 Stable,并部署 Counter 合约。 -- [**Stable SDK**](/cn/explanation/sdk-overview) — 使用类型化的 TypeScript 客户端在 Stable 上进行转账、跨链桥接和兑换。 +- [**快速入门**](/cn/tutorial/quick-start):连接到测试网,为钱包注资,并发送您的第一笔 USDT0 交易。 +- [**发送您的第一笔 USDT0**](/cn/tutorial/send-usdt0):相同余额上的原生和 ERC-20 传输,附带 TypeScript 示例。 +- [**部署智能合约**](/cn/tutorial/smart-contract):搭建 Foundry,配置 Stable,并部署 Counter 合约。 +- [**Stable SDK**](/cn/explanation/sdk-overview):使用类型化的 TypeScript 客户端在 Stable 上进行转账、桥接和兑换。 diff --git a/docs/pages/cn/explanation/confidential-transfer.mdx b/docs/pages/cn/explanation/confidential-transfer.mdx index 5696fe3..a9ae3e4 100755 --- a/docs/pages/cn/explanation/confidential-transfer.mdx +++ b/docs/pages/cn/explanation/confidential-transfer.mdx @@ -1,21 +1,60 @@ --- source_path: explanation/confidential-transfer.mdx -source_sha: 162fe40acbfbf24c5d2c60a861caa4b54175cd47 -title: "隐私转账(Confidential Transfer" -description: "在满足合规要求的前提下保护 USDT 交易隐私的机密转账机制。" +source_sha: 44b9b0047f5252a2aa10b8e93a64f42854c9182d +title: "保密转账" +description: "Stable 网络上,符合监管要求的、隐私保护型 USDT 交易的保密转账机制。" +diataxis: "explanation" --- -# 隐私转账(Confidential Transfer +# 保密转账 -随着区块链在企业中的应用不断加速,尤其是在稳定币领域,**对交易隐私的需求日益增长**。许多企业在处理财务操作时需要保持隐私性,以保护如付款金额等敏感信息。为满足这一需求,Stable 正在开发**隐私转账(Confidential Transfer)功能**,以在隐私保护与监管合规之间实现平衡。 +**保密转账**是 Stable 上的一个隐私层,可以在屏蔽 USDT0 转账**金额**的同时,保持发件人和收件人地址公开可见。屏蔽的金额只有交易双方和授权的监管审计人员才能读取。该机制使用零知识 (ZK) 加密来证明有效性,而无需透露具体金额。此功能正在开发中;本页面描述了目标模型。 -Stable 利用零知识加密(Zero-Knowledge Cryptography, 简称 ZK)技术,构建了一个**隐私转账层(Confidential Transfer Layer)**,使交易双方可以在不公开链上交易金额的前提下完成代币转账。在此机制下: +## 它解决的问题 -- **交易金额将被加密隐藏**,而非直接记录在链上。 -- **发送方和接收方地址依然公开可见**,以便于遵守金融监管和审计要求。 +标准链上转账是完全透明的;任何人都可以读取发件人、收件人和金额。对于商业支付,这种透明度是数据泄露问题: -这种设计保证了:**交易金额仅对交易参与方和授权的监管审计方可见**,在保护用户隐私的同时,也不牺牲法律合规性。 +- 零售商在链上支付供应商的款项,会将订单量和批发价格暴露给任何观察者。 +- 财务部门在账户之间转移资金,会公开其仓位规模。 +- 工资发放会将薪资数据发布到整个网络。 -在当前业界的实现中,Solana 的 Confidential Transfer 模型被认为是该功能的有力候选方案之一。然而,Stable 仍在积极探索其他架构,力求找到最具可行性和可扩展性的解决方案。 +完全不透明(Monero 风格)可以解决这个问题,但会破坏合规性:监管机构和审计人员无法验证交易。选择性保密(金额隐藏,各方可审计)是 Stable 的目标模式。 -最终选定的方案将必须契合 Stable 的核心使命:**为企业提供安全、合规且具备企业级可靠性的区块链基础设施**。 +## 什么可见,什么不可见 + +| 字段 | 在链上可见 | 已屏蔽 | +| :--- | :--- | :--- | +| 发件人地址 | ✓ | | +| 收件人地址 | ✓ | | +| 转账金额 | | ✓ | +| 辅助元数据 | | ✓ | + +屏蔽的金额经过加密。有效的证明可以证明转账是余额一致的(没有通货膨胀,没有负数),而不会透露金额本身。只有发件人、收件人和授权的监管审计人员才能解密屏蔽值。 + +## 它如何适应合规模型 + +两个特性使设计可审计: + +- **确定性审计员访问。** 监管审计员持有密钥,可以解密其管辖范围内交易的屏蔽金额。商业隐私针对随机观察者得到保护;合规审查则不会。 +- **标准地址透明度。** 针对地址级别流(制裁检查、资金来源分析)运行的 AML/KYC 工具,与任何透明链使用相同的公共地址图。 + +## 何时使用它 + +保密转账适用于金额具有商业敏感性,但交易对手适当地公开的任何流程: + +- 供应商和发票支付,其中订单规模会泄露定价。 +- 财务操作,其中仓位规模会泄露策略。 +- 工资发放,其中个人薪资不应被竞争对手索引。 +- 大额场外结算,其中与订单簿信息相关的价格发现存在风险。 + +对于也需要地址级别隐私的流程(例如举报人捐款),仅靠保密转账是不够的。这些用例需要 Stable 不提供的额外地址模糊原语。 + +## 状态 + +保密转账正在开发中。有关时间安排,请参阅[路线图](/cn/explanation/technical-roadmap)。该机制将作为标准 USDT0 转账的专用转账路径推出;未选择加入的现有应用程序不受影响。 + +## 推荐阅读 + +- [**USDT 作为 Gas**](/cn/explanation/usdt-as-gas-token):了解保密转账所保护的资产模型。 +- [**资金流向**](/cn/explanation/flow-of-funds):了解保密性在端到端支付生命周期中的作用。 +- [**路线图**](/cn/explanation/technical-roadmap):追踪保密转账的发布时间。 diff --git a/docs/pages/cn/explanation/consensus.mdx b/docs/pages/cn/explanation/consensus.mdx index 3959443..e4fe0a0 100755 --- a/docs/pages/cn/explanation/consensus.mdx +++ b/docs/pages/cn/explanation/consensus.mdx @@ -1,42 +1,42 @@ --- source_path: explanation/consensus.mdx -source_sha: e1ddd035470323b6b114d15deb175eb5f478febb +source_sha: c3243c12a02eb788cf914984ffa1f57726929778 title: "共识" -description: "StableBFT 共识协议设计、基于 DAG 的升级路线图,以及 200,000 TPS 吞吐量基准测试。" +description: "StableBFT 共识协议设计、基于 DAG 的升级路线图以及 20 万 TPS 吞吐量基准。" diataxis: "explanation" --- # 共识 -## 基于 StableBFT 的 PoS 共识 +## 基于 StableBFT 的权益证明共识 -Stable Blockchain 采用 **StableBFT**,这是一种基于 CometBFT 构建的定制化 PoS 共识协议,能够实现高吞吐量、低延迟和强可靠性。StableBFT 提供确定性最终性(区块一经纳入即为最终状态,不存在分叉),并具备拜占庭容错能力,可容忍多达 1/3 的验证者发生故障或恶意行为。 +Stable 区块链利用 **StableBFT**(一种基于 CometBFT 构建的定制化权益证明共识协议)来提供高吞吐量、低延迟和高可靠性。StableBFT 提供确定性终结性(区块在纳入时即最终确定,没有分叉)和拜占庭容错能力,即使多达 1/3 的验证者发生故障或恶意行为也能保持。 -为进一步优化共识性能,Stable 计划在不久的将来实施以下改进: +为了进一步优化共识性能,Stable 计划在不久的将来实施以下改进: -- **解耦交易与共识传播**:将交易传播层与共识传播层分离,可以防止交易侧的网络拥塞干扰共识通信。 -- **将交易直接广播给区块提议者**:在当前模型中,交易通过节点之间的点对点传播进行扩散,从而在整个网络中产生大量传播流量。Stable 旨在通过使交易直接广播给区块提议者来提升效率。 +- **解耦交易和共识流言传播**:将交易流言传播层与共识流言传播层分离,防止交易侧的网络拥堵干扰共识通信。 +- **直接向区块提议者广播交易**:在当前模型中,交易通过节点之间的点对点流言传播来传播,导致整个网络中存在大量的流言流量。Stable 旨在通过允许交易直接广播到区块提议者来提高效率。 ## 未来路线图:基于 DAG 的共识 -为显著加速共识,Stable 计划将其协议升级为基于 DAG 的设计,可实现高达 5 倍的速度提升。 +为了显著加速共识,Stable 计划将其协议升级为基于 DAG 的设计,该设计能够将速度提高 5 倍。 -像 PBFT 和 HotStuff 这样的传统基于视图(view-based)的 BFT 协议,在稳定的网络条件下针对低延迟进行了优化。然而,它们在出现中断时性能会显著下降,并且在临时故障后往往会经历较长的恢复延迟。 +传统的基于视图的 BFT 协议(如 PBFT 和 HotStuff)针对稳定网络条件下的低延迟进行了优化。然而,它们在中断期间会显著退化,在临时故障后经常会出现长时间的恢复延迟。 -像 Narwhal 和 Tusk 这样的第一代基于 DAG 的引擎表明,将数据传播与共识排序解耦可以消除单一提议者瓶颈,并提升网络不稳定状态下的健壮性。然而,它们的架构与 CometBFT 等系统并不直接兼容,因为它们偏离了传统的基于高度(height-based)的区块语义和内存池设计。 +第一代基于 DAG 的引擎(如 Narwhal 和 Tusk)表明,将数据传播与共识排序解耦可以消除单一提议者瓶颈,并提高网络不稳定下的鲁棒性。然而,它们的架构与 CometBFT 等系统不直接兼容,因为它们偏离了传统的高度基于区块的语义和内存池设计。 -[Autobahn](/cn/explanation/autobahn) 提供了一种 PBFT-on-DAG 架构,能够更自然地与 Stable 的共识层集成,同时在正常条件下提供低延迟,并在面对网络故障时实现快速恢复。Stable 团队与 Autobahn 论文的作者保持着密切的合作关系,并将利用 Autobahn 的架构来最大化 StableBFT 的性能。 +[Autobahn](/cn/explanation/autobahn) 提供了一种 PBFT-on-DAG 架构,该架构与 Stable 的共识层更自然地集成,同时在正常条件下提供低延迟,并在网络故障时快速恢复。Stable 团队与 Autobahn 论文的作者保持着密切关系,并将利用 Autobahn 的架构来最大限度地提高 StableBFT 的性能。 -构建于 Autobahn 之上的 StableBFT 将实现: +基于 Autobahn 构建的 StableBFT 将实现: -- 通过消除单一领导者限制,实现并行提议处理。 -- 通过将数据传播与最终排序分离,实现更快的最终性。 -- 通过强健的 BFT 机制,增强应对网络异常的韧性。 +- 通过消除单领导者限制来实现并行提案处理。 +- 通过将数据传播与最终排序分离来加快终结性。 +- 通过强大的 BFT 机制增强对网络不利条件的弹性。 -这种先进的共识设计基于内部概念验证支持更高的吞吐量,该验证已在受控环境中展示出超过 200,000 TPS(仅共识)的性能。 +这种先进的共识设计基于内部概念验证,支持更高的吞吐量,在受控环境中已证明超过 200,000 TPS(仅共识)。 -## 下一步推荐 +## 推荐阅读 -- [**Autobahn**](/cn/explanation/autobahn) — 阅读支撑 StableBFT 基于 DAG 升级路径的协议论文。 -- [**执行**](/cn/explanation/execution) — 了解区块如何从共识进入并行执行。 -- [**最终性**](/cn/explanation/finality) — 在基于 RPC 进行构建时应用 Stable 的单槽最终性。 +- [**Autobahn**](/cn/explanation/autobahn):阅读支撑 StableBFT 基于 DAG 升级路径的协议论文。 +- [**执行**](/cn/explanation/execution):了解区块如何从共识进入并行执行。 +- [**终结性**](/cn/explanation/finality):在针对 RPC 进行构建时应用 Stable 的单槽终结性。 diff --git a/docs/pages/cn/explanation/contracts-guides.mdx b/docs/pages/cn/explanation/contracts-guides.mdx index 90decfb..7744eab 100644 --- a/docs/pages/cn/explanation/contracts-guides.mdx +++ b/docs/pages/cn/explanation/contracts-guides.mdx @@ -1,32 +1,32 @@ --- source_path: explanation/contracts-guides.mdx -source_sha: d11a9b3683251378d49f56b7994d0f90de10bd7b +source_sha: 9399f7ec9f6cb709da5f547e311c8bbaa678d941 title: "合约指南" -description: "所有合约指南、概念和参考:部署流程、系统模块、JSON-RPC 兼容性以及与 Ethereum 的差异。" +description: "所有合约指南、概念和参考:部署流程、系统模块、JSON-RPC 兼容性以及与以太坊的区别。" diataxis: "explanation" --- # 合约指南 -合约选项卡下的每个指南、概念和参考,按你想要完成的目标分组。 +“合约”选项卡下的所有指南、概念和参考,按您要完成的任务分组。 -## 构建并发布合约 +## 构建和发布合约 -- [**部署**](/cn/tutorial/smart-contract) — 搭建 Foundry 项目并将 Counter 部署到 Stable 测试网。 -- [**验证**](/cn/how-to/verify-contract) — 将源代码上传到 Stablescan,让用户能够阅读和调用你的合约。 -- [**索引事件**](/cn/how-to/index-contract) — 使用 ethers.js 构建实时事件流,并进行历史数据回填。 +- [**部署**](/cn/tutorial/smart-contract):搭建 Foundry 项目并部署 Counter 到 Stable 测试网。 +- [**验证**](/cn/how-to/verify-contract):将源代码上传到 Stablescan,以便用户可以阅读和调用您的合约。 +- [**索引事件**](/cn/how-to/index-contract):使用 ethers.js 构建实时事件流,并支持历史数据回填。 ## 调用系统模块 -- [**使用系统模块**](/cn/how-to/use-system-modules) — 从 Solidity 或 ethers.js 调用 Bank、Distribution 和 Staking 预编译合约。 -- [**追踪解绑完成**](/cn/how-to/track-unbonding) — 订阅通过 StableSystem 预编译合约发出的 UnbondingCompleted 事件。 +- [**使用系统模块**](/cn/how-to/use-system-modules):从 Solidity 或 ethers.js 调用 Bank、Distribution 和 Staking 预编译。 +- [**追踪解除绑定完成情况**](/cn/how-to/track-unbonding):订阅通过 StableSystem 预编译发出的 UnbondingCompleted 事件。 ## 参考 -- [**系统模块参考**](/cn/reference/system-modules-api-overview) — 预编译合约地址以及各模块的 ABI 指针。 -- [**JSON-RPC API**](/cn/reference/json-rpc-api) — 支持的 `eth_*`、`net_*`、`web3_*` 和 `debug_*` 方法。 +- [**系统模块参考**](/cn/reference/system-modules-api-overview):预编译地址和每个模块的 ABI 指针。 +- [**JSON-RPC API**](/cn/reference/json-rpc-api):支持的 `eth_*`、`net_*`、`web3_*` 和 `debug_*` 方法。 ## 基础概念 -- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior) — 双重角色余额、对账事件以及合约设计规则。 -- [**与 Ethereum 的差异**](/cn/explanation/ethereum-comparison) — Gas 代币、最终性、优先级小费以及 EVM 兼容性。 +- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior):双重角色余额、对账事件和合约设计规则。 +- [**与以太坊的区别**](/cn/explanation/ethereum-comparison):Gas token、最终性、优先小费和 EVM 兼容性。 diff --git a/docs/pages/cn/explanation/contracts-overview.mdx b/docs/pages/cn/explanation/contracts-overview.mdx index bfbb138..067fa40 100644 --- a/docs/pages/cn/explanation/contracts-overview.mdx +++ b/docs/pages/cn/explanation/contracts-overview.mdx @@ -1,36 +1,36 @@ --- source_path: explanation/contracts-overview.mdx -source_sha: e9d40ccc5abb2839ea1f7689ed0a06df4be5064c +source_sha: d004e6f88f0f2db9748b4114627eabb27e41c94c title: "Stable 上的合约" -description: "在 Stable 上部署、验证和索引智能合约。完整的 EVM 兼容性,以及面向 Bank、Distribution 和 Staking 模块的预编译合约。" +description: "在 Stable 上部署、验证和索引智能合约。完整的 EVM 兼容性以及银行、分发和质押模块的预编译。" diataxis: "explanation" --- # Stable 上的合约 -Stable 完全兼容 EVM。Solidity、Vyper、Hardhat、Foundry、ethers.js 和 viem 都无需修改即可使用。只要将工具指向 Stable 的 RPC,现有合约即可原样部署。在标准 EVM 之上,Stable 将协议级模块(Bank、Distribution、Staking)以预编译合约的形式暴露在固定地址上,因此你的 Solidity 可以直接调用质押和奖励分发功能,而无需重新实现它们。 +Stable 完全兼容 EVM。Solidity、Vyper、Hardhat、Foundry、ethers.js 和 viem 都可以原样使用。一旦您将工具指向 Stable 的 RPC,现有合约就可以按原样部署。在标准 EVM 的基础上,Stable 将协议级模块(银行、分发、质押)作为预编译合约暴露在固定地址,因此您的 Solidity 可以调用质押和奖励分发,而无需重新实现它们。 -## 你可以构建什么 +## 您可以构建什么 -- **标准应用合约**(ERC-20、ERC-721、托管、AMM),使用任意 EVM 工具链。 -- **经过验证、已索引的合约**,在 Stablescan 上通过 ethers.js 提供实时事件流。 -- **协议集成合约**,可从 Solidity 调用 Bank / Distribution / Staking 预编译合约。 -- **系统交易监听器**,通过标准的 `eth_getLogs` 监视协议发出的事件(例如解绑完成)。 +- **标准应用合约** (ERC-20, ERC-721, 托管, AMM),使用任何 EVM 工具链。 +- 通过 ethers.js 在 Stablescan 上**已验证、已索引的合约**,带有实时事件流。 +- **协议集成合约**,从 Solidity 调用银行/分发/质押预编译。 +- **系统交易监听器**,通过标准的 `eth_getLogs` 监听协议发出的事件(例如,解除绑定完成)。 ## Stable 的不同之处 -- **USDT0 是 gas 代币。** `maxPriorityFeePerGas` 必须为 `0`。原生转账中的 `value` 字段携带的是 USDT0,而不是 ETH。参见[使用 USDT0 作为 gas](/cn/how-to/work-with-usdt-gas)。 -- **USDT0 具有双重角色。** 持有原生 USDT0 的合约,其余额可能因 ERC-20 的 `transferFrom` 或 `permit` 而发生变化——切勿在 `uint256` 中镜像原生余额。参见 [Stable 上的 USDT0 行为](/cn/explanation/usdt0-behavior)。 -- **预编译地址在测试网和主网中是固定的。** 将它们作为常量固化到你的合约中。 +- **USDT0 是 Gas 代币。** `maxPriorityFeePerGas` 必须为 `0`。原生转账中的 `value` 字段承载的是 USDT0,而不是 ETH。请参阅[使用 USDT0 作为 Gas](/cn/how-to/work-with-usdt-gas)。 +- **USDT0 具有双重身份。** 持有原生 USDT0 的合约可以通过 ERC-20 `transferFrom` 或 `permit` 更改其余额。切勿在 `uint256` 中镜像原生余额。请参阅[Stable 上的 USDT0 行为](/cn/explanation/usdt0-behavior)。 +- **预编译地址在测试网和主网中是固定的。** 将它们作为常量烧录到您的合约中。 ## 从这里开始 -- [**部署**](/cn/tutorial/smart-contract) — 搭建 Foundry,配置 Stable,并部署 Counter。 -- [**验证**](/cn/how-to/verify-contract) — 使用 forge verify-contract 将源码上传到 Stablescan。 -- [**索引**](/cn/how-to/index-contract) — 使用 ethers.js 订阅事件并回填历史日志。 +- [**部署**](/cn/tutorial/smart-contract):搭建 Foundry,配置 Stable,并部署 Counter。 +- [**验证**](/cn/how-to/verify-contract):使用 forge verify-contract 将源代码上传到 Stablescan。 +- [**索引**](/cn/how-to/index-contract):使用 ethers.js 订阅事件并回填历史日志。 -## 推荐下一步 +## 下一步建议 -- [**合约指南索引**](/cn/explanation/contracts-guides) — 合约指南、预编译参考和系统模块 ABI 的完整列表。 -- [**使用系统模块**](/cn/how-to/use-system-modules) — 从 Solidity 和 ethers.js 调用 Bank / Distribution / Staking。 -- [**JSON-RPC 参考**](/cn/reference/json-rpc-api) — Stable 支持哪些 `eth_*` 和 `debug_*` 方法。 +- [**合约指南索引**](/cn/explanation/contracts-guides):合约指南、预编译参考和系统模块 ABI 的完整列表。 +- [**使用系统模块**](/cn/how-to/use-system-modules):从 Solidity 和 ethers.js 调用银行/分发/质押。 +- [**JSON-RPC 参考**](/cn/reference/json-rpc-api):Stable 支持哪些 `eth_*` 和 `debug_*` 方法。 diff --git a/docs/pages/cn/explanation/core-concepts.mdx b/docs/pages/cn/explanation/core-concepts.mdx index a9761f1..55e653a 100755 --- a/docs/pages/cn/explanation/core-concepts.mdx +++ b/docs/pages/cn/explanation/core-concepts.mdx @@ -1,20 +1,20 @@ --- source_path: explanation/core-concepts.mdx -source_sha: 7400248a80aa3b8112e72c47e08229fbae84e654 +source_sha: 97f2155b7916504732f1b78674bbf3ec1909e8e2 title: "核心概念" -description: "在开始构建之前,先理解 Stable 的四个核心概念:USDT0 作为 gas、有保障的区块空间、转账聚合,以及 EVM 兼容性。" +description: "在开始构建之前,请先了解 Stable 的四个核心概念:USDT0 作为燃料代币、保证块空间、转账聚合和 EVM 兼容性。" diataxis: "explanation" --- # 核心概念 -掌握四个概念就足以开始构建。每个小节都会定义概念、展示示例,并链接到完整参考文档。 +掌握这四个概念足以开始构建。每个部分都定义了概念,展示了它的工作原理,并链接到完整的参考资料。 -## USDT0 作为 gas +## USDT0 作为燃料代币 -你用 USDT0 支付交易费用,这正是你已经持有并用于交易的同一种资产。无需为第二种代币充值或进行管理。 +您可以使用 USDT0 支付交易费,这是您已经持有和交易的相同资产。无需为第二个代币注资或管理。 -USDT0 既是原生 gas 资产(18 位小数,通过 `address(x).balance` 读取),也是一个 ERC-20 代币(6 位小数,通过 `USDT0.balanceOf(x)` 读取)。两种接口操作的是同一个底层余额,协议会自动协调这 12 位的精度差异。 +USDT0 既是原生燃料代币资产(18 位小数,通过 `address(x).balance` 读取),也是 ERC-20 代币(6 位小数,通过 `USDT0.balanceOf(x)` 读取)。这两个接口对相同的底层余额进行操作,协议会自动协调 12 位小数的精度差距。 ```solidity // Both read the same balance: @@ -23,34 +23,34 @@ uint256 erc20 = IERC20(USDT0).balanceOf(user); // 6 decimals ``` :::warning -余额协调会在储备地址 `0x5113954bbC0eD721F1C68671EBa3d91e9e9bF7b5` 处发出额外的 `Transfer` 事件。重放 `Transfer` 事件的索引器必须过滤掉发往和来自该地址的转账,否则它们会在无声中重复计算余额。 +余额调节会在保留地址 `0x5113954bbC0eD721F1C68671EBa3d91e9e9bF7b5` 发出额外的 `Transfer` 事件。重放 `Transfer` 事件的索引器必须过滤进出此地址的转账,否则它们将默默地重复计算余额。 ::: -阅读更多:[USDT0 作为 gas](/cn/explanation/usdt-as-gas-token) · [USDT0 在 Stable 上的行为](/cn/explanation/usdt0-behavior)。 +阅读更多:[USDT0 作为燃料代币](/cn/explanation/usdt-as-gas-token) · [USDT0 在 Stable 上的行为](/cn/explanation/usdt0-behavior)。 -## 有保障的区块空间 +## 保证块空间 -Stable 会为预先分配的企业工作负载保留每个区块的一部分容量。即使在通用流量拥堵时,预留流量也能以可预测的延迟和成本结算;它不参与费用市场的竞争。 +Stable 为预分配的企业工作负载保留了每个区块容量的一部分。即使在一般流量拥堵时,保留的流量也能以可预测的延迟和成本进行结算;它不参与费用市场竞争。 -这种行为在调用者层面是透明的。你以常规方式提交交易;分配在协议层面针对已注册的账户应用。 +这种行为在调用者层面是透明的。您以正常方式提交交易;分配在协议层面应用于注册账户。 -阅读更多:[有保障的区块空间](/cn/explanation/guaranteed-blockspace)。 +阅读更多:[保证块空间](/cn/explanation/guaranteed-blockspace)。 ## USDT 转账聚合器 -高频次的 USDT0 转账会被批量处理,并使用受 MapReduce 启发的流水线并行验证。单个账户的失败会被隔离,因此一笔有问题的转账不会中止整个批次。 +大批量 USDT0 转账通过 MapReduce 启发的管道进行批处理和并行验证。每个账户的故障都是隔离的,因此一个错误的转账不会中止批处理。 -调用者侧的转账 API 保持不变。你以常规方式提交转账,无需修改代码即可获得吞吐量提升。 +调用者侧的转账 API 保持不变。您以正常方式提交转账,无需更改代码即可提高吞吐量。 阅读更多:[USDT 转账聚合器](/cn/explanation/usdt-transfer-aggregator)。 ## EVM 兼容性 -标准的 EVM 工具无需改动即可使用。在 EVM 层面,有三种行为与以太坊不同(上文介绍过的 USDT0 作为 gas 是第四种)。 +标准 EVM 工具无需修改即可工作。在 EVM 层面,有三种行为与以太坊不同(上面介绍的 USDT0 作为燃料代币是第四种)。 -**单槽最终性。** 交易一旦被包含进区块即为最终确定。区块大约每 0.7 秒产生一次。 +**单槽最终性。** 交易一旦包含在区块中即为最终交易。区块大约每 0.7 秒产出一次。 -**无优先小费。** `maxPriorityFeePerGas` 始终会被忽略。实际的 gas 价格是协议设定的基础费用。 +**无优先级小费。** `maxPriorityFeePerGas` 始终被忽略。有效的 Gas 价格是协议设置的基础费用。 ```typescript import { ethers } from "ethers"; @@ -73,23 +73,23 @@ console.log("Included at gas price:", tx.gasPrice?.toString()); Included at gas price: 1000000000 ``` -**双重身份的 USDT0,移植风险。** 从以太坊移植的合约不应镜像原生余额,应拒绝向 `address(0)` 的转账,且不应依赖 `EXTCODEHASH` 来检测地址重用。 +**双重角色 USDT0,移植风险。** 从以太坊移植的合约不应镜像原生余额,应拒绝 `address(0)` 转账,并且不应依赖 `EXTCODEHASH` 进行地址重用检测。 :::warning -将一个在内部变量中镜像原生余额的合约移植到 Stable 上是不安全的。一次外部的 `USDT0.transferFrom` 调用可以在不调用任何合约代码的情况下耗尽该合约的原生余额。始终在转账时刻用 `address(this).balance` 进行偿付能力检查。 +在 Stable 上移植在内部变量中镜像原生余额的合约是不安全的。外部 `USDT0.transferFrom` 调用可以在不调用任何合约代码的情况下耗尽合约的原生余额。始终在转账时使用 `address(this).balance` 进行偿付能力检查。 ::: -阅读更多:[与以太坊的差异](/cn/explanation/ethereum-comparison) · [Stable 上的合约](/cn/explanation/contracts-overview) · [USDT0 迁移清单](/cn/explanation/usdt0-behavior)。 +阅读更多:[与以太坊的区别](/cn/explanation/ethereum-comparison) · [Stable 上的合约](/cn/explanation/contracts-overview) · [USDT0 迁移清单](/cn/explanation/usdt0-behavior)。 ## 机密转账(计划中) -Stable 有一项计划中的功能,用于实现零知识转账,在隐藏金额的同时对授权方保持可审计性。该功能尚未上线。 +Stable 有一个针对零知识转账的计划功能,可以隐藏金额,同时允许授权方审计。该功能尚未上线。 阅读更多:[机密转账](/cn/explanation/confidential-transfer)。 -## 下一步推荐 +## 建议阅读 -- [**快速开始**](/cn/tutorial/quick-start) — 连接到测试网并发送第一笔交易。 -- [**USDT0 行为**](/cn/explanation/usdt0-behavior) — 在不触碰双重身份陷阱的情况下将合约移植到 Stable。 -- [**Gas 定价**](/cn/reference/gas-pricing-api) — 在 Stable 的费用模型下正确构造交易。 -- [**生产就绪**](/cn/how-to/production-readiness) — 在发布到主网之前验证集成。 +- [**快速入门**](/cn/tutorial/quick-start):连接到测试网并发送第一笔交易。 +- [**USDT0 行为**](/cn/explanation/usdt0-behavior):将合约移植到 Stable,避免双重角色陷阱。 +- [**Gas 定价**](/cn/reference/gas-pricing-api):在 Stable 的费用模型上正确构建交易。 +- [**生产就绪**](/cn/how-to/production-readiness):在发布到主网之前验证集成。 diff --git a/docs/pages/cn/explanation/core-optimization-overview.mdx b/docs/pages/cn/explanation/core-optimization-overview.mdx index 7afb71c..2eb6074 100755 --- a/docs/pages/cn/explanation/core-optimization-overview.mdx +++ b/docs/pages/cn/explanation/core-optimization-overview.mdx @@ -1,13 +1,14 @@ --- source_path: explanation/core-optimization-overview.mdx -source_sha: 64589b294e0b6057b4feb1811f4e81864d52dab7 +source_sha: 29de6d48ee5097a621ab02f579847af6d068dc9d title: "概览" -description: "涵盖共识、执行、数据库与 RPC 各层的 Stable 全栈优化方案概述。" +description: "Stable 全栈优化的介绍,涵盖共识、执行、数据库和 RPC 层。" +diataxis: "explanation" --- # 概览 -## 全流程核心优化 +## 全栈核心优化 区块链交易生命周期 -一笔区块链交易从提交到最终确认,需要经历多个紧密相连的阶段。交易首先通过 **RPC** 提交,进入 **内存池(mempool)**,被打包进区块后通过 **共识机制** 验证,再由 **状态机(state machine)** 执行,最终写入 **数据库** 进行持久化。只有在完成整个流程后,用户才能收到确认结果。 +区块链交易的生命周期,从提交到最终结果,会经历多个紧密连接的阶段。一笔交易首先通过 **RPC** 接口提交,被添加到 **mempool**,打包成区块,通过**共识**验证,由**状态机**执行,最后写入**数据库**中的持久化存储。只有完成这个完整的流程,用户才能收到确认结果。 -仅优化某一个阶段是远远不够的。任何环节的低效都会影响系统整体性能。因此,Stable 致力于从上到下全面优化。 +仅仅孤立地改进一个阶段是不够的。流程中的任何低效都可能影响系统的整体性能。这就是为什么 Stable 专注于从上到下优化区块链堆栈。 -请查看以下页面,了解 Stable 如何从共识层、执行层、数据库层到 RPC 层,对各个架构模块进行系统性升级优化,以确保交易能稳定地以高性能处理。 +以下页面描述了 Stable 如何升级其架构的每个层(共识、执行、数据库和 RPC),以确保可靠和高性能的交易处理。 + +## 接下来推荐 + +- [**共识**](/cn/explanation/consensus):了解 StableBFT 如何扩展 CometBFT 以实现高吞吐量和低延迟。 +- [**执行**](/cn/explanation/execution):了解 Stable EVM 如何通过 Block-STM 和乐观区块处理并行运行交易。 +- [**存储 (StableDB)**](/cn/explanation/stable-db):了解解耦状态提交和内存映射存储如何消除磁盘 I/O 瓶颈。 +- [**高性能 RPC**](/cn/explanation/high-performance-rpc):了解分离读写操作的分流式 RPC 架构。 diff --git a/docs/pages/cn/explanation/distribution-module.mdx b/docs/pages/cn/explanation/distribution-module.mdx index 348b276..098976f 100755 --- a/docs/pages/cn/explanation/distribution-module.mdx +++ b/docs/pages/cn/explanation/distribution-module.mdx @@ -1,311 +1,38 @@ --- source_path: explanation/distribution-module.mdx -source_sha: 704e0b6d878ca629ffa66f024070c339d066eca1 -title: 分配模块 -description: "在 EVM 环境中桥接 x/distribution 模块以管理手续费收集和奖励提取的预编译合约。" +source_sha: b4b638cbe7c29d11dc0a29398fd8c1280d898d93 +title: "Distribution 模块" +description: "Distribution 预编译模块将质押奖励(提取地址、奖励查询和佣金管理)呈现给 EVM 合约。" +diataxis: "explanation" --- -# 分配模块 +# Distribution 模块 -## 概述 +`x/distribution` 模块处理委托人 (delegator) 和验证人 (validator) 的质押奖励累积和提取。其预编译模块将此行为桥接到 EVM,因此 Solidity 合约无需直接与 Cosmos SDK 交互即可领取奖励、设置提取地址和查询未结奖励。 -`distribution` 预编译合约作为桥梁,使 Stable SDK 的 `x/distribution` 模块功能能在 EVM 环境中使用。 +## 它公开了什么 -## 目录 +- **设置提取地址**:委托人指定哪个地址接收他们的奖励。默认情况下,奖励会进入委托人自己的地址;设置提取地址会将奖励路由到其他地方(对于合约管理的质押很有用)。 +- **提取委托人奖励**:一次调用即可从单个验证人那里领取所有未结奖励。 +- **提取验证人佣金**:验证人从委托人奖励中领取他们累积的佣金。 +- **查询方法**:无需交易即可读取奖励余额、佣金率和社区池状态。 -1. **[概念](#concepts)** -2. **[配置](#configuration)** -3. **[方法](#methods)** -4. **[事件](#events)** +## 授权语义 -## 概念 +预编译模块检查调用者是否是要修改其状态的委托人(或验证人)。您不能领取他人的奖励或更改他们的提取地址。 -在 `distribution` 预编译合约中,会进行额外检查以确保委托者或存款者是调用者。 +## 何时使用它 -## 配置 +- 资金库或质押聚合器按计划领取奖励:直接调用 `withdrawDelegatorRewards`。 +- DAO 将质押奖励路由到财务地址:设置一次提取地址,然后奖励自动流动。 +- 前端显示当前奖励余额:使用查询方法(无需交易)。 -合约地址和gas费用已预定义。 +## 在哪里可以找到 ABI -### 合约地址 +完整的方法签名、输入/输出类型和发出的事件在[Distribution 预编译参考](/cn/reference/distribution-module-api)中。 -- `0x0000000000000000000000000000000000000801` +## 下一步建议 -## 方法 - -### `setWithdrawAddress` - -设置用于接收委托者向验证者委托代币奖励的地址。 -有时,当委托者是自我委托时,验证者地址被用作委托者。 - -当提取者地址成功设置时,会发出 `SetWithdrawAddress` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的地址| -|withdrawerAddress|address|接收委托奖励的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果提取者地址成功设置,则为true| - -### `withdrawDelegatorRewards` - -提取委托者从验证者那里应得的奖励。 -验证者奖励给委托者的所有类型的代币都在单次交易中提取。 - -当奖励成功提取时,会发出 `WithdrawDelegatorRewards` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的地址| -|validatorAddress|address|验证者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|amount|Coin[]|委托者将获得的各种代币奖励| - -`Coin` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|denom|string|奖励的denomination| -|amount|uint256|奖励的数量| - -### `withdrawValidatorCommission` - -提取验证者的佣金。 -验证者作为佣金获得的所有类型的代币都在单次交易中提取。 - -当佣金成功提取时,会发出 `WithdrawValidatorCommission` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|validatorAddress|address|验证者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|amount|Coin[]|验证者将获得的各种代币佣金| - -### `validatorDistributionInfo` - -返回代表验证者将获得奖励的分配信息。验证者可以在自己的地址上向自己委托代币,这被称为自绑定。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|validatorAddress|address|验证者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|distributionInfo|ValidatorDistributionInfo|验证者的分配信息| - -`ValidatorDistributionInfo` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|operatorAddress|address|验证者操作员的地址| -|selfBondRewards|DecCoin[]|验证者的自绑定金额| -|commission|DecCoin[]|验证者的佣金| - -`DecCoin` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|denom|string|奖励的denomination| -|amount|uint256|奖励的数量| -|precision|uint8|奖励的精度| - -### `validatorOutstandingRewards` - -返回验证者的未结算奖励。未结算奖励表示由验证者的佣金和自绑定奖励以及委托者的总奖励组成的奖励总额。如果有验证者A,委托者B、C和D委托给A,那么验证者的未结算奖励是A的佣金和自绑定奖励 + B、C和D的奖励的总和。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|validatorAddress|address|验证者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|rewards|DecCoin[]|验证者的未结算奖励| - -### `validatorCommission` - -返回验证者的佣金。此方法用于在调用 `withdrawValidatorCommission` 方法之前检索验证者的佣金。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|validatorAddress|address|验证者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|commission|DecCoin[]|验证者的佣金| - -### `validatorSlashes` - -返回验证者在起始高度和结束高度之间的削减历史。削减是当验证者恶意行为或违反网络规则(如双重签名、不当行为或不遵循链规则)时施加的罚款。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|validatorAddress|address|验证者的地址| -|startingHeight|uint64|起始高度| -|endingHeight|uint64|结束高度| -|pageRequest|PageReq|分页请求| - -`PageReq` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|key|bytes|分页的键| -|offset|uint64|分页的偏移量| -|limit|uint64|分页的限制| -|countTotal|bool|是否计算总页数| -|reverse|bool|是否反转分页| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|slashes|ValidatorSlashEvent[]|验证者的削减| -|pagination|PageResp|分页响应| - -`ValidatorSlashEvent` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|validatorPeriod|uint64|验证者的期间| -|fraction|Dec|削减的分数| - -`Dec` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|value|uint64|Dec的值| -|precision|uint8|Dec的精度| - -`PageResp` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|nextKey|bytes|分页的下一个键| -|total|uint64|总页数| - -### `delegationRewards` - -返回委托者从验证者那里获得的奖励。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的十六进制地址| -|validatorAddress|address|验证者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|rewards|DecCoin[]|委托者从验证者那里获得的奖励| - -### `delegationTotalRewards` - -返回委托者从所有验证者那里获得的总奖励。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的十六进制地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|rewards|DelegationDelegatorReward[]|委托者从所有验证者那里获得的总奖励| -|total|DecCoin[]|奖励的总额| - -`DelegationDelegatorReward` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|validatorAddress|address|验证者的地址| -|reward|DecCoin[]|委托者从验证者那里获得的奖励| - -### `delegatorValidators` - -返回委托者绑定的验证者。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的十六进制地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|validators|string[]|委托者绑定的验证者| - -### `delegatorWithdrawAddress` - -返回通过 `setWithdrawAddress` 方法设置的接收委托奖励的地址。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的十六进制地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|withdrawAddress|address|接收委托奖励的地址| - -## 事件 - -### SetWithdrawAddress - -|名称|类型|索引|描述| -|---|---|---|---| -|caller|address|Y|调用者(委托者)的地址| -|withdrawAddress|address|N|接收委托奖励的地址| - -### WithdrawDelegatorRewards - -|名称|类型|索引|描述| -|---|---|---|---| -|delegatorAddress|address|Y|委托者的地址| -|validatorAddress|address|Y|验证者的地址| -|amount|uint256|N|奖励的数量| - -### WithdrawValidatorCommission - -|名称|类型|索引|描述| -|---|---|---|---| -|validatorAddress|address|Y|验证者的地址| -|commission|uint256|N|佣金的总数量| \ No newline at end of file +- [**Distribution 预编译参考**](/cn/reference/distribution-module-api):调用 `withdrawDelegatorRewards`,设置提取地址,并读取奖励余额。 +- [**Staking 模块**](/cn/explanation/staking-module):了解委托(这些奖励的来源)的工作原理。 +- [**系统交易**](/cn/explanation/system-transactions):了解解绑完成如何作为事件到达 EVM。 diff --git a/docs/pages/cn/explanation/eip-7702.mdx b/docs/pages/cn/explanation/eip-7702.mdx index acbf012..3db884e 100755 --- a/docs/pages/cn/explanation/eip-7702.mdx +++ b/docs/pages/cn/explanation/eip-7702.mdx @@ -1,21 +1,53 @@ --- source_path: explanation/eip-7702.mdx -source_sha: 0abc92a6ce7f1df42ce8f247d3a7cccab8819f6d -title: EIP-7702 -description: "支持 EIP-7702,使 EOA 临时作为智能账户运行,改善钱包与支付体验。" +source_sha: 599d3ed0fdc99452166ebb51a8d74932622954f6 +title: "EIP-7702" +description: "EOA 的批量支付、消费限额和会话密钥,无需新建账户或钱包迁移。" +diataxis: "explanation" --- # EIP-7702 -Stable 支持 EIP-7702,引入了统一账户模型,使外部账户(EOA)可临时以智能账户方式运行。 +Stable 支持 **EIP-7702**,它允许 EOA **将其账户代码设置为现有智能合约**。EOA 执行该合约的逻辑,同时保留其原始地址和私钥。委托是持久的,直到 EOA 明确更改或清除它。 -关键特性: +有关完整规范,请参阅 [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)。 -- 用户可继续使用原有的私钥签名交易 -- 执行时可临时具备智能合约逻辑,无需永久升级账户 -- 实现安全的支付与托管授权流程 -- 改善钱包与商户使用 USDT 时的体验 +## EIP-7702 在 Stable 上实现了什么 -开发者: +EIP-7702 允许现有 EOA 执行智能合约逻辑,而无需账户迁移。在 Stable 以 USDT 为中心的支付环境中,这支持以下模式: -- 用户无需部署新合约即可获得合约级功能,降低接入门槛,简化托管逻辑。 +- **批量支付**: 多个调用(例如,在一个工资支付周期中向多个收款人支付)在一个原子交易中执行。 +- **消费限额**: 委托合约对 EOA 强制执行每日上限或每笔交易限额。 +- **会话密钥**: EOA 向 dApp 授予范围受限、有时效的交易权限,而无需暴露所有者的私钥。 + +:::note +**准备好实施了吗?** 请参阅 [账户抽象 (EIP-7702) 实施指南](/cn/reference/eip-7702-api),了解合约模板、授权签名和交易提交。 +::: + +## 工作原理 + +EIP-7702 引入了一种新的交易类型 (`0x04`),它带有一个 `authorizationList`。每个授权指定一个智能合约,EOA 将为该交易执行该合约的代码。流程如下: + +1. **选择或部署委托合约**: 一个标准的 Solidity 合约,实现了您希望 EOA 运行的逻辑。您可以使用现有的已部署合约或部署您自己的合约。尽可能使用经过审计的合约。 +2. **签署授权**: EOA 所有者签署一条消息,指定委托合约。 +3. **提交 EIP-7702 交易**: 交易包含授权,EOA 在执行期间运行委托的代码。 + +提交后,EOA 的账户代码被设置为委托。随后的 EOA 交易将执行委托的逻辑,直到所有者清除或替换委托。 + +## 不变之处 + +- **无需新账户**: 用户保留其现有的 EOA 地址和私钥。没有迁移步骤。 +- **现有密钥仍然签名**: EOA 的私钥对授权和任何后续交易进行签名。EIP-7702 没有引入新的签名方案。 +- **标准 EVM 执行**: 委托作为常规合约代码运行。调试或跟踪合约执行的工具保持不变。 + +## 安全考虑 + +- **委托访问是全面的。** 在委托期间,委托合约对 EOA 拥有完全执行权限。将委托选择视为信任决策:恶意委托可能会耗尽资产。 +- **委托是持久的。** 它不会在单笔交易结束时过期。当所有者不再需要时,必须明确清除或替换委托。 +- **Gas 成本略高**,这是由于授权处理,但在委托批量处理多个调用时可以抵消。在 Stable 上,基础费用为 1 gwei,gas 以 USDT0 计价,额外的授权开销远低于一美分,与标准 ERC-20 传输的成本相当。 + +## 接下来推荐 + +- [**账户抽象 (EIP-7702)**](/cn/reference/eip-7702-api):针对委托合约实施批量支付、消费限额和会话密钥。 +- [**USDT 作为 Gas**](/cn/explanation/usdt-as-gas-token):了解 EIP-7702 交易运行的 Gas 模型。 +- [**Gas 豁免**](/cn/explanation/gas-waiver):将委托与应用程序代替用户支付 Gas 的 Gas 豁免流程进行比较。 diff --git a/docs/pages/cn/explanation/erc-3009.mdx b/docs/pages/cn/explanation/erc-3009.mdx index 1a94cf4..1fdb456 100644 --- a/docs/pages/cn/explanation/erc-3009.mdx +++ b/docs/pages/cn/explanation/erc-3009.mdx @@ -1,40 +1,40 @@ --- source_path: explanation/erc-3009.mdx -source_sha: a3574e36ec8a922102e44d799c5aedbe2d3cb53c +source_sha: 355aa51b2e83bc01b1345eb0ec5d437956854d01 title: "使用签名授权进行结算" -description: "ERC-3009 允许代币持有者通过签名消息来授权转账,而无需直接调用合约。这是 Stable 上 x402 支付背后的结算机制。" +description: "通过签署消息来授权代币转账,无需直接调用合约。ERC-3009 是 Stable 上 x402 支付的结算机制。" diataxis: "explanation" --- # 使用签名授权进行结算 -ERC-3009 允许代币持有者通过签名消息来授权转账。任何人随后都可以提交该签名授权,在链上执行转账。发送方无需直接调用合约。 +ERC-3009 允许代币持有者通过签署消息来授权转账。任何人都可以提交该签名授权以在链上执行转账。发送者无需直接调用合约。 -这是 Stable 上 [x402](/cn/explanation/x402) 支付背后的结算机制。 +这是 Stable 上 [x402](/cn/explanation/x402) 支付的结算机制。 -## 它解决了什么问题? +## 解决了什么问题? -### 授权额度问题 +### 授权问题 -传统的 ERC-20 第三方转账模式是 `approve` + `transferFrom`。发送方首先调用 `approve` 授予支出额度,然后第三方调用 `transferFrom` 转移资金。这存在众所周知的问题: +ERC-20 传统第三方转账模式是 `approve` + `transferFrom`。发送者首先调用 `approve` 授予消费额度,然后第三方调用 `transferFrom` 转移资金。这存在众所周知的问题: -- **需要两笔交易**:发送方必须先发送一笔链上 `approve` 交易,任何转账才能进行。这需要消耗 gas 并增加延迟。 -- **无限额度风险**:为了避免重复的授权交易,许多应用程序请求无限支出权限,从而产生重大安全风险。 +- **需要两笔交易**:发送者在任何转账发生之前必须发送一笔链上 `approve` 交易。这会产生 gas 费用并增加延迟。 +- **无限授权风险**: 为了避免重复的授权交易,许多应用程序请求无限消费权限,这带来了重大的安全风险。 -ERC-3009 采用了不同的方法。发送方不授予额度,而是为特定转账签署一次性授权。无需单独的授权步骤,也不会留下持续的支出权限。 +ERC-3009 采取了不同的方法。发送者不是授予额度,而是签署一次性授权,用于特定转账。没有单独的批改步骤,也没有遗留的消费权限。 -### 顺序 nonce 问题 +### 顺序 Nonce 问题 -ERC-2612(`permit`)也支持签名授权,但它使用顺序 nonce。多个 permit 之间存在顺序依赖:如果 nonce 5 未被消耗,nonce 6 就永远无法执行。 +ERC-2612 (`permit`) 也支持签名授权,但它使用顺序 Nonce。多个 permit 具有排序依赖性:如果 Nonce 5 未被消耗,Nonce 6 将永远无法执行。 -ERC-3009 通过**唯一 nonce** 解决了这个问题。每个授权使用一个 32 字节的值,而不是顺序计数器。多个授权可以独立创建和提交,以任意顺序进行,彼此不相互依赖。 +ERC-3009 通过 **唯一 Nonce** 解决了这个问题。每个授权使用 32 字节的值,而不是顺序计数器。多个授权可以独立创建和提交,以任何顺序,互不依赖。 -### 对比 +### 比较 -| **属性** | **ERC-20**(`approve`) | **ERC-2612**(`permit`) | **ERC-3009** | +| **属性** | **ERC-20** (`approve`) | **ERC-2612** (`permit`) | **ERC-3009** | | :--- | :--- | :--- | :--- | -| 链上步骤 | 2(`approve` + `transferFrom`) | 1(`transferFrom`) | 1(`transferWithAuthorization`) | -| 使用额度模型 | 必需(链上交易) | 是(通过 `permit` 设置额度) | 不需要(签名) | +| 链上步骤 | 2 (`approve` + `transferFrom`) | 1 (`transferFrom`) | 1 (`transferWithAuthorization`) | +| 使用授权模型 | 需要(链上交易) | 是(通过 `permit` 设置授权) | 不需要(签名) | | Nonce 模型 | 顺序 | 顺序 | 唯一 | | 并发授权 | 否 | 否 | 是 | @@ -42,35 +42,35 @@ ERC-3009 通过**唯一 nonce** 解决了这个问题。每个授权使用一个 ### transferWithAuthorization -发送方签署一条包含转账详情的 EIP-712 类型化数据消息。任何人随后都可以使用该签名消息在代币合约上调用 `transferWithAuthorization`。合约验证签名、检查有效期窗口、执行转账,并将 nonce 标记为已使用。 +发送者签署一个包含转账详情的 EIP-712 类型数据消息。然后任何人都可以用该签名消息调用代币合约上的 `transferWithAuthorization`。合约验证签名,检查有效期窗口,执行转账,并将 Nonce 标记为已使用。 签名授权包含: -- `from`:发送方(签名者)的地址 -- `to`:接收方的地址 +- `from`:发送者(签名者)的地址 +- `to`:接收者的地址 - `value`:转账金额 - `validAfter`:此授权可执行的最早时间(Unix 时间戳) - `validBefore`:此授权可执行的最晚时间(Unix 时间戳) - `nonce`:确保唯一性的 32 字节值 -时间窗口(`validAfter`/`validBefore`)让发送方可以精确控制转账可以发生的时间。授权可以安排在未来执行、设定截止时间,或两者兼具。如果窗口在提交之前过期,授权将变为无效,资金仍归发送方所有。 +时间窗口(`validAfter`/`validBefore`)使发送者能够精确控制转账何时发生。授权可以安排在未来、给定截止日期或两者兼有。如果窗口在提交前过期,则授权无效,资金仍归发送者所有。 ### receiveWithAuthorization -此函数的工作方式与 `transferWithAuthorization` 完全相同,但多了一项检查:**调用者必须是接收方**。这可以防止抢跑攻击,即第三方观察到一笔待处理的授权并抢先提交以操纵交易顺序。 +此函数的工作方式与 `transferWithAuthorization` 完全相同,但有一个额外检查:**调用者必须是接收者**。这可以防止抢先攻击,即第三方观察到待处理的授权并首先提交以操纵交易顺序。 -这在支付场景中很有用,因为应由接收方(商家或服务提供商)来发起结算。 +这在支付场景中很有用,其中接收者(商家或服务提供商)应该是发起结算的一方。 ### cancelAuthorization -发送方可以在授权被执行之前撤销一个未使用的授权。发送方签署一条 EIP-712 取消消息,合约会将 nonce 标记为已使用而不执行转账。原始授权将无法再被提交。 +发送者可以在授权执行之前撤销未使用的授权。发送者签署一个 EIP-712 取消消息,合约将 Nonce 标记为已使用而不执行转账。原始授权将不再可提交。 -## 内置的安全特性 +## 内置安全属性 -- **一次性使用**:每个唯一 nonce 只能使用一次。重复提交相同的签名授权将会回滚。 -- **有时间限制**:`validAfter`/`validBefore` 窗口确保授权不会无限期有效。 -- **自包含**:一个签名授权一笔特定转账,转给一个特定接收方、转一个特定金额。不会留下持续权限。 -- **非托管**:提交者从不持有发送方的资金。转账在合约内部直接从发送方转到接收方。 +- **一次性使用**:每个唯一的 Nonce 只能使用一次。重新提交相同的签名授权将回滚。 +- **有时限**:`validAfter`/`validBefore` 窗口确保授权不会无限期有效。 +- **自包含**:一个签名授权一次特定转账给一个特定接收者,用于一个特定金额。没有遗留权限。 +- **非托管**:提交者从不持有发送者的资金。转账直接在合约内从发送者转移到接收者。 ## Stable 上的 ERC-3009 @@ -78,21 +78,21 @@ Stable 上的 USDT0 原生实现了 ERC-3009。任何应用程序都可以使用 ### 单资产结算 -在以太坊上,即便使用 ERC-3009,提交者仍需要 ETH 来支付调用 `transferWithAuthorization` 的 gas。转账本身是 USDT,但执行却依赖于另一种原生资产。 +在以太坊上,即使使用 ERC-3009,提交者也需要 ETH 来支付调用 `transferWithAuthorization` 的 gas 费。转账本身是以 USDT 进行的,但执行取决于单独的原生资产。 -在 Stable 上,USDT0 同时充当支付代币和 gas 代币。从授权到链上结算,整个支付生命周期都运行在单一稳定币上。在任何步骤中都不需要单独的原生资产。 +在 Stable 上,USDT0 既是支付代币也是 gas 代币。从授权到链上结算的整个支付生命周期都在单一稳定币上运行。在任何步骤都不需要单独的原生资产。 -正是这一特性使 Stable 上的 ERC-3009 成为更高层支付协议的坚实基础。[x402](/cn/explanation/x402) 直接利用了这一点,在标准 HTTP 通信中将 ERC-3009 用作其链上结算机制。 +这一特性使得 Stable 上的 ERC-3009 成为更高级别支付协议的坚实基础。[x402](/cn/explanation/x402) 直接利用了这一点,使用 ERC-3009 作为其在标准 HTTP 通信中的链上结算机制。 -## 要点总结 +## 主要观点 -- ERC-3009 允许代币持有者通过签名消息来授权转账。任何人都可以提交该签名授权来执行转账。 -- 它用一次性、自包含的授权取代了 ERC-20 额度模型。无需 `approve` 步骤、无持续权限、无双花风险。 -- 唯一 nonce 允许以任意顺序并发创建和提交多个授权。 -- Stable 上的 USDT0 原生支持 ERC-3009,由于仅使用 USDT0 即可完成结算,它为 x402 提供了实用的基础。 +- ERC-3009 允许代币持有者通过签名消息授权转账。任何人都可以提交该签名授权以执行转账。 +- 它用一次性、自包含的授权取代了 ERC-20 授权模型。没有 `approve` 步骤,没有遗留权限,没有双重支付风险。 +- 唯一 Nonce 允许并发创建和提交多个授权,以任何顺序。 +- Stable 上的 USDT0 原生支持 ERC-3009,并且由于结算可以仅使用 USDT0 完成,它为 x402 提供了实用的基础。 **另请参阅:** - [USDT 作为 Gas](/cn/explanation/usdt-as-gas-token) - [USDT0 在 Stable 上的行为](/cn/explanation/usdt0-behavior) -- [x402(HTTP 原生支付)](/cn/explanation/x402) +- [x402 (HTTP 原生支付)](/cn/explanation/x402) diff --git a/docs/pages/cn/explanation/ethereum-comparison.mdx b/docs/pages/cn/explanation/ethereum-comparison.mdx index c9ded29..5228994 100644 --- a/docs/pages/cn/explanation/ethereum-comparison.mdx +++ b/docs/pages/cn/explanation/ethereum-comparison.mdx @@ -1,81 +1,81 @@ --- source_path: explanation/ethereum-comparison.mdx -source_sha: 725ca9815a4f258f89945ec7c668c9729a1652c8 +source_sha: 899ef035bfd583ce5d1f14916e2dbd9df613a7bb title: "以太坊对比" -description: "Stable 完全兼容 EVM。从以太坊移植时哪些保持不变、哪些会改变以及需要注意的事项。" +description: "Stable 完全兼容 EVM。在从以太坊移植时,哪些保持不变,哪些会改变,以及需要注意什么。" diataxis: "explanation" --- # 以太坊对比 -Stable 完全兼容 EVM,因此大多数以太坊工具、库和合约模式无需修改即可使用。下面的章节将逐一介绍从以太坊迁移到 Stable 时哪些保持不变、哪些会改变。 +Stable 完全兼容 EVM,因此大多数以太坊工具、库和合约模式都无需修改即可使用。以下部分将介绍从以太坊迁移到 Stable 时哪些保持不变,哪些会改变。 -## 哪些保持不变 +## 保持不变的地方 -Stable 与以太坊开发生态系统保持完全兼容: +Stable 保持与以太坊开发生态系统的完全兼容: | **领域** | **兼容性** | | :--- | :--- | -| 语言 | Solidity、Vyper | -| 工具 | Hardhat、Foundry | -| 库 | ethers.js、web3.js | -| 合约模式 | 所有标准 EVM 约定(ERC-20、ERC-721、ERC-1155、代理等) | -| RPC 接口 | 支持大多数 `eth_*` 方法(`eth_call`、`eth_sendRawTransaction`、`eth_getBalance`、`eth_getLogs`、`eth_estimateGas` 等)。完整列表请参见 [JSON-RPC API](/cn/reference/json-rpc-api) | +| 语言 | Solidity, Vyper | +| 工具 | Hardhat, Foundry | +| 库 | ethers.js, web3.js | +| 合约模式 | 所有标准 EVM 约定 (ERC-20, ERC-721, ERC-1155, 代理等) | +| RPC 接口 | 支持大多数 `eth_*` 方法 (`eth_call`, `eth_sendRawTransaction`, `eth_getBalance`, `eth_getLogs`, `eth_estimateGas` 等)。有关完整列表,请参阅 [JSON-RPC API](/cn/reference/json-rpc-api) | -现有的智能合约、部署脚本和前端集成只需更改 RPC 端点和链 ID 即可面向 Stable。 +通过更改 RPC 端点和链 ID,现有的智能合约、部署脚本和前端集成可以目标 Stable。 -## 哪些不同 +## 不同之处 有四种行为与以太坊不同。 ### 1. 单槽最终性 -以太坊需要多个区块确认才能将交易视为最终确认。Stable 提供单槽最终性:交易一旦被包含在某个区块中即为最终确认。 +以太坊需要多次区块确认才能认为交易最终确定。Stable 提供单槽最终性:交易一旦包含在区块中即为最终确定。 -对开发者而言,这意味着: +对于开发人员而言,这意味着: -- 交易一旦出现在已确认的区块中,其状态更改即为最终且不可逆转。 +- 一旦交易出现在已确认的区块中,其状态变化就是最终且不可逆的。 - 应用程序可以安全地依赖区块包含作为结算确认。 -即便具备确定性最终性,处理金融敏感流程的应用程序仍应: +即使是确定性最终性,处理金融敏感流的应用程序也应该: -- 在进行依赖性操作(例如解锁、赎回)之前,通过 RPC 或发出的事件验证交易是否成功。 -- 为自动化和批量操作实现重试和对账逻辑,以处理临时提交或 RPC 错误。 +- 在执行依赖操作(例如,解锁、赎回)之前,通过 RPC 或发出的事件验证交易是否成功。 +- 为自动化和批量操作实施重试和协调逻辑,以处理瞬时提交或 RPC 错误。 ### 2. Gas 代币:USDT0 -在 Stable 上,交易费用以 USDT0 支付,而非波动性的原生代币。这提供了以 USDT 计价、可预测的低 gas 成本。 +在 Stable 上,交易费用以 USDT0 支付,而不是波动性原生代币。这提供以 USDT 计价的、可预测的低 Gas 成本。 -- 用户需要在其钱包中持有 USDT0 才能提交交易。 -- 交易中的 `value` 字段仍可用于发送 USDT0,类似于在以太坊上发送 ETH 的方式。 -- 详情请参见 [USDT 作为 gas](/cn/explanation/usdt-as-gas-token)。 +- 用户钱包中需要有 USDT0 才能提交交易。 +- 交易中的 `value` 字段仍然可以用于发送 USDT0,类似于以太坊上发送 ETH 的方式。 +- 详情请参阅 [以 USDT 作为 Gas](/cn/explanation/usdt-as-gas-token)。 -### 3. 无优先小费 +### 3. 没有优先级小费 -Stable 使用单组件 gas 模型。不存在基于小费的交易排序。 +Stable 使用单一组件 Gas 模型。没有基于小费的交易排序。 - `maxPriorityFeePerGas` 被忽略(始终为 0)。 - 交易排序不受费用竞价影响。 -- 钱包应隐藏或禁用优先小费输入字段。 -- 详情请参见 [Gas 定价](/cn/explanation/gas-pricing)。 +- 钱包应隐藏或禁用优先级小费输入字段。 +- 详情请参阅 [Gas 定价](/cn/explanation/gas-pricing)。 ### 4. USDT0 双重角色行为 -USDT0 既作为原生 gas 代币,又作为 ERC-20 代币。这在余额语义、授权安全性以及某些操作码假设方面引入了行为差异。完整详情请参见 [USDT0 在 Stable 上的行为](/cn/explanation/usdt0-behavior)。 +USDT0 既充当原生 Gas 代币,又充当 ERC-20 代币。这导致在余额语义、许可安全性和某些操作码假设方面存在行为差异。有关完整详细信息,请参阅 [Stable 上的 USDT0 行为](/cn/explanation/usdt0-behavior)。 -## 快速对比 +## 快速比较 | **参数** | **Stable** | **以太坊** | | :--- | :--- | :--- | | Gas 代币 | USDT0 | ETH | | 最终性 | 单槽 | 多区块确认 | -| 出块时间 | ~0.7 秒 | ~12 秒 | -| 优先小费(`maxPriorityFeePerGas`) | 被忽略(始终为 0) | 用于排序 | +| 区块时间 | ~0.7 秒 | ~12 秒 | +| 优先级小费 (`maxPriorityFeePerGas`) | 忽略 (始终为 0) | 用于排序 | | EIP-1559 交易格式 | 支持 | 支持 | | EVM 兼容性 | 完全 | 不适用 | -## 推荐的后续内容 +## 推荐阅读 -- [**USDT 作为 gas**](/cn/explanation/usdt-as-gas-token) — 了解取代 ETH 作为 gas 的资产模型。 -- [**Gas 定价**](/cn/explanation/gas-pricing) — 详细了解单组件费用模型。 -- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior) — 针对双重角色资产语义、授权安全性和 `EXTCODEHASH` 行为审计合约。 +- [**以 USDT 作为 Gas**](/cn/explanation/usdt-as-gas-token):了解用于替代 ETH 作为 Gas 的资产模型。 +- [**Gas 定价**](/cn/explanation/gas-pricing):详细审查单组件费用模型。 +- [**Stable 上的 USDT0 行为**](/cn/explanation/usdt0-behavior):审计合约以了解双重角色资产语义、许可安全性和 `EXTCODEHASH` 行为。 diff --git a/docs/pages/cn/explanation/execution.mdx b/docs/pages/cn/explanation/execution.mdx index 8c70f5a..271b654 100755 --- a/docs/pages/cn/explanation/execution.mdx +++ b/docs/pages/cn/explanation/execution.mdx @@ -1,11 +1,12 @@ --- source_path: explanation/execution.mdx -source_sha: 9afd5c0b659254ef8509480e9de4da6d351fc6d9 -title: "执行层" -description: "基于 Block-STM 的并行执行、乐观区块处理及未来 StableVM++ 性能优化。" +source_sha: bc64781e476fda556f242c5ec924b0e026a13f33 +title: "执行" +description: "Stable EVM 并行执行,采用 Block-STM、乐观区块处理,以及未来 StableVM++ 改进。" +diataxis: "explanation" --- -# 执行层 +# 执行 ## Stable EVM @@ -15,58 +16,58 @@ description: "基于 Block-STM 的并行执行、乐观区块处理及未来 Sta alt="Stable EVM" /> -**Stable EVM** 是 Stable 区块链的以太坊虚拟机兼容执行层,使用户能够通过现有的以太坊工具和钱包(如 MetaMask)无缝与链进行交互。Stable EVM 结合了 EVM 的开发体验与 StableSDK 的模块化、高性能基础设施。 +**Stable EVM** 是 Stable 的以太坊兼容执行层。现有的以太坊工具和钱包,如 MetaMask,无需更改即可与 Stable 交互。Stable EVM 将 EVM 的开发者体验与 Stable SDK 的模块化基础设施相结合。 -Stable 的以太坊兼容执行层,支持使用现有的以太坊工具与钱包无缝交互。同时 Stable EVM 引入一系列 预编译合约,允许 EVM 智能合约安全且原子性地调用Stable底层接口。通过这种设计,智能合约可执行包括代币转账、质押、参与治理等特权操作。 +为了弥合 Stable EVM 和 Stable SDK 之间的鸿沟,Stable EVM 引入了一系列**预编译**。这些预编译将原生的 Stable SDK 模块功能暴露给 EVM 智能合约,使它们能够安全、原子地调用核心链逻辑。智能合约因此可以执行特权操作,例如代币转移、质押或参与治理。 -## 未来路线图一:Optimistic并行执行(OPE) +## 未来路线图 1:乐观并行执行 -传统区块链系统依赖顺序执行机制,逐个处理交易以确保所有节点的一致状态。虽然这种方式保证了确定性,但极大限制了吞吐量和可扩展性,尤其在现代区块链需要支持每秒成千上万笔交易时更为突出。 +历史上,区块链系统一直依赖于顺序执行,即每个事务按顺序处理,以确保所有节点上的状态确定性。虽然这种设计保证了一致性,但它严重限制了吞吐量和可伸缩性,尤其是在现代区块链旨在支持每秒数万笔事务时。 -为突破此瓶颈,Stable 将采用 **Block-STM**,一种已验证的并行执行引擎,支持 **Optimistic并行执行(Optimistic Parallel Execution,简称 OPE)**,允许在保证确定性的前提下并行处理交易,显著提升性能。 +为了克服这一限制,Stable 正在采用 **Block-STM**,这是一种经过验证的并行执行引擎,可实现**乐观并行执行(OPE)**。这允许事务并行执行,同时保持确定性,显著提高性能。 -### Block-STM 的工作原理 +### Block-STM 工作原理 -Block-STM 使用Optimistic并发控制机制:首先假设交易之间不会冲突并进行并行执行,随后进入验证阶段检查冲突并处理重执行。核心依赖以下五项关键技术: +Block-STM 使用乐观并发控制机制:事务首先在假设它们不会冲突的情况下并行执行。然后,在验证阶段,检测并处理任何冲突,通过重新执行来解决。该过程依赖于以下五种关键技术: **1. 多版本内存结构** -Block-STM 为每个内存键(memory key)存储多个版本: +Block-STM 为每个内存键存储多个版本: -- 每个交易读取先前交易已提交的最新版本; -- 执行过程中,读取和写入都会进行版本标记; -- 验证阶段会检查这些版本以确认是否存在冲突。 +- 每个事务读取先前事务提交的最新版本。 +- 在执行期间,读取和写入都进行版本控制。 +- 随后,在验证期间,检查这些版本的一致性以检测冲突。 -**2. 基于读取集(Read-Set)/写入集(Write-Set)的验证机制** +**2. 基于读写集的验证** -- 执行时,交易会记录其读取的键及其版本(Read-Set); -- 执行结束后,其写入操作记录为 Write-Set; -- 验证阶段,若任意 Read-Set 中的键在执行期间被其他交易修改,则该交易判定为冲突,程序中止然后进行重试并增加尝试编号(incarnation)。 +- 在执行期间,每个事务都会将其读取的键和版本记录在读写集中。 +- 在执行结束时,它将其写集记录到多版本内存中。 +- 在验证期间,如果另一个事务修改了读写集中的任何键,则该事务被标记为冲突。然后它被中止并以递增的化身号重新执行。 -**3. 通过 ESTIMATE 标记实现快速冲突检测** +**3. 使用 ESTIMATE 标记快速检测冲突** -- 失败的交易会将其 Write-Set 标记为 ESTIMATE; -- 若其他交易读取到 ESTIMATE 标记的值,会立即停止并等待该交易重试(触发 `READ_ERROR`); -- 该机制可快速识别依赖关系,减少不必要的执行负担。 +- 当事务失败时,其写集会用 ESTIMATE 标志标记。 +- 如果另一个事务读取 ESTIMATE 标记的值,它会立即停止并等待重新执行(由 `READ_ERROR` 触发)。 +- 这有助于通过快速识别依赖关系来减少开销,而无需重新执行整个事务集。 **4. 预设交易顺序** -- 区块内的所有交易按照预设的确定顺序执行; -- 验证与提交阶段也遵循上述相同顺序; -- 即便并行执行,这能确保所有节点最终状态仍一致。 +- 区块内的所有交易都按照预设的、确定性的顺序执行。 +- 验证和提交阶段也遵循相同的顺序。 +- 这确保了即使并行执行,所有节点也能达到相同的最终状态。 -**5. 任务调度器(Collaborative Scheduler)** +**5. 协作调度器** -- 任务调度器以线程安全的方式为执行和验证分配任务; -- 优先处理索引较早的交易,加速处理早期提交的任务、减少重试; -- 调度器管理已多次尝试的任务,直到成功提交。 +- 协作调度器以线程安全的方式在执行和验证工作器之间分配任务。 +- 它优先处理低索引事务,以加速早期提交并最小化重新执行。 +- 调度器管理事务的化身,以便重复尝试直到它们成功提交。 -### Block-STM 的核心优势 +### Block-STM 的主要优势 -- **无锁并行**:基于 MVCC(多版本并发控制),允许多个交易同时读取/写入,无需加锁。在执行后才进行冲突检查,最大限度提升吞吐量。 -- **ESTIMATE 标记机制**:失败交易通过 ESTIMATE 标记提前通知依赖交易暂停,避免资源浪费。 -- **高效调度与优先提交机制**:通过任务调度器优先提交索引较早的交易,提高整体吞吐并缩短执行周期。 -- **确定性与共识兼容性**:即使某些交易需要重试,也将在相同顺序下提交,确保所有节点达成相同的最终一致性。 +- **无锁并行化**:通过利用 MVCC(多版本并发控制),Block-STM 允许多个事务并发读写,无需互斥锁。冲突仅在执行后检查,在初始处理阶段实现最大吞吐量。 +- **通过 ESTIMATE 标记实现最小开销**:失败的事务会用 ESTIMATE 标记来标记它们的写集,示意依赖事务提前暂停,避免浪费执行。这可以更快地收敛到有效的执行路径。 +- **高效调度和优先级提交**:使用协作调度器,系统通过首先提交低索引事务来最小化重试。这提高了整体吞吐量并缩短了执行周期。 +- **确定性和共识兼容性**:因为每个事务都遵循固定顺序,即使重新执行的事务最终也会以相同的顺序提交。这确保了所有节点之间的安全和确定性状态一致性,即使在并行化环境中也保持了共识的完整性。 ### Stable 上的 OPE @@ -76,22 +77,28 @@ Block-STM 为每个内存键(memory key)存储多个版本: alt="Optimistic Parallel Execution on Stable" /> -Stablechain 将把 **Optimistic并行执行(OPE)** 作为其执行层的核心功能,并结合 **Optimistic区块处理(Optimistic Block Processing,简称 OBP)**。需要注意的是,OPE 与 OBP 是互补但本质不同的两种优化策略。 +Stable 将把**乐观并行执行(OPE)**作为其执行层的核心功能,并结合**乐观区块处理(OBP)**。请注意,OPE 和 OBP 是互补但根本不同的策略。 ### 关于 OBP -- OBP 并不涉及并行,而是优化执行时机; -- 在 `ProcessProposal` 阶段,Stable 会在交易 gossip 的同时预先执行区块; -- 执行结果缓存在内存中,在 `FinalizeBlock` 阶段复用,节省时间并避免重复计算。 +- OBP 与并行无关,而是与执行时机有关。 +- 在 `ProcessProposal` 阶段,Stable 在区块被传播到其他节点时预执行它们。 +- 生成的状态被缓存到内存中,并在 `FinalizeBlock` 期间重用,从而节省时间并减少重复计算。 -通过结合 OPE 与 OBP,Stable 能在高交易负载下最大限度降低执行延迟与资源争用,带来卓越性能表现。 +通过结合 OPE 和 OBP,Stable 可以最大限度地减少执行延迟和资源争用,在高事务负载下提供卓越性能。 -### 性能预期 +### 预期性能提升 -内部基准测试表明,结合 **基于 Block-STM 的 OPE** 与 **StableDB**,Stable 的交易处理吞吐量有望提升 **至少 2 倍**。 +内部基准测试表明,通过**基于 Block-STM 的 OPE** 和 **StableDB** 集成,Stable 可以实现端到端事务处理**至少 2 倍的吞吐量提升**。 -## 未来路线图二:StableVM++ +## 未来路线图 2:StableVM++ -虽然 OPE 与 OBP 聚焦于优化「并行执行多笔交易」,但另一个关键的提升性能手段是:「如何更高效地处理每一笔交易」。 +虽然像乐观并行执行(OPE)和乐观区块处理(OBP)这样的努力侧重于优化*如何并发执行多个事务*,但还有另一个重要的性能杠杆:*每个单独事务的处理效率*。 -Stable 正在探索替代的 EVM 实现方式以加速交易执行。在当前选项中,**EVMONE**(一个高性能 C++ 编写的 EVM)是最具潜力的替代现有 Go 实现的EVM。理论基准测试表明,这一更换预计将带来高达 **6 倍的 EVM 执行性能提升**。 +Stable 目前正在探索替代 EVM 实现以提高执行速度。在众多候选者中,用 C++ 编写的高性能 EVM **EVMONE** 脱颖而出,有望取代现有的基于 Go 的 EVM。根据理论基准测试,预计这种切换将使 **EVM 执行性能提高 6 倍**。 + +## 接下来推荐 + +- [**存储 (StableDB)**](/cn/explanation/stable-db):了解分离的状态提交如何在不阻塞磁盘 I/O 的情况下馈送执行。 +- [**高性能 RPC**](/cn/explanation/high-performance-rpc):了解将执行结果呈现给客户端的分路径 RPC。 +- [**以太坊兼容性**](/cn/explanation/ethereum-compatibility):使用标准 EVM 工具针对 Stable 移植现有合约。 diff --git a/docs/pages/cn/explanation/flow-of-funds.mdx b/docs/pages/cn/explanation/flow-of-funds.mdx index 860a5bc..c723626 100644 --- a/docs/pages/cn/explanation/flow-of-funds.mdx +++ b/docs/pages/cn/explanation/flow-of-funds.mdx @@ -1,67 +1,67 @@ --- source_path: explanation/flow-of-funds.mdx -source_sha: ff06fe4313b45eaf2ea4b93e3e3e507b5dba22e3 -title: "资金流转" -description: "USDT 在 Stable 上的端到端生命周期,从入金、链上转账到出金结算。" +source_sha: 2f5b1dee38396eae48f9ded863b7b2c508bf6b4d +title: "资金流" +description: "USDT 在 Stable 上的端到端生命周期,从入金到链上转账再到出金结算。" diataxis: "explanation" --- -# 资金流转 +# 资金流 -Stable 是首条专为稳定币支付打造的区块链。该网络针对高吞吐、低延迟的稳定币交易进行了优化,提供 P2P 支付和商户收款,并以 USDT 实现即时结算。应用层的 gas 赞助与减免使服务提供商能够为终端用户提供零手续费的体验,带来主流支付网络般的感受,同时屏蔽了区块链系统的复杂性。 +Stable 是首个专为稳定币支付而构建的区块链。该网络针对高吞吐量、低延迟的稳定币交易进行了优化,实现了 USDT 的即时结算点对点支付和商家收款。应用层燃气费赞助和减免使提供商能够为终端用户提供零费用体验,提供主流支付网络的感受,同时抽象化区块链系统的复杂性。 -本页介绍 Stable 上资金的完整生命周期:USDT 如何进入网络、在参与者之间流转,以及如何退出回归法币通道。 +本页面描述了 Stable 上资金的完整生命周期:USDT 如何进入网络、在参与者之间移动以及退回到法币通道。 ## 1. 客户存款(入金) -用户通过以下三种主要渠道之一将资金引入网络: +用户通过以下三种主要渠道之一将资金存入网络: -- **加密货币转账**:任何主流加密货币在 Stable 上被桥接或转换为 USDT0。USDT0 是 USDT 的全链标准,也是网络上的主要形态。 -- **法币入金**:通过银行卡、ACH 或本地支付方式将法币转换为 USDT0,直接发送到用户的钱包。 -- **CEX 提现**:用户从支持的中心化交易所提现 USDT,选择 Stable 作为目标网络。交易所直接结算到用户的钱包。 +- **加密货币转账**:任何主要的加密货币都可通过桥接或转换为 Stable 上的 USDT0。USDT0 是 USDT 的全链标准,也是网络上的主要形式。 +- **法币入金**:银行卡、ACH 或本地支付方式将法币转换为 USDT0,直接存入用户的钱包。 +- **CEX 提款**:用户从支持的中心化交易所提取 USDT,选择 Stable 作为目标网络。交易所直接结算到用户的钱包。 -在所有情况下,最终状态都相同:用户的钱包直接在 Stable 上持有 USDT(以 USDT0 形式)。 +在所有情况下,最终状态都是相同的:用户的钱包直接在 Stable 上持有 USDT(作为 USDT0)。 -## 2. P2P / 商户转账(链上收款) +## 2. P2P / 商家转账(链上支付) -资金进入 Stable 后,客户即可将 USDT 直接发送给另一位用户或商户。链上转账的关键特性: +资金一旦进入 Stable,客户就会直接将 USDT 发送给其他用户或商家。链上转账的关键特性: -- **即时结算**:转账在链上立即完成。 -- **非托管**:在使用非托管钱包的情况下,源地址与目标地址之间的用户余额绝不会经过任何 PSP 或中介之手。 -- **单一资产**:由于 USDT 既是 gas 资产又是结算资产,流程中没有额外的代币,也没有隐藏的价差。 -- **零 gas 选项**:gas 减免使终端用户无需管理区块链费用即可转移资金。详见 [Gas 减免](/cn/reference/gas-waiver-api)。 +- **即时结算**:转账立即在链上结算。 +- **非托管**:在非托管钱包的情况下,在源头和目的地之间,没有任何 PSP 或中间机构接触用户余额。 +- **单一资产**:由于 USDT 既是燃气费又是结算资产,因此流程中没有额外的代币,也没有隐藏的利差。 +- **零燃气费选项**:燃气费减免允许终端用户无需管理区块链费用即可转移资金。有关详细信息,请参阅[燃气费减免](/cn/reference/gas-waiver-api)。 -## 3. 用户 / 商户余额 +## 3. 用户/商家余额 -商户在自己直接掌控的 Stable 钱包中接收 USDT。资金在用户或商户的托管下保存于链上。这些钱包可由支付服务提供商代表用户创建和管理。 +商家会在自己的直接控制下,在 Stable 钱包中收到 USDT。资金以用户或商家的托管方式保存在链上。这些钱包可以由支付提供商代表用户创建和管理。 -## 4. 商户提现(出金 / 付款) +## 4. 商家提款(出金/付款) -当商户或用户请求链下法币结算时: +当商家或用户请求链下法币结算时: -1. 服务提供商通过银行或付款通道发起转换(USDT → 法币)。 -2. 资金被记入商户所选的账户。 +1. 提供商通过银行或支付渠道启动转换(USDT → 法币)。 +2. 资金记入商家指定的账户。 -服务提供商仅在为商户兑现时才重新进入流程,而不参与生态系统内部的转账。日常的 P2P 流转无需任何中介;服务提供商仅在存款(向商户账户转入 USDT)或提现(USDT → 法币)时参与。 +提供商仅在商家提款时重新进入流程,而不是在生态系统内部转账期间。日常 P2P 流程不需要中介;提供商仅在存款(USDT 转账到商家账户)或提款(USDT → 法币)时参与。 ## 跨资产交易 Stable 还支持付款方持有非 USDT 加密货币的场景。 -### 用户兑换为另一种加密货币 +### 用户交易为另一种加密货币 -用户可以通过集成的交易所、经纪商或链上 DEX 持有或兑换为另一种加密货币(例如 BTC 或 ETH)。在付款时,系统会自动将所选的加密货币转换为 USDT,然后将其传输到商户的 Stable 钱包。无论用户偏好哪种资产,所有链上结算都始终以 USDT 进行。 +用户可以通过集成交易所、经纪商或链上 DEX 持有或交易另一种加密货币(例如 BTC 或 ETH)。在支付时,系统会自动将所选加密货币转换为 USDT,然后将其传输到商家的 Stable 钱包。所有链上结算将继续以 USDT 进行,无论用户偏好哪种资产。 -### 商户接受加密货币付款 +### 商家接受加密货币支付 -商户无需直接接受或管理多种加密货币。他们始终在自己的 Stable 钱包中收到 USDT,从而在整个网络中保持单一结算货币。这种设计将商户的外汇风险降至最低,并简化了对账和报告工作。 +商家无需直接接受或管理多种加密货币。他们始终在 Stable 钱包中收到 USDT,从而在整个网络中保持单一结算货币。这种设计最大限度地降低了商家的外汇风险,并简化了对账和报告。 -### 服务提供商在转换中的角色 +### 提供商在转换中的作用 -转换逻辑(例如 BTC → USDT)可由交易所合作伙伴、流动性提供商或支付服务提供商自有的资金部门处理。商户始终免受波动性或流动性风险的影响;他们只会收到 USDT。 +转换逻辑(例如,BTC → USDT)可以由交易所合作伙伴、流动性提供商或支付提供商自己的金库处理。商家免受波动或流动性风险的影响;他们只接收 USDT。 -## 下一步推荐 +## 推荐阅读 -- [**USDT 作为 gas**](/cn/explanation/usdt-as-gas-token) — 了解 USDT0 如何在 Stable 上同时作为原生 gas 和 ERC-20 余额。 -- [**桥接到 Stable**](/cn/explanation/usdt0-bridging) — 了解 USDT0 如何通过 OFT Mesh 或 Legacy Mesh 从其他链转移到 Stable。 -- [**发送你的第一笔 USDT0**](/cn/tutorial/send-usdt0) — 使用标准 EVM 工具在测试网上提交一笔 USDT0 转账。 +- [**USDT 作为燃气代币**](/cn/explanation/usdt-as-gas-token):了解 USDT0 如何在 Stable 上既充当原生燃气又充当 ERC-20 余额。 +- [**桥接到 Stable**](/cn/explanation/usdt0-bridging):了解 USDT0 如何通过 OFT Mesh 或 Legacy Mesh 从其他链转移到 Stable。 +- [**发送您的第一笔 USDT0**](/cn/tutorial/send-usdt0):使用标准 EVM 工具在测试网上提交 USDT0 转账。 diff --git a/docs/pages/cn/explanation/gas-pricing.mdx b/docs/pages/cn/explanation/gas-pricing.mdx index feb776f..f6d5d24 100755 --- a/docs/pages/cn/explanation/gas-pricing.mdx +++ b/docs/pages/cn/explanation/gas-pricing.mdx @@ -1,25 +1,42 @@ --- source_path: explanation/gas-pricing.mdx -source_sha: 2df550135708d69fa3d4b68bf1579652c4fff68d -title: Gas 定价机制 -description: "以 USDT0 支付、无优先费的 Stable 单一组件 Gas 定价模型。" +source_sha: cee955370fcdfb739edadd48366ac6c984cbc9d9 +title: "Gas 费用" +description: "Stable 采用单一组件的 Gas 费模型,没有优先级小费,以 USDT0 计价提供可预测的成本。" +diataxis: "explanation" --- -# Gas 定价机制 +# Gas 费用 -Stable 采用单一组成部分的 Gas 费模型: +Stable 采用简化的单一组件 Gas 费模型,旨在消除费用波动并提供可预测的低交易成本。交易排序不受小费竞价的影响。有效的 Gas 价格仅由协议的基础费用决定。 -- **不支持优先费用( 禁用maxPriorityFeePerGas)** -- 费用仅基于基础的执行成本 -- 以 **USDT0** 支付 +## 为什么采用此模型 -设计理由: +单一组件设计具有三个特点: -- 消除 Gas 波动,保证支付可预测性 -- 简化用户体验,避免通过支付额外报酬使验证节点优先处理交易 +- **可预测的成本**:费用纯粹基于基础执行成本。小费拍卖不会引入差异。 +- **USDT 计价**:Gas 以 USDT0 定价,因此开发人员或用户在考虑美元成本时不必考虑原生代币价格波动。 +- **极低的费用**:在 1 gwei 的基础费下,原生 USDT0 转账(21,000 gas)大约花费 **0.0000021 USDT0**。即使是复杂的合约交互,费用也远低于一美分。 -开发者注意: +## 与以太坊的比较 -- 不支持指定优先费用以加速交易 -- 钱包应隐藏或禁用优先费用的设置 -- Gas 预估需基于 Stable RPC 的定价预测 +| **参数** | **Stable** | **以太坊** | +| :--- | :--- | :--- | +| Gas 代币 | USDT0 | ETH | +| 基础费用 | 是 | 是 | +| 优先级小费 (`maxPriorityFeePerGas`) | 被忽略(始终为 0) | 用于排序 | +| EIP-1559 交易格式 | 支持 | 支持 | + +Stable 接受 EIP-1559 (Type 2) 交易,但 `maxPriorityFeePerGas` 总是被忽略。交易排序不受小费竞价的影响。 + +## 影响 + +- **钱包**应隐藏或禁用优先级小费输入字段。显示它们可能会让用户感到困惑,因为该值无效。 +- **分析仪表盘**不应跟踪优先级费用。它们将始终为零。 +- **交易构建工具**应明确将 `maxPriorityFeePerGas` 设置为 `0`,然后从最新区块的基础费用计算 `maxFeePerGas`,并保留一个安全边际。 + +## 接下来推荐 + +- [**Gas 费用参考**](/cn/reference/gas-pricing-api):根据 Stable 的费用模型构建交易、估算 Gas 并配置工具。 +- [**USDT 作为 Gas**](/cn/explanation/usdt-as-gas-token):了解 USDT0 如何同时充当原生 Gas 和 ERC-20 余额。 +- [**以太坊比较**](/cn/explanation/ethereum-comparison):审查从以太坊移植时将遇到的所有行为差异。 diff --git a/docs/pages/cn/explanation/gas-waiver.mdx b/docs/pages/cn/explanation/gas-waiver.mdx index 89ef90a..20389de 100755 --- a/docs/pages/cn/explanation/gas-waiver.mdx +++ b/docs/pages/cn/explanation/gas-waiver.mdx @@ -1,267 +1,61 @@ --- source_path: explanation/gas-waiver.mdx -source_sha: 094d0be55d626fd84d16fee6f1f842dd11be54d8 -title: Gas 豁免人 -description: "通过治理批准地址实现免 Gas 交易的 Gas Waiver 协议与 Waiver Server API。" +source_sha: 7995b37c002721e3b84297b0e4c3ba54281c0d14 +title: "Gas 费用减免" +description: "Gas 费用减免让应用程序为用户支付 Gas 费。经治理批准的费用减免通过提交封装交易来执行已签名的有效载荷,且 Gas 价格为零。" +diataxis: "explanation" --- -# Gas 豁免人 +# Gas 费用减免 -## 摘要 +经治理批准的地址(称为**费用减免方**)提交一个封装交易,其中包含用户签名的有效载荷,并以 `gasPrice = 0` 执行。用户无需持有 USDT0,也无需支付 Gas 费。Stable 公司运营着一个这样的费用减免服务;合作伙伴也可以通过验证器治理注册自己的费用减免地址。 -Gas 豁免人(免 Gas 费)功能通过允许一小部分经过治理批准的地址("豁免人")提交 `gasPrice = 0` 的交易,实现 Stable 链上终端用户的无 Gas 费交易。Stable 目前运营一个豁免人服务("豁免人服务器"),合作伙伴可以集成该服务,无需实现特定协议的封包逻辑即可提供无 Gas 费用户体验。 +## 工作原理 -本文档规定了 Gas 豁免人 机制、交易格式、治理控制以及面向合作伙伴的豁免人服务器 API。 +Gas 费用减免采用封装交易模式: -## 范围 +1. **用户签署一个 `InnerTx`**,其中 `gasPrice = 0`。用户的签名端到端保留;费用减免方不能修改有效载荷,否则会使其失效。 +2. **费用减免方将 `InnerTx` 封装到 `WrapperTx` 中**,发送到协议标记地址 (`0x000000000000000000000000000000000000f333`),其中 `value = 0`,`gasPrice = 0`,并将已签名的 `InnerTx` 作为其数据有效载荷。 +3. **验证器检测到标记**,检查费用减免方的授权和策略约束,并以用户身份(`from`、`nonce`、调用语义)执行内部交易。 -本规范涵盖: +Gas 记账在费用减免机制内处理。用户不支付任何费用;封装器不支付任何费用;验证器根据每个费用减免策略承担成本。 -- 免 Gas 费交易的协议级规则 -- 封包交易机制和标记地址 -- 治理控制的授权和允许的目标 -- 用于提交已签名用户交易的豁免人服务器接口 +## 授权和策略 -## 定义 +费用减免方由验证器治理控制,而不是应用程序逻辑。治理提供: -- **Waiver(豁免人)**:通过验证者治理在链上注册的以太坊地址,授权提交免 Gas 费交易。 -- **InnerTx(内部交易)**:终端用户签名的交易,`gasPrice = 0`。 -- **WrapperTx(封包交易)**:由豁免人签名的交易,将用户的 `InnerTx` 传输到链上并授权执行。 -- **Marker address(标记地址)**:用于识别豁免人封包交易的哨兵地址:`0x000000000000000000000000000000000000f333`。 -- **AllowedTarget(允许的目标)**:一种策略,将豁免人限制在特定的合约地址和方法选择器。 +- **可审查的注册**:每个费用减免地址都在链上注册,并在状态中可见。 +- **撤销**:验证器可以随时移除行为不当的费用减免方。 +- **通过 `AllowedTarget` 进行范围访问**:每个费用减免方都绑定到特定的目标合约和方法选择器集合。如果内部 `to` 地址和方法选择器超出该范围,协议将拒绝任何封装器。 -## 概述 +有效的封装交易必须满足以下所有条件: -Gas 豁免人 使用封包交易模式: +- `WrapperTx.to == 0x000000000000000000000000000000000000f333`(标记地址)。 +- `WrapperTx.from` 是通过治理在链上注册的费用减免方。 +- `WrapperTx.gasPrice == 0` 和 `InnerTx.gasPrice == 0`。 +- `WrapperTx.value == 0`。 +- `InnerTx.to` 和提取的方法选择器由费用减免方的 `AllowedTarget` 策略允许。 -1. 用户使用 `gasPrice = 0` 签署 `InnerTx`。 -2. 豁免人将 `InnerTx` 封包成 `WrapperTx` 并广播。 -3. 验证者检测到标记交易,验证豁免人授权和策略约束,然后执行嵌入的 `InnerTx`。 - -Stable 运营一个豁免人服务(豁免人服务器),该服务在链上注册为授权豁免人。合作伙伴通过豁免人服务器 API 集成,提交已签名的 `InnerTx` 负载。 - -## 协议规范 - -### 标记地址路由 - -当且仅当满足以下条件时,交易被视为豁免人封包交易: - -- `to == 0x000000000000000000000000000000000000f333`。 - -协议将交易的 `data` 字段解释为编码的内部交易负载,并使用以下豁免人验证规则进行处理。 - -### 授权和策略检查 - -对于每个候选封包交易,验证者必须执行: - -1. **豁免人授权** - - `WrapperTx.from` 必须是通过治理在链上注册的豁免人地址。 -2. **Gas 豁免** - - `WrapperTx.gasPrice` 必须等于 `0`。 - - `InnerTx.gasPrice` 必须等于 `0`。 -3. **目标白名单** - - `InnerTx.to` 和从 `InnerTx.data` 提取的方法选择器必须被豁免人的 `AllowedTarget` 策略允许。 -4. **Value 限制** - - `WrapperTx.value` 必须等于 `0`。 - -若以上任何一条未通过,则封包交易将被拒绝,封包内部的交易也无法执行。 - -### 执行语义 - -如果所有检查通过: - -1. 协议以用户身份执行 `InnerTx`,保留用户的 `from`、`nonce` 和调用语义。 -2. Gas 计费由豁免人机制处理:用户不支付 Gas 费,豁免人交易根据功能定义使用 `gasPrice = 0`。 -3. 封包交易必须提供足够的 `gasLimit` 以覆盖 `InnerTx` 的执行(包括解包和验证的开销)。 - -## 交易格式 - -### WrapperTx - -封包交易由豁免人签署并发送到标记地址。 - -```javascript -WrapperTx { - from: waiver_address, - to: 0x000000000000000000000000000000000000f333, - value: 0, // 必须为零 - data: RLP(InnerTx), // RLP 编码的内部交易 - gasPrice: 0, // 必须为零 - gasLimit: sufficient_for_inner, // 必须覆盖内部执行 + 开销 - nonce: waiver_nonce -} -``` - -### InnerTx - -内部交易由终端用户签署。 - -```javascript -InnerTx { - from: user_address, - to: target_contract, - value: value, - data: call_data, - gasPrice: 0, // 必须为零 - gasLimit: execution_gas, - nonce: user_nonce -} -``` - -## 治理控制的访问 - -豁免人授权由验证者治理在链上管理。 - -治理控制提供: - -- 可审查的豁免人地址授权 -- 豁免人注册和更新的链上透明度 -- 撤销能力 -- 通过 `AllowedTarget` 进行每个豁免人的范围界定 +如果任何条件失败,验证器将拒绝封装器,而不执行内部交易。 ## 安全模型 -### 终端用户签名完整性 - -用户签署 `InnerTx`。豁免人不允许修改内部交易负载而不使签名失效。合作伙伴仍必须确保用户仅签署预期的交易负载。 - -### 信任边界 - -如果合作伙伴通过豁免人服务器路由提交,Gas 豁免人 引入了服务依赖性: - -- 服务的可用性影响提交无 Gas 费交易的能力。 -- 授权保留在链上;只有注册的豁免人地址才能产生有效的封包提交。 - -## 合作伙伴集成 - -合作伙伴通过以下方式集成: - -1. 从用户收集已签名的 `InnerTx`(`gasPrice = 0`)。 -2. 将已签名的内部交易提交到豁免人服务器 API。 -3. 处理流式结果并向终端用户显示交易哈希。 - -## 豁免人服务器 - -### 概述 - -豁免人服务器将已签名的用户 `InnerTx` 负载封包并广播为豁免人授权的封包交易。合作伙伴无需构造封包交易或操作豁免人地址。 - -### 端点和基础 URL - -基础 URL: - -- 主网:待定 -- 测试网:`https://waiver.testnet.stable.xyz` - -### 身份验证 - -除健康检查外,所有端点都需要 Bearer Token 身份验证: - -``` -Authorization: Bearer -``` - -### API - -#### GET `/v1/health` - -健康检查端点。 - -身份验证:无。 - -#### POST `/v1/submit` - -提交一批已签名的内部交易。 - -身份验证:必需(`Bearer`)。 - -请求正文: - -```json -{ - "transactions": ["0x", "0x"] -} -``` - -响应以 NDJSON(换行符分隔的 JSON)流式传输。每行对应一个提交的交易索引。 - -示例: - -```json -{"index":0,"id":"abc123","success":true,"txHash":"0x..."} -{"index":1,"id":"def456","success":false,"error":{"code":"VALIDATION_FAILED","message":"invalid signature"}} -``` - -#### GET `/v1/submit` - -用于流式提交的 WebSocket 接口。 - -身份验证:必需(`Bearer`)。 - -### 集成示例 - -```javascript -const WAIVER_SERVER = "https://waiver.testnet.stable.xyz"; - -async function submitGaslessTransaction(signedInnerTxHex, apiKey) { - const response = await fetch(`${WAIVER_SERVER}/v1/submit`, { - method: "POST", - headers: { - "Content-Type": "application/json", - "Authorization": `Bearer ${apiKey}`, - }, - body: JSON.stringify({ - transactions: [signedInnerTxHex], - }), - }); - - const reader = response.body.getReader(); - const decoder = new TextDecoder(); - - while (true) { - const { done, value } = await reader.read(); - if (done) break; - - const lines = decoder.decode(value).trim().split("\n"); - for (const line of lines) { - const result = JSON.parse(line); - console.log(result); - } - } -} -``` - -### 创建用户 InnerTx - -合作伙伴负责构造 `gasPrice = 0` 的 `InnerTx`,然后收集用户签名。 +- **用户签名完整性**:用户签署 `InnerTx`。费用减免方不能修改有效载荷,否则会使签名无效。合作伙伴仍有责任确保用户只签署预期的有效载荷。 +- **链上授权**:授权存在于链上。只有治理注册的费用减免地址才能提交有效的封装,无论请求源自何处。 +- **服务可用性边界**:当合作伙伴通过 Stable 托管的费用减免服务器路由时,提交的可用性取决于服务。协议级别的授权保证不受影响。 -示例: +## 何时使用 Gas 费用减免 -```javascript -import { ethers } from "ethers"; +Gas 费用减免适用于最终用户无需持有 USDT0 来支付 Gas 费的任何流程: -async function createInnerTx(userWallet, contractAddress, callData, nonce) { - const innerTx = { - to: contractAddress, - data: callData, - value: value, - gasPrice: 0, // 豁免人必须为 0 - gasLimit: 100000, - nonce: nonce, - chainId: 2201, // 主网为 988,测试网为 2201 - }; +- 消费者应用程序正在引导尚未有稳定币余额的用户。 +- 代理驱动的流程,其中代理的钱包支付 Gas 费。 +- 企业支付轨道,其中运营商承担网络成本。 - return await userWallet.signTransaction(innerTx); -} -``` +对于用户持有 USDT0 但希望将多个调用捆绑到一个签名交易的流程,请参阅[EIP-7702 委托](/cn/reference/eip-7702-api)。 -### 错误代码 +## 推荐下一步 -- `PARSE_ERROR`:解析交易失败 -- `INVALID_REQUEST`:请求正文格式错误 -- `BATCH_SIZE_EXCEEDED`:批处理大小超过允许的最大值 -- `VALIDATION_FAILED`:交易验证失败 -- `BROADCAST_FAILED`:广播到链失败 -- `RATE_LIMITED`:超过速率限制 -- `QUEUE_FULL`:服务器队列已满 -- `TIMEOUT`:请求超时 +- [**启用无 Gas 交易**](/cn/how-to/integrate-gas-waiver):通过 API 密钥提交和 NDJSON 响应集成托管的费用减免服务器 API。 +- [**Gas 费用减免协议**](/cn/reference/gas-waiver-api):阅读完整的协议规范:标记路由、封装格式、治理控制。 +- [**USDT 作为 Gas 费**](/cn/explanation/usdt-as-gas-token):了解费用减免方承担的 Gas 费代币。 diff --git a/docs/pages/cn/explanation/guaranteed-blockspace.mdx b/docs/pages/cn/explanation/guaranteed-blockspace.mdx index e179777..fe428a6 100755 --- a/docs/pages/cn/explanation/guaranteed-blockspace.mdx +++ b/docs/pages/cn/explanation/guaranteed-blockspace.mdx @@ -1,42 +1,49 @@ --- source_path: explanation/guaranteed-blockspace.mdx -source_sha: f7ea9d588c7686dd55bd3c0f2323ad749b03d1c9 -title: "保证区块空间(Guaranteed Blockspace)" -description: "为企业合作伙伴预留交易吞吐量的区块空间保障分配机制。" +source_sha: e4251f3214551742d492fdfe9dfc33077cb77d76 +title: "保证区块空间" +description: "保证区块空间分配,为企业合作伙伴提供在 Stable 网络上预留的吞吐量容量。" +diataxis: "explanation" --- -# 保证区块空间(Guaranteed Blockspace) +# 保证区块空间 -## 企业需要稳定的支付基础设施 +**保证区块空间**是一种专用的区块空间分配模型,它为注册的企业合作伙伴预留了每个区块固定份额的容量,无论更广泛的网络条件如何。通过保证路径路由的交易以可预测的延迟和成本执行。工资支付、结算和供应商付款不会与公共内存池流量竞争。 -随着稳定币的持续发展,越来越多的企业将其纳入财务操作中,例如支付、资金调拨和跨境结算。这一趋势在那些获取稳定法币受限的地区尤为明显。在非洲、拉丁美洲等通货膨胀严重、货币管控严格的市场,稳定币正逐渐成为这些地区企业持续运营的关键工具。 +:::note +**计划中。** 保证区块空间是前瞻性路线图项目。有关时间安排,请参阅[路线图](/cn/explanation/technical-roadmap)。 +::: -当前,大部分稳定币交易发生在通用型公链上,例如 Ethereum、Solana 和 Tron。这些网络虽提供了高可组合性和智能合约支持,但它们并未针对**费用可预测性**或**执行确定性**进行专门设计。 +## 为什么这很重要 -- **Ethereum**:2022 年 5 月 1 日,Yuga Labs 的 “Otherside” NFT 铸造事件在 Ethereum 上燃烧了超过 2 亿美元的 Gas 费,峰值 Gas 价格超过 8,000 gwei,造成整个网络交易费用剧烈波动,缺乏可预测性。 -- **其他区块链网络**:在 Solana 和 Base 等低费用网络中,由于存在 MEV 和套利机会,激励机制导致大量交易垃圾(spam)泛滥。自动化机器人频繁向链上提交交易以从中捕获价值,从而造成网络拥堵,影响真实用户的正常使用。 +通用链在负载下的费用可预测性方面设计不足: -![来源:Flashbots 与 Robert Miller 联合发布的《MEV 与扩容的极限》报告](/images/share-of-gas.png) +- **以太坊**:2022 年 5 月 1 日,Yuga Labs 的“Otherside”NFT 铸造将峰值 gas 推高到 8,000 gwei 以上,并烧毁了超过 2 亿美元的费用,打破了任何需要确定性成本的工作负载。 +- **低费用网络**如 Solana 和 Base 吸引了 MEV 和套利垃圾邮件,因此合法交易与机器人流量竞争以获得包含。 -*来源:Flashbots 与 Robert Miller 联合发布的《MEV 与扩容的极限》报告* +![来源:Flashbots 和 Robert Miller 的 MEV 和扩容限制](/images/share-of-gas.png) -若企业要大规模采用稳定币进行支付,其底层基础设施必须具备**支付可靠性**。这意味着必须在任何网络条件下都能提供可预测的交易速度与稳定的交易费用。否则,基于通用区块链的稳定币支付将难以满足企业级应用的要求。 +*来源:Flashbots 和 Robert Miller 的 MEV 和扩容限制* -## 保证区块空间(Guaranteed Blockspace) +企业支付流无法容忍这种差异。保证区块空间直接解决了这个问题。 -为保障企业支付操作的稳定性与可靠性,Stable 将推出 **保证区块空间(Guaranteed Blockspace)** 支持。 +## 保证如何工作 -保证区块空间(Guaranteed Blockspace) 是一种**专属的区块容量分配机制**,旨在为企业客户预留固定比例的区块空间,无论网络整体负载如何。关键性的交易(如工资发放、结算清算、供应商支付)都可在可预测的交易时间与成本下完成执行。 +保证在三个层面强制执行: -该机制通过以下方式实现: +- **保证内存池**:验证者从专门的内存池中提取保证交易,该内存池与公共流量隔离。 +- **验证者级别预留**:每个验证者为保证通道预留了每个区块 gas 容量的预定义部分。确定性包含由此产生。 +- **专用 RPC 节点**:保证区块空间 API 通过隔离的 RPC 端点路由交易,因此提交延迟不会随着公共 RPC 负载而飙升。 -- **专属内存池(Guaranteed Mempool)**:验证节点会从独立的企业交易内存池中提取优先级高的交易,避免与一般交易争夺资源。 -- **验证节点级别的处理流程**:每个验证节点为企业用户预留固定比例的区块空间,确保这类交易能以高确定性地被包含进块中。 -- **专属 RPC 服务**:企业级 API 会通过独立的 RPC 服务器发送交易,减少资源争抢,提升吞吐稳定性。 +对于注册的合作伙伴,结果是: -保证区块空间为商业用户带来以下优势: +- **独家路由路径**:提交不与公共内存池流量竞争。 +- **保证包含**:无论网络拥堵如何,每个区块都预留了容量。 +- **无去中心化权衡**:验证者开放性和网络参与性得以保留;保证与公共通道并存,而不是凌驾于其上。 +- **关键业务操作的可靠链上性能**,即使在负载下。 -- **专属交易通道**:通过独立的交易传输路径,确保交易享有优先访问专属区块空间的权限。 -- **交易执行保障**:即使在高负载网络条件下,每个区块内都能确保企业交易的优先执行权。 -- **保持网络去中心化特性**:不影响验证节点的开放性或网络参与者的操作自由。 -- **关键操作的链上性能保障**:即使网络拥堵,企业的关键链上交易依旧可以保持可靠、高效运行。 +## 下一步建议 + +- [**保证结算**](/cn/explanation/upcoming-use-cases):查看依赖于保证区块空间的支付模式:具有确定性包含的定时 DvP 结算周期。 +- [**USDT 作为 gas**](/cn/explanation/usdt-as-gas-token):了解流经保证区块空间的资产。 +- [**代币经济学**](/cn/reference/tokenomics):审查 STABLE 质押如何支撑验证者的区块空间保证。 diff --git a/docs/pages/cn/explanation/high-performance-rpc.mdx b/docs/pages/cn/explanation/high-performance-rpc.mdx index 212d7ad..2bab70d 100755 --- a/docs/pages/cn/explanation/high-performance-rpc.mdx +++ b/docs/pages/cn/explanation/high-performance-rpc.mdx @@ -1,86 +1,92 @@ --- source_path: explanation/high-performance-rpc.mdx -source_sha: bc4a47aca13a4da0d335144b2d417952fc657edc +source_sha: e9b9e14a5ef34ddf17d96530fc4c39dcce765caf title: "高性能 RPC" -description: "读写分离的 Stable RPC 架构,实现高吞吐量与低延迟的链上数据访问。" +description: "Stable 的分路 RPC 架构将读写分离,以实现高吞吐量、低延迟的访问。" +diataxis: "explanation" --- # 高性能 RPC -在构建高性能区块链的过程中,仅仅优化共识机制或出块速度是不够的。**RPC 层** 是区块链与用户之间的接口,是实现端到端用户体验的关键组成部分。Stable 提出一种高性能 RPC 架构,旨在突破传统 RPC 的性能瓶颈。 +在追求高性能区块链的过程中,仅仅优化共识或区块生产是不够的。RPC 层是端到端用户体验的关键组成部分,因为它是区块链与其用户之间的接口。Stable 提出了一种新的 RPC 专用架构,以克服传统 RPC 设计的局限性。 -## 为什么高性能 RPC 至关重要 +## 为什么高性能 RPC 很重要 -### 用户连接区块链的入口 +### 用户通向区块链的网关 -**RPC** 是用户与区块链交互的主要方式: +**远程过程调用 (RPC)** 接口是用户与区块链交互的主要方式: -- 钱包通过 RPC 广播交易; -- DApps 借助 RPC 查询链上状态来渲染界面、准备交易、进行模拟、获取事件和日志等; -- 区块浏览器、索引服务和交易机器人程序都依赖 RPC 实时获取数据。 +- 钱包使用 RPC 广播交易。 +- dApp 通过 RPC 查询状态,以使用链上数据渲染 UI、准备和模拟交易、获取日志和事件等。 +- 浏览器、索引器和机器人全部依赖 RPC 获取实时数据。 -即使底层区块链处理交易的速度极快、出块迅速,如果 RPC 响应缓慢、延迟高,用户的整体体验仍将受到影响。事实上,在现实使用中,RPC 常常成为链上体验的性能瓶颈。 +即使区块链能够以闪电般的速度处理交易并快速生成区块,如果用户由于 RPC 速度慢而遇到延迟和卡顿,这一切都将毫无意义。实际上,RPC 往往是整体用户体验中的瓶颈。 -因此,Stable 的高性能区块链路线图中将 **优化RPC架构** 明确作为优先任务。 +Stable 的高性能链路线图明确将 **RPC 优化** 作为一个首要任务。 -## 传统 RPC 架构的弊端 +## 传统 RPC 架构的问题 -### 单一的架构设计与资源争用 +### 单体设计和资源争用 Traditional RPC Architecture -传统上,RPC 节点通常是功能扩展的全节点,它们同时负责: +传统上,RPC 节点只是一个经过改造的全节点,暴露了额外的 RPC 端点。这意味着: -- 在同一时间处理区块链的同步与RPC请求; -- 若要扩展 RPC 能力,只能新增完整节点,导致必须重复执行状态同步、共识配置等繁重流程; -- 共识、执行与 RPC 服务共用同一 CPU、内存与磁盘资源。一旦某一部分高负载,**将会拖慢其他模块的性能**,例如在交易高峰期,RPC 延迟大幅上升。 +- 链同步和处理 RPC 请求发生在同一个实例上。 +- 为了扩展 RPC,团队必须启动全新的全节点,从而触发耗费资源的操作,例如状态同步和共识设置。 +- 共识、执行和 RPC 都共享相同的 CPU、内存和磁盘。在交易负载较高期间,繁忙的组件会**饿死其他组件**,从而降低 RPC 性能。 -此外,传统架构通常并不区分读取与写入请求的处理方式。即使读取请求(如 `eth_getBalance`)在调用量上远超写入交易,两者仍在同一逻辑结构中混合处理,造成系统整体效率低下、可扩展性差。 +此外,传统 RPC 架构对读密集型和写密集型操作的处理方式相同。尽管读查询(例如 `eth_getBalance`)在数量上远远超过写事务,但它们在处理方式上没有区别。这种设计本质上是低效且不可扩展的。 -## Stable 的 RPC 架构 +## Stable RPC 架构 -Stable 提出了 **路径分离(Split-Path)RPC 架构**,将读取与写入操作分离,并分别进行独立优化。 +Stable 引入了一种分路 RPC 架构,将读写操作分离并独立优化。 Stable RPC Architecture ### 核心原则 -- 将 RPC 按功能拆分为多个轻量高效的节点; -- 使用轻量级 RPC 边缘节点进行扩展,以提升系统可扩展性; -- 根据不同功能优化路径,通过更高效的数据结构来减少请求延迟,实现更直接的链上数据访问或管理。 +- 根据功能将 RPC 分离为高效的轻量级 RPC 节点。 +- 使用轻量级 RPC 作为边缘节点,以增强可扩展性。 +- 优化特定功能 RPC 的数据路径,以减少延迟,提供更直接的访问或通过更高效的数据结构进行管理。 ### 性能提升 -在读取路径下,Stable 的内部测试结果显示: +新读 RPC 路径的内部基准测试表明: -- 单节点吞吐量超 **10,000 次/秒(RPS)**; -- 同一环境下,端到端延迟 **低于 100ms**; -- 边缘节点支持线性扩展,**无需状态同步或共识负担**。 +- 在相同环境下,支持超过 10,000 RPS 的吞吐量,端到端延迟低于 100 毫秒。 +- 边缘节点线性可扩展,无需全状态同步或共识开销。 -Stable 的新型 RPC 架构在高流量场景下仍可维持流畅、迅捷的用户交互体验。 +Stable 的新 RPC 架构即使在高流量事件期间也能带来显着更流畅、更快的用户体验。 -## 未来工作方向 +## 未来工作 -### 优化 EVM View 查询 +### 优化 EVM 视图调用 -一个备受关注的研究方向是:**为 `eth_call` 等 EVM 只读操作提供专有支持**: +一项令人兴奋的持续研究领域是专门支持 EVM 视图操作 (`eth_call`): -- 此类调用不涉及状态更新或交易确认; -- 可在轻量、无状态的运行环境中执行,只需当前状态快照; -- 未来可设计专门针对 `eth_call` 的 RPC 节点,进一步降低响应时间,同时减轻主节点负担。 +- 这些操作不需要事务提交或状态更新。 +- 执行可以在轻量级无状态环境中进行,仅使用当前状态快照。 +- 可以专门为这些操作设计一个专门的 RPC 节点,从而提供更快的响应时间并减轻主全节点的负载。 -### 全节点原生集成 Indexer +### 将索引器直接集成到节点中 -通过将索引器(Indexer)原生集成至全节点,可以显著加快向 DApps 提供数据的速度: +通过将索引器直接集成到节点中,可以向 dApp 提供最快的数据。 -- 当前架构:Node → RPC → Indexer(如 The Graph)→ 存储 → DApp; -- 提议架构:集成 Indexer 的 Node → 数据库 → DApp; -- 由于省略了额外的网络通信步骤,索引数据可被原生调用,大幅提升查询效率与实时性。 +- 典型架构:节点 → RPC → 索引器(例如 The Graph)→ 存储 → dApp +- 建议架构:带有索引器的节点 → 数据库 → dApp +- 这种架构可以实现更快的数据传输,因为索引器原生集成到节点中,从而消除了网络通信步骤。 + +## 下一步建议 + +- [**JSON-RPC API**](/cn/reference/json-rpc-api):使用 Stable 暴露的 `eth_*` 方法进行合约读取、事务提交和日志过滤。 +- [**执行**](/cn/explanation/execution):了解执行如何向 RPC 层提供状态。 +- [**存储 (StableDB)**](/cn/explanation/stable-db):查看 RPC 读取查询的存储层。 diff --git a/docs/pages/cn/explanation/integrate-overview.mdx b/docs/pages/cn/explanation/integrate-overview.mdx index 81fb043..7be9b22 100644 --- a/docs/pages/cn/explanation/integrate-overview.mdx +++ b/docs/pages/cn/explanation/integrate-overview.mdx @@ -1,34 +1,34 @@ --- source_path: explanation/integrate-overview.mdx -source_sha: d27d65208399664dc2a63d2133789c860d4bd32f +source_sha: 9dd60bd0150dd9582e3cfb0bba0a72469b34a1bc title: "概览" -description: "在以 USDT 为原生代币的 Layer 1 上连接 Stable、发送 USDT0 并构建支付流程所需的一切。" +description: "连接到 Stable、发送 USDT0 并在 USDT 原生 Layer 1 上构建支付流所需的一切。" diataxis: "explanation" --- # 概览 -Stable 是一条兼容 EVM 的 Layer 1 区块链,其中 USDT0 是原生 gas 代币。大多数以太坊工具、库和合约模式无需修改即可使用。你只需将 RPC 指向 Stable 并切换 chain ID 即可连接。 +Stable 是一个与 EVM 兼容的 Layer 1,其中 USDT0 是原生的 gas 代币。大多数以太坊工具、库和合约模式无需修改即可工作。您只需将 RPC 指向 Stable 并切换链 ID 即可连接。 -## 连接与充值 +## 连接和充值 -- [**连接**](/cn/reference/connect) — 主网和测试网 chain ID、RPC 端点、区块浏览器。 -- [**为你的测试网钱包充值**](/cn/how-to/use-faucet) — 通过水龙头获取测试网 USDT0,或从 Sepolia 跨链桥接。 -- [**Stable SDK**](/cn/explanation/sdk-overview) — 使用类型化的 TypeScript 客户端进行转账、桥接和兑换。 +- [**连接**](/cn/reference/connect):主网和测试网链 ID、RPC 端点、区块浏览器。 +- [**为您的测试网钱包充值**](/cn/how-to/use-faucet):通过水龙头或从 Sepolia 桥接获取测试网 USDT0。 +- [**Stable SDK**](/cn/explanation/sdk-overview):使用类型化的 TypeScript 客户端进行转账、桥接和兑换。 -## 使用 USDT0 构建 +## 使用 USDT0 进行构建 -- [**发送你的第一笔 USDT0**](/cn/tutorial/send-usdt0) — 原生和 ERC-20 转账的 TypeScript 示例。 -- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior) — 双角色余额对账、合约设计要求、迁移清单。 -- [**与以太坊的差异**](/cn/explanation/ethereum-comparison) — 单槽最终性、USDT0 gas、无优先费小费。 -- [**零 gas 交易**](/cn/how-to/integrate-gas-waiver) — 通过 Waiver Server API 集成 Gas Waiver。 +- [**发送您的第一笔 USDT0**](/cn/tutorial/send-usdt0):使用 TypeScript 示例进行原生和 ERC-20 转账。 +- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior):双重角色余额核对、合约设计要求、迁移清单。 +- [**与以太坊的区别**](/cn/explanation/ethereum-comparison):单槽最终性、USDT0 gas、无优先小费。 +- [**零 Gas 交易**](/cn/how-to/integrate-gas-waiver):通过 Waiver Server API 集成 Gas Waiver。 ## 支付 -- [**ERC-3009**](/cn/explanation/erc-3009) — 带授权的转账:链上结算原语。 -- [**x402**](/cn/explanation/x402) — HTTP 原生支付,无需账户或 API 密钥。 -- [**P2P 支付**](/cn/reference/p2p-payments) — 原生和 ERC-3009 委托转账。 +- [**ERC-3009**](/cn/explanation/erc-3009):带授权的转账:链上结算原语。 +- [**x402**](/cn/explanation/x402):无需账户或 API 密钥的 HTTP 原生支付。 +- [**P2P 支付**](/cn/reference/p2p-payments):原生和 ERC-3009 委托转账。 ## 生态系统 -各类提供商和基础设施已在 Stable 上运行:跨链桥、[官方 Uniswap v3 部署](/cn/reference/dexes)、预言机、RPC、钱包、托管等等。浏览[生态系统](/cn/reference/bridges)章节查看完整列表。 +已在 Stable 上运行的提供商和基础设施:桥、[规范的 Uniswap v3 部署](/cn/reference/dexes)、预言机、RPC、钱包、托管等等。浏览[生态系统](/cn/reference/bridges)部分获取完整列表。 diff --git a/docs/pages/cn/explanation/key-features.mdx b/docs/pages/cn/explanation/key-features.mdx index b320642..68f7b05 100755 --- a/docs/pages/cn/explanation/key-features.mdx +++ b/docs/pages/cn/explanation/key-features.mdx @@ -1,21 +1,36 @@ --- source_path: explanation/key-features.mdx -source_sha: ec20a9f726140707f7ebd0cb56b921b3fc4e26b2 -title: '核心功能' -description: "Stable 区块链的核心技术特性:EVM 兼容、dPoS 共识、亚秒级最终性与 USDT 原生设计。" +source_sha: 743dbe77cee418846f01652fecf871c2ab504539 +title: '主要功能' +description: "Stable 的主要技术规格(单槽确定性、USDT0 作为燃料、完全 EVM 兼容性)以及在此基础上构建的 USDT 特有功能。" +diataxis: "explanation" --- -# 核心功能 +# 主要功能 -Stable 是一条高性能区块链,专为支持 USDT 相关活动而设计。基于 **委托权益证明(dPoS)** 机制构建,Stable 实现了 **完全兼容 EVM**,并达成 **亚秒级出块时间**,确保交易快速可靠地达成最终性。作为一个 **专注于 USDT 的网络**,Stable 提供了一系列优化用户体验的 USDT 专属功能。 +Stable 是一个委托权益证明 Layer 1,具有单槽最终性、完全 EVM 兼容性,并以 USDT0 作为原生 gas 代币。以下功能决定了日常集成。每个功能都链接到详细介绍它的页面。 -主要功能包括: +## 协议级功能 -- **亚秒级交易最终性**:实现亚秒级出块和单轮次最终确认 -- **100% EVM 兼容性**:支持所有 Ethereum 工具和智能合约 -- **USDT 作为 Gas 代币**:USDT0 作为其原生 Gas 代币。USDT0 同时作为用于支付 Gas 和进行价值转移的原生资产,并作为支持 `approve`、`transfer`、`transferFrom` 和 `permit` 的 ERC20 代币。 -- **USDT0 跨链转移**:支持从包括 Ethereum、Arbitrum、HyperEVM 等 EVM 区块链,以及 Tron 等其他区块链通过跨链桥转移 USDT0 -- **Stable Pay 提供 Web2.5 用户体验**:通过 Stable Pay 实现无缝的链上交互体验 +| 功能 | 含义 | +| :--- | :--- | +| **单槽确定性** | 交易一旦进入区块即为最终确认。无需多区块确认等待。 | +| **完全 EVM 兼容性** | Solidity、Vyper、Foundry、Hardhat、ethers、viem 和 `eth_*` RPC 方法无需更改即可工作。 | +| **USDT0 作为燃料** | 同一资产既是原生余额又是 ERC-20 代币。无需持有单独的 gas 代币。 | +| **跨链桥接** | USDT0 通过 LayerZero OFT 从 Ethereum、Arbitrum、HyperEVM、Tron 和其他链移动到 Stable。 | -未来,Stable 还将推出更多功能,以进一步提升 USDT 的可用性和网络效率。其中包括 **USDT Transfer Aggregator(USDT 转账聚合器)**,可将多个 USDT 转账打包为单一交易以提升处理效率;以及 **企业专用区块空间 Enterprise Blockspace**,为机构用户提供可预测、稳定的 USDT 使用环境。 +## USDT 特有功能 +- [**USDT 作为燃料**](/cn/explanation/usdt-as-gas-token):USDT0 在同一余额中既作为原生 gas 代币又作为 ERC-20 代币。 +- [**Gas 豁免**](/cn/explanation/gas-waiver):治理授权的豁免提交包装器交易,以零 gas 价格代表用户执行。 +- [**保证区块空间**](/cn/explanation/guaranteed-blockspace):企业合作伙伴为支付流在每个区块中确保预留容量。 +- [**USDT 转账聚合器**](/cn/explanation/usdt-transfer-aggregator):大容量 USDT0 转账批量处理成并行化、容错的结算捆绑。 +- [**私密转账**](/cn/explanation/confidential-transfer):零知识密码学屏蔽转账金额,同时保持参与方可审计。 + +有关当前已上线和路线图上的升级,请参阅[路线图](/cn/explanation/technical-roadmap)。 + +## 下一步建议 + +- [**以太坊比较**](/cn/explanation/ethereum-comparison):识别将 DApp 从以太坊移植到 Stable 时保持不变和发生变化的地方。 +- [**资金流向**](/cn/explanation/flow-of-funds):追踪 USDT 从充值到链上转账再到提现结算。 +- [**架构概览**](/cn/explanation/core-optimization-overview):了解提供这些功能的共识、执行、数据库和 RPC 层。 diff --git a/docs/pages/cn/explanation/learn-overview.mdx b/docs/pages/cn/explanation/learn-overview.mdx index b323ae2..fc3e380 100644 --- a/docs/pages/cn/explanation/learn-overview.mdx +++ b/docs/pages/cn/explanation/learn-overview.mdx @@ -1,8 +1,8 @@ --- source_path: explanation/learn-overview.mdx -source_sha: 67ee178c4a5e4a4fbf9902ff3c40a022a75818eb +source_sha: a3bae707c2afb7477e50291b1b1311296a75a208 title: "学习" -description: "Stable 的概念、架构和用例叙述。它是什么、与以太坊有何不同,以及 USDT0 作为 gas 背后的思维模型。" +description: "Stable 的概念、架构和用例叙述。它是什么,它与以太坊有何不同,以及 USDT0 作为 gas 背后的心智模型。" diataxis: "explanation" --- @@ -10,28 +10,28 @@ diataxis: "explanation" ## 基础 -- [**概览**](/cn/explanation/overview) — Stable 是什么,以及如何阅读本文档。 -- [**核心特性**](/cn/explanation/key-features) — 关键规格:单槽最终性、USDT0 作为 gas、完全 EVM 兼容。 -- [**与以太坊的区别**](/cn/explanation/ethereum-comparison) — 从以太坊移植时,哪些保持不变,哪些会发生变化。 -- [**核心概念**](/cn/explanation/core-concepts) — USDT0 的双重角色、有保障的区块空间、转账聚合器、最终性。 +- [**概览**](/cn/explanation/overview):Stable 是什么以及如何阅读本文档。 +- [**主要特性**](/cn/explanation/key-features):主要规格:单槽终结,USDT0 作为 gas,完全 EVM 兼容。 +- [**与以太坊的区别**](/cn/explanation/ethereum-comparison):从以太坊移植时,哪些保持不变,哪些会改变。 +- [**核心概念**](/cn/explanation/core-concepts):USDT0 双重角色,保证的区块空间,转账聚合器,终结性。 ## USDT0 行为 -- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior) — 双重角色余额、对账事件以及合约设计规则。 -- [**USDT 作为 gas**](/cn/explanation/usdt-as-gas-token) — Stable 为何使用 USDT0 支付 gas,以及这对费用意味着什么。 -- [**资金流转**](/cn/explanation/flow-of-funds) — USDT 在 Stable 上端到端的流动方式。 -- [**USDT0 特性**](/cn/explanation/usdt-features-overview) — 每一项 USDT0 专属特性及其链接。 +- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior):双重角色余额、调节事件和合约设计规则。 +- [**USDT 作为 Gas**](/cn/explanation/usdt-as-gas-token):Stable 为什么使用 USDT0 支付 Gas 以及这对费用意味着什么。 +- [**资金流向**](/cn/explanation/flow-of-funds):USDT 如何在 Stable 上进行端到端转移。 +- [**USDT0 特性**](/cn/explanation/usdt-features-overview):每个 USDT0 特有的特性,附带链接。 ## 架构 -- [**技术概览**](/cn/explanation/tech-overview) — 在一个页面中介绍共识、执行、数据库和 RPC 各层。 -- [**核心优化**](/cn/explanation/core-optimization-overview) — 实现亚秒级最终性背后的性能工作。 -- [**最终性**](/cn/explanation/finality) — 单槽最终性、重组行为,以及"已确认"的含义。 -- [**Gas 定价**](/cn/explanation/gas-pricing) — 以 USDT0 计价的仅基础费用模型。 +- [**技术概览**](/cn/explanation/tech-overview):共识、执行、数据库和 RPC 层都在一页中。 +- [**核心优化**](/cn/explanation/core-optimization-overview):亚秒级终结性背后的性能工作。 +- [**终结性**](/cn/explanation/finality):单槽终结性、重组行为以及“已确认”的含义。 +- [**Gas 定价**](/cn/explanation/gas-pricing):仅基于基础费用的模型,以 USDT0 计价。 ## 用例叙述 -- [**支付**](/cn/explanation/use-case-payments) — Stable 为何适合 P2P、订阅、发票和按次付费。 -- [**薪资发放**](/cn/explanation/use-case-payroll) — 在 Stable 上批量和定时执行薪资发放。 -- [**代付交易**](/cn/explanation/use-case-sponsored) — 让应用为其用户承担 gas。 -- [**私密转账**](/cn/explanation/use-case-private) — 即将推出的保密支付流程。 +- [**支付**](/cn/explanation/use-case-payments):为什么 Stable 适合 P2P、订阅、发票和按次付费。 +- [**薪资**](/cn/explanation/use-case-payroll):在 Stable 上进行批量和定期薪资运行。 +- [**赞助交易**](/cn/explanation/use-case-sponsored):允许应用程序为其用户支付 Gas。 +- [**私密转账**](/cn/explanation/use-case-private):即将推出的保密支付流程。 diff --git a/docs/pages/cn/explanation/mpp-sessions.mdx b/docs/pages/cn/explanation/mpp-sessions.mdx index 483a491..afb488a 100644 --- a/docs/pages/cn/explanation/mpp-sessions.mdx +++ b/docs/pages/cn/explanation/mpp-sessions.mdx @@ -1,49 +1,49 @@ --- source_path: explanation/mpp-sessions.mdx -source_sha: 872aae7c355e2b4c4bcc1af096a3aafd94b6c629 +source_sha: 6f43e7cd526e4569c47f211fd30a611e3f3cbd50 title: "MPP 会话" -description: "通过链下凭证流式传输微支付并进行一次净额结算,而不是每个请求都进行一次链上支付。" +description: "通过链下凭证和一次性净结算,而非每个请求一次链上支付,实现微支付流。" diataxis: "explanation" --- # MPP 会话 -会话是一种 MPP 支付意图,它将许多小额支付批量合并为单笔链上结算。客户端只需向托管合约存入一次资金,然后为每个请求签署廉价的链下凭证。只有净额会在链上结算,这使得流式工作负载中每个请求的亚分级经济模型成为可能。 +会话(Session)是一种 MPP 支付意图,它将许多小额支付批量处理为一次链上结算。客户端一次性将资金存入托管账户,然后为每个请求签署便宜的链下凭证。只有净额在链上结算,这使得按请求计费的次级货币经济对于流式工作负载来说是可行的。 ## 会话的工作原理 -1. **存款。** 客户端将预算转入结算层上的会话托管合约。托管合约持有资金,并暴露一个结算函数,用于向卖方付款并退还剩余部分。 -2. **每个请求一个凭证。** 对于每个付费请求,客户端签署一个携带 `(sessionId, cumulativeAmount, nonce, expiry)` 的链下凭证。服务器会检查累计金额是否单调递增且在存入余额范围内。此步骤无需任何链上操作。 -3. **结算。** 在会话结束时或按配置的节奏,协调者将最新的凭证提交给托管合约。托管合约向卖方支付累计金额,并将剩余余额返还给客户端。只有这笔交易会触及链上。 +1. **存款。** 客户端将预算转入结算层上的会话托管合约。托管账户持有资金并公开一个结算函数,用于支付给卖家并退还剩余资金。 +2. **每个请求一个凭证。** 对于每个已支付的请求,客户端签署一个链下凭证,其中包含 `(sessionId, cumulativeAmount, nonce, expiry)`。服务器检查累积金额是否单调递增且在存款余额范围内。此步骤无需链上操作。 +3. **结算。** 在会话结束时或在配置的周期内,协调人将最新的凭证提交给托管账户。托管账户向卖家支付累积金额,并将剩余余额退还给客户端。只有此交易触及链。 -当最新凭证被结算或凭证过期时,会话即告完成。 +当最新的凭证结算完毕或凭证过期时,会话即告结束。 -## 何时使用会话还是单次扣费 +## 何时使用会话与扣款 | **工作负载** | **最佳意图** | | :--- | :--- | -| 按 token 计费的 LLM 推理、按帧计费的视频、实时数据流。向同一卖方进行的许多小额支付。 | 会话 | -| 一次性付费 API 调用、单次购买资源、每笔交易独立的代理间商务。 | 单次扣费 | +| 按令牌计费的 LLM 推理、按帧计费的视频、实时数据流。向同一卖家进行多次小额支付。 | 会话 | +| 一次性付费 API 调用、单次购买资源、代理到代理的商业,其中每个交易都是独立的。 | 扣款 | -盈亏平衡点取决于每个请求的链上结算相对于请求价格的昂贵程度。一旦你在 gas 上支付的费用超过了支付本身,会话就是正确的模式。 +盈亏平衡点取决于每个请求的链上结算成本相对于请求价格的昂贵程度。一旦您支付的 Gas 费高于支付金额,会话就是正确的模式。 -## 代理使用场景 +## 代理用例 -- **按 token 计费的 LLM 推理。** 客户端流式接收补全内容,并为每批 token 签署一个凭证;推理服务器在会话结束时结算。 -- **按帧计费的视频。** 消费生成视频的代理为每 N 帧签署凭证;渲染器在流关闭时结算。 -- **实时数据源。** 订阅者为预言机或市场数据流的每个 tick 付费,每个会话窗口结算一次。 +- **按令牌计费的 LLM 推理。** 客户端流式传输完成内容,并为每批令牌签署凭证;推理服务器在会话结束时结算。 +- **按帧计费的视频。** 消费生成视频的代理为每 N 帧签署凭证;渲染器在流关闭时结算。 +- **实时数据馈送。** 订阅者根据预言机或市场数据流的每次跳动支付费用,每个会话窗口结算一次。 -## 在 Stable 上的状态 +## Stable 上的状态 -会话需要两个 Stable 目前尚未提供的组件: +会话需要 Stable 目前不提供的两个部分: -1. 一个面向 USDT0 的会话感知托管合约,用于持有存款并暴露 `settleVouchers`(或等效)函数。 -2. 一个协调者,在卖方侧签发凭证并在买方侧进行验证,将提交批量发送给托管合约。 +1. 一个支持会话的 USDT0 托管合约,用于持有存款并公开一个 `settleVouchers`(或等效)函数。 +2. 一个协调人,负责在卖家端签发凭证并在买家端验证凭证,并将提交批量发送到托管账户。 -在两者都上线之前,MPP 会话在 Stable 上还无法使用。对于当今的高频代理支付,开销最低的模式是通过 Stable 的 [Gas 减免](/cn/how-to/integrate-gas-waiver) 提交的 **单次扣费** 意图,它消除了卖方侧的每笔交易 gas 成本,并使买方的 USDT0 余额成为唯一需要管理的资产。请参阅 [在 Stable 上构建 MPP 端点](/cn/how-to/build-mpp-endpoint) 了解每个请求的单次扣费模式。 +在两者都发布之前,MPP 会话无法在 Stable 上使用。对于目前高频的代理支付,开销最低的模式是通过 Stable 的 [Gas 豁免](/cn/how-to/integrate-gas-waiver)提交的**扣款**意图,该意图取消了卖家方的每笔交易 Gas 成本,并将买家的 USDT0 余额作为唯一需要管理的资产。有关每个请求扣款模式,请参阅[在 Stable 上构建 MPP 端点](/cn/how-to/build-mpp-endpoint)。 -## 下一步推荐 +## 下一步建议 -- [**MPP 概念**](/cn/explanation/mpp) — 阅读更广泛的标准,包括单次扣费和订阅意图。 -- [**代理结算**](/cn/explanation/agent-settlement) — 了解 MPP 会话在 Stable 代理支付通道中的位置。 -- [**在 Stable 上构建 MPP 端点**](/cn/how-to/build-mpp-endpoint) — 在会话功能尚未到来之前,今天就使用单次扣费意图。 +- [**MPP 概念**](/cn/explanation/mpp):阅读更广泛的标准,包括扣款和订阅意图。 +- [**代理结算**](/cn/explanation/agent-settlement):了解 MPP 会话在 Stable 上的代理支付轨道中的位置。 +- [**在 Stable 上构建 MPP 端点**](/cn/how-to/build-mpp-endpoint):在会话即将推出时,立即使用扣款意图。 diff --git a/docs/pages/cn/explanation/mpp.mdx b/docs/pages/cn/explanation/mpp.mdx index 44edbb7..a6794aa 100644 --- a/docs/pages/cn/explanation/mpp.mdx +++ b/docs/pages/cn/explanation/mpp.mdx @@ -1,63 +1,63 @@ --- source_path: explanation/mpp.mdx -source_sha: 9aafb5fd6791e2d6d14b6cb938ce94878b0e27a1 -title: "Machine Payments Protocol (MPP)" -description: "了解 MPP——这一扩展 x402 的 IETF 标准跟踪支付规范,以及如何用它在 Stable 上进行 USDT0 支付。" +source_sha: 02666af168909bb96414ce0c52d158b4af376522 +title: "机器支付协议 (MPP)" +description: "了解 MPP,这是一个扩展 x402 的 IETF-track 支付标准,以及如何在 Stable 上使用它进行 USDT0 支付。" diataxis: "explanation" --- -# Machine Payments Protocol (MPP) +# 机器支付协议 (MPP) -MPP(Machine Payments Protocol,机器支付协议)是一个开放标准,用于在请求 HTTP 资源的同一请求中完成对该资源的付款。它扩展了 [x402](/cn/explanation/x402),新增了支付意图(charge、subscription、session)、多通道支持(稳定币、银行卡、Lightning)、生产特性(幂等性、正文摘要绑定、过期机制)以及额外的传输方式(MCP、WebSocket)。该协议处于 IETF 标准跟踪进程中。 +MPP(机器支付协议)是一个开放标准,用于在请求 HTTP 资源的同时支付这些资源。它通过新的支付意图(收费、订阅、会话)、多轨道支持(稳定币、银行卡、闪电网络)、生产功能(幂等性、主体摘要绑定、过期)和附加传输(MCP、WebSocket)扩展了 [x402](/cn/explanation/x402)。该协议正在 IETF 标准化进程中。 -## MPP 与 x402 +## MPP 和 x402 -MPP 客户端向后兼容:MPP 客户端无需任何更改即可调用现有的 x402 服务器。两种协议的差异之处: +MPP 客户端是向后兼容的:MPP 客户端可以在不更改的情况下调用现有的 x402 服务器。两种协议的区别在于: | **方面** | **x402** | **MPP** | | :--- | :--- | :--- | -| 支付意图 | 按请求收费 | Charge、subscription、session | -| 通道 | 仅区块链 | 稳定币、银行卡、Lightning、自定义 | -| 生产特性 | 有限 | 幂等性、正文摘要绑定、过期机制 | -| 传输方式 | HTTP | HTTP、MCP/JSON-RPC、WebSocket | +| 支付意图 | 按请求收费 | 收费、订阅、会话 | +| 轨道 | 仅区块链 | 稳定币、银行卡、闪电网络、自定义 | +| 生产功能 | 有限 | 幂等性、主体摘要绑定、过期 | +| 传输 | HTTP | HTTP、MCP/JSON-RPC、WebSocket | | 标头(客户端 ↔ 服务器) | `PAYMENT-REQUIRED` / `PAYMENT-SIGNATURE` / `PAYMENT-RESPONSE` | `WWW-Authenticate` / `Authorization` / `Payment-Receipt` | -| 治理 | 社区协议 | IETF 标准跟踪 | -| 方法编写权 | 由基金会控制 | 无需许可 | +| 治理 | 社区协议 | IETF 标准化进程 | +| 方法编写 | 基金会控制 | 无需许可 | ## 挑战、凭证、收据 -MPP 将每个付费请求封装成客户端与资源服务器之间的三步交换: +MPP 将每个付费请求封装在客户端和资源服务器之间的三步交换中: -1. **挑战(Challenge)。** 服务器返回 `402 Payment Required` 以及一个 `WWW-Authenticate` 标头,其中列出所支持的方法、金额和过期时间。 -2. **凭证(Credential)。** 客户端选择一种方法,对支付凭证进行签名,并附带一个携带序列化凭证的 `Authorization` 标头重新提交请求。 -3. **收据(Receipt)。** 服务器验证凭证、结算付款,并在响应中返回一个包含结算引用的 `Payment-Receipt` 标头。 +1. **挑战。** 服务器响应 `402 Payment Required` 和一个 `WWW-Authenticate` 标头,其中包含支持的方法、金额和过期时间。 +2. **凭证。** 客户端选择一个方法,签署支付证明,并使用包含序列化凭证的 `Authorization` 标头重新提交请求。 +3. **收据。** 服务器验证凭证,结算支付,并返回响应,其中包含一个 `Payment-Receipt` 标头,其中包含结算参考。 -挑战可以通过正文摘要在密码学上绑定到请求正文,因此为某个请求签名的凭证无法在另一个不同的请求上重用。 +一个挑战可以通过主体摘要与请求主体进行加密绑定,因此为T一个请求签署的凭证不能在另一个请求中重复使用。 ## 支付意图 -**Charge(收费)。** 针对单个资源的一次性付款。凭证授权一次精确金额的转账。 +**收费。** 对单个资源进行一次性支付。凭证授权一次精确金额的转账。 -**Subscription(订阅)。** 在单个受限范围凭证下的周期性付款。凭证授权在一个计费周期内重复收费,由通道强制执行续订节奏。 +**订阅。** 在单个范围凭证下进行定期支付。凭证授权在计费周期内重复收费,由轨道强制执行续订周期。 -**Session(会话)。** 使用链下凭单的按量付费。客户端先将资金存入托管一次,然后为每个请求签名低成本的链下凭单。只有净额在链上结算。详见 [MPP 会话](/cn/explanation/mpp-sessions)。 +**会话。** 通过链下凭证按使用量付费。客户端将资金一次性存入托管,然后为每个请求签署廉价的链下凭证。只有净金额在链上结算。有关详细信息,请参阅 [MPP 会话](/cn/explanation/mpp-sessions)。 -## 传输方式 +## 传输 -MPP 在多种传输方式上定义了相同的挑战 / 凭证 / 收据交换: +MPP 定义了通过多种传输的相同挑战/凭证/收据交换: -- **HTTP。** 默认方式。标头如上所列。 -- **MCP / JSON-RPC。** 让 MCP 服务器能够对单个工具调用进行变现。AI 客户端在调用工具前签名一份凭证。 -- **WebSocket。** 持久连接,支持带内凭单充值,专为流式会话设计。 +- **HTTP。** 默认。标头如上所示。 +- **MCP / JSON-RPC。** 允许 MCP 服务器通过单个工具调用实现货币化。AI 客户端在调用工具之前签署凭证。 +- **WebSocket。** 具有带内凭证充值的持久连接,专为流媒体会话设计。 ## Stable 上的 MPP -MPP 并未自带 Stable 支付方法。`mppx` SDK([wevm/mppx](https://github.com/wevm/mppx))包含针对 Tempo 和 Stripe 的方法,而 `mpp.dev` 列出了 Tempo、Stripe、Lightning、Solana、Stellar、Monad 和 RedotPay。目前这两个列表中都没有 Stable。 +MPP 不附带 Stable 支付方法。`mppx` SDK ([wevm/mppx](https://github.com/wevm/mppx)) 包含 Tempo 和 Stripe 的方法,而 `mpp.dev` 列出了 Tempo、Stripe、Lightning、Solana、Stellar、Monad 和 RedotPay。今天 Stable 不在这两个列表上。 -该标准无需许可,因此你可以编写自己的方法。对于 Stable 上的 USDT0,`verify()` 钩子是针对 ERC-3009 的签名验证,结算则委托给现有的结算服务:诸如 [Semantic Pay](https://docs.semanticpay.io) 或 [Heurist](https://docs.heurist.ai/x402-products/facilitator) 这样的 x402 facilitator,或 Stable 自有的 [Gas 豁免](/cn/how-to/integrate-gas-waiver)。完整演练请参阅 [在 Stable 上构建 MPP 端点](/cn/how-to/build-mpp-endpoint)。 +该标准是无需许可的,因此您可以编写自己的方法。对于 Stable 上的 USDT0,`verify()` 钩子是针对 ERC-3009 的签名验证,结算委托给现有的结算服务:一个像 [Semantic Pay](https://docs.semanticpay.io) 或 [Heurist](https://docs.heurist.ai/x402-products/facilitator) 这样的 x402 协调器,或者 Stable 自己的 [Gas Waiver](/cn/how-to/integrate-gas-waiver)。请参阅 [在 Stable 上构建 MPP 端点](/cn/how-to/build-mpp-endpoint) 以获取完整的演练。 -## 推荐后续 +## 推荐阅读 -- [**在 Stable 上构建 MPP 端点**](/cn/how-to/build-mpp-endpoint) — 为 USDT0 编写三个 MPP 自定义方法钩子并结算一笔真实付款。 -- [**MPP 会话**](/cn/explanation/mpp-sessions) — 使用链下凭单进行微支付流式传输,并一次性净额结算。 -- [**x402**](/cn/explanation/x402) — 阅读 MPP 所泛化的原始 HTTP-402 协议。 +- [**在 Stable 上构建 MPP 端点**](/cn/how-to/build-mpp-endpoint):为 USDT0 编写三个 MPP 自定义方法钩子,并结算真实的支付。 +- [**MPP 会话**](/cn/explanation/mpp-sessions):通过链下凭证和一次净结算流式传输微支付。 +- [**x402**](/cn/explanation/x402):阅读 MPP 泛化的原始 HTTP-402 协议。 diff --git a/docs/pages/cn/explanation/payment-use-cases-overview.mdx b/docs/pages/cn/explanation/payment-use-cases-overview.mdx index e5ead51..7a3f6ae 100644 --- a/docs/pages/cn/explanation/payment-use-cases-overview.mdx +++ b/docs/pages/cn/explanation/payment-use-cases-overview.mdx @@ -1,31 +1,31 @@ --- source_path: explanation/payment-use-cases-overview.mdx -source_sha: 4318f96f731d9b094368974969e39818ddee3488 +source_sha: bf9607c6c0449af0e3eb7cfc9a817d9c0e9cb9f2 title: "用例概述" -description: "Stable 上的支付模式:P2P 转账、订阅计费、发票结算、按调用付费 API。" +description: "Stable 上的支付模式:P2P 转账、订阅计费、发票结算、按次付费 API。" diataxis: "explanation" --- # 用例概述 -Stable 支持多种支付模式,从简单的钱包到钱包转账,到代理驱动的服务支付。下面的用例涵盖了当今可投入生产的模式。对于即将推出的模式(保证结算、隐私支付、代理间商务),请参阅[即将推出的用例](/cn/explanation/upcoming-use-cases)。 +Stable 支持多种支付模式,从简单的钱包到钱包转账到代理驱动的服务支付。以下用例涵盖了目前已投入生产的模式。对于即将推出的模式(有担保的结算、保密支付、代理到代理的商业交易),请参阅[即将推出的用例](/cn/explanation/upcoming-use-cases)。 ## 实时用例 -- [**P2P 支付**](/cn/reference/p2p-payments) — 钱包到钱包的 USDT0 转账。亚秒级结算,通过 Gas Waiver 实现零 gas。 -- [**订阅计费**](/cn/reference/subscriptions) — 通过 EIP-7702 实现的拉取式定期计费。订阅者授权一次,提供商每个周期收款。 -- [**发票结算**](/cn/reference/invoices) — 使用确定性 nonce 的 B2B 发票支付。链上结算自动关联到发票。 -- [**按调用付费 API**](/cn/reference/pay-per-call) — 通过 x402 中间件实现的按请求 HTTP 支付。无需账户、无需 API 密钥、无需计费周期。 +- [**P2P 支付**](/cn/reference/p2p-payments):钱包到钱包的 USDT0 转账。亚秒级结算,通过 Gas Waiver 实现零 Gas 费。 +- [**订阅计费**](/cn/reference/subscriptions):通过 EIP-7702 实现拉取式循环计费。订阅者授权一次,提供商每个周期收取费用。 +- [**发票结算**](/cn/reference/invoices):通过确定性随机数进行的 B2B 发票支付。链上结算自动关联到发票。 +- [**按次付费 API**](/cn/reference/pay-per-call):通过 x402 中间件实现的每次请求 HTTP 支付。无需账户,无需 API 密钥,无需计费周期。 ## 共享基础 -大多数模式都构建在相同的两个协议之上: +大多数模式都建立在相同的两个协议之上: -- **[ERC-3009](/cn/explanation/erc-3009)**:用于委托结算的签名授权。被发票、按调用付费和 P2P 应用发起的转账使用。 -- **[x402](/cn/explanation/x402)**:基于标准请求头的 HTTP 原生支付。被按调用付费 API 和 MCP 驱动的支付流程使用。 -- **[EIP-7702](/cn/explanation/eip-7702)**:用于定期授权的 EOA 委托。被订阅计费使用。 +- **[ERC-3009](/cn/explanation/erc-3009)**:用于委托结算的签名授权。被发票、按次付费和 P2P 应用程序发起的转账使用。 +- **[x402](/cn/explanation/x402)**:通过标准头部的 HTTP 原生支付。被按次付费 API 和 MCP 驱动的支付流程使用。 +- **[EIP-7702](/cn/explanation/eip-7702)**:用于循环授权的 EOA 委托。被订阅计费使用。 ## 下一步推荐 -- [**ERC-3009**](/cn/explanation/erc-3009) — 从核心结算标准开始。 -- [**即将推出的用例**](/cn/explanation/upcoming-use-cases) — 预览代理间商务、保证结算和隐私支付。 +- [**ERC-3009**](/cn/explanation/erc-3009):从核心结算标准开始。 +- [**即将推出的用例**](/cn/explanation/upcoming-use-cases):预览代理到代理的商业交易、担保结算和保密支付。 diff --git a/docs/pages/cn/explanation/payments-guides.mdx b/docs/pages/cn/explanation/payments-guides.mdx index 0665c2f..39b28af 100644 --- a/docs/pages/cn/explanation/payments-guides.mdx +++ b/docs/pages/cn/explanation/payments-guides.mdx @@ -1,35 +1,35 @@ --- source_path: explanation/payments-guides.mdx -source_sha: 11c29bc514f62bd2d382c961ee76bd928b60daf7 +source_sha: 0454891901e0f1fe522a9dd1a91c5d73fd7519d7 title: "支付指南" -description: "所有支付指南、概念和参考:发送 USDT0、P2P、订阅、发票、按次付费、跨链桥接和零 Gas。" +description: "所有支付指南、概念和参考:发送 USDT0、P2P、订阅、发票、按次付费、桥接和零手续费。" diataxis: "explanation" --- # 支付指南 -“支付”标签下的每个指南、概念和参考,按你想要完成的任务分组。 +支付选项卡下的所有指南、概念和参考,按您要执行的操作分组。 ## 发送和转账 -- [**发送你的第一笔 USDT0**](/cn/tutorial/send-usdt0) — 在同一余额上进行原生和 ERC-20 转账。 -- [**零 Gas 交易**](/cn/how-to/zero-gas-transactions) — 通过 Gas Waiver 支付费用来转账 USDT0。 -- [**将 USDT0 用作 Gas**](/cn/how-to/work-with-usdt-gas) — 正确构造交易:优先小费为 0,`value` 以 USDT0 计。 -- [**将 USDT0 桥接到 Stable**](/cn/tutorial/bridge-usdt0) — 使用 LayerZero OFT 从 Ethereum Sepolia 桥接。 +- [**发送您的第一个 USDT0**](/cn/tutorial/send-usdt0):在同一账户上的原生和 ERC-20 转账。 +- [**零手续费交易**](/cn/how-to/zero-gas-transactions):使用 Gas Waiver 支付的 USDT0 转账。 +- [**使用 USDT0 作为手续费**](/cn/how-to/work-with-usdt-gas):正确构建交易:优先级费用为 0,`value` 为 USDT0。 +- [**将 USDT0 桥接到 Stable**](/cn/tutorial/bridge-usdt0):使用 LayerZero OFT 从 Ethereum Sepolia 桥接。 ## 构建支付流程 -- [**了解 P2P 支付**](/cn/how-to/build-p2p-payments) — 在一个应用中实现钱包 + 发送 + 接收 + 历史记录。 -- [**订阅和收款**](/cn/how-to/subscribe-and-collect) — 通过 EIP-7702 实现基于拉取的循环计费。 -- [**使用发票付款**](/cn/how-to/pay-with-invoice) — 使用带确定性 nonce 的 ERC-3009 进行发票结算。 -- [**构建按次付费 API**](/cn/how-to/build-pay-per-call) — 使用 x402 中间件将 HTTP 端点货币化。 +- [**了解 P2P 支付**](/cn/how-to/build-p2p-payments):钱包 + 发送 + 接收 + 历史记录,全部集成在一个应用程序中。 +- [**订阅和收款**](/cn/how-to/subscribe-and-collect):通过 EIP-7702 实现基于拉取的定期计费。 +- [**使用发票付款**](/cn/how-to/pay-with-invoice):ERC-3009 具有确定性随机数,用于发票结算。 +- [**构建按次付费 API**](/cn/how-to/build-pay-per-call):使用 x402 中间件将 HTTP 端点货币化。 ## 协议和参考 -- [**ERC-3009**](/cn/explanation/erc-3009) — Transfer With Authorization:签名结算原语。 -- [**x402(HTTP 原生支付)**](/cn/explanation/x402) — 服务器返回 402,客户端签名,facilitator 在链上结算。 -- [**P2P 支付参考**](/cn/reference/p2p-payments) — 模型概述以及与传统支付通道的比较。 -- [**订阅参考**](/cn/reference/subscriptions) — 基于拉取的计费模型及其权衡。 -- [**发票参考**](/cn/reference/invoices) — 确定性 nonce 结算模型。 -- [**按次付费参考**](/cn/reference/pay-per-call) — x402 定价和端点发现模型。 -- [**即将推出的用例**](/cn/explanation/upcoming-use-cases) — 保证结算、机密支付、代理对代理。 +- [**ERC-3009**](/cn/explanation/erc-3009):带授权的转账:签名结算原语。 +- [**x402(HTTP 原生支付)**](/cn/explanation/x402):服务器响应 402,客户端签名,协调器在链上结算。 +- [**P2P 支付参考**](/cn/reference/p2p-payments):模型概述以及与传统方式的比较。 +- [**订阅参考**](/cn/reference/subscriptions):基于拉取的计费模型和权衡。 +- [**发票参考**](/cn/reference/invoices):确定性随机数结算模型。 +- [**按次付费参考**](/cn/reference/pay-per-call):x402 定价和端点发现模型。 +- [**即将推出的用例**](/cn/explanation/upcoming-use-cases):保证结算、保密支付、代理间支付。 diff --git a/docs/pages/cn/explanation/payments-overview.mdx b/docs/pages/cn/explanation/payments-overview.mdx index bac4379..79af3a7 100644 --- a/docs/pages/cn/explanation/payments-overview.mdx +++ b/docs/pages/cn/explanation/payments-overview.mdx @@ -1,46 +1,46 @@ --- source_path: explanation/payments-overview.mdx -source_sha: 2fea137885b2c4afe4b47e7f020f28cdf919a044 -title: "Stable 上的支付" -description: "在 Stable 上构建支付流程:P2P 转账、订阅、发票、按次调用 API、零 gas 流程以及跨链桥接。" +source_sha: ca8b4d0fe13257b16803c7c519f2126a47977183 +title: "在 Stable 上支付" +description: "在 Stable 上构建支付流:P2P 转账、订阅、发票、按次计费 API、零 Gas 费用流和桥接。" diataxis: "explanation" --- -# Stable 上的支付 +# 在 Stable 上支付 -Stable 是围绕支付构建的。USDT0 是原生资产,也是 gas 代币,因此结算和手续费共享同一个余额。单槽终局性(single-slot finality)意味着一笔转账可在一秒内完成。ERC-3009、EIP-7702 和 x402 都是原生基元,而非变通方案——你可以用一个签名完成结算、从委托账户中拉取资金,或者无需运行计费系统即可按 HTTP 请求收费。 +Stable 围绕支付构建。USDT0 是原生资产和 Gas 代币,因此结算和费用共享一个余额。单槽最终性意味着转账在不到一秒的时间内清算。ERC-3009、EIP-7702 和 x402 是原生原语,而非权宜之计。您可以凭签名结算,从委托账户中提取,或按 HTTP 请求收费,而无需运行计费堆栈。 -## 你可以构建什么 +## 您可以构建什么 -- **P2P 转账** — 原生 USDT0 转账,21k gas,亚秒级终局性。 -- **订阅** — 基于拉取的周期性计费,使用 EIP-7702 委托。 -- **发票结算** — 使用带确定性 nonce 的 ERC-3009 `transferWithAuthorization`,实现精确对账。 -- **按次调用 API** — 使用 x402 中间件实现按请求的 USDT0 支付;无需 API 密钥,无需注册。 -- **零 gas 用户体验** — 通过 Gas Waiver 服务实现应用赞助的交易。 -- **跨链 USDT0** — 通过 LayerZero OFT 从以太坊及其他网络进行桥接。 +- **P2P 转账**:原生 USDT0 发送,21k Gas 费,亚秒级最终性。 +- **订阅**:通过 EIP-7702 委托实现的拉取式循环计费。 +- **发票结算**:具有确定性 Nonce 的 ERC-3009 `transferWithAuthorization`,用于精确对账。 +- **按次计费 API**:用于按请求支付 USDT0 的 x402 中间件;无需 API 密钥,无需注册。 +- **零 Gas 费用 UX**:通过 Gas Waiver 服务实现应用程序赞助的交易。 +- **跨链 USDT0**:来自以太坊和其他网络的 LayerZero OFT 桥接。 ## Stable 的不同之处 -- **一种资产搞定一切**:发送方无需持有单独的 gas 代币。 -- **原生 ERC-3009**:USDT0 直接实现了 `transferWithAuthorization`,因此支付只需一个签名即可结算,无需 approve 步骤。 -- **确定性终局**:区块在提交的那一刻即为最终状态。无需等待确认。 -- **原生 x402**:facilitator 通过 Gas Waiver 不支付 gas,因此每次请求的结算成本可保持在一美分以下。 +- **一个资产用于所有用途**:发送方无需持有单独的 Gas 代币。 +- **原生 ERC-3009**:USDT0 直接实现 `transferWithAuthorization`,因此支付可通过签名结算,无需批准步骤。 +- **确定性最终性**:区块在提交后立即最终确定。无需等待确认。 +- **原生 x402**:通过 Gas Waiver,促成者无需支付 Gas 费,因此每次请求的结算成本保持在 1 美分以下。 ## 从这里开始 -- [**发送你的第一笔 USDT0**](/cn/tutorial/send-usdt0) — 在同一余额上进行原生和 ERC-20 转账。 -- [**零 gas 交易**](/cn/how-to/zero-gas-transactions) — 通过 Gas Waiver 支付手续费来转账 USDT0。 -- [**学习 P2P 支付**](/cn/how-to/build-p2p-payments) — 从零构建一个钱包 + 发送 + 接收 + 历史记录的应用。 -- [**构建按次调用 API**](/cn/how-to/build-pay-per-call) — 使用 x402 为 HTTP 端点按请求定价。 -- [**Stable SDK**](/cn/explanation/sdk-overview) — 使用类型化客户端,几行代码即可实现转账、桥接和兑换。 +- [**发送您的第一笔 USDT0**](/cn/tutorial/send-usdt0):在同一余额上进行原生和 ERC-20 转账。 +- [**零 Gas 费用交易**](/cn/how-to/zero-gas-transactions):使用 Gas Waiver 支付费用来转账 USDT0。 +- [**学习 P2P 支付**](/cn/how-to/build-p2p-payments):从头开始构建一个钱包 + 发送 + 接收 + 历史应用程序。 +- [**构建按次计费 API**](/cn/how-to/build-pay-per-call):使用 x402 按请求为 HTTP 端点定价。 +- [**Stable SDK**](/cn/explanation/sdk-overview):使用类型化客户端,只需几行代码即可进行转账、桥接和兑换。 -## 支付基元 +## 支付原语 -- [**ERC-3009**](/cn/explanation/erc-3009) — Transfer With Authorization:发票和 x402 背后的结算标准。 -- [**x402(HTTP 原生支付)**](/cn/explanation/x402) — 服务器响应 402,客户端签署 ERC-3009,facilitator 在链上结算。 +- [**ERC-3009**](/cn/explanation/erc-3009):授权转账:发票和 x402 背后的结算标准。 +- [**x402 (HTTP 原生支付)**](/cn/explanation/x402):服务器响应 402,客户端签署 ERC-3009,促成者在链上结算。 -## 接下来推荐 +## 下一步推荐 -- [**支付指南索引**](/cn/explanation/payments-guides) — 支付标签下的所有指南、概念和参考资料。 -- [**订阅与收款**](/cn/how-to/subscribe-and-collect) — 通过 EIP-7702 实现基于拉取的周期性计费。 -- [**使用发票付款**](/cn/how-to/pay-with-invoice) — 使用带确定性 nonce 的 ERC-3009 实现精确对账。 +- [**支付指南索引**](/cn/explanation/payments-guides):“支付”选项卡下的所有指南、概念和参考。 +- [**订阅和收款**](/cn/how-to/subscribe-and-collect):通过 EIP-7702 实现的拉取式循环计费。 +- [**使用发票支付**](/cn/how-to/pay-with-invoice):具有确定性 Nonce 的 ERC-3009,用于精确对账。 diff --git a/docs/pages/cn/explanation/sdk-overview.mdx b/docs/pages/cn/explanation/sdk-overview.mdx index ea1a219..efea774 100644 --- a/docs/pages/cn/explanation/sdk-overview.mdx +++ b/docs/pages/cn/explanation/sdk-overview.mdx @@ -1,14 +1,14 @@ --- source_path: explanation/sdk-overview.mdx -source_sha: db4361dfdc3233c02ea6e871850e34e477964a67 +source_sha: efcb1b7d8aaf0782573a67c4964ac01904c220ae title: "Stable SDK" -description: "使用类型化的 TypeScript SDK,只需几行代码即可转账 USDT0、跨链桥接以及在 Stable 上兑换代币。" +description: "使用类型化的 TypeScript SDK,只需几行代码即可在 Stable 上传输 USDT0、跨链桥接和兑换代币。" diataxis: "explanation" --- # Stable SDK -`@stablechain/sdk` 是 Stable 的官方 TypeScript 客户端。它对 viem 进行了封装,为你最常用的操作提供了精简的类型化 API:转账 USDT0、在链之间桥接以及在 Stable 上兑换代币。路由、授权、小数位数和链切换都已为你处理好。 +`@stablechain/sdk` 是 Stable 官方的 TypeScript 客户端。它封装了 Viem,提供了一个小巧、类型化的 API,用于处理你最常使用的操作:传输 USDT0、在链之间进行桥接以及在 Stable 上兑换代币。路由、授权、小数位和链切换都已为你处理好。 ```ts import { createStable, Network } from "@stablechain/sdk"; @@ -30,31 +30,31 @@ const { txHash } = await stable.transfer({ txHash: 0x8f3a...2d41 ``` -## SDK 的功能 +## SDK 功能 -- **`transfer`** — 在 Stable 上发送原生 USDT0 或任意 ERC-20 代币。Gas 会自动以 USDT0 支付。 -- **`quoteBridge` / `bridge`** — 跨链转账。USDT0 → USDT0 使用 LayerZero,其他情况使用 LI.FI。路由会自动为你选择。 -- **`quoteSwap` / `swap`** — 通过 LI.FI 进行同链代币兑换,内部已处理 ERC-20 授权。 +- **`transfer`**:发送原生 USDT0 或 Stable 上的任何 ERC-20 代币。Gas 费会自动以 USDT0 支付。 +- **`quoteBridge` / `bridge`**:跨链传输。USDT0 → USDT0 使用 LayerZero,其他所有代币使用 LI.FI。系统会自动为你选择路由。 +- **`quoteSwap` / `swap`**:通过 LI.FI 进行同链代币兑换,ERC-20 授权在内部处理。 -该 SDK 以 [`@stablechain/sdk`](https://www.npmjs.com/package/@stablechain/sdk) 发布在 npm 上,并需要 `viem >= 2.0.0` 作为对等依赖。 +SDK 已发布到 npm,名称为 [`@stablechain/sdk`](https://www.npmjs.com/package/@stablechain/sdk),并要求 `viem >= 2.0.0` 作为 peer dependency。 -## 何时使用(以及何时不使用) +## 何时使用(何时不使用) -当你想要一个类型化的、有既定约定的客户端来隐藏路由和授权样板代码时,请使用该 SDK。当你需要直接控制交易构造、自定义 gas 策略,或进行 transfer / bridge / swap 之外的合约调用时,请使用原生 viem 或 ethers。 +当你想要一个类型化、规范化的客户端,并隐藏路由和授权样板文件时,请使用 SDK。当你需要直接控制交易构建、自定义 gas 策略或进行 transfer/bridge/swap 之外的合约调用时,请降级到原始的 Viem 或 Ethers。 :::note -该 SDK 支持使用任何兼容 viem 的签名器进行签名:私钥 `Account`、像 `custom(window.ethereum)` 这样的浏览器 `Transport`,或者预先构建的 `WalletClient`(例如 wagmi 的 `useWalletClient` 返回的那个)。 +SDK 使用任何兼容 Viem 的签名器进行签名:私钥 `Account`、浏览器 `Transport`(如 `custom(window.ethereum)`)或预构建的 `WalletClient`(例如,wagmi 的 `useWalletClient` 返回的客户端)。 ::: ## 从这里开始 -- [**快速开始**](/cn/tutorial/sdk-quickstart) — 安装 SDK 并在测试网上运行你的第一次转账、桥接和兑换。 -- [**SDK 参考**](/cn/reference/sdk) — 每个方法、配置选项、枚举和错误类。 -- [**与 viem 一起使用**](/cn/how-to/sdk-with-viem) — 服务端账户、浏览器钱包,以及自带的 `WalletClient`。 -- [**与 wagmi 一起使用**](/cn/how-to/sdk-with-wagmi) — 使用 `useWalletClient` 和 hooks 将 SDK 接入 React 应用。 +- [**快速入门**](/cn/tutorial/sdk-quickstart):安装 SDK 并在测试网上运行你的首次转账、桥接和兑换。 +- [**SDK 参考**](/cn/reference/sdk):所有方法、配置选项、枚举和错误类。 +- [**与 viem 一起使用**](/cn/how-to/sdk-with-viem):服务器端账户、浏览器钱包以及自带的 `WalletClient`。 +- [**与 wagmi 一起使用**](/cn/how-to/sdk-with-wagmi):使用 `useWalletClient` 和 hooks 将 SDK 连接到 React 应用程序。 -## 推荐的下一步 +## 下一步推荐 -- [**从 npm 安装**](https://www.npmjs.com/package/@stablechain/sdk) — 在 npmjs.com 上查看该包并检查最新版本。 -- [**连接到 Stable**](/cn/reference/connect) — 主网和测试网的链 ID、RPC 端点和浏览器。 -- [**为测试网钱包充值**](/cn/how-to/use-faucet) — 在运行快速开始之前,从水龙头获取测试网 USDT0。 +- [**从 npm 安装**](https://www.npmjs.com/package/@stablechain/sdk):在 npmjs.com 上查看软件包并检查最新版本。 +- [**连接到 Stable**](/cn/reference/connect):主网和测试网的链 ID、RPC 端点和浏览器。 +- [**资助测试网钱包**](/cn/how-to/use-faucet):在运行快速入门之前,从水龙头获取测试网 USDT0。 diff --git a/docs/pages/cn/explanation/stable-db.mdx b/docs/pages/cn/explanation/stable-db.mdx index 042af6a..727d6dc 100755 --- a/docs/pages/cn/explanation/stable-db.mdx +++ b/docs/pages/cn/explanation/stable-db.mdx @@ -1,80 +1,87 @@ --- source_path: explanation/stable-db.mdx -source_sha: f8e6552090f6f352bcdbfa82870803979ea82c1e -title: "StableDB" -description: "通过解耦状态提交、MemDB 和 mmap 消除磁盘 I/O 瓶颈的 StableDB 架构。" +source_sha: 1b5136d111f56a7a32bf3730d44d97755770091f +title: "存储 (StableDB)" +description: "StableDB 架构采用解耦状态提交、MemDB 和 mmap,以消除磁盘 I/O 瓶颈。" +diataxis: "explanation" --- -# StableDB +# 存储 (StableDB) -区块链端到端性能的主要瓶颈之一是 **磁盘 I/O(Disk I/O)**。尤其是在区块执行后提交和存储状态数据的操作,是性能的关键瓶颈。Stable 通过架构创新,使用如 `MemDB`、`VersionDB` 以及文件内存映射存储(`mmap`),显著提升系统吞吐量。 +端到端区块链性能的主要瓶颈之一是 **磁盘 I/O**。具体来说,在区块执行后提交和存储状态数据是关键瓶颈。Stable 通过架构创新(如 `MemDB`、`VersionDB` 和内存映射存储 (`mmap`))解决了这个问题,从而显著提高了吞吐量。 -## 为什么磁盘 I/O 是性能瓶颈 +## 为什么磁盘 I/O 是瓶颈 -### 状态转换与持久化 +### 状态转换和持久化 -每当执行一批交易并产出区块时,区块链系统都会从一个状态转变为下一个状态。这个过程分为两个基本阶段: +每当执行一个事务区块时,区块链就会从一个状态转换到下一个状态。这个过程有两个基本阶段: -1. **状态提交(State Commitment)**:在交易执行完成后,提交新的状态。 -2. **状态存储(State Storage)**:已提交的状态被持久化到磁盘,用于长期访问和历史验证。 +1. **状态提交**:事务执行后提交新的应用状态。 +2. **状态存储**:将提交的状态持久化到磁盘,以供长期访问和历史验证。 状态提交与存储耦合 -在传统架构中,状态存储与状态提交是**紧密耦合**的,这意味着: +在传统架构中,状态存储与状态提交是**紧密耦合**的。这意味着: -- 节点在继续执行下一个区块之前,必须等待新状态完全写入磁盘。 -- 状态数据被写入磁盘中随机的位置,这导致在后续交易执行中读取状态时出现高延迟。 +- 节点必须等待新状态完全存储到磁盘后才能继续执行下一个区块。 +- 状态数据写入随机的磁盘位置,这些位置未映射到固定地址。这导致在执行后续事务期间检索状态数据时延迟较高。 -即使共识层和执行层做了大量优化,这种对低效的串行磁盘操作的依赖仍然限制了整个系统的性能上限。 +即使共识和执行层经过高度优化,这种对慢速磁盘操作的序列化依赖也会限制整个系统可实现的性能。 -## 针对高吞吐量的数据库优化 +## 优化数据库操作以提高吞吐量 -为了解决这些限制,Stable 提出了两项核心架构优化:**解耦状态操作** 和 **引入内存映射数据库优化(mmap)**。 +为了克服这些限制,Stable 提出了两项架构增强功能,重点是**解耦状态操作**和**引入内存映射数据库优化**。 -### 1. 拆解状态提交与存储 +### 1. 解耦状态提交和存储 状态提交与存储拆解 -第一步是将状态提交与其存储过程拆解: +第一步是将状态提交与其存储解耦: -- 在提交新状态后,节点可以立即执行下一个区块。 -- 状态的持久化操作在后台异步进行。 +- 提交新状态后,节点立即继续执行下一个区块。 +- 状态实际持久化到磁盘是异步在后台进行的。 -这种分离让执行可以得到立即的处理,绕过磁盘写入带来的延迟,从而消除阻塞依赖,大幅提升端到端性能。 +这种分离允许即时执行并跳过慢速磁盘写入的延迟,从而消除阻塞依赖项并最终提高端到端性能。 -### 2. 基于 `mmap` 的 `MemDB` 和 `VersionDB` +### 2. 通过 `mmap` 引入 `MemDB` 和 `VersionDB` -进一步通过 `mmap`(内存映射文件)实现双数据库模型: +Stable 以双数据库模型增强了这一点,该模型由 `mmap`(内存映射文件访问)提供支持: - **MemDB(内存数据库)**: - - 存储近期频繁访问的活跃状态。 - - 使用固定地址映射(通过 `mmap`),支持快速的数据查找。 - - 适用于大多数以近期状态为目标的交易场景。 + - 存储频繁访问的最新和活动状态。 + - 通过 `mmap` 使用固定地址映射,实现快速且确定性的查找。 + - 非常适合大多数以最近修改状态为目标的事务工作负载。 - **VersionDB(历史数据库)**: - - 存储更早期的历史状态。 - - 优化用于归档和长周期查询,针对低频访问设计。 + - 在磁盘上存储旧的历史状态。 + - 针对归档和长期查询进行了优化,不用于高频访问。 -这种设计确保**热点数据通过内存驻留结构快速响应**,而冷数据则由较慢的持久化存储承担。通过结合 `mmap` 访问与状态智能分层,Stable 能够显著降低区块执行过程中的数据库读写延迟。 +这种设计确保**热数据由快速、驻留内存的结构提供服务**,而冷数据则卸载到较慢的持久存储。通过将 `mmap` 访问与智能状态分层相结合,Stable 可以显著降低区块执行期间的数据库读/写延迟。 -## 预期收益与已有实践 +## 预期收益和先例 -这种架构优化并非理论设想,已有 Sei 和 Cronos 等高性能区块链采用类似的解耦式内存映射数据库架构,实测可带来 ** 高达 2 倍的整体 TPS 性能提升**。 +这种架构优化不仅是理论上的。它已经被 Sei 和 Cronos 等高性能区块链实现。两者都采用了类似的解耦架构和内存映射数据库,并观察到**整体 TPS 提高了 2 倍**。 -Stable 也预期将获得类似的性能提升,因为该架构不再受限于存储层瓶颈,系统的共识与执行性能可以按需扩展,而不会被磁盘操作拖慢。 +Stable 也预期有类似的收益,因为架构将不再受存储层的瓶颈限制。相反,共识和执行性能可以扩展,而不会受到磁盘操作的限制。 -## 延伸阅读 +## 进一步阅读 -如需深入了解相关技术与实现细节,请参阅: +有关更多技术深入研究和实现细节,请参阅: -- [ADR-065:Cosmos Store V2 架构](https://docs.cosmos.network/main/build/architecture/adr-065-store-v2) +- [ADR-065: Cosmos Store V2 架构](https://docs.cosmos.network/main/build/architecture/adr-065-store-v2) - [MemIAVL:实用指南](https://hackmd.io/@yihuang/rkeCvy5xh) - [Cronos MemIAVL 节点配置](https://docs.cronos.org/for-node-hosts/running-nodes/memiavl) -- [Sei 的数据库设计方案](https://4pillars.io/ko/articles/sei-db) +- [Sei 的数据库设计方法](https://4pillars.io/ko/articles/sei-db) + +## 下一步建议 + +- [**高性能 RPC**](/cn/explanation/high-performance-rpc):了解 RPC 层如何公开状态读取而不会与写入发生冲突。 +- [**执行**](/cn/explanation/execution):了解执行如何写入此处介绍的存储层。 +- [**共识**](/cn/explanation/consensus):查看在区块到达存储之前对其进行排序的共识层。 diff --git a/docs/pages/cn/explanation/staking-module.mdx b/docs/pages/cn/explanation/staking-module.mdx index 948c0c2..6346da2 100755 --- a/docs/pages/cn/explanation/staking-module.mdx +++ b/docs/pages/cn/explanation/staking-module.mdx @@ -1,414 +1,48 @@ --- source_path: explanation/staking-module.mdx -source_sha: b2ec42174c8f286072288127461ab39c538fd932 -title: 质押模块 -description: "通过 EVM 智能合约进行验证者参与和委托的 Staking 预编译合约。" +source_sha: 32af1af02985137c678f7ed6d46376607121b6bf +title: "Stake 模块" +description: "Stake 预编译合约将委托、解除委托和验证者管理暴露给 EVM 合约,通过授权检查强制执行调用者身份。" +diataxis: "explanation" --- -# 质押模块 +# Stake 模块 -## 概述 +`x/staking` 模块控制 Stable 上的验证者参与和委托。它的预编译合约使得这些操作可以从 Solidity 调用,因此合约可以委托 STABLE、在解绑期后解除委托、在验证者之间重新委托或查询验证者状态,而无需离开 EVM。 -`staking` 预编译合约作为桥梁,使 Stable SDK 的 `x/staking` 模块功能能在 EVM 环境中使用。 +## 暴露的功能 -## 目录 +- **创建验证者**:注册一个新验证者,包括描述、佣金率和初始自我委托。 +- **编辑验证者**:更新验证者元数据和佣金参数。 +- **委托**:将 STABLE 质押给验证者。 +- **解除委托**:开始从验证者解除绑定(代币将在解绑期后可用)。 +- **重新委托**:在不解除绑定的情况下在验证者之间转移质押。 +- **取消解除委托**:在解绑期完成之前取消正在进行的解除绑定。 +- **查询方法**:读取验证者集合、委托记录、解除绑定记录和参数。 -1. **[概念](#concepts)** -2. **[配置](#configuration)** -3. **[方法](#methods)** -4. **[事件](#events)** +## 授权语义 -## 概念 +预编译合约执行两个检查: -在 Stable SDK 的 `x/staking` 模块中,必须在链初始化时注册绑定denomination以进行质押。 -验证者和委托者只能使用绑定denomination质押代币。 -在 `staking` 预编译合约中,会进行额外检查以确保验证者或委托者是调用者。 +1. 绑定面额(质押代币)必须在链初始化时注册。在 Stable 上,这是 STABLE 代币。 +2. 调用者必须与被修改状态的验证者或委托者匹配。您不能通过直接调用预编译合约来代表他人进行委托。 -## 配置 +## 解绑完成 -合约地址和gas费用已预定义。 +当解绑期结束时,代币变得可流通,但 SDK 会悄悄地处理此过程,EVM 不会看到直接事件。Stable 的[系统交易](/cn/explanation/system-transactions)机制弥合了这一点:一旦解绑完成,协议通过 `StableSystem` 预编译合约发出 `UnbondingCompleted` 事件,因此 dApp 可以通过标准 EVM 日志订阅。 -### 合约地址 +## 何时使用 -- `0x0000000000000000000000000000000000000800` +- 质押协议通过保险库合约管理委托:当用户存入和取出时调用 `delegate` 和 `undelegate`。 +- 治理仪表板需要一个实时的验证者集合:使用查询方法。 +- 重质押或流动性质押产品跟踪解绑完成:订阅 `UnbondingCompleted` 事件(一旦该指南发布,请参见[跟踪解绑完成](/cn/how-to/track-unbonding))。 -## 方法 +## 何处查找 ABI -### `createValidator` +完整的方法签名、结构定义和发出的事件在[Stake 预编译合约参考](/cn/reference/staking-module-api)中。 -创建一个验证者。 -验证者必须以来自操作员的初始委托创建。 -对于潜在的委托者,验证者应提供他们的信息和佣金率计划。 -委托者可以通过公开信息和市场机制的自然调节来选择验证者委托他们自己的代币。 +## 推荐阅读 -当验证者成功注册时,会发出 `CreateValidator` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|description|Description|验证者的信息| -|commissionRates|CommissionRates|验证者奖励质押代币的佣金率| -|minSelfDelegation|uint256|验证者的最小自委托金额| -|validatorAddress|address|验证者的地址| -|pubkey|string|验证者的公钥| -|value|uint256|最初自委托给验证者的质押代币数量| - -`Description` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|moniker|string|验证者的名称| -|identity|string|验证者的身份| -|website|string|验证者网站的URL| -|securityContact|string|安全联系信息| -|details|string|验证者的额外描述| - -`CommissionRates` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|rate|uint256|验证者获得的当前佣金率| -|maxRate|uint256|最大佣金率(不能设置得比这更高)| -|maxChangeRate|uint256|验证者一天内可以更改的最大佣金率| - -`rate` 应设置为市场可接受的适当值。 - -- 如果验证者的佣金率较高,委托者的利润就较低。 -- 如果验证者的佣金率较低,验证者的利润就较低,这使得运营变得困难。 - -由于高 `maxRate` 会让委托者担心验证者意外设置高佣金率,因此应小心设置 `maxRate`。`maxChangeRate` 在初始化后不可更改。 - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果验证者成功注册,则为true| - -### `editValidator` - -验证者更新其信息。 -验证者只能更新除了 `CommissionRates` 结构中不可更改字段(如 `maxRate` 和 `maxChangeRate`)之外的信息。 - -当验证者成功更新时,会发出 `EditValidator` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|description|Description|验证者的信息| -|validatorAddress|address|验证者的地址| -|commissionRate|int256|验证者奖励质押代币的佣金率| -|minSelfDelegation|int256|验证者的最小自委托金额| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果验证者成功更新,则为true| - -### `delegate` - -委托者设置要委托给验证者的代币数量。 - -当委托成功完成时,会发出 `Delegate` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的地址| -|validatorAddress|address|验证者的地址| -|amount|uint256|委托给验证者的质押代币数量| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果委托成功完成,则为true| - -#### 事件 - -`newShares` 表示委托者的所有权比例。 -即使委托相同数量的代币,计算出的份额也可能因时间而异。 - -### `undelegate` - -委托者提取委托给验证者的代币数量。 - -当取消委托成功完成时,会发出 `Unbond` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的地址| -|validatorAddress|address|验证者的地址| -|amount|uint256|愿意从验证者那里取消委托的质押代币数量| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果取消委托成功完成,则为true| - -### `redelegate` - -委托者将委托给验证者的代币数量重新委托给另一个验证者。 - -当重新委托成功完成时,会发出 `Redelegate` 事件。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的地址| -|validatorSrc|string|源验证者的地址| -|validatorDst|string|目标验证者的地址| -|amount|uint256|重新委托的质押代币数量| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|success|bool|如果重新委托成功完成,则为true| - -### `delegation` - -返回委托者和验证者之间的委托信息。 -如果未找到委托,`shares` 和 `balance` 将为 `0`。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的地址| -|validatorAddress|address|验证者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|shares|uint256|委托的份额| -|balance|Coin|委托代币的数量和denomination| - -`Coin` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|denom|string|奖励的denomination| -|amount|uint256|奖励的数量| - -### `unbondingDelegation` - -返回委托者和验证者之间的解绑委托信息。 -如果未找到解绑委托,将返回空的 `UnbondingDelegationOutput`。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的地址| -|validatorAddress|address|验证者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|unbondingDelegation|UnbondingDelegationOutput|解绑委托的信息| - -`UnbondingDelegationOutput` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|validatorAddress|address|验证者的地址| -|delegatorAddress|address|委托者的地址| -|entries|UnbondingDelegationEntry[]|解绑委托的条目| - -`UnbondingDelegationEntry` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|creationHeight|uint64|条目的创建高度| -|completionTime|uint64|条目的完成时间| -|initialBalance|Coin|条目的初始余额| -|balance|Coin|条目的余额| - -### `validator` - -返回验证者信息。 -如果未找到验证者,将返回空的 `ValidatorOutput`。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|validatorAddress|address|验证者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|validator|Validator|验证者的信息| - -`Validator` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|operatorAddress|address|验证者的地址| -|consensusPubkey|string|验证者的公钥| -|jailed|bool|验证者是否被监禁| -|status|int32|验证者的状态| -|tokens|uint256|委托给验证者的质押代币数量| -|delegatorShares|uint256|委托份额的数量| -|description|string|验证者的描述| -|unbondingHeight|int64|验证者解绑的高度| -|unbondingTime|int64|验证者解绑的时间| -|commission|uint256|验证者奖励质押代币的佣金率| -|minSelfDelegation|uint256|验证者的最小自委托金额| - -### `validators` - -返回所有与状态匹配的验证者。 -如果未找到验证者,将返回空的 `ValidatorsOutput`。 - -状态在 `x/staking` 模块中声明,可以是以下之一: - -- 0 : "BOND_STATUS_UNSPECIFIED", 未指定状态 -- 1 : "BOND_STATUS_UNBONDING", 验证者正在解绑 -- 2 : "BOND_STATUS_UNBONDED", 验证者已解绑 -- 3 : "BOND_STATUS_BONDED", 验证者已绑定 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|status|string|验证者的状态| -|pageRequest|PageReq|分页请求| - -`PageReq` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|key|bytes|页面的键| -|offset|int64|页面的偏移量| -|limit|int64|页面的限制| -|countTotal|bool|是否计算结果总数| -|reverse|bool|是否反转结果| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|validators|Validator[]|验证者数组| -|pageResponse|PageResp|分页响应| - -`PageResp` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|nextKey|bytes|页面的下一个键| -|total|uint64|结果的总数| - -### `redelegation` - -返回委托者、源验证者和目标验证者的重新委托信息。 -如果未找到重新委托,将返回空的 `RedelegationOutput`。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的地址| -|srcValidatorAddress|address|源验证者的地址| -|dstValidatorAddress|address|目标验证者的地址| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|redelegation|RedelegationOutput|重新委托的信息| - -`RedelegationOutput` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的地址| -|validatorSrcAddress|address|源验证者的地址| -|validatorDstAddress|address|目标验证者的地址| -|entries|RedelegationEntry[]|重新委托的条目| - -`RedelegationEntry` 是一个包含以下字段的结构: - -|名称|类型|描述| -|---|---|---| -|creationHeight|uint64|条目的创建高度| -|completionTime|uint64|条目的完成时间| -|initialBalance|Coin|条目的初始余额| -|balance|Coin|条目的余额| - -### `redelegations` - -返回委托者、源验证者和目标验证者的所有重新委托。 -如果未找到重新委托,将返回空的 `RedelegationResponse` 和 `PageResp`。 - -#### 输入参数 - -|名称|类型|描述| -|---|---|---| -|delegatorAddress|address|委托者的地址| -|srcValidatorAddress|address|源验证者的地址| -|dstValidatorAddress|address|目标验证者的地址| -|pageRequest|PageReq|分页请求| - -#### 输出参数 - -|名称|类型|描述| -|---|---|---| -|response|RedelegationResponse[]|重新委托的信息| -|pageResponse|PageResp|分页响应| - -## 事件 - -### CreateValidator - -|名称|类型|索引|描述| -|---|---|---|---| -|valiAddr|address|Y|验证者的地址| -|value|uint256|N|最初自委托给验证者的质押代币数量| - -### EditValidator - -|名称|类型|索引|描述| -|---|---|---|---| -|valiAddr|address|Y|验证者的地址| -|commissionRate|int256|N|验证者奖励质押代币的更新佣金率| -|minSelfDelegation|int256|N|验证者的更新最小自委托金额| - -### Delegate - -|名称|类型|索引|描述| -|---|---|---|---| -|delegatorAddr|address|Y|委托者的地址| -|validatorAddr|string|Y|验证者的地址| -|amount|uint256|N|委托给验证者的质押代币数量| -|newShares|uint256|N|委托后的委托份额数量| - -### Unbond - -|名称|类型|索引|描述| -|---|---|---|---| -|delegatorAddr|address|Y|委托者的地址| -|validatorAddr|string|Y|验证者的地址| -|amount|uint256|N|从验证者取消委托的质押代币数量| -|completionTime|uint256|N|取消委托的完成时间| - -### Redelegate - -|名称|类型|索引|描述| -|---|---|---|---| -|delegatorAddr|address|Y|委托者的地址| -|validatorSrcAddress|address|Y|源验证者的地址| -|validatorDstAddress|address|Y|目标验证者的地址| -|amount|uint256|N|重新委托的质押代币数量| -|completionTime|uint256|N|重新委托的完成时间| \ No newline at end of file +- [**Stake 预编译合约参考**](/cn/reference/staking-module-api):调用 `delegate`、`undelegate`、`redelegate` 并读取验证者状态。 +- [**系统交易**](/cn/explanation/system-transactions):了解解绑完成如何以事件形式到达 EVM。 +- [**分发模块**](/cn/explanation/distribution-module):提取此处管理的委托所赚取的奖励。 diff --git a/docs/pages/cn/explanation/system-modules-overview.mdx b/docs/pages/cn/explanation/system-modules-overview.mdx index 286dd55..428e98a 100755 --- a/docs/pages/cn/explanation/system-modules-overview.mdx +++ b/docs/pages/cn/explanation/system-modules-overview.mdx @@ -1,39 +1,39 @@ --- source_path: explanation/system-modules-overview.mdx -source_sha: 9fceb608b81d160096165cf2420612413f756df2 +source_sha: e9d156bb03d4413c1981f308ba7c076759d9baa8 title: "系统模块" -description: "Stable 通过预编译合约将 Cosmos-SDK 协议模块暴露给 EVM,使 dApp 无需重写即可调用质押、分配和银行操作。" +description: "从 EVM 调用质押、分发和银行操作。Stable 将 Cosmos-SDK 协议模块作为预编译合约公开,无需重写。" diataxis: "explanation" --- # 系统模块 -Stable 的核心协议行为位于 SDK 模块中:`x/bank`、`x/distribution`、`x/staking`。为了让这些行为能从 EVM 访问,Stable 将每个模块作为固定地址上的**预编译合约**暴露出来。用 Solidity 编写的合约直接调用预编译,EVM 会将调用路由到原生 SDK 处理程序。预编译在协议层面实现,使其比等效的 Solidity 重新实现显著更省 gas。 +Stable 的核心协议行为存在于 SDK 模块中: `x/bank` 、 `x/distribution` 和 `x/staking` 。为了使 EVM 可以访问此行为,Stable 将每个模块作为**预编译合约**公开在固定地址。用 Solidity 编写的合约直接调用预编译,EVM 将调用路由到原生 SDK 处理程序。预编译是在协议级别实现的,因此它们比等效的 Solidity 重新实现节省了更多的 gas。 -## 三个模块 +## 这三个模块 | 模块 | 预编译地址 | 用途 | | :--- | :--- | :--- | -| [Bank](/cn/explanation/bank-module) | `0x0000…1003` (STABLE) | 代币转账、余额记账、授权管理、为授权合约执行铸造/销毁。 | -| [Distribution](/cn/explanation/distribution-module) | `0x0000…0801` | 质押奖励领取、奖励查询、提取地址管理。 | -| [Staking](/cn/explanation/staking-module) | `0x0000…0800` | 委托、解除委托、重新委托、验证人查询。 | -| [系统交易](/cn/explanation/system-transactions) | `0x0000…9999` | 协议为 SDK 层操作(例如解绑完成)发出的 EVM 事件。 | +| [银行](/cn/explanation/bank-module) | `0x0000…1003` (STABLE) | 代币转账、余额记账、津贴管理、授权合约的铸造/销毁。 | +| [分发](/cn/explanation/distribution-module) | `0x0000…0801` | 质押奖励认领、奖励查询、提款地址管理。 | +| [质押](/cn/explanation/staking-module) | `0x0000…0800` | 委托、取消委托、重新委托、验证器查询。 | +| [系统交易](/cn/explanation/system-transactions) | `0x0000…9999` | SDK 层操作(例如解除绑定完成)的协议发出的 EVM 事件。 | -上面的每个页面都解释了该模块的功能、何时使用以及在哪里找到它的 ABI。 +上面每个页面都解释了模块的功能、何时使用以及在哪里可以找到其 ABI。 -## 为什么用预编译,而不是 Solidity +## 为什么是预编译,而不是 Solidity -两个原因: +原因有二: -- **Gas 效率。** 预编译运行在协议的原生执行路径中。等效的 Solidity 合约会以显著更高的 gas 成本重新实现相同的逻辑。 -- **单一可信来源。** 质押、分配和代币供应是协议层面的状态。通过预编译暴露这些状态,避免维护一个可能与 SDK 产生偏差的重复 Solidity 实现。 +- **Gas 效率。** 预编译在协议的原生执行路径中运行。等效的 Solidity 合约将重新实现相同的逻辑,但 gas 成本明显更高。 +- **单一事实来源。** 质押、分发和代币供应是协议级状态。通过预编译公开它们可以避免维护重复的 Solidity 实现,这可能会偏离 SDK。 ## 授权 -某些预编译方法(`mint`、`burn`、协议层面的质押操作)需要调用方授权。`x/precompile` 模块维护着一个链上白名单,来自未注册合约的调用会被回退。这使得特权操作受治理门控,同时不会阻碍 EVM 对只读/转账方法的常规使用。 +某些预编译方法(`mint`、`burn`、协议级质押操作)需要调用者授权。`x/precompile` 模块维护一个链上白名单,未注册合约的调用会回滚。这使得特权操作受到治理限制,同时不阻止 EVM 对读/转账方法的通用使用。 -## 推荐后续阅读 +## 下一步建议 -- [**Bank 模块**](/cn/explanation/bank-module) — 了解代币转账、授权以及铸造/销毁授权模型。 -- [**Staking 模块**](/cn/explanation/staking-module) — 了解委托和验证人管理如何到达 EVM。 -- [**系统交易**](/cn/explanation/system-transactions) — 了解解绑完成等协议层面的事件如何以 EVM 日志的形式呈现。 +- [**银行模块**](/cn/explanation/bank-module):了解代币转账、津贴和铸造/销毁授权模型。 +- [**质押模块**](/cn/explanation/staking-module):了解委托和验证器管理如何到达 EVM。 +- [**系统交易**](/cn/explanation/system-transactions):了解解除绑定完成等协议级事件如何作为 EVM 日志显示。 diff --git a/docs/pages/cn/explanation/system-transactions.mdx b/docs/pages/cn/explanation/system-transactions.mdx index 77d4090..674f196 100755 --- a/docs/pages/cn/explanation/system-transactions.mdx +++ b/docs/pages/cn/explanation/system-transactions.mdx @@ -1,355 +1,60 @@ --- source_path: explanation/system-transactions.mdx -source_sha: 59aa5ae83041e3012bd580b2771601277b1ddf1c -title: System Transactions -description: "将 SDK 层质押事件桥接为 EVM 日志以实现 dApp 全面可见性的系统交易机制。" +source_sha: 0ca908e75feea70023fe71db75e2068f4c824b90 +title: "系统交易" +description: "系统交易将 Cosmos-SDK 事件桥接到 EVM 日志,因此像解除绑定的完成等操作会以 dApp 可以订阅的标准事件形式出现。" +diataxis: "explanation" --- -# System Transactions +# 系统交易 -## 摘要 +EVM 应用程序通过 `eth_getLogs` 等标准接口订阅链上活动。但是,在 Stable 上,一些最重要的操作(例如抵押完成解除绑定)发生在 SDK 模块内部,这些模块不会自然地发出 EVM 事件。**系统交易**弥补了这一可见性差距:协议本身提交 EVM 交易,这些交易为 SDK 层操作发出事件,使它们可以通过 dApp 已经使用的同一日志流进行索引。 -系统交易为 Stable 协议提供了一种为 Stable SDK 操作发出 EVM 事件的方式。当质押事件(如解绑完成)在 SDK 层发生时,协议会自动生成发出相应事件的 EVM 交易,使这些操作对 EVM 工具和应用程序完全可见。 +## 为什么这很重要 -## 动机 +考虑跟踪用户的代币何时完成解除绑定。如果没有系统交易,dApp 将需要: -Stable 上的 EVM 用户和应用程序期望通过标准 EVM 接口(如 `eth_getLogs`)监控区块链事件。但关键操作发生在 Stable SDK 模块中,这些模块不会自然地发出 EVM 事件。这造成了可见性差距:EVM dapps 无法轻松跟踪用户的代币何时完成解绑。 +- 运行一个单独的索引器,它会监视 SDK 事件并将其存储在自己的数据库中。这增加了操作开销并引入了一个新的故障点。 +- 定期轮询 REST 端点。这会导致 5-10 秒的延迟,更高的 RPC 负载,并且需要维护两个客户端堆栈(web3 + REST)。 -系统交易弥合了这一差距。当质押模块完成解绑操作时,Stable 的 x/stable 模块会检测到该事件并生成一个调用 StableSystem 预编译合约(`0x0000000000000000000000000000000000009999`)的系统交易。然后,预编译合约会发出任何 dapp 都可以订阅的适当 EVM 事件。系统交易使用特殊的发送者地址(`0x8888888888888888888888888888888888888888`)运行,只有协议才能使用该地址。这可以防止任何人伪造协议事件,同时保持事件发出在链上的无需信任和可验证性。 +系统交易通过 dApp 已经用于 EVM 日志的同一 WebSocket 连接,向 dApp 提供实时事件通知。无需单独的索引器,也无需轮询 REST。 -## 规范 +## 工作流程 -系统交易通过三个主要组件工作:x/stable 模块的 EndBlocker、PrepareProposal 处理程序和 StableSystem 预编译合约。 - -### 架构概述 - -system-transaction-architecture - -### StableSystem 预编译合约 - -StableSystem 预编译合约位于 `0x0000000000000000000000000000000000009999`,处理需要发出 EVM 事件的协议级操作。目前它支持解绑完成通知。 - -```solidity -interface IStableSystem { - /// @notice 处理排队的解绑完成并发出 EVM 事件 - /// @param blockHeight 处理完成的区块高度 - /// @dev 只能由系统交易调用(from = 0x8888888888888888888888888888888888888888) - /// @dev 每次调用最多处理 100 个完成 - /// @dev 自动从队列中删除已处理的完成 - function notifyUnbondingCompletions(int64 blockHeight) external; - - /// @notice 当解绑操作完成时发出 - /// @param delegator 委托代币的地址 - /// @param validator 代币委托给的验证者地址 - /// @param amount 完成解绑的代币数量(以 uusdc 为单位) - event UnbondingCompleted( - address indexed delegator, - address indexed validator, - uint256 amount - ); - - /// @notice 调用者未授权(不是系统交易发送者) - error Unauthorized(); -} +```text +1. 协议事件: SDK 层操作完成(例如,抵押解除绑定)。 +2. 检测: x/stable EndBlocker 检测到事件并将其排队到状态中。 +3. 系统交易: 在下一个区块的 PrepareProposal 中,协议生成一个 + 调用 StableSystem 预编译的系统交易。 +4. EVM 发出: 预编译处理排队条目并发出标准 + EVM 事件 — dApp 通过 eth_getLogs 和订阅看到它们。 ``` -### 系统交易发送者 - -系统交易使用 `0x8888888888888888888888888888888888888888` 作为发送者地址。该地址: - -- 不需要签名验证 -- 只能由 PrepareProposal 中创建的交易使用 -- 用户或合约无法伪造 -- 通过 SystemTxDecorator ante 处理程序跳过费用扣除 - -EVM 通过检查 `msg.sender == 0x8888888888888888888888888888888888888888` 来识别系统交易。预编译合约可以使用此功能来限制仅协议操作。 - -### 事件驱动流程 - -当用户的解绑期完成时,会发生以下情况: - -1. **Stable SDK 层:** 质押模块的 EndBlocker 完成解绑并发出 EventTypeCompleteUnbonding,包含委托者地址、验证者地址和金额。 -2. **检测:** x/stable 模块的 EndBlocker 在质押之后运行,并扫描区块事件日志中的解绑事件。每当有代币完成解绑,该模块都将在队列中添加一条记录,包含委托者地址、验证者地址、金额和区块高度。 -3. **系统交易生成**:在下一个区块的 PrepareProposal 中,应用程序查询所有排队的完成。如果存在任何完成,它会创建一个调用 StableSystem.notifyUnbondingCompletions(blockHeight) 的系统交易,使用当前区块高度。此交易放在区块前面,在任何用户交易之前。 -4. **执行:** 在区块执行期间,系统交易首先运行。预编译合约查询该区块高度排队的完成状态,为每个完成发出一个 UnbondingCompleted 事件(最多 100 个),并从队列中删除它们。 -5. **EVM 可见性:** 事件出现在交易收据和日志中,对 eth_getLogs 查询、区块浏览器和任何监控 StableSystem 预编译合约的应用程序可见。 - -### 批处理 - -为防止区块变得过大,系统每个区块最多处理 100 个解绑完成。如果队列中存在 150 条记录: - -- 区块 N:创建处理完成 0-99 的系统交易 -- 区块 N+1:创建处理完成 100-149 的系统交易 - -预编译合约直接查询状态,而不是在 calldata 中接收完成数据。这使交易大小可预测,并将数据从昂贵的 calldata 移动到更便宜的状态读取。 - -## 使用示例 - -最常见的用例是需要在解绑期完成时通知用户的质押仪表板。以下是如何设置解绑完成监听器。 - -```javascript -import { ethers } from 'ethers'; - -// StableSystem 预编译合约地址 -const STABLE_SYSTEM_ADDRESS = '0x0000000000000000000000000000000000009999'; - -// UnbondingCompleted 事件的 ABI -const STABLE_SYSTEM_ABI = [ - 'event UnbondingCompleted(address indexed delegator, address indexed validator, uint256 amount)' -]; - -// 连接到 Stable 网络 -const provider = new ethers.JsonRpcProvider('https://rpc.testnet.stable.xyz'); -const stableSystem = new ethers.Contract( - STABLE_SYSTEM_ADDRESS, - STABLE_SYSTEM_ABI, - provider -); - -// 订阅所有解绑完成 -stableSystem.on('UnbondingCompleted', (delegator, validator, amount, event) => { - console.log('解绑完成!'); - console.log('委托者:', delegator); - console.log('验证者:', validator); - console.log('金额:', ethers.formatEther(amount), '代币'); - console.log('区块:', event.log.blockNumber); - console.log('交易哈希:', event.log.transactionHash); -}); - -``` - -此监听器将在任何用户的解绑完成时触发。在生产环境中部署 dApp 时需要过滤特定用户的事件。 - -### 过滤特定用户的事件 - -要仅接收特定委托者地址的事件,请使用索引事件参数创建过滤器: - -```javascript -// 仅监视特定用户的解绑 -const userAddress = '0xabcd...'; - -const filter = stableSystem.filters.UnbondingCompleted(userAddress); - -stableSystem.on(filter, (delegator, validator, amount, event) => { - // 这仅针对指定用户的解绑触发 - showNotification(`您的 ${ethers.formatEther(amount)} 代币解绑完成!`); - refreshUserBalance(userAddress); -}); -``` - -如果您正在构建特定于验证者的仪表板,您还可以按验证者过滤: - -```javascript -// 监视来自特定验证者的所有解绑 -const validatorAddress = '0x1234...'; - -const validatorFilter = stableSystem.filters.UnbondingCompleted(null, validatorAddress); - -stableSystem.on(validatorFilter, (delegator, validator, amount) => { - updateValidatorStats(validator, amount); -}); -``` - -### 查询历史事件 - -如果您的 dApp 需要显示过去解绑完成的历史记录,您可以使用带有区块范围的事件过滤器查询历史事件: - -```javascript -// 获取用户在最近 1000 个区块中的所有解绑 -const currentBlock = await provider.getBlockNumber(); -const filter = stableSystem.filters.UnbondingCompleted(userAddress); - -const events = await stableSystem.queryFilter( - filter, - currentBlock - 1000, - currentBlock -); - -const unbondingHistory = events.map(event => ({ - delegator: event.args.delegator, - validator: event.args.validator, - amount: ethers.formatEther(event.args.amount), - blockNumber: event.blockNumber, - txHash: event.transactionHash -})); - -console.log('最近的解绑:', unbondingHistory); - -``` - -## 集成指南 - -### 步骤 1:添加 Stable System 合约接口 - -首先,将 StableSystem 预编译合约接口添加到您的项目中。如果您使用 Foundry 或 Hardhat,请创建一个新的接口文件: - -```solidity -interface IStableSystem { - event UnbondingCompleted( - address indexed delegator, - address indexed validator, - uint256 amount - ); -} -``` - -如果您正在构建一个没有 Solidity 合约的纯前端 dApp,您只需要事件的 ABI 片段: - -```javascript -const STABLE_SYSTEM_ABI = [ - 'event UnbondingCompleted(address indexed delegator, address indexed validator, uint256 amount)' -]; -``` - -### 步骤 2:设置事件监听器 - -初始化您的 ethers.js provider 并创建指向 StableSystem 预编译合约地址的合约实例。预编译合约始终部署在 Stable 测试网和主网的 `0x00000000000....0000009999`。 - -*注意:预编译合约尚未部署在 Stable 主网上,将在 v1.2.0 升级后提供。* - -```javascript -const provider = new ethers.JsonRpcProvider(RPC_URL); -const stableSystem = new ethers.Contract( - '0x0000000000000000000000000000000000009999', - STABLE_SYSTEM_ABI, - provider -); -``` - -### 步骤 3:在应用程序逻辑中处理事件 - -订阅事件并相应地更新应用程序状态。常见模式包括: - -- **余额更新**:当解绑完成时,刷新用户的代币余额 -- **通知系统**:在用户的解绑完成时显示 toast 通知 -- **仪表板统计**:实时更新质押指标和图表 -- **交易历史**:将已完成的解绑添加到用户的活动源 - -### 步骤 4:处理连接问题 - -由于事件订阅依赖于持久的 websocket 连接,因此为生产 dApp 实现重新连接逻辑: - -```javascript -let reconnectAttempts = 0; -const MAX_RECONNECT_ATTEMPTS = 5; - -function setupEventListener() { - const provider = new ethers.WebSocketProvider('wss://rpc.testnet.stable.xyz'); - - provider.on('error', (error) => { - console.error('Provider 错误:', error); - if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) { - reconnectAttempts++; - setTimeout(() => setupEventListener(), 5000); - } - }); - - const stableSystem = new ethers.Contract( - '0x0000000000000000000000000000000000009999', - STABLE_SYSTEM_ABI, - provider - ); - - stableSystem.on('UnbondingCompleted', handleUnbonding); -} -``` - -## 为什么采用这种方法? - -### 与自定义索引器相比 - -以前,Stable SDK 要求 dApp 开发人员运行自定义索引器,监视 SDK 事件并将它们存储在数据库中。这增加了操作开销并引入了潜在的故障点。 - -使用系统交易,无需单独的索引器基础设施。EVM 的日志系统原生支持这类事件,每个 RPC 节点都已经索引和提供。任何标准 web3 库都可以订阅这些事件,无需额外工具。 - -### 与轮询 SDK 端点相比 - -没有系统交易,EVM dApps 需要定期调用 Stable SDK REST 端点来检查解绑期是否已完成。这会产生几个问题: - -- **延迟增加**:5-10 秒的轮询间隔意味着用户可能需要等待那么长时间才能看到更新 -- **更高的负载**:每个 dApp 实例轮询端点都会增加 RPC 基础设施的负载 -- **复杂性**:dApps 需要同时处理 web3 提供程序(用于 EVM 交互)和 Stable SDK REST 客户端(用于 SDK 查询) -- **无实时更新**:轮询本质上无法提供即时通知 - -系统交易通过 dApps 已经用于 EVM 交互的相同 websocket 连接提供实时事件通知。这简化了开发人员体验并降低了基础设施成本。 - -## 安全保证 - -### 无需信任的事件发出 - -系统交易在 `PrepareProposal` ABCI 阶段创建,只有验证者才能执行。用户提交的交易无法伪造系统发送者地址(`0x8888888888888888888888888888888888888888`),因为 EVM 的状态转换逻辑强制只有到 StableSystem 预编译合约地址的交易才能跳过签名验证。 - -这意味着: - -- 用户无法伪造解绑完成事件 -- 用户无法从自己的交易中调用 `notifyUnbondingCompletions` -- 发出 `UnbondingCompleted` 事件的唯一方法是在 Stable SDK 质押模块中实际完成解绑 - -### 无额外信任假设 - -系统交易不会引入超出区块链共识已经需要的新安全假设。如果您相信验证者正确执行区块,您就可以相信系统交易事件准确反映了 Stable SDK 状态变化。 - -事件发出过程是确定性的:给定 `EndBlock` 中相同的 SDK 事件,所有诚实的验证者将在 `PrepareProposal` 期间产生相同的系统交易。共识机制确保验证者就包含哪些系统交易达成一致。 - -### 区块最终性 - -Stable 区块链通过 StableBFT 的共识机制使用快速最终性。一旦提交了一个区块,它就会立即最终化,无法重组。这意味着一旦您收到 `UnbondingCompleted` 事件,您就可以相信它是永久的。 - -不需要像在概率最终性链上那样等待多个确认。dApps 可以在收到事件后立即更新用户余额并显示通知。 - -## 性能和限制 - -### 批处理大小约束 - -每个区块通过系统交易最多处理 100 个解绑完成。此限制存在是为了防止在解绑活动高峰期间区块大小无限制。 - -在实践中,假设平均区块时间为 0.7 秒,每个区块 100 个完成提供了约 9000 个完成/分钟的吞吐量。正常的质押活动很少达到此限制。在特殊情况下,完成可能会在完全处理之前排队几个区块。 - -### Gas 消耗 - -系统交易在执行期间消耗 gas,这在区块的 gas 限制中计算。gas 成本与正在处理的完成数量成线性比例: - -- 基本函数调用:约 21,000 gas -- 每个事件发出:约 3,000 gas -- 读取状态:每个完成约 2,000 gas - -100 个完成的完整批次消耗大约 521,000 gas。由于 Stable 的区块 gas 限制为 100,000,000,这代表不到 0.6% 的可用区块空间。 - -### 通知延迟 - -当解绑期在区块 N 期间完成时: - -1. Stable 模块的 `EndBlock` 在区块 N 的状态中排队完成 -2. 区块 N+1 的 `PrepareProposal` 创建系统交易 -3. 系统交易在区块 N+1 期间执行,发出事件 - -这意味着解绑完成和发出 EVM 事件之间存在一个区块的延迟(大约 0.7 秒)。对于大多数用例,此延迟是可以接受的,因为解绑期本身为 7 天。 +系统交易由验证者在区块提议期间创建,而不是由用户创建。它位于区块的开头,在任何用户交易之前。 -### 高负载场景 +## StableSystem 预编译 -如果解绑完成的到达速度快于每个区块 100 个,它们会在队列中累积。队列按 FIFO 顺序处理,因此最旧的完成始终首先通知。 +事件流经 `StableSystem` 预编译,位于 `0x0000000000000000000000000000000000009999`。目前,它为质押解除绑定发出一个事件(`UnbondingCompleted`)。该协议旨在将此扩展到其他 SDK 操作(验证者佣金更改,治理执行),采用相同的模式。 -在持续的高负载期间,队列可能会暂时增长。但是,一旦高峰消退,完成较少的后续区块将逐渐排空队列。该系统旨在处理突发而不丢失事件。 +## 安全模型 -## 未来扩展 +两个属性使事件流值得信赖: -系统交易机制为将任何 Stable SDK 操作桥接到 EVM 事件空间提供了通用模式。虽然目前仅用于解绑完成,但该架构可以扩展以涵盖其他用例: +- **仅限协议发送者。** 系统交易使用 `0x8888888888888888888888888888888888888888` 作为其发送者。EVM 状态转换规则只允许从该地址发送到 `StableSystem` 预编译的交易跳过签名验证。用户无法伪造事件或从自己的交易中调用受限的预编译函数。 +- **确定性事件发送。** 每个诚实的验证者都会为相同的协议事件生成相同的系统交易。除了标准共识之外,没有额外的信任假设。 -### 质押操作 +## 批处理 -除了解绑之外,其他质押事件可以发出 EVM 通知: +为了限制区块大小,每个区块最多处理 100 个解除绑定完成。在 Stable 大约 700 毫秒的区块时间内,这大约是每分钟 9,000 个解除绑定完成,远高于典型的质押活动。如果爆发超出每个区块的限制,解除绑定完成将以 FIFO 顺序排队,并在后续区块中处理。 -- 验证者的佣金率变化 -- 验证者入狱和出狱 +SDK 事件与 EVM 事件发出之间存在一个区块(约 700 毫秒)的延迟,这相对于 7 天的解除绑定期本身可以忽略不计。 -### 治理执行 +## ABI 查找位置 -当治理提案通过并执行时,系统交易可以发出带有提案 ID 和执行结果的事件。这将允许 dApps 对参数变化或升级做出反应,而无需轮询治理模块。 +`StableSystem` 接口、事件签名和发送者授权规则位于 [系统交易参考](/cn/reference/system-transactions-api) 中。 -### 通用事件桥 +## 下一步建议 -该模式可以推广为可配置的事件桥,其中每个模块注册哪些 SDK 事件应该镜像到 EVM。这将提供对所有 Stable SDK 操作的全面可见性,而无需每个模块的自定义逻辑。关键架构原则是系统交易仍然是协议级功能,仅由验证者在区块提案期间创建。 +- [**系统交易参考**](/cn/reference/system-transactions-api): 了解 `IStableSystem` 接口、Gas 核算和授权规则。 +- [**质押模块**](/cn/explanation/staking-module): 查看以系统交易事件形式出现的 SDK 操作。 +- [**系统模块概述**](/cn/explanation/system-modules-overview): 返回到预编译暴露的模块列表。 diff --git a/docs/pages/cn/explanation/technical-roadmap.mdx b/docs/pages/cn/explanation/technical-roadmap.mdx index 541d645..018d3d6 100755 --- a/docs/pages/cn/explanation/technical-roadmap.mdx +++ b/docs/pages/cn/explanation/technical-roadmap.mdx @@ -1,21 +1,14 @@ --- source_path: explanation/technical-roadmap.mdx -source_sha: 51096f595fa958dae93321c10dc7be09f153ba92 -title: "技术路线图" -description: "涵盖数据库、执行、共识及 USDT 专项性能优化的 Stable 分阶段技术路线图。" +source_sha: 669bf747b8f3b656b8509625ece8a50946d431f8 +title: "路线图" +description: "Stable 的分阶段优化路线图:今日已上线、即将推出以及未来规划。" +diataxis: "explanation" --- -# 技术路线图 +# 路线图 -## Stable 针对稳定币的全栈优化路径 - -从用户提交交易到最终结果确认,交易生命周期要经历多个阶段:交易首先通过 RPC 广播,然后进入内存池(mempool),然后被打包进区块,经过共识验证、执行,最终将结果状态写入数据库。只有完成这些步骤,用户才能获得最终的交易结果。 - -这个过程中任何一个环节存在瓶颈,都会影响整体系统性能。Stable 致力于优化交易路径中的每一步,以最大化提升性能并减少延迟。 - -Stable 的核心技术将分阶段推出,每一阶段都旨在提升每秒交易数(TPS),同时不牺牲交易的终局性。计划中的优化包括状态数据库处理、执行层、共识机制以及 USDT 特定流程的优化。 - -下文将概述当前区块链架构中的常见性能瓶颈,以及 Stable 的优化方案。 +Stable 将分三个阶段优化交易管道的每一层(共识、执行、存储、RPC 和 USDT 特定流程)。本页面将展示已发布、正在进行中和仍在规划中的内容。 技术路线图 -## 第 1 阶段 - -### StableBFT - -Stable 区块链最初将采用 StableBFT,这是一种基于 CometBFT 的定制化 PoS 协议,提供高吞吐、低延迟与强可靠性。该协议具备终局性,能容忍三分之一的节点故障。未来,Stable 将升级为基于 DAG 的共识机制,实现 5 倍的共识速度提升。 - -### USDT 作为原生 Gas - -在 Stable 上,USDT0 作为其原生 Gas 代币。USDT0 同时作为用于支付 Gas 和进行价值转移的原生资产,并作为支持 `approve`、`transfer`、`transferFrom` 和 `permit` 的 ERC20 代币。 - -### Stable Pay与 Stable Name - -Stable Pay使用直观设计和社交登录等功能,而已有用户则可直接连接现有钱包,无需迁移。Stable 钱包将提供网页版钱包和原生的手机钱包,保障用户在任何设备上都能安全访问数字资产。 - -与钱包配套的是 Stable Name:这是一套友好的别名系统,用于替代繁琐且容易出错的 EVM 地址格式,采用唯一且可读性强的标识符。用户只需通过 Stable Name 即可完成收发代币,免去管理十六进制字符串的烦恼。该系统大大减少了交易出错的几率,提升了与加密资产交互的整体体验,使 Stable 成为进入区块链生态的便捷入口。 - -## 第 2 阶段 +## 阶段 1:USDT 的基础层 -### **并行执行** +状态:**主网已上线。** -60–80% 的交易之间并不冲突,可以安全地并行执行。但大多数区块链系统仍采用顺序执行,造成不必要的延迟。 +### StableBFT:已上线 -Stable 将采用Optimistic并行执行模型以提高吞吐量。交易在假设无冲突的前提下并行执行,若检测到冲突,则将相关交易回滚并按顺序重新执行。此模型在确保正确性的同时带来显著的性能提升。 +基于 CometBFT 构建的定制 PoS 共识协议。提供确定性最终确定性,并能容忍多达三分之一验证者的拜占庭故障。有关当前实现,请参阅[共识](/cn/explanation/consensus)。 -### **状态数据库优化** +### USDT 作为原生 Gas:已上线 -区块链性能的主要瓶颈之一是磁盘 I/O 慢。在执行完区块后,状态需被提交(commit)和存储。传统模式中,验证节点需等待状态完全存储完毕后才能继续执行下一区块。 +USDT0 是用于 Gas 支付和价值转移的原生资产,同时支持 ERC-20 接口(`approve`、`transfer`、`transferFrom`、`permit`)。请参阅 [USDT 作为 Gas 令牌](/cn/explanation/usdt-as-gas-token)。 -Stable 通过拆解状态提交与状态存储来优化该流程。验证节点可在内存中提交最新状态,从而继续下一轮区块执行,同时允许历史状态延迟写入磁盘。这显著降低了执行延迟。 +### Stable Pay 和 Stable Name:进行中 -此外,Stable 计划采用 `mmap`(内存映射文件)机制,将文件放置到内存中,加速存储性能。在内存中实时提交状态,同时将归档状态写入磁盘,大幅减少磁盘 I/O 延迟,并提升读写吞吐量。 +Stable Pay 是一种 Web2.5 用户体验钱包,旨在简化新用户的入职流程,同时兼容现有的 Web3 钱包。Stable Name 是一个用户友好的别名系统,用人类可读的标识符替换原始 EVM 地址,用于发送和接收令牌。 -### **USDT 转账聚合器** +## 阶段 2:USDT 体验层 -为支持大规模 USDT0 转账,Stable 将实现转账聚合机制。USDT0 的转账交易将被批量打包处理,从而降低每笔交易的系统开销,提高整体吞吐量。 +状态:**开发中。** 状态数据库优化将在 v1.4.0 升级中发布。其余项目仍在开发中。 -### **企业专用区块空间** +### 状态数据库优化:将在 v1.4.0 中发布 -企业在使用区块链基础设施时,通常需要可预测的交易延迟,而在网络拥堵时,这种可预测性可能下降。 +Stable 将状态提交与状态存储解耦。验证者在内存中提交最新状态,而历史状态则延迟到磁盘。由 `mmap` 支持的 `MemDB` 和 `VersionDB` 处理实时提交而不会阻塞磁盘 I/O。请参阅[存储 (StableDB)](/cn/explanation/stable-db)。 -Stable 通过专用区块空间模型解决该问题,为企业客户保证固定比例的区块容量。该保障机制包括: +### 乐观并行执行:已规划 -- 验证节点级定制:验证节点为企业客户预留空间。 -- 专属 RPC 节点:企业交易通过独立的内存池和 API 接口优先处理。 +实际遥测数据显示,60-80% 的交易与不相交的状态交互,可以安全地并行执行。Stable 将在无冲突假设下乐观地执行交易,并在检测到冲突时进行回滚和顺序重新执行。这在提高吞吐量的同时保持了正确性。 -该模式确保关键企业在不同网络条件下也能保持稳定性能。 +### USDT 转账聚合器:已规划 -## 第 3 阶段 +USDT0 转账的聚合机制,将转账分组并集体处理,减少了每笔交易的开销,提高了整体吞吐量。请参阅 [USDT 转账聚合器](/cn/explanation/usdt-transfer-aggregator)。 -### **基于 Autobahn 的高级共识(StableBFT)** +### 有保证的区块空间:已规划 -第一代基于 DAG 的 BFT 引擎(如 Narwhal 和 Tusk)表明,通过将数据传播与共识排序解耦拆解,可消除单个 proposer 的瓶颈。然而,直接将这类系统引入 CometBFT 环境会与高度依赖区块高度的开发习惯及传统内存池设计发生冲突。 +为企业合作伙伴预留的区块容量,通过验证者级别的预留和专用 RPC 端点强制执行。即使在网络拥塞的情况下,也能为关键任务支付流程提供可预测的延迟。请参阅[有保证的区块空间](/cn/explanation/guaranteed-blockspace)。 -Autobahn 提供了一种 PBFT-on-DAG 架构,更自然地与 Stable 的共识层集成。基于 Autobahn 构建的 StableBFT 将实现: +## 阶段 3:USDT 的全栈优化层 -- 消除单领导者限制,支持并行交易处理; -- 通过分离数据传播与最终排序,加快交易确认速度; -- 通过强健的 BFT 机制提升对网络攻击的抵抗性。 +状态:**已规划。** -根据内部测试结果,该共识协议已在可控环境下实现超过 200,000 TPS(仅共识层)的处理能力。 +### Autobahn 上的 StableBFT -### **StableVM++** +基于 DAG 的 BFT 共识,与 Stable 基于 CometBFT 的共识层自然集成。有关当前协议,请参阅 [StableBFT](/cn/explanation/consensus),有关目标架构,请参阅 [Autobahn](/cn/explanation/autobahn)。内部概念验证已在受控环境中展示了超过 200,000 TPS(仅共识)。 -StableVM++ 是高性能执行引擎,将用 C++ 实现替代当前基于 Go 的 EVM。此更替预计将带来最高 6 倍的执行速度提升,极大增强链上处理能力。 +### StableVM++ -### **高性能 RPC** +高性能执行引擎,用 C++ 实现替换基于 Go 的 EVM。预计可将 EVM 执行速度提高 6 倍。 -高吞吐量的去中心化应用依赖于快速准确的 RPC 与索引服务。Stable 的高性能 RPC 架构将包括: +### 高性能 RPC -- **节点级优化**:实时链状态处理,提升 RPC 响应速度; -- **集成式索引器**:低延迟索引服务,在保证一致性的情况下提升应用层 API 效率 ; -- **强健的 Pub/Sub 系统**:可扩展的 WebSocket 架构,提供可靠的推送和事件通知机制; -- **混合负载均衡器**:基于操作类型智能分配流量,最大化利用资源并减少瓶颈。 +一个完整的 RPC 堆栈,涵盖节点级增强(实时链状态处理)、节点集成索引(低延迟应用 API)、通过 WebSocket 的可扩展 pub/sub 以及按操作类型路由的混合负载均衡器。有关当前分流路径架构,请参阅[高性能 RPC](/cn/explanation/high-performance-rpc)。 -这些优化将使 Stable 能为 dApp 和企业用户提供稳定且可扩展的访问接口。 +## 接下来推荐 +- [**架构概览**](/cn/explanation/core-optimization-overview):了解路线图演变的当前堆栈状态。 +- [**代币经济学**](/cn/reference/tokenomics):回顾为整个路线图中的验证者激励提供资金的经济模型。 +- [**技术概览**](/cn/explanation/tech-overview):返回架构摘要。 diff --git a/docs/pages/cn/explanation/upcoming-use-cases.mdx b/docs/pages/cn/explanation/upcoming-use-cases.mdx index 6b4c588..c975b38 100644 --- a/docs/pages/cn/explanation/upcoming-use-cases.mdx +++ b/docs/pages/cn/explanation/upcoming-use-cases.mdx @@ -1,71 +1,71 @@ --- source_path: explanation/upcoming-use-cases.mdx -source_sha: 60bc4f5649c065fd4f2d42ce273fb2f4d47c5a26 -title: "即将推出的应用场景" -description: "Stable 即将支持的支付模式:有保障的结算、隐私支付以及代理之间的商业交易。" +source_sha: bbbfc76afcdf37c4b3634f515323f16cf0f08796 +title: "即将推出的用例" +description: "Stable 即将推出的支付模式:保证结算、保密支付和代理对代理商务。" diataxis: "explanation" --- -# 即将推出的应用场景 +# 即将推出的用例 -Stable 正在构建超越简单转账和 API 计费的支付模式。下面的案例涵盖了有时间保障的结算、保护隐私的支付以及自主代理商务。其中一些功能目前已有早期形式可用;另一些则依赖于 Stable 目前正在开发中的功能。 +Stable 正在构建超越简单转账和 API 计费的支付模式。以下案例涵盖了时间保证结算、隐私保护支付和自主代理商务。其中一些已以早期形式实现功能;另一些则依赖于 Stable 当前正在开发中的功能。 -## 有保障的结算 +## 保证结算 -由预留区块容量支持的可靠支付结算,确保无论网络状况如何,交易都能被包含。 +通过预留的区块容量支持可靠的支付结算,确保无论网络状况如何都能包含交易。 ### 概念 -有些支付是定时结算周期的一部分,而非独立的转账。在这些流程中,结算必须在周期关闭之前完成,以便下一个状态转换能够按计划进行。如果所需的支付被延迟超过该窗口,周期可能会失败、顺延到下一个窗口,或需要手动恢复。 +某些支付是定时结算周期的一部分,而非独立的转账。在这些流程中,结算必须在周期结束前完成,以便下一个状态转换能按计划进行。如果所需支付延迟超出该窗口,周期可能会失败、滚动到下一个窗口或需要手动恢复。 -Stable 的 [有保障的区块空间](/cn/explanation/guaranteed-blockspace) 通过为符合条件的支付流程预留执行容量来解决这一问题。其目标不仅仅是更快的结算,而是在精确的时间约束内实现运营上可靠的完成。 +Stable 的[保证区块空间](/cn/explanation/guaranteed-blockspace)通过为符合条件的支付流程预留执行容量来解决此问题。目标不仅仅是更快的结算,而是在精确的时间限制内实现操作上可靠的完成。 ### 预期场景 -一个代币化资产平台每隔几分钟运行一次定时的 DvP(货银对付,Delivery versus Payment)结算。现金部分以批次形式提交,只有当整个支付批次在当前结算周期关闭之前被包含时,证券才会被释放。在正常情况下,这会立即完成。在突发流量期间,部分包含会导致结算周期失败或顺延。借助有保障的结算,平台为支付批次预留容量,使周期能够确定性地关闭。 +一个代币化资产平台每隔几分钟运行一次计划的 DvP(交割对支付)结算。现金部分作为批次提交,只有当全部支付批次在当前结算周期结束前被包含时,证券才会被释放。在正常情况下,这会立即清除。在突发流量期间,部分包含将导致失败或回滚的结算周期。通过保证结算,平台为支付批次预留容量,因此周期可以确定性地结束。 -### 实现条件 +### 实现基础 -有保障的区块空间将链上支付转变为可调度的操作。结算周期可以基于严格的时间假设来设计,批量支付可以在单个窗口内原子化地提交,上游系统可以将区块包含视为一种依赖关系,而非一种期望。 +保证区块空间将链上支付转化为可调度操作。结算周期可以根据严格的时间假设进行设计,批次支付可以在单个窗口内原子性提交,上游系统可以将区块包含视为依赖而非期望。 -## 隐私支付 +## 保密支付 -保护隐私的 USDT0 转账,所选交易细节对公开观察者屏蔽,同时对交易各方和授权审计员保持可验证。 +隐私保护的 USDT0 转账,其中选定的交易详情对公共观察者是隐藏的,但仍可由交易双方和授权审计师验证。 ### 概念 -标准的链上转账完全透明;任何人都可以看到发送方、接收方和金额。对于商业支付而言,这种透明度可能会将商业敏感信息暴露给任何监控链的人。 +标准链上转账是完全透明的;任何人都可以看到发送方、接收方和金额。对于商业支付,这种透明度可能会向任何监控链的人暴露商业敏感信息。 -Stable 正在开发 [隐私转账](/cn/explanation/confidential-transfer),这是一个使用零知识密码学的隐私层,可为链上交易实现选择性的保密。被屏蔽的数值只有交易相关方和授权的监管审计员才能访问。 +Stable 正在开发[保密转账](/cn/explanation/confidential-transfer),这是一个使用零知识密码学实现的隐私层,可为链上交易提供选择性保密。屏蔽的值仅可由相关方和授权的监管审计师访问。 ### 预期场景 -一家大型零售商在链上与多个供应商结算库存采购。在透明的链上,竞争对手可以监控这些交易,以反向推断供应商关系、订单量和批发价格。借助隐私转账,商业敏感的细节被屏蔽,而链上记录仍可作为可验证的结算凭证,供双方和授权审计员使用。 +一家大型零售商通过链上与多个供应商结算库存采购。在透明的链上,竞争对手可以通过监控这些交易反向工程出供应商关系、订单量和批发价格。通过保密转账,商业敏感细节被屏蔽,而链上记录仍可作为双方和授权审计师的可验证结算收据。 -## 代理之间的支付 +## 代理对代理支付 -由 AI 代理自主发起和结算的支付,在交易环节中无需人工批准或干预。 +AI 代理之间自主发起和结算的支付,无需人工批准或干预交易循环。 ### 概念 -随着 AI 代理承担越来越多的运营任务,它们将需要从其他代理那里采购服务。在当前的工作流程中,这需要人工参与来批准每笔采购、选择供应商或验证交易对手是否可信。代理之间的支付通过让代理在单个交易环节中自主查找、评估和支付服务,消除了这一瓶颈。 +随着 AI 代理承担更多运营任务,它们将需要从其他代理那里采购服务。在当前工作流中,这需要人工审批每次采购、选择供应商或验证交易对手是否值得信赖。代理对代理支付通过允许代理在单个交易循环中自主查找、评估和支付服务来消除这一瓶颈。 -这种模式依赖于若干新兴协议的协同工作:代理发现与信任([ERC-8004](https://eips.ethereum.org/EIPS/eip-8004))、安全通信([XMTP](https://xmtp.org))以及能够实时结算的支付通道([x402](/cn/explanation/x402))。 +这种模式依赖于几个新兴协议协同工作:代理发现和信任 ([ERC-8004](https://eips.ethereum.org/EIPS/eip-8004))、安全通信 ([XMTP](https://xmtp.org)) 和可以实时结算的支付轨道 ([x402](/cn/explanation/x402))。 ### 预期流程 -1. **发现**:买方代理查询 ERC-8004 身份注册表,以查找提供所需能力(例如图像生成)的代理。注册表返回匹配的代理身份及相关元数据。 -2. **验证**:买方在 ERC-8004 注册表中检查每个候选者。身份、信誉评分和验证证明决定了哪些提供方足够可信,可以进行交易。 -3. **协商**:买方通过 XMTP 向选定的提供方发送任务参数。两个代理通过加密消息就价格、截止时间和交付格式达成一致。 -4. **支付**:买方调用提供方的 HTTP 端点。提供方返回 402 响应。买方签署 ERC-3009 授权,并附带支付头重试。促成方在 Stable 上结算支付,提供方返回结果。 -5. **评价**:交付后,买方向 ERC-8004 信誉注册表提交反馈,更新提供方的评分以供未来交互参考。 +1. **发现**:买方代理查询 ERC-8004 身份注册表以查找提供所需能力(例如,图像生成)的代理。注册表返回匹配的代理身份和相关元数据。 +2. **验证**:买方检查每个候选方的 ERC-8004 注册表。身份、声誉分数和验证证明决定了哪些提供商足够值得信赖以进行交易。 +3. **协商**:买方通过 XMTP 将任务参数发送给选定的提供商。两个代理通过加密消息商定价格、截止日期和交付物格式。 +4. **支付**:买方调用提供商的 HTTP 端点。提供商回复 402。买方签署 ERC-3009 授权并使用支付头重试。协调者在 Stable 上结算支付,提供商返回结果。 +5. **评分**:交付后,买方将反馈发布到 ERC-8004 声誉注册表,更新提供商的评分以供将来交互。 -### 实现条件 +### 实现基础 -代理之间的支付将服务采购转变为一个完全可编程的环节。代理可以比较提供方、切换供应商,并实时结算支付,而无需人工调度或审批队列。这使得构建自主供应链成为可能,代理可以以机器速度持续采购、支付和交付服务,将商务扩展到超越手动协调所能支持的范围。 +代理对代理支付将服务采购转化为一个完全可编程的循环。代理可以比较提供商、切换供应商并实时结算支付,无需人工调度或审批队列。这使得构建自主供应链成为可能,其中代理以机器速度持续采购、支付和交付服务,将商业扩展到人工协调所能支持的范围之外。 -## 下一步推荐 +## 下一步建议 -- [**有保障的区块空间**](/cn/explanation/guaranteed-blockspace) — 了解有保障结算背后的协议级机制。 -- [**隐私转账**](/cn/explanation/confidential-transfer) — 查看 Stable 正在构建的隐私模型。 -- [**x402**](/cn/explanation/x402) — 理解代理之间流程背后的结算协议。 +- [**保证区块空间**](/cn/explanation/guaranteed-blockspace):查看保证结算背后的协议级机制。 +- [**保密转账**](/cn/explanation/confidential-transfer):了解 Stable 正在构建的隐私模型。 +- [**x402**](/cn/explanation/x402):理解代理对代理流程背后的结算协议。 diff --git a/docs/pages/cn/explanation/usdt-as-gas-token.mdx b/docs/pages/cn/explanation/usdt-as-gas-token.mdx index 5f59fb9..f68caa8 100755 --- a/docs/pages/cn/explanation/usdt-as-gas-token.mdx +++ b/docs/pages/cn/explanation/usdt-as-gas-token.mdx @@ -1,33 +1,34 @@ --- source_path: explanation/usdt-as-gas-token.mdx -source_sha: b672e8cd0f0a20007892a2ef01a8ac79eda14c2d -title: USDT as Gas -description: "USDT0 作为 Stable 原生 Gas 代币的工作原理,实现可预测的交易费用。" +source_sha: 8097bf3fd47c99a316f073bd5a34afccef59988a +title: USDT 作为 Gas +description: "USDT0 如何作为 Stable 的原生 Gas 代币,取代波动性资产,实现可预测的交易费用。" +diataxis: "explanation" --- -# USDT as Gas +# USDT 作为 Gas -Stable 是围绕 USDT 稳定币构建的。USDT0 是 USDT 的原生跨链版本,是支撑 Stable 生态系统的核心资产。 +**您使用 USDT0 支付费用。没有第二种代币,无需封装,无需充值 ETH 等值物。** USDT0 既是原生 Gas 代币,又是同一个余额上的 ERC-20 代币。用于支付的资产同时也可以支付发送该支付的交易费用。费用以美元计价,而不是波动的原生代币。 -## 摘要 +这种设计与以太坊的行为有所不同,影响了余额语义、授权安全性以及某些操作码的假设。如果您正在从以太坊移植合约,请在部署前参阅 [USDT0 在 Stable 上的行为](/cn/explanation/usdt0-behavior) 以获取迁移核对清单。 -Stable 是一个使用 USDT0 作为原生 Gas 代币的 EVM 兼容区块链。USDT0 同时作为 Gas 支付和价值转移的原生资产,以及支持 `approve`、`transfer`、`transferFrom` 和 `permit` 的 ERC20 代币。 +## 摘要 -这种设计让交易成本可预测并以美元计价,简化了用户体验。然而,它引入了与以太坊不同的行为差异,影响余额语义、授权安全性和某些操作码假设。 +Stable 是一个 EVM 兼容的区块链,使用 USDT0 作为其原生 Gas 代币。USDT0 同时作为用于 Gas 支付和价值转移的原生资产,以及支持 `approve`、`transfer`、`transferFrom` 和 `permit` 的 ERC-20 代币。 -本文档指定了 Stable 的 USDT0 Gas 机制,描述了由此产生的行为差异,并定义了在 Stable 上部署的智能合约所需和推荐的开发模式。 +本文档详细说明了 Stable 的 USDT0 Gas 机制,描述了由此产生的行为差异,并定义了在 Stable 上部署智能合约所需和推荐的开发模式。 ## 版本说明 -随着 Stable v1.2.0,USDT0 成为 Stable 上的原生 Gas 代币,取代了 gUSDT。作为此过渡的一部分: +随着 Stable v1.2.0 的发布,USDT0 成为 Stable 上的原生 Gas 代币,取代了 gUSDT。作为此次过渡的一部分: -- gUSDT 即将下线。 -- 现有的 gUSDT 余额会自动转换为 USDT0。 -- 用户和应用程序不再需要封包和解包代币来支付费用或转移价值。 +- gUSDT 正在逐步淘汰。 +- 现有的 gUSDT 余额将自动转换为 USDT0。 +- 用户和应用程序不再需要封装和解封装流程来支付费用或转移价值。 -在 v1.2.0 之后,USDT0 同时作为: +在 v1.2.0 之后,USDT0 同时用作: -- 网络费用资产(gas),以及 +- 网络费用资产(Gas),以及 - 具有 `approve`、`permit`、`transfer` 和 `transferFrom` 的标准 ERC20 代币。 ## 网络地址 @@ -40,56 +41,57 @@ USDT0 代币合约地址: ## 术语 - **Stable**:一个 EVM 兼容的区块链,其中 USDT0 是原生 Gas 代币。 -- **USDT0**:USDT 的原生跨链版本,同时作为: +- **USDT0**:USDT 的全链版本,既可以作为: - 用于 Gas 和价值转移的原生资产,以及 - 具有授权和许可语义的 ERC20 代币。 -- **原生余额**:由 `address(x).balance` 返回的余额,以 USDT0 计价。 -- **Gas 费**:在 EIP-1559 式费用市场下计算的以 USDT0 支付的交易费用。 +- **原生余额**:通过 `address(x).balance` 返回的余额,以 USDT0 计价。 +- **Gas 费**:以 USDT0 支付的交易费,根据 EIP-1559 风格的费用市场计算。 ## 什么是 USDT0? -USDT0 是使用 LayerZero 的全链可替代代币 (OFT) 标准的 USDT 的原生跨链版本。USDT0 与 USDT 1:1 锚定,旨在跨多个区块链移动,而无需传统的桥接工作流程或封包表示。 +USDT0 是 USDT 的全链表示,使用 LayerZero 的全链可替代代币(OFT)标准。USDT0 与 USDT 1:1 挂钩,旨在跨多个区块链移动,无需传统的桥接流程或封装表示。 -在跨链转移 USDT0 时,代币在某些源链上被锁定(取决于链的原生 USDT 支持)或销毁,然后通过 LayerZero 的跨链消息在目标链上铸造。这保持了 1:1 锚定,同时将流动性整合到单个可互操作的资产中,而不是分散的链本地池。 +当跨链转移 USDT0 时,代币将在某些源链(取决于链的原生 USDT 支持)上锁定或销毁。然后通过 LayerZero 的跨链消息传递在目标链上铸造。这在保持 1:1 锚定的同时,将流动性整合到一个可互操作的资产中,而不是分散的链本地池。 -对于用户,这可以实现更快的入门、降低的操作复杂性和改进的流动性流动性。 +对于用户而言,这可以实现更快的上手、降低操作复杂性并提高流动性移动性。 ## USDT0 和 Stable -USDT0 是支撑 Stable 链上经济和日常使用的核心资产。由于同一资产用于支付费用和转移价值,Stable 减少了以下方面的摩擦: +USDT0 是驱动 Stable 链上经济和日常使用的核心资产。由于相同的资产用于支付费用和转移价值,Stable 减少了以下方面的摩擦: -- **普通用户**:更简单的入门和更少的代币概念 +- **日常用户**:更简单的上手和更少的代币概念 - **开发人员**:更简单的费用和价值流 - **企业**:简化的会计和财务运营 -Stable 还可以通过允许用户通过 LayerZero 从其他网络入门 USDT0 来从第一天开始访问深度 USDT 流动性。 +Stable 还可以通过 LayerZero 使从其他网络迁移 USDT0 的用户从第一天起即可访问深厚的 USDT 流动性。 ## 假设和先决条件 -对于以下内容,读者应该理解: +对于以下内容,您需要了解: - Solidity 执行语义和原生价值转移 -- ERC20 授权机制和许可流程 -- 标准智能合约安全模式,包括 Checks-Effects-Interactions +- ERC20 授权机制和许可流 +- 标准智能合约安全模式,包括检查-效果-交互 ## 1. Gas 和费用模型 ### 1.1 概述 -Stable 以 USDT0 计价所有交易费用。Gas 定价遵循 EIP-1559 式模型,具有动态调整的基础费用。 +Stable 以 USDT0 计价所有交易费用。Gas 定价遵循 EIP-1559 风格的模型,具有动态调整的基础费用。 交易费用定义为: -``` +```text fee = gasUsed × baseFee ``` + 交易可以使用标准 EIP-1559 参数指定 `maxFeePerGas`。 -*注意:Stable 不支持优先小费。不要设置 `maxPriorityFeePerGas`,否则小费金额将丢失。* +*注意:Stable 不支持优先小费。请勿设置 `maxPriorityFeePerGas`,否则小费金额将丢失。* ### 1.2 交易提交 -客户端应从最近的区块获取最新的基础费用,并在计算 `maxFeePerGas` 时包含安全边际。 +客户端应从最新区块获取最新的基础费用,并在计算 `maxFeePerGas` 时包含安全边际。 示例(说明性): @@ -110,22 +112,22 @@ const maxFeePerGas = baseFee * 2n + maxPriorityFeePerGas; ## 2. Stable 如何启用 USDT0 作为 Gas 代币 -Stable 使用预扣费和退款结算模型在 USDT0 中收取 Gas 费。 +Stable 使用预充值和退款结算模型以 USDT0 收取 Gas。 ### 示例交易 -Alice 向 Bob 发送 100 USDT0。 +爱丽丝向鲍勃发送 100 USDT0。 -### 2.1 Ante-handler 阶段 +### 2.1 前置处理阶段 在 `MonoEVMAnteHandler` 中的交易验证期间: -1. 读取 Alice 的 USDT0 余额。 -2. 协议验证 Alice 可以覆盖: +1. 读取爱丽丝的 USDT0 余额。 +2. 协议验证爱丽丝是否可以支付: - 交易价值(100 USDT0),以及 - 最大可能的 Gas 费(`gasWanted × fee`)。 -3. 预先转移最大 Gas 费: - - `alice → fee_collector` 以 USDT0。 +3. 最大 Gas 费预付: + - `alice → fee_collector` 以 USDT0 支付。 ### 2.2 执行阶段 @@ -140,12 +142,12 @@ Alice 向 Bob 发送 100 USDT0。 执行后: -1. 协议计算预扣费的未使用部分: - ``` +1. 协议计算预充值费用中未使用的部分: + ```text refund = (gasWanted − gasUsed) × baseFee ``` -2. 退还未使用的费用: - - `fee_collector → alice` 以 USDT0。 +2. 未使用的费用被退还: + - `fee_collector → alice` 以 USDT0 支付。 ## 3. 余额语义和行为差异 @@ -155,8 +157,8 @@ Alice 向 Bob 发送 100 USDT0。 在 Stable 上,合约的原生 USDT0 余额也可能由于基于 ERC20 授权的操作而改变,包括 `transferFrom` 和 `permit`。这些操作可以在不调用任何合约代码的情况下减少合约的原生余额。 -因此,以下假设在 Stable 上无效: -- 合约的原生余额只能在合约被调用时减少。 +因此,以下假设在 Stable 上是无效的: +- 合约的原生余额只有在合约被调用时才会减少。 ## 4. 合约设计要求 @@ -164,7 +166,7 @@ Alice 向 Bob 发送 100 USDT0。 合约不得依赖内部变量来镜像原生余额。 -不安全模式的示例: +不安全模式示例: ```solidity uint256 public deposited; @@ -174,11 +176,11 @@ function deposit() external payable { } ``` -如果通过基于授权的转移耗尽 USDT0,此类变量可能与实际原生余额不同。 +如果 USDT0 通过基于授权的转账被消耗,此类变量可能会与实际原生余额不一致。 ### 4.2 必需模式:实际余额偿付能力检查 -所有原生价值转移必须在转移之前立即使用 `address(this).balance` 验证偿付能力。 +所有原生价值转移必须在转移前立即使用 `address(this).balance` 验证偿付能力。 示例: @@ -186,7 +188,7 @@ function deposit() external payable { require(address(this).balance >= amount, "insufficient balance"); ``` -提款必须遵循 Checks-Effects-Interactions 顺序: +提款必须遵循检查-效果-交互顺序: ```solidity uint256 amount = credit[msg.sender]; @@ -198,19 +200,19 @@ payable(msg.sender).call{value: amount}(""); ### 4.3 状态进展必须独立于余额 -依赖进展、里程碑或完成条件的协议逻辑必须使用非余额状态变量(如计数器或纪元)显式跟踪这些内容。 +依赖于进展、里程碑或完成条件的协议逻辑必须使用非余额状态变量(例如计数器或纪元)明确跟踪这些变量。 -原生余额只能在支付时用于偿付能力验证。 +原生余额只能用于支付时的偿付能力验证。 ### 4.4 授权暴露 托管用户资金的合约不应向外部地址授予 USDT0 授权。 -如果无法避免授权,合约应: +如果授权不可避免,合约应: - 仅批准确切金额 - 使用后立即重置授权 -- 将余额排空风险视为已知限制 +- 将剩余的消耗风险视为已知限制 ## 5. 地址状态假设 @@ -218,7 +220,7 @@ payable(msg.sender).call{value: amount}(""); 合约不得依赖 `EXTCODEHASH(addr) == 0x0` 来推断地址从未被使用过。 -任何地址使用的概念都必须在合约状态中显式跟踪。 +任何地址使用概念都必须在合约状态中明确跟踪。 示例: @@ -230,54 +232,54 @@ mapping(address => bool) public used; 在 Stable 上: -- 向 `address(0)` 的原生 USDT0 转移会回滚。 -- 向 `address(0)` 的 ERC20 USDT0 转移也会回滚。 +- 原生 USDT0 转移到 `address(0)` 会回滚。 +- ERC20 USDT0 转移到 `address(0)` 也会回滚。 -没有通过转移到零地址来销毁 USDT0 的支持机制。 +没有支持的机制通过转移到零地址来销毁 USDT0。 合约必须: - 明确拒绝 `address(0)` 作为接收者 - 重新设计任何假设零地址销毁的逻辑 -- 如果需要不可逆丢失语义,请使用显式接收合约 +- 如果需要不可逆的损失语义,请使用明确的接收合约 ## 7. 测试要求 Stable 部署的测试套件应包括: -- 基于授权的排空场景(`approve` + `transferFrom`) -- 使用实际原生余额的偿付能力执行 +- 基于授权的消耗场景(`approve` + `transferFrom`) +- 使用实际原生余额强制执行偿付能力 - 不依赖 `EXTCODEHASH` 的地址使用逻辑 -- 零地址转移的显式失败情况 +- 零地址转移的明确失败情况 -## 8. 迁移检查清单 +## 8. 迁移核对清单 将合约从以太坊移植到 Stable 时: -- 删除内部原生余额镜像 -- 用 `address(this).balance` 替换所有偿付能力检查 -- 删除所有到 `address(0)` 的原生或 ERC20 转移 -- 审计所有 USDT0 批准 -- 添加涵盖许可和基于授权流程的测试 +- 移除内部原生余额镜像 +- 将所有偿付能力检查替换为 `address(this).balance` +- 移除所有对 `address(0)` 的原生或 ERC20 转移 +- 审计所有 USDT0 审批 +- 添加涵盖许可和基于授权的流程的测试 ## 9. 总结 -Stable 使用 USDT0 作为 Gas 代币提供了可预测的费用和统一的价值会计,同时改变了关于原生余额行为的核心假设。 +Stable 使用 USDT0 作为 Gas 代币,提供可预测的费用和统一的价值核算,同时改变了对原生余额行为的核心假设。 -Stable 上的正确合约设计需要: +在 Stable 上正确进行合约设计需要: - 将 USDT0 视为双重角色资产 -- 针对实际余额执行偿付能力 -- 避免基于授权的余额排空 -- 消除对以太坊特有的余额及地址假设的依赖 +- 对实际余额强制执行偿付能力 +- 避免基于授权的消耗路径 +- 消除对以太坊特定余额和地址假设的依赖 ## 常见问题 -**我们现在使用 USDT0 作为封包的原生代币。升级后,哪个代币应该被视为封包的原生代币?** +**我们今天使用 USDT0 作为封装的原生代币。升级后,哪个代币应该被视为封装的原生代币?** -升级后,USDT0 既是原生代币又是 ERC-20 代币。您应该直接使用 USDT0,不再需要封包或解包。 +升级后,USDT0 既是原生代币又是 ERC-20 代币。您应该直接使用 USDT0,不再需要封装或解封装。 -**原始的 USDT0 合约地址(`0x779Ded0c9e1022225f8E0630b35a9b54bE713736`)会发生什么变化?** +**USDT0 原始合约地址 (`0x779Ded0c9e1022225f8E0630b35a9b54bE713736`) 会发生什么?** 没有任何变化。相同的地址仍然有效并继续代表 USDT0。 @@ -285,10 +287,16 @@ Stable 上的正确合约设计需要: 是的。升级后,原生代币标识符/地址是 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736`。 -**那么 `0x0000000000000000000000000000000000001000` 呢?它还会作为 gUSDT 的代币地址使用吗,我们应该保留它吗?** +**那 `0x0000000000000000000000000000000000001000` 呢?它仍然用作 gUSDT 的代币地址吗,我们应该保留它吗?** + +不。您可以将其删除。升级后将不再使用它。 + +**对于 DEX calldata,协议会停止使用 `0x0000000000000000000000000000000000001000` 作为“原生代币”标识符,转而使用 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736` 吗?** -不会。您可以删除它。升级后将不再使用它。 +是的。升级后,DEX 应使用 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736` 作为原生代币标识符。 -**对于 DEX calldata,协议是否会停止使用 `0x0000000000000000000000000000000000001000` 作为"原生代币"标识符,而改用 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736`?** +## 下一步推荐 -正确。升级后,DEX 应使用 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736` 作为原生代币标识符。 +- [**发送您的第一个 USDT0**](/cn/tutorial/send-usdt0):使用标准的 EVM 工具在测试网上提交 USDT0 传输。 +- [**Gas 定价**](/cn/reference/gas-pricing-api):根据 Stable 的单一组件费用模型构建交易。 +- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior):审计合约,检查双重角色资产语义、余额核对和 `EXTCODEHASH` 行为。 diff --git a/docs/pages/cn/explanation/usdt-features-overview.mdx b/docs/pages/cn/explanation/usdt-features-overview.mdx index 0c039ac..16f0fd8 100755 --- a/docs/pages/cn/explanation/usdt-features-overview.mdx +++ b/docs/pages/cn/explanation/usdt-features-overview.mdx @@ -1,19 +1,43 @@ --- source_path: explanation/usdt-features-overview.mdx -source_sha: e87a73a1555cb99466a5e342be525e638b2e005a -title: 概览 -description: "Stable USDT 专属功能概述,包括原生 Gas、保障区块空间与转账聚合。" +source_sha: 67a8a81a92b665ffc6eb9a704a78524905a219dd +title: "概述" +description: "Stable 五项 USDT 特有功能如何协同工作,使稳定币支付流程能够实际规模化应用。" +diataxis: "explanation" --- -# 概览 +# 概述 -## USDT 专属功能 +Stable 的 USDT 特定功能并非相互独立的选项集合。它们是组合搭配的。每项功能都消除了稳定币支付从演示走向生产时出现的特定摩擦。本页面解释了为什么这五项功能共同存在。 -Stable 是一条专为 USDT 打造的 Layer 1 区块链网络。协议的每一个组件都围绕 USDT 的无摩擦转账进行优化,致力于为全球最广泛使用的稳定币提供一个高性能、简洁流畅的运行环境。 +## 摩擦堆栈 -除了核心基础设施外,Stable 还提供一系列 USDT 专属功能,进一步提升整体用户体验: +大多数通用链上的稳定币支付架构都会遇到相同的堆栈问题: -- **USDT 作为 Gas Token**:USDT0 作为其原生 Gas 代币。USDT0 同时作为用于支付 Gas 和进行价值转移的原生资产,并作为支持 `approve`、`transfer`、`transferFrom` 和 `permit` 的 ERC20 代币。 -- **保证区块空间(Guaranteed Blockspace)**:保证区块空间是一种专为企业客户设计的区块容量分配模型,可保证其在任何网络条件下都拥有固定份额的区块资源,实现确定性延迟与费用。 -- **USDT0 转账聚合器(Transfer Aggregator)**:通过隔离并聚合 USDT0 转账交易,实现极致吞吐量的同时,确保公平性且不影响其他交易类型。 -- **隐私转账(Confidential Transfer)**:Stable 计划采用零知识加密(ZK Cryptography)实现加密的 USDT 转账。交易金额将在链上隐藏,同时保留发送方与接收方地址公开,以满足合规审计需求。 +1. **用户必须持有第二种代币** (ETH, SOL) 才能支付移动稳定币交易的 gas 费。这是一个导致转化率下降的入门步骤。 +2. **即使有第二种代币,用户也必须支付 gas 费。** 这打破了商家和支付应用所需要的“一美元对一美元”的心智模型。 +3. **交易成本随网络活动而波动。** 工资发放、财务运营和批量结算无法规划成本或包含性。 +4. **每笔交易的限制限制了吞吐量。** 大量 USDT 资金流会遇到全链竞争,并与不相关的活动一样降低性能。 +5. **每笔交易都可公开观察。** 供应商付款、薪资发放和财务转移会泄露具有商业敏感性的数据。 + +## 功能如何协同 + +Stable 通过专用机制解决每个摩擦: + +| 摩擦 | 机制 | 页面 | +| :--- | :--- | :--- | +| 单独的 Gas 代币 | USDT0 是原生 Gas 代币 | [USDT 作为 Gas](/cn/explanation/usdt-as-gas-token) | +| 用户支付所有 Gas 费 | 治理授权的豁免涵盖 Gas 费 | [Gas 豁免](/cn/explanation/gas-waiver) | +| 成本和包含性差异 | 为注册合作伙伴保留区块容量 | [保证的区块空间](/cn/explanation/guaranteed-blockspace) | +| 吞吐量上限 | 并行化 USDT0 传输批处理 | [USDT 传输聚合器](/cn/explanation/usdt-transfer-aggregator) | +| 公开金额可见性 | 通过 ZK 加密实现选择性隐私 | [保密传输](/cn/explanation/confidential-transfer) | + +其中任何一项都有帮助。将它们结合起来,它们使 Stable 成为一个支付团队可以像在传统卡网络上一样建模成本、延迟和隐私的链,同时具有区块链的结算终结性。 + +有关 Stable 与通用 EVM 链之间所有差异的完整信息,请参阅[以太坊对比](/cn/explanation/ethereum-comparison)。有关 USDT 端到端通过这些功能的实际示例,请参阅[资金流转](/cn/explanation/flow-of-funds)。 + +## 下一步建议 + +- [**USDT 作为 Gas**](/cn/explanation/usdt-as-gas-token):了解同时替代 ETH 作为 Gas 和支付的资产。 +- [**资金流转**](/cn/explanation/flow-of-funds):追踪 USDT 从入金到链上转移再到出金结算的整个过程。 +- [**桥接到 Stable**](/cn/explanation/usdt0-bridging):了解 USDT0 如何从其他链转移到 Stable。 diff --git a/docs/pages/cn/explanation/usdt-transfer-aggregator.mdx b/docs/pages/cn/explanation/usdt-transfer-aggregator.mdx index dab4e81..131943c 100755 --- a/docs/pages/cn/explanation/usdt-transfer-aggregator.mdx +++ b/docs/pages/cn/explanation/usdt-transfer-aggregator.mdx @@ -1,78 +1,84 @@ --- source_path: explanation/usdt-transfer-aggregator.mdx -source_sha: 5bb6c55476a5ceeb97e510d458c977ec91c2a539 +source_sha: 23229418f878c0594cd6e8e891e188b95df6c4ec title: "USDT 转账聚合器" -description: "将大批量 USDT0 转账打包为并行化、高容错结算的 USDT 转账聚合机制。" +description: "USDT 转账聚合器将大批量 USDT0 转账批量处理成并行、容错的结算。" +diataxis: "explanation" --- # USDT 转账聚合器 -作为一条专为 USDT 交易优化的区块链,Stable 被设计用于处理极高频次的代币转账,同时保持系统的整体响应。为了在优化 USDT 特定性能的同时兼顾一般交易的多样性,Stable 引入了 USDT 转账聚合器机制。这是一种高效、可扩展的解决方案,可对 USDT0 转账进行高度并行化和容错处理。 +**USDT 转账聚合器**将 USDT0 转账打包成并行、容错的批次,而不是按顺序处理每笔转账。它将 USDT0 的吞吐量与执行管道的其余部分隔离开来,因此大批量的稳定币活动不会挤占其他交易。 -## 为什么需要 USDT 转账聚合器? +:::note +**计划中。** 聚合器是一个具有前瞻性的路线图项目。以下内容描述了目标设计。有关时间安排,请参阅[路线图](/cn/explanation/technical-roadmap)。 +::: -支持大规模 USDT 使用的挑战在于如何同时优化吞吐量和保持不同交易处理的公平性: +## 存在原因 -- 传统的 ERC20 代币转账按顺序处理,在高交易负载下成为性能瓶颈。 -- 如果仅优先考虑 USDT 的吞吐量,可能会排挤其他交易,导致整条链的性能下降。 +两个约束相互拉扯: -USDT 转账聚合器通过将 USDT 转账隔离优化,避免影响执行流程中的其他部分,从而解决了这一矛盾。 +- 传统的 ERC-20 转账是按顺序处理的。在高负载下,这是一个瓶颈。 +- 简单地给 USDT0 优先级会挤占其他交易并降低一般链性能。 -## 并行聚合与验证 - -> *以下内容基于当前战略规划,属于前瞻性设计。随着经验积累和优先级调整,路线图可能会有所更新。* -> +聚合器通过将 USDT0 转账拉入专门的并行管道来解决这个问题,使主执行路径保持不变,以处理其他所有事务。 -聚合系统的核心是一个可并行化的聚合与验证管道,灵感来自 `MapReduce` 计算模型。系统不再按顺序处理每一笔转账,而是以批次为单位,聚合所有账户的输入输出后,再统一进行余额更新。 +## 并行聚合与验证 -### 关键流程 +转账聚合系统的核心是可并行化的聚合与验证管道,其灵感来自 `MapReduce` 计算模型。系统不是按顺序处理每笔转账,而是执行捆绑级别的计算,在执行余额更新之前聚合跨账户的输入和输出。 -1. **账户差异聚合(Aggregate Account Diffs)** - - 每笔转账都映射到发送方与接收方。 - - 为每个账户生成一个差异日志(diff journal),代表该账户的净变化: - - 发送总额为负值。 - - 接收总额为正值。 +### 关键步骤 +1. **聚合账户差异** + - 每笔转账都映射到发送方和接收方。 + - 为每个账户生成一个代表净代币移动的差异日志: + - 借记总额(发送)为负值。 + - 贷记总额(接收)为正值。 2. **余额验证** - - 系统确保全局余额守恒:总输入等于总输出。 - - 每个账户的净变动通过并行方式独立验证资金是否充足。 - - 资金不足的账户将被标记,但不会影响该批次执行。 - -3. **MapReduce 并行模型** - - **Map 阶段**:根据所有收支转账计算每个账户的净变化值。 - - **Reduce 阶段**:聚合这些变化以确定最终状态更新。 + - 系统确保全局余额不变量:总输入等于总输出。 + - 每个账户的净变化都独立并行验证,以确认资金充足。 + - 资金不足的账户会被标记,而不会暂停捆绑。 +3. **用于并行的 MapReduce 模型** + - **Map 阶段**:根据所有传入/传出转账计算每个账户的净增量。 + - **Reduce 阶段**:聚合这些增量以确定最终状态更新。 ## 技术亮点 ### 并行计算模型 -- 利用预编译合约实现余额校验与差异计算的并行处理。 -- 相比传统的串行 ERC20 执行,大幅减少执行时间。 +- 利用预编译合约中的并行性来并发检查余额和计算差异。 +- 与传统的顺序 ERC20 处理相比,大大减少了执行时间。 -### 依赖关系分析 +### 依赖分析 -- 识别转账之间的依赖关系(如多个发送来自同一账户)。 -- 预先标记高风险转账(如可能余额不足),以减少级联失败。 +- 识别重叠转账(例如,来自同一账户的多次发送)。 +- 预先标记高风险转账(例如,可能资金不足),以最大限度地减少级联故障。 ### 模块化故障处理 -- 转账在账户级别上被隔离,只有出现问题的账户会被影响。 -- 无冲突的转账将正常执行与确认,不受影响。 +- 转账在账户级别进行隔离,因此只有有问题的账户受到影响。 +- 非冲突转账正常执行并最终确定。 + +### 选择性故障处理 + +传统的转账处理在一个区块内是全有或全无的。Stable 的聚合模型引入了细粒度的、按账户的故障隔离: -### 选择性失败处理 +- 如果账户的 `当前余额 + 净差异 < 0`,系统仅将该账户的转账标记为失败。 +- 涉及其他账户的转账照常进行。 +- 这种选择性回滚机制确保无效或恶意转账不会损害整个捆绑的完整性。 -传统的转账处理在一个区块中通常是“要么全部成功,要么全部失败”。Stable 的聚合模型引入了更精细的账户级失败隔离机制: +## 提议者驱动或基于声誉的排序 -- 若某账户的 `当前余额 + 净变化 < 0`,系统只标记该账户的转账失败。 -- 涉及其他账户的转账将正常继续执行。 -- 此选择性回滚机制确保无效或恶意转账不会破坏整个批次的完整性。 +为了进一步优化执行并避免状态冲突,Stable 结合了聚合转账的预处理排序机制: -## 提议者驱动或声誉排序机制 +- **基于声誉的排序**:具有良好历史或经验证可靠性的发送方被优先处理,从而降低失败和重新排序的风险。 +- **基于提议者的排序**:交易可以由受信任的提议者节点排序,该节点构建捆绑以最大程度地减少冲突并最大化吞吐量。 +- **捆绑转账优先**:聚合的 USDT 转账优先于一般交易,从而减少依赖冲突并开启更清晰的执行窗口。 -为进一步优化执行并避免状态冲突,Stable 对聚合转账引入预处理排序机制: +Stable 的 USDT 转账聚合器是一种有针对性的优化,可在不降低一般交易处理速度的情况下最大限度地提高 USDT0 转账的吞吐量。通过结合并行执行、模块化故障处理和智能排序策略,Stable 为稳定币驱动的经济提供了可扩展的基础。快速、频繁和无摩擦的代币转账成为常态。 -- **基于声誉的排序**:拥有良好交易历史或信誉的账户优先执行,降低失败率与重新排序成本。 -- **提议者排序**:可信提议者节点可根据依赖关系排序交易,减少冲突并提高吞吐。 -- **聚合转账优先执行**:聚合后的 USDT 转账优先于一般交易执行,减少依赖冲突,释放执行空间。 +## 下一步建议 -Stable 的 USDT 转账聚合器机制是一项针对性优化,能够在不影响通用交易处理性能的前提下,最大化 USDT0 转账的吞吐量。通过结合并行执行、模块化失败处理与智能排序策略,Stable 为以稳定币驱动的经济体提供了高扩展性的基础架构,使快速、频繁、无摩擦的代币转账成为常态。 +- [**支付用例**](/cn/explanation/payment-use-cases-overview):查看从聚合吞吐量中受益最大的支付模式:P2P、订阅、按次付费。 +- [**执行**](/cn/explanation/execution):查看聚合器构建于其上的并行执行引擎。 +- [**USDT 作为 Gas**](/cn/explanation/usdt-as-gas-token):了解聚合器所移动的资产模型。 diff --git a/docs/pages/cn/explanation/usdt0-behavior.mdx b/docs/pages/cn/explanation/usdt0-behavior.mdx index eb03c5f..662acee 100644 --- a/docs/pages/cn/explanation/usdt0-behavior.mdx +++ b/docs/pages/cn/explanation/usdt0-behavior.mdx @@ -1,69 +1,69 @@ --- source_path: explanation/usdt0-behavior.mdx -source_sha: f89e6903b80296f17e2bf1fc9e76ab88b15175c6 +source_sha: 17a1c5d1a4aae70266159154d52063d08fbb0378 title: "USDT0 在 Stable 上的行为" -description: "USDT0 在 Stable 上同时作为原生资产和 ERC-20 代币运行。请审计合约的余额对账、授权安全和操作码行为。" +description: "USDT0 在 Stable 上既是原生资产又是 ERC-20 代币。审计合约以进行余额核对、代币许可安全和操作码行为检查。" diataxis: "explanation" --- # USDT0 在 Stable 上的行为 -**如果你正在从 Ethereum 移植合约,请在部署前阅读本页。** Stable 上的 USDT0 既是原生 gas 代币,又是基于同一余额的 ERC-20 代币。因此,四个在 Ethereum 上被假定成立的行为会失效:合约的原生余额可以在没有调用该合约的情况下发生变化;`EXTCODEHASH` 可能在零值和空哈希之间来回切换;向零地址转账会回滚;并且单个逻辑转账可能因小数余额对账而发出多个 `Transfer` 事件。 +**如果你正在从以太坊移植合约,在部署前请阅读此页面。** Stable 上的 USDT0 既是原生 Gas 代币,又是同一个余额上的 ERC-20 代币。因此,四种以太坊假定的行为会受到影响:合约的原生余额会未调用合约而发生变化,`EXTCODEHASH` 可以在零和空哈希之间振荡,零地址转账会回滚,以及一个逻辑转账可能会由于小数余额核对而发出多个 `Transfer` 事件。 -本页将逐一讲解这些情况,并提供安全的合约模式。如果你只读一节,请阅读 [迁移检查清单](#migration-checklist)。它是“把你的 Ethereum 合约移植到这里”的摘要。 +本页面将详细介绍每种情况,并提供安全的合约模式。如果你只阅读一个部分,请阅读[迁移清单](#migration-checklist)。这是将你的以太坊合约移植到这里的摘要。 ## 双重角色概述 -Stable 上的 USDT0 既是原生 gas 代币,又是 ERC-20 代币。这种双重角色模型影响余额行为、合约设计和事件处理。下面各节将逐一讲解双重角色改变预期行为的每种情况。 +Stable 上的 USDT0 既是原生 Gas 代币,又是 ERC-20 代币。这种双重角色模型会影响余额行为、合约设计和事件处理。以下各节将详细介绍双重角色改变预期行为的每种情况。 -关于 USDT0 为何以这种方式运行的背景信息,请参阅 [USDT 作为 gas](/cn/explanation/usdt-as-gas-token)。要通过真实转账体验这种行为,请参阅 [发送你的第一笔 USDT0](/cn/tutorial/send-usdt0)。 +有关 USDT0 为什么以这种方式运行的背景信息,请参阅[USDT 作为 Gas](/cn/explanation/usdt-as-gas-token)。要通过真实转账体验这种行为,请参阅[发送你的第一个 USDT0](/cn/tutorial/send-usdt0)。 -## 余额对账 +## 余额核对 -USDT0 作为原生资产使用 18 位小数,作为 ERC-20 代币使用 6 位小数。原生转账和 ERC-20 转账操作的是同一底层余额,但 12 位的精度差距意味着当转账涉及亚整数精度时,系统必须对小数金额进行对账。 +USDT0 作为原生资产使用 18 位小数,作为 ERC-20 代币使用 6 位小数。原生转账和 ERC-20 转账在同一个底层余额上操作,但 12 位的精度差距意味着当转账涉及小于整数的精度时,系统必须核对小数金额。 -``` +```text before - 0.000001 USDT0 (ERC-20) + 0.000000000000000000 USDT0 (internal) + 0.000001 USDT0 (ERC-20) + 0.000000000000000000 USDT0 (内部) // address(account).balance = 0.000001000000000000 // USDT0.balanceOf(account) = 0.000001 -if transfer 0.0000001 USDT0 to another account +如果将 0.0000001 USDT0 转账到另一个账户 after - 0.000000 USDT0 (ERC-20) + 0.000000900000000000 USDT0 (internal) + 0.000000 USDT0 (ERC-20) + 0.000000900000000000 USDT0 (内部) // address(account).balance = 0.000000900000000000 // USDT0.balanceOf(account) = 0.000000 ``` -这可能导致 `address(account).balance` 和 `USDT0.balanceOf(account)` 之间相差最多 0.000001 USDT0。 +这可能导致 `address(account).balance` 和 `USDT0.balanceOf(account)` 最多相差 0.000001 USDT0。 ## 事件处理 -每次对账转账都会发出一个额外的 `Transfer` 事件。单个逻辑 USDT0 转账可能产生最多两个额外的 `Transfer` 事件,具体取决于发送方和接收方的小数余额受到怎样的影响: +每次核对转账都会发出一个额外的 `Transfer` 事件。一次逻辑上的 USDT0 转账最多可以产生两个额外的 `Transfer` 事件,具体取决于发送方和接收方小数余额受到的影响: -- **发送方调整**:如果发送方的小数余额不足,0.000001 USDT0 会从发送方转移到储备地址。这会发出一个额外的 `Transfer` 事件。 -- **接收方调整**:如果接收方的小数余额溢出,0.000001 USDT0 会从储备地址转移到接收方。这会发出一个额外的 `Transfer` 事件。 -- **两者同时调整**:如果同一次转账中两种情况都发生,则绕过储备地址。发送方在主转账中直接将 0.000001 USDT0 转给接收方。不会发出额外的事件。 +- **发送方调整**:如果发送方的小数余额不足,0.000001 USDT0 会从发送方转移到保留地址。这会发出一个额外的 `Transfer` 事件。 +- **接收方调整**:如果接收方的小数余额溢出,0.000001 USDT0 会从保留地址转移到接收方。这会发出一个额外的 `Transfer` 事件。 +- **双向调整**:如果两个条件在同一笔转账中发生,则会绕过保留地址。发送方会将 0.000001 USDT0 作为主转账的一部分直接转账给接收方。不会发出额外的事件。 -这些辅助事件涉及储备地址 `0x5113954bbC0eD721F1C68671EBa3d91e9e9bF7b5`。通过重放 `Transfer` 事件来跟踪 USDT0 余额的索引器和链下服务,必须过滤或考虑进出该地址的转账。 +这些辅助事件涉及保留地址 `0x5113954bbC0eD721F1C68671EBa3d91e9e9bF7b5`。通过重放 `Transfer` 事件来跟踪 USDT0 余额的索引器和链下服务必须过滤或考虑进出此地址的转账。 ## 合约设计要求 ### 原生余额可变性 -在 Ethereum 上,合约的原生余额通常仅因合约执行而发生变化。在 Stable 上,合约的原生 USDT0 余额还可能因基于 ERC-20 授权的操作而变化,包括 `transferFrom` 和 `permit`。这些操作可以在不调用任何合约代码的情况下减少合约的原生余额。 +在以太坊上,合约的原生余额通常只因合约执行而改变。在 Stable 上,合约的原生 USDT0 余额也可能因基于 ERC-20 许可的操作而改变,包括 `transferFrom` 和 `permit`。这些操作可以在不调用任何合约代码的情况下减少合约的原生余额。 因此,以下假设在 Stable 上是无效的: -> 只有在合约被调用时,合约的原生余额才会减少。 +> 合约的原生余额只有在合约被调用时才会减少。 ### 不要镜像原生余额 -在 Ethereum 上,使用内部变量跟踪存款是很常见的做法。在 Stable 上,这是不安全的,因为 ERC-20 `transferFrom` 可以从外部抽空原生余额。 +在以太坊上,使用内部变量跟踪存款是很常见的。在 Stable 上,这是不安全的,因为 ERC-20 `transferFrom` 可以在外部耗尽原生余额。 ```solidity -// UNSAFE on Stable +// 在 Stable 上不安全 uint256 public deposited; function deposit() external payable { @@ -71,55 +71,55 @@ function deposit() external payable { } ``` -### 转账前始终检查真实余额 +### 在转账前始终检查真实余额 -所有原生价值转账必须在转账之前使用 `address(this).balance` 验证偿付能力,而不是使用内部记账变量: +所有原生价值转账都必须在转账前使用 `address(this).balance` 验证偿付能力,而不是内部会计变量: ```solidity -// SAFE +// 安全 function withdraw() external { uint256 amount = credit[msg.sender]; credit[msg.sender] = 0; - require(address(this).balance >= amount, "insufficient balance"); + require(address(this).balance >= amount, "余额不足"); payable(msg.sender).call{value: amount}(""); } ``` -### 状态推进必须与余额无关 +### 状态进展必须与余额无关 -依赖于进度、里程碑或完成条件的协议逻辑,必须使用非余额状态变量(如计数器或纪元)显式跟踪这些状态。原生余额应仅在支付时用于偿付能力验证。 +依赖于进展、里程碑或完成条件的协议逻辑必须使用非余额状态变量(例如计数器或纪元)明确跟踪这些条件。原生余额应仅用于支付时的偿付能力验证。 -### 禁止零地址转账 +### 无零地址转账 -在 Stable 上,向 `address(0)` 进行原生转账和 ERC-20 转账都会回滚。 +在 Stable 上,无论是原生转账还是 ERC-20 转账到 `address(0)` 都会回滚。 ```solidity -// REVERT on Stable +// 在 Stable 上回滚 payable(address(0)).call{value: amount}("") USDT0.transfer(address(0), amount); ``` -任何发送原生 USDT0 的合约逻辑都应在转账调用之前验证接收方,并显式拒绝 `address(0)`: +任何发送原生 USDT0 的合约逻辑都应在转账调用前验证接收方并明确拒绝 `address(0)`: ```solidity -// SAFE -require(recipient != address(0), "zero address recipient"); +// 安全 +require(recipient != address(0), "零地址接收方"); payable(recipient).call{value: amount}(""); ``` -如果合约使用零地址转账作为销毁机制,则必须重新设计。如果需要不可逆的损失语义,请使用显式的销毁(sink)合约。 +如果合约使用零地址转账作为销毁机制,则必须重新设计。如果需要不可逆转的损失语义,请使用显式接收器合约。 ### EXTCODEHASH 行为 -在 Ethereum 上,`EXTCODEHASH` 操作码返回: +在以太坊上,`EXTCODEHASH` 操作码返回: -- **零哈希**(`0x0000...`):如果某地址从未被使用过(nonce=0、balance=0、无代码)。 -- **空哈希**(`0xc5d2…a470`,即空代码的 Keccak-256 哈希):如果某地址存在但没有代码。 +- **零哈希** (`0x0000...`):如果一个地址从未使用过(nonce=0,balance=0,无代码)。 +- **空哈希** (`0xc5d2…a470`,空代码的 Keccak-256 哈希):如果一个地址存在但没有代码。 -在 Ethereum 上,一旦某地址从零哈希转换为空哈希,它就无法再回到零哈希。在 Stable 上,由于 USDT0 支持基于 `permit()` 的授权,地址可以在不发送交易的情况下创建授权。结合 `transferFrom()`,这允许原生余额在 nonce 不递增的情况下发生变化,从而可能使 `EXTCODEHASH` 在零哈希和空哈希之间来回切换。 +在以太坊上,一旦一个地址从零哈希变为为空哈希,它就不能再返回到零哈希。在 Stable 上,因为 USDT0 支持基于 `permit()` 的许可,一个地址可以创建许可而无需发送交易。结合 `transferFrom()`,这允许在不增加 nonce 的情况下更改原生余额,这可能导致 `EXTCODEHASH` 在零哈希和空哈希之间振荡。 ```solidity -// UNSAFE on Stable +// 在 Stable 上不安全 function isUnusedAddress(address addr) public view returns (bool) { bytes32 codeHash; assembly { @@ -132,7 +132,7 @@ function isUnusedAddress(address addr) public view returns (bool) { 请改用显式跟踪: ```solidity -// SAFE +// 安全 contract SafeAddressTracker { mapping(address => bool) public hasBeenUsed; @@ -148,40 +148,40 @@ contract SafeAddressTracker { ## 测试要求 -针对 Stable 部署的测试套件应包括: +Stable 部署的测试套件应包括: -- 基于授权的抽空场景(`approve` + `transferFrom`) +- 基于许可的耗尽场景(`approve` + `transferFrom`) - 使用真实原生余额强制执行偿付能力 - 不依赖 `EXTCODEHASH` 的地址使用逻辑 -- 零地址转账的显式失败案例 +- 零地址转账的明确失败情况 -## 迁移检查清单 +## 迁移清单 -从 Ethereum 移植合约到 Stable 时: +将合约从以太坊移植到 Stable 时: - 移除内部原生余额镜像 - 将所有偿付能力检查替换为 `address(this).balance` -- 移除所有向 `address(0)` 的原生或 ERC-20 转账 -- 审计所有 USDT0 授权 -- 添加涵盖 `permit` 和基于授权流程的测试 -- 验证链下索引器能够处理来自小数余额对账的辅助 `Transfer` 事件 +- 移除所有到 `address(0)` 的原生或 ERC-20 转账 +- 审计所有 USDT0 许可 +- 添加涵盖 `permit` 和基于许可流程的测试 +- 验证链下索引器是否处理小数余额核对产生的辅助 `Transfer` 事件 ## 关键要点 -在 Stable 上正确的合约设计需要: +在 Stable 上进行正确的合约设计需要: - 将 USDT0 视为双重角色资产 -- 针对真实余额强制执行偿付能力 -- 避免基于授权的抽空路径 -- 消除对 Ethereum 特定余额和地址假设的依赖 +- 根据真实余额强制执行偿付能力 +- 避免基于许可的耗尽路径 +- 消除对以太坊特定余额和地址假设的依赖 链下服务和索引器应: -- 考虑来自小数余额对账的辅助 `Transfer` 事件 -- 使用直接余额查询,而不是基于事件的余额重构 +- 考虑小数余额核对产生的辅助 `Transfer` 事件 +- 使用直接余额查询而不是基于事件的余额重建 -## 推荐的后续阅读 +## 推荐阅读 -- [**USDT 作为 gas**](/cn/explanation/usdt-as-gas-token) — 理解 USDT0 为何同时作为原生资产和 ERC-20 代币运行。 -- [**发送你的第一笔 USDT0**](/cn/tutorial/send-usdt0) — 在测试网上通过原生和 ERC-20 路径提交一笔 USDT0 转账。 -- [**Ethereum 对比**](/cn/explanation/ethereum-comparison) — 查看从 Ethereum 移植时的每一处行为差异。 +- [**USDT 作为 Gas**](/cn/explanation/usdt-as-gas-token):了解 USDT0 为什么既作为原生资产又作为 ERC-20 代币运行。 +- [**发送你的第一个 USDT0**](/cn/tutorial/send-usdt0):在测试网上通过原生和 ERC-20 路径提交 USDT0 转账。 +- [**以太坊对比**](/cn/explanation/ethereum-comparison):查看从以太坊移植时的所有行为差异。 diff --git a/docs/pages/cn/explanation/usdt0-bridging.mdx b/docs/pages/cn/explanation/usdt0-bridging.mdx index 0c4c7ac..8a78fca 100644 --- a/docs/pages/cn/explanation/usdt0-bridging.mdx +++ b/docs/pages/cn/explanation/usdt0-bridging.mdx @@ -1,48 +1,48 @@ --- source_path: explanation/usdt0-bridging.mdx -source_sha: a85e32a5812a12a5f3c2161fd245a44c27bde59d -title: "跨链桥接到 Stable" -description: "USDT0(OFT Mesh)和原生 USDT(Legacy Mesh)跨链桥接到 Stable 的机制。" +source_sha: 5f1ebb65fed31c4fdb6210c4644248cff79ad5a7 +title: "桥接到 Stable" +description: "USDT0 (OFT Mesh) 和原生 USDT (Legacy Mesh) 跨链桥接到 Stable 的机制。" diataxis: "explanation" --- -# 跨链桥接到 Stable +# 桥接到 Stable -USDT 通过两条桥接路径之一进入 Stable,具体取决于它在源链上的形态。这两条路径都会将 USDT0 交付到用户在 Stable 上的钱包。 +USDT 通过以下两种桥接路径之一到达 Stable,具体取决于它在源链上的形式。这两种路径都将 USDT0 交付到用户在 Stable 上的钱包。 :::note -**两条路径,同一结果:** -- **OFT Mesh**:源链已经拥有 USDT0。在源链上销毁,在 Stable 上铸造。跨链 1:1。示例:Arbitrum、Ethereum、Optimism、Polygon、Unichain、Ink、Bera、Mantle、Hyperliquid、MegaETH(共 21 条链)。 -- **Legacy Mesh**:源链仅有原生 USDT。通过 Arbitrum 作为枢纽进行路由。对转账金额收取 0.03% 费用。示例:Tron、TON。 +**两条路径,一个结果:** +- **OFT Mesh**:源链已有 USDT0。在源链上销毁,在 Stable 上铸造。跨链 1:1。示例:Arbitrum, Ethereum, Optimism, Polygon, Unichain, Ink, Bera, Mantle, Hyperliquid, MegaETH (总共 21 条链)。 +- **Legacy Mesh**: 源链只有原生 USDT。通过 Arbitrum 作为中心路由。收取转账金额的 0.03% 手续费。示例:Tron, TON。 ::: -下面各节将详细描述每条路径。 +以下部分详细描述了每条路径。 ## USDT0 OFT Mesh 与 Legacy Mesh -Stable 参与两个互补的跨链转账网络。 +Stable 参与了两个相互补充的跨链传输网络。 ### OFT Mesh -任何支持 USDT0 的链都可以参与 OFT Mesh。在 OFT Mesh 内,USDT0 跨链转账保持 1:1 的价值比率。当发生转账时,源链上的 USDT0 代币被销毁,并在目标链上铸造等量的代币。当前 OFT Mesh 参与者包括 Arbitrum、Bera、Conflux、Ethereum、Flare、Hedera、Hyperliquid、Ink、Mantle、MegaETH、Monad、Morph、MP1、Optimism、Plasma、Polygon、Rootstock、Sei、Stable、Tempo、Unichain 和 X Layer。 +任何支持 USDT0 的链都可以参与 OFT Mesh。在 OFT Mesh 中,USDT0 跨链传输保持 1:1 的价值比。当发生传输时,源链上的 USDT0 代币被销毁,并在目标链上铸造等量的代币。当前的 OFT Mesh 参与者包括 Arbitrum, Bera, Conflux, Ethereum, Flare, Hedera, Hyperliquid, Ink, Mantle, MegaETH, Monad, Morph, MP1, Optimism, Plasma, Polygon, Rootstock, Sei, Stable, Tempo, Unichain, 和 X Layer。 ### Legacy Mesh -任何拥有原生 USDT(而非 USDT0)的链都可以通过 Legacy Mesh 进行路由。Legacy Mesh 采用枢纽辐射式架构,由 Arbitrum 作为 USDT0 的中央枢纽。该模型利用 Arbitrum 上的 USDT0 流动性池。USDT0 团队对转账金额收取 0.03% 的费用。当前 Legacy Mesh 参与者包括 Tron 和 TON。 +任何拥有原生 USDT(而非 USDT0)的链都可以通过 Legacy Mesh 进行路由。Legacy Mesh 遵循中心辐射架构,Arbitrum 作为 USDT0 的中心枢纽。这种模式利用了 Arbitrum 上的 USDT0 流动性池。USDT0 团队对转账金额收取 0.03% 的手续费。当前的 Legacy Mesh 参与者包括 Tron 和 TON。 -Ethereum 和 Arbitrum 同时参与两个 Mesh:这些链上的用户可以通过 OFT 路径(销毁/铸造 USDT0)或 Legacy 路径(通过 Arbitrum 枢纽锁定原生 USDT)进行桥接。 +Ethereum 和 Arbitrum 同时参与了这两种 Mesh:这些链上的用户可以通过 OFT 路径(销毁/铸造 USDT0)或 Legacy 路径(通过 Arbitrum 枢纽锁定原生 USDT)进行桥接。 --- -## 路径 1:将 USDT0 桥接到 Stable(OFT 支持的链) +## 路径 1:将 USDT0 桥接到 Stable (OFT 支持的链) -当用户已在 OFT 支持的源链(如 Arbitrum 或 Ink)上持有 USDT0 时,适用此路径。 +当用户已经在 OFT 支持的源链(如 Arbitrum 或 Ink)上持有 USDT0 时,此路径适用。 -### 参与方 +### 参与者 | 名称 | 链上? | 负责方 | | --- | --- | --- | -| 用户 | N/A | 用户 | +| 用户 | 不适用 | 用户 | | USDT0 OUpgradable | ✅ | USDT0 的智能合约 | | LayerZero Endpoint V2 | ✅ | LayerZero 的智能合约 | | MessageLib Registry | ✅ | LayerZero 的智能合约 | @@ -53,53 +53,53 @@ Ethereum 和 Arbitrum 同时参与两个 Mesh:这些链上的用户可以通 ### 流程图 -将 USDT0 桥接到 Stable:OFT Mesh 流程 +将 USDT0 桥接到 Stable: OFT Mesh 流程 ### 详细步骤 -#### 1. 发起转账(链上,源链) +#### 1. 启动传输 (链上,源链) -用户在源链上的 **USDT0 OUpgradable** 合约上调用 `lzSend` 方法。该交易包含消息负载、目标 LayerZero 端点和合约地址,以及诸如 gas 上限和费用等配置参数。 +用户在源链上的 **USDT0 OUpgradable** 合约上调用 `lzSend` 方法。交易包括消息负载、目标 LayerZero 端点和合约地址,以及诸如 gas 限制和费用之类的配置参数。 -#### 2. 数据包创建(链上,源链) +#### 2. 包创建 (链上,源链) -源 LayerZero 端点打包 OApp 的消息,使用指定的源 MessageLib 合约对其进行编码,并将其发送到安全栈(DVN)和 Executor,完成发送交易。 +源 LayerZero Endpoint 封装 OApp 的消息,使用指定的源 MessageLib 合约对其进行编码,并将其发送到 Security Stack (DVNs) 和 Executor,完成发送交易。 -#### 3. 消息验证(链下,DVN) +#### 3. 消息验证 (链下,DVNs) -去中心化验证网络(DVN)在目标合约执行消息之前独立验证消息。只有获得 OApp 授权的 DVN 才能执行验证。USDT0 桥接要求三个 DVN 对每条消息进行签名:LayerZero Labs、Canary 和 USDT0。要查看任何路径上的规范配置,请参阅 [LayerZeroScan 上 USDT0 的 OApp](https://layerzeroscan.com/)。 +去中心化验证网络 (DVNs) 在目标合约执行消息之前独立验证消息。只有 OApp 授权的 DVN 才能执行验证。USDT0 桥接需要三个 DVN 签署每条消息:LayerZero Labs、Canary 和 USDT0。对于任何路径的规范配置,请参阅 [LayerZeroScan 上的 USDT0 OApp](https://layerzeroscan.com/)。 -#### 4. 标记为可验证(链上,Stable) +#### 4. 标记为可验证 (链上,Stable) -一旦所有所需的 DVN 验证了消息,目标 MessageLib 合约就会将其标记为可验证。 +一旦所有必需的 DVN 验证了消息,目标 MessageLib 合约就将其标记为可验证。 -#### 5. 验证提交(链下,Executor) +#### 5. 验证提交 (链下,Executor) -Executor 将经过验证的消息提交到目标 LayerZero 端点,为执行做好准备。 +Executor 将已验证的消息提交给目标 LayerZero Endpoint,准备执行。 -#### 6. 数据包验证(链上,Stable) +#### 6. 包验证 (链上,Stable) -目标 LayerZero 端点确认 Executor 交付的数据包与 DVN 验证的数据包匹配。 +目标 LayerZero Endpoint 确认 Executor 传递的包与 DVN 验证的包一致。 -#### 7. 消息执行(链下,Executor) +#### 7. 消息执行 (链下,Executor) -Executor 在目标链上调用 `lzReceive`,触发 Stable 上的 USDT0 OUpgradable 合约进行消息处理。 +Executor 调用目标链上的 `lzReceive`,触发 Stable 上的 USDT0 OUpgradable 合约处理消息。 -#### 8. 完成(链上,Stable) +#### 8. 完成 (链上,Stable) -Stable 上的 USDT0 OUpgradable 合约处理经过验证的消息,完成跨链转账。USDT0 被铸造到用户的地址。 +Stable 上的 USDT0 OUpgradable 合约处理已验证的消息,完成跨链传输。USDT0 被铸造到用户的地址。 --- -## 路径 2:将原生 USDT 桥接到 Stable(Legacy Mesh) +## 路径 2:将原生 USDT 桥接到 Stable (Legacy Mesh) -当用户在 Legacy Mesh 链(如 Tron)上持有原生 USDT 时,适用此路径。转账在到达 Stable 之前会通过 Arbitrum 作为中间枢纽进行路由。 +当用户在 Legacy Mesh 链(例如 Tron)上持有原生 USDT 时,此路径适用。传输通过 Arbitrum 作为中间枢纽,然后到达 Stable。 -### 参与方 +### 参与者 | 名称 | 链上? | 负责方 | | --- | --- | --- | -| 用户 | N/A | 用户 | +| 用户 | 不适用 | 用户 | | USDT Pool | ✅ | USDT0 的智能合约 | | USDT0 Pool | ✅ | USDT0 的智能合约 | | MultiHopComposer | ✅ | LayerZero 的智能合约 | @@ -114,38 +114,38 @@ Stable 上的 USDT0 OUpgradable 合约处理经过验证的消息,完成跨链 ### 流程图 -将原生 USDT 从 Tron 桥接到 Stable:Legacy Mesh 流程 +将原生 USDT 从 Tron 桥接到 Stable: Legacy Mesh 流程 ### 详细步骤 -#### 1. 发起转账(链上,Tron) +#### 1. 启动传输 (链上,Tron) -用户发起桥接交易,并将原生 USDT 发送到 Tron 上的 **USDT Pool** 合约。USDT 被锁定在池中。然后 USDT Pool 合约向 Tron 上的 LayerZero Endpoint 合约发送一条消息。 +用户发起桥接交易,并将原生 USDT 发送到 Tron 上的 **USDT Pool** 合约。USDT 被锁定在池中。USDT Pool 合约然后向 Tron 上的 LayerZero Endpoint 合约发送消息。 -#### 2. 向 Legacy Mesh 发送消息(链下) +#### 2. 向 Legacy Mesh 发送消息 (链下) -LayerZero Endpoint 合约将消息发送到 **USDT0 Legacy Mesh Operator**,由其验证消息。 +LayerZero Endpoint 合约将消息发送到 **USDT0 Legacy Mesh Operator**,后者验证消息。 -#### 3. 发起 MultiHop 转账(链上,Arbitrum) +#### 3. 启动 MultiHop 传输 (链上,Arbitrum) -USDT0 Legacy Mesh Operator 在 Arbitrum 上的 LayerZero **MultiHopComposer** 合约上调用 `lzCompose()` 方法。无需额外的用户交互,MultiHopComposer 合约即可执行从 Arbitrum 到 Stable 的 USDT0 铸造-销毁桥接转账。 +USDT0 Legacy Mesh Operator 调用 Arbitrum 上 LayerZero **MultiHopComposer** 合约的 `lzCompose()` 方法。无需额外的用户交互,MultiHopComposer 合约从 Arbitrum 到 Stable 执行 USDT0 铸造和销毁桥接传输。 :::note -MultiHopComposer 合约完全无需许可,并且没有 `owner()`,以确保不可变性。 +MultiHopComposer 合约是完全无许可的,没有 `owner()` 以确保不变性。 ::: -#### 4. 将 USDT0 转移到 Stable(链上和链下) +#### 4. 将 USDT0 传输到 Stable (链上和链下) -其余步骤遵循与[将 USDT0 桥接到 Stable](#path-1--bridging-usdt0-to-stable-oft-supported-chains)(上述第 1–8 步)完全相同的路径。Arbitrum 上的 USDT0 OUpgradable 合约通过 LayerZero 发送,DVN 进行验证,USDT0 在 Stable 上铸造。 +其余步骤与[将 USDT0 桥接到 Stable](#路径-1-将-usdt0-桥接到-stable-oft-支持的链)(上述步骤 1-8)完全相同。Arbitrum 上的 USDT0 OUpgradable 合约通过 LayerZero 发送,DVN 进行验证,USDT0 在 Stable 上铸造。 ### 注意事项 - Arbitrum 上的 USDT0 流动性由 USDT0 团队管理。 -- Legacy Mesh 对转账金额收取 0.03% 的费用。 +- Legacy Mesh 对转账金额收取 0.03% 的手续费。 - 用户无需直接与 Arbitrum 交互;MultiHop 流程是自动的。 ## 接下来推荐 -- [**资金流转**](/cn/explanation/flow-of-funds) — 查看 USDT 从入金到结算的端到端生命周期。 -- [**桥接教程**](/cn/tutorial/bridge-usdt0) — 使用 LayerZero OFT Adapter 将测试 USDT 从 Sepolia 桥接到 Stable 测试网。 -- [**USDT 作为 gas**](/cn/explanation/usdt-as-gas-token) — 了解该资产到达 Stable 后的作用。 +- [**资金流向**](/cn/explanation/flow-of-funds):查看 USDT 从上线到结算的端到端生命周期。 +- [**桥接教程**](/cn/tutorial/bridge-usdt0):使用 LayerZero OFT Adapter 将测试 USDT 从 Sepolia 桥接到 Stable 测试网。 +- [**USDT 作为 gas 代币**](/cn/explanation/usdt-as-gas-token):了解资产到达 Stable 后会做什么。 diff --git a/docs/pages/cn/explanation/use-case-payments.mdx b/docs/pages/cn/explanation/use-case-payments.mdx index a2ced64..1177031 100644 --- a/docs/pages/cn/explanation/use-case-payments.mdx +++ b/docs/pages/cn/explanation/use-case-payments.mdx @@ -1,27 +1,27 @@ --- source_path: explanation/use-case-payments.mdx -source_sha: be885bce36996d4c407707fece27e6072a06046d +source_sha: a5e26e7574265dccbb0f71370598384bdeeea5f6 title: "支付与转账" -description: "Stable 如何通过单一资产模型、零费用的用户体验以及即时终结性来支持 P2P 支付和商户结算。" +description: "Stable 如何通过单资产模型、零费用用户体验和即时终结性支持 P2P 支付和商家结算。" diataxis: "explanation" --- # 支付与转账 -围绕一种既负责转移资金又支付交易费用的资产构建的 P2P 支付和商户结算。 +P2P 支付和商家结算围绕一种资产构建,这种资产既用于资金转移也用于支付交易费用。 -## 问题所在 +## 问题 -在通用型链上,用户必须持有一种单独的 gas 代币(ETH、SOL)才能转移稳定币。这打破了"发送一美元,接收一美元"的心理模型,并在新用户引导环节造成转化流失——因为只持有 USDT 的付款人甚至无法提交转账。 +在通用链上,用户必须持有单独的 Gas 代币(ETH、SOL)才能转移稳定币。这打破了“发送一美元,接收一美元”的心智模型,并在用户入驻时造成了转换流失,因为一个只有 USDT 的支付者甚至无法提交转账。 -## Stable 的解决方案 +## Stable 如何解决 -- **USDT0 既是 gas 代币也是支付资产。** 用户只需一种资产即可发送或接收。参见 [USDT 作为 gas](/cn/explanation/usdt-as-gas-token)。 -- **Gas 豁免让应用程序可以代用户支付 gas**,从而实现零费用的用户体验,用户无需接触第二种代币。参见 [Gas 豁免](/cn/explanation/gas-waiver)。 -- **单槽终结性意味着结算即时完成。** 转账一旦进入区块即为最终确认。参见 [以太坊对比](/cn/explanation/ethereum-comparison)。 +- **USDT0 既是 Gas 代币也是支付资产。** 用户只需一种资产即可发送或接收。请参阅[作为 Gas 的 USDT](/cn/explanation/usdt-as-gas-token)。 +- **Gas 豁免允许应用程序代表用户支付 Gas**,从而实现零费用用户体验,而用户无需接触第二种代币。请参阅[Gas 豁免](/cn/explanation/gas-waiver)。 +- **单槽最终性意味着结算即时。** 一旦转账进入区块,它就是最终的。请参阅[以太坊对比](/cn/explanation/ethereum-comparison)。 -## 后续推荐 +## 下一步建议 -- [**USDT 作为 gas**](/cn/explanation/usdt-as-gas-token) — 了解这种同时取代 ETH 用于 gas 和支付的资产。 -- [**Gas 豁免**](/cn/explanation/gas-waiver) — 了解应用程序如何通过治理批准的豁免地址来代付用户 gas。 -- [**以太坊对比**](/cn/explanation/ethereum-comparison) — 回顾从以太坊迁移时会发生哪些变化(终结性、gas 代币、优先级小费)。 +- [**作为 Gas 的 USDT**](/cn/explanation/usdt-as-gas-token):了解同时替代 ETH 作为 Gas 和支付的资产。 +- [**Gas 豁免**](/cn/explanation/gas-waiver):了解应用程序如何通过治理批准的豁免地址支付用户 Gas。 +- [**以太坊对比**](/cn/explanation/ethereum-comparison):回顾从以太坊迁移时发生的变化(最终性、Gas 代币、优先提示)。 diff --git a/docs/pages/cn/explanation/use-case-payroll.mdx b/docs/pages/cn/explanation/use-case-payroll.mdx index a91deb6..39fd01a 100644 --- a/docs/pages/cn/explanation/use-case-payroll.mdx +++ b/docs/pages/cn/explanation/use-case-payroll.mdx @@ -1,27 +1,27 @@ --- source_path: explanation/use-case-payroll.mdx -source_sha: ed009fb2792af92e0a8a47e182f31875bd4f6e60 -title: "薪资发放与批量支付" -description: "Stable 如何通过批量结算、预留区块空间和金额屏蔽来处理大批量支付。" +source_sha: 354e35fd7b7a6c13e98c31a2a409b2ba69fd1e35 +title: "薪资与大规模支付" +description: "Stable 如何通过批量结算、预留区块空间和屏蔽金额来处理大批量支付。" diataxis: "explanation" --- -# 薪资发放与批量支付 +# 薪资与大规模支付 -为员工、承包商和供应商进行大规模支付,具备可预测的吞吐量、可预测的成本,并为敏感金额提供隐私保护。 +大规模支付员工、承包商和供应商,具有可预测的吞吐量、可预测的成本以及对敏感金额的隐私保护。 -## 问题所在 +## 问题 -大批量稳定币支付在共享链上会触及单笔交易吞吐量限制。成本会随网络拥堵而波动,因此昨天还能低成本完成的薪资发放,今天可能就会成本飙升。除此之外,薪资和供应商金额对任何观察链上情况的人都是公开可见的,这会泄露具有商业敏感性的数据。 +大批量稳定币支付在共享链上会遇到每笔交易的吞吐量限制。成本随网络拥塞而波动,因此昨天低成本完成的薪资支付今天可能会飙升。最重要的是,薪资和供应商金额对任何关注链的人都是公开可见的,这会泄露商业敏感数据。 ## Stable 如何解决 -- **USDT 转账聚合器将大批量转账批处理为并行化的结算捆绑包**,因此单次发放不会受到单笔交易开销的瓶颈限制。参见 [USDT 转账聚合器](/cn/explanation/usdt-transfer-aggregator)。 -- **保障区块空间为已注册的合作伙伴在每个区块中提供预留容量**,因此无论网络在做什么,纳入和成本都保持可预测。参见 [保障区块空间](/cn/explanation/guaranteed-blockspace)。 -- **机密转账使用零知识密码学屏蔽金额**,因此薪资和供应商发放不会在链上公布敏感数字。参见 [机密转账](/cn/explanation/confidential-transfer)。 +- **USDT 传输聚合器将大批量传输打包成并行结算捆绑包**,因此单次运行不会受每笔交易开销的瓶颈限制。请参阅[USDT 传输聚合器](/cn/explanation/usdt-transfer-aggregator)。 +- **保证的区块空间为注册合作伙伴提供每个区块的预留容量**,因此无论网络正在做什么,包含和成本都保持可预测。请参阅[保证的区块空间](/cn/explanation/guaranteed-blockspace)。 +- **保密传输使用零知识加密屏蔽金额**,因此薪资和供应商支付不会在链上发布敏感数字。请参阅[保密传输](/cn/explanation/confidential-transfer)。 -## 后续推荐 +## 下一步建议 -- [**USDT 转账聚合器**](/cn/explanation/usdt-transfer-aggregator) — 了解大批量 USDT0 转账如何批处理为并行化的结算捆绑包。 -- [**保障区块空间**](/cn/explanation/guaranteed-blockspace) — 了解已注册的合作伙伴如何在每个区块中获得预留容量。 -- [**机密转账**](/cn/explanation/confidential-transfer) — 了解 ZK 密码学如何屏蔽转账金额,同时保持各方可审计。 +- [**USDT 传输聚合器**](/cn/explanation/usdt-transfer-aggregator):了解大批量 USDT0 传输如何打包成并行结算捆绑包。 +- [**保证的区块空间**](/cn/explanation/guaranteed-blockspace):了解注册合作伙伴如何确保每个区块的预留容量。 +- [**保密传输**](/cn/explanation/confidential-transfer):查看零知识加密如何屏蔽传输金额,同时保持各方可审计。 diff --git a/docs/pages/cn/explanation/use-case-private.mdx b/docs/pages/cn/explanation/use-case-private.mdx index e07acc0..42e2a76 100644 --- a/docs/pages/cn/explanation/use-case-private.mdx +++ b/docs/pages/cn/explanation/use-case-private.mdx @@ -1,25 +1,25 @@ --- source_path: explanation/use-case-private.mdx -source_sha: 20cbf4e27161a85cc05ee6fac25c62038f669526 -title: "私密转账" -description: "Stable 如何使用零知识密码学屏蔽商业敏感的转账金额,同时保持各方可审计。" +source_sha: 8f0641a2b202bf5867149966cfef72f010035339 +title: "隐私转账" +description: "Stable 如何使用零知识密码学来保护商业上敏感的转账金额,同时保持各方的可审计性。" diataxis: "explanation" --- -# 私密转账 +# 隐私转账 -资金管理操作、供应商付款和工资发放等场景中,金额具有商业敏感性,不应向全世界公开。 +财务操作、供应商付款和工资发放,其中金额具有商业敏感性,不应向外界公布。 -## 问题所在 +## 问题 -所有标准的 EVM 转账都是公开可见的。一次工资发放或供应商结算会在链上泄露关键的业务数据:谁向谁付款、付了多少、付款频率如何。竞争对手、交易方以及任何抓取网络数据的人,无需询问就能重建出工资区间、供应商定价和资金动向。 +所有标准的 EVM 转账都是公开可观测的。工资发放或供应商结算会在链上泄露业务关键数据:谁付了谁,付了多少,以及支付频率。竞争对手、交易对手以及任何抓取网络的人都可以在不询问的情况下重建工资范围、供应商定价和财务变动。 -## Stable 的应对方式 +## Stable 如何解决 -- **保密转账使用零知识密码学来屏蔽转账金额**,同时为合规保持各方可审计,因此敏感数字在不牺牲审计记录的情况下保持私密。参见[保密转账](/cn/explanation/confidential-transfer)。 -- **资金流向展示了保密转账在完整 USDT 生命周期中的位置**,从入金到出金。参见[资金流向](/cn/explanation/flow-of-funds)。 +- **机密转账使用零知识密码学来保护转账金额**,同时保持各方的可审计性以遵守合规要求,因此敏感数字在不牺牲审计追踪的情况下保持私密。请参阅 [机密转账](/cn/explanation/confidential-transfer)。 +- **资金流向展示了机密转账在 USDT 完整生命周期(从入金到出金)中的位置**。请参阅 [资金流向](/cn/explanation/flow-of-funds)。 -## 下一步推荐 +## 下一步建议 -- [**保密转账**](/cn/explanation/confidential-transfer) — 了解 ZK 密码学如何在保持各方可审计的同时屏蔽转账金额。 -- [**资金流向**](/cn/explanation/flow-of-funds) — 追踪 USDT 从入金、链上转账到出金结算的全过程。 +- [**机密转账**](/cn/explanation/confidential-transfer): 查看 ZK 密码学如何保护转账金额,同时保持各方的可审计性。 +- [**资金流向**](/cn/explanation/flow-of-funds): 追踪 USDT 从入金、链上转账到出金结算的整个过程。 diff --git a/docs/pages/cn/explanation/use-case-sponsored.mdx b/docs/pages/cn/explanation/use-case-sponsored.mdx index 9b5b2e8..48fdcee 100644 --- a/docs/pages/cn/explanation/use-case-sponsored.mdx +++ b/docs/pages/cn/explanation/use-case-sponsored.mdx @@ -1,25 +1,25 @@ --- source_path: explanation/use-case-sponsored.mdx -source_sha: 1b76f6180d916d240582c1b5a275b8f34de0ec9a -title: "赞助和无 gas 体验" -description: "Stable 如何让应用完全代表用户承担 gas 费用,使得用户上手无需先获取 gas 代币。" +source_sha: 999da6d81c1f78260db57dbebeb5bd08c06a2679 +title: "赞助和无 Gas 体验" +description: "Stable 如何让应用程序完全承担用户的 Gas 费,这样用户无需先获取 Gas 代币即可进行入职操作。" diataxis: "explanation" --- -# 赞助和无 gas 体验 +# 赞助和无 Gas 体验 -有些应用希望从用户体验中彻底移除 gas,让首次使用的用户无需先获取第二种资产即可登录并交易。 +应用程序希望完全消除用户体验中的 Gas 费,以便首次用户无需先获取第二个资产即可登录和交易。 -## 问题所在 +## 问题 -要求用户在使用应用前先获取 gas 代币,会造成一个上手门槛,导致面向消费者的产品转化率骤降。一个只持有 USDT(或者什么都没有)的新用户无法提交交易,而把他们引导到单独的交易所去购买 gas,正是大多数人流失的地方。 +要求用户在使用应用程序前获取 Gas 代币会造成入职障碍,从而扼杀面向消费者产品的转化率。一个只持有 USDT(或根本没有)的新用户无法提交交易,而将他们推到单独的交易所购买 Gas 是他们流失的主要原因。 ## Stable 如何解决 -- **Gas 豁免:经治理批准的豁免地址代表用户提交以零 gas 价格执行的封装交易**,使应用全程承担 gas,用户看到的则是一次免费操作。参见 [Gas 豁免](/cn/explanation/gas-waiver)。 -- **EIP-7702 会话密钥让 dApp 持有受限范围、有时限的权限**,从而能够代表用户提交交易,而无需用户对每一笔交易签名。参见 [EIP-7702](/cn/explanation/eip-7702)。 +- **Gas 豁免:治理批准的豁免提交包装交易,以零 Gas 价格代表用户执行**,因此应用程序端到端地支付 Gas 费,用户看到的是免费操作。请参阅[Gas 豁免](/cn/explanation/gas-waiver)。 +- **EIP-7702 会话密钥允许 dApp 持有范围受限、有时效的权限**,因此它可以代表用户提交交易,而无需用户逐个签名。请参阅[EIP-7702](/cn/explanation/eip-7702)。 -## 下一步推荐 +## 下一步建议 -- [**Gas 豁免**](/cn/explanation/gas-waiver) — 了解经治理批准的豁免如何以零 gas 价格提交封装交易。 -- [**EIP-7702**](/cn/explanation/eip-7702) — 理解 EOA 如何将受限范围、有时限的权限委托给 dApp。 +- [**Gas 豁免**](/cn/explanation/gas-waiver):了解治理批准的豁免如何以零 Gas 价格提交包装交易。 +- [**EIP-7702**](/cn/explanation/eip-7702):了解 EOA 如何将范围受限、有时效的权限委托给 dApp。 diff --git a/docs/pages/cn/explanation/x402.mdx b/docs/pages/cn/explanation/x402.mdx index f6b98eb..a71429b 100644 --- a/docs/pages/cn/explanation/x402.mdx +++ b/docs/pages/cn/explanation/x402.mdx @@ -1,109 +1,109 @@ --- source_path: explanation/x402.mdx -source_sha: ac981560e97b0d313b0161b1c62f92445042814a -title: "将 HTTP 端点货币化" -description: "x402 是一个基于 HTTP 构建的支付协议。服务器请求付款,客户端签名,促成方在链上结算。无需账户、无需 API 密钥、无需订阅。" +source_sha: dd8747ecc00fbdce4e4a4514c28699826e04e4e4 +title: "HTTP 端点变现" +description: "x402 是一种 HTTP 支付协议。服务器要求付款,客户端签名,协调方在链上结算。无需账户、API 密钥或订阅。" diataxis: "explanation" --- -# 将 HTTP 端点货币化 +# HTTP 端点变现 -x402 是一个基于 HTTP 构建的支付协议。服务器返回 `402 Payment Required` 以及付款详情,客户端签署一份 [ERC-3009](/cn/explanation/erc-3009) 授权,促成方在链上结算。整个交换过程通过标准的 HTTP 标头完成。客户端只需要一个钱包:无需注册、无需 API 密钥、无需信用卡登记。 +x402 是一种基于 HTTP 构建的支付协议。服务器以 `402 Payment Required` 和支付详情进行响应,客户端签署 [ERC-3009](/cn/explanation/erc-3009) 授权,协调方在链上结算。整个交换过程通过标准 HTTP 头进行。客户端只需要一个钱包:无需注册、无需 API 密钥、无需注册卡信息。 -这适用于任何客户端为资源或服务向服务器付款的场景:API 访问、数字内容、商户结账或代理之间的付款。 +这适用于客户端付费给服务器以获取资源或服务的任何场景:API 访问、数字内容、商家结账或代理到代理的支付。 -## x402 与 MPP +## x402 和 MPP -x402 是最初的 HTTP-402 支付协议。[机器支付协议 (MPP)](/cn/explanation/mpp) 是一个更广泛的、IETF 标准轨道的后继协议,它增加了支付意图(会话、订阅)、多轨支持(卡、Lightning)以及生产特性(正文摘要绑定、幂等性)。MPP 客户端向后兼容:它们无需更改即可调用 x402 服务器。 +x402 是最初的 HTTP-402 支付协议。[机器支付协议 (MPP)](/cn/explanation/mpp) 是一个更广泛的、IETF 跟踪的继任者,它增加了支付意图(会话、订阅)、多轨道支持(卡片、闪电网络)和生产功能(主体摘要绑定、幂等性)。MPP 客户端向后兼容:它们可以在不更改的情况下调用 x402 服务器。 -如今在 Stable 上,最直接的途径是通过 Semantic Pay 或 Heurist 使用 x402。要在同一 USDT0 轨道上使用 MPP 的传输格式,请参阅[在 Stable 上构建 MPP 端点](/cn/how-to/build-mpp-endpoint)。 +目前在 Stable 上,最直接的路径是通过 Semantic Pay 或 Heurist 的 x402。要使用 MPP 的 USDT0 轨道线格式,请参阅[在 Stable 上构建 MPP 端点](/cn/how-to/build-mpp-endpoint)。 ## 它解决了什么问题? -如今在互联网上为服务付款需要在每一步都进行用户干预:注册账户、登录、登记付款方式。这种模式无法扩展到: +如今在互联网上支付服务需要用户在每个步骤都进行干预:注册账户、登录、注册支付方式。这种模式不适用于: -- 太小而不足以证明基础设施成本合理的服务 -- 太便宜而无法承担卡网络费用的交易 -- 无法执行注册流程的自主代理(AI、机器人、IoT 设备) +- 服务规模过小,不足以支持基础设施成本 +- 交易费用过低,无法支付卡网络费用 +- 无法执行注册流程的自主代理(AI、机器人、物联网设备) -有了 x402,客户端只需要一个钱包即可付款。 +有了 x402,客户端只需要一个钱包即可支付。 | **方面** | **传统计费** | **使用 x402** | | :--- | :--- | :--- | | 需要账户 | 是 | 否 | | 需要 API 密钥 | 是 | 否 | -| 最低可行价格 | ~$0.30(卡处理下限) | ~$0.001(链上) | -| 结算时间 | 数天(卡网络) | 亚秒级(在 Stable 上) | -| 需要 PCI 合规 | 是 | 否 | +| 最低可行价格 | ~$0.30 (卡处理底价) | ~$0.001 (链上) | +| 结算时间 | 几天 (卡网络) | 亚秒级 (在 Stable 上) | +| 需要 PCI 合规性 | 是 | 否 | ## 工作原理 ### 三种角色 -**客户端**是任何需要资源的一方:网页应用、后端服务、CLI 工具或 AI 代理。客户端只需要一个钱包(一个可以签署 ERC-3009 授权的私钥)。 +**客户端**是需要资源的一方:Web 应用、后端服务、CLI 工具或 AI 代理。客户端只需要一个钱包(可以签署 ERC-3009 授权的私钥)。 -**服务器**是任何提供资源的一方。服务器通过将 x402 中间件附加到其端点来定义什么收费多少。 +**服务器**是提供资源的一方。服务器通过将 x402 中间件附加到其端点来定义成本。 -**促成方**是结算服务。它接收来自服务器的已签名付款,对其进行验证,提交链上交易,并返回结果。促成方从不持有客户端的资金。转账直接在代币合约内从客户端转移到服务器。 +**协调方**是结算服务。它接收服务器签名的付款,验证付款,提交链上交易,并返回结果。协调方从不持有客户端的资金。转账直接在代币合约中从客户端转移到服务器。 -在 Stable 上,[Semantic Pay](https://x402.semanticpay.io) 运营着一个公共促成方。 +在 Stable 上,[语义支付(Semantic Pay)](https://x402.semanticpay.io)运营着一个公共协调方。 -### 付款流程 +### 支付流程 -1. **客户端请求资源。** 客户端向服务器发送正常的 HTTP 请求(GET、POST 等)。 -2. **服务器返回 402。** 服务器返回 HTTP `402 Payment Required` 以及一个包含客户端所需全部信息的 `PAYMENT-REQUIRED` 标头:需要付多少款、哪种代币、哪个网络以及将资金发送到哪里。 -3. **客户端签名并重新提交。** 客户端读取付款要求,为指定金额签署一份 ERC-3009 授权,并使用包含已签名授权的 `PAYMENT-SIGNATURE` 标头重新提交原始请求。 -4. **促成方验证并结算。** 服务器将已签名的付款转发给其促成方。促成方验证签名,在链上提交 `transferWithAuthorization` 调用,确认后,服务器返回所请求的资源以及一个包含结算收据的 `PAYMENT-RESPONSE` 标头。 +1. **客户端请求资源。**客户端向服务器发送正常的 HTTP 请求(GET、POST 等)。 +2. **服务器响应 402。**服务器返回 HTTP `402 Payment Required` 以及 `PAYMENT-REQUIRED` 头,其中包含客户端所需的所有信息:支付金额、代币、网络以及收款地址。 +3. **客户端签名并重新提交。**客户端读取支付要求,签署指定金额的 ERC-3009 授权,并使用包含签名授权的 `PAYMENT-SIGNATURE` 头重新提交原始请求。 +4. **协调方验证并结算。**服务器将签名的付款转发给其协调方。协调方验证签名,在链上提交 `transferWithAuthorization` 调用,一旦确认,服务器将返回请求的资源以及包含结算收据的 `PAYMENT-RESPONSE` 头。 -### 三个标头 +### 三个头 -所有付款信息都通过标准的 HTTP 标头传输,以 Base64 编码: +所有支付信息都通过标准 HTTP 头以 Base64 编码传输: -| **标头** | **方向** | **内容** | +| **头** | **方向** | **内容** | | :--- | :--- | :--- | -| `PAYMENT-REQUIRED` | 服务器到客户端 | 付款方案、代币地址、金额、收款人地址、网络标识符 | -| `PAYMENT-SIGNATURE` | 客户端到服务器 | 证明客户端已授权转账的已签名 ERC-3009 授权 | -| `PAYMENT-RESPONSE` | 服务器到客户端 | 包括交易哈希和确认状态的结算结果 | +| `PAYMENT-REQUIRED` | 服务器到客户端 | 支付方案、代币地址、金额、收款人地址、网络标识符 | +| `PAYMENT-SIGNATURE` | 客户端到服务器 | 签署的 ERC-3009 授权,证明客户端已授权转账 | +| `PAYMENT-RESPONSE` | 服务器到客户端 | 结算结果,包括交易哈希和确认状态 | -这种设计适用于任何 HTTP 客户端、任何编程语言以及任何支持自定义标头的基础设施。 +此设计适用于任何 HTTP 客户端、任何编程语言以及任何支持自定义标头的基础设施。 ## Stable 上的 x402 -x402 协议定义了付款如何通过 HTTP 工作。Stable 提供使其在生产环境中实用的结算环境。 +x402 协议定义了 HTTP 上的支付方式。Stable 提供了使其在生产环境中实用的结算环境。 ### 亚秒级最终性 -Stable 的共识提供亚秒级的区块最终性(约 700 毫秒),使 x402 促成方能够实时验证和结算交易。这对于 AI 代理或 IoT 设备可能快速连续执行许多小额付款的高频自动化交互至关重要。 +Stable 的共识提供亚秒级区块最终性(约 700 毫秒),允许 x402 协调方实时验证和结算交易。这对于 AI 代理或物联网设备可能快速连续执行许多小额支付的高频自动化交互至关重要。 ### 单一资产结算 -在 Stable 上,USDT0 既是原生 gas 代币,也是付款代币。整个 x402 付款生命周期仅在 USDT0 上运行。客户端仅持有 USDT0,促成方使用其结算的同一代币提交交易。对于使用 x402 的 AI 代理而言,这意味着代理钱包只需管理一种资产。 +在 Stable 上,USDT0 既是原生 Gas 代币,也是支付代币。整个 x402 支付生命周期仅在 USDT0 上运行。客户端仅持有 USDT0,协调方使用其结算的相同代币提交交易。对于使用 x402 的 AI 代理,这意味着代理钱包只需管理一种资产。 ### 微定价 -价格以 USDT0 原子单位(6 位小数)计价:成本参数 `"1000"` 恰好转换为 $0.001。这种精度使 x402 服务器能够将价格设置为一美分的几分之一。 +价格以 USDT0 原子单位(6 位小数)计价:成本参数 `"1000"` 对应于精确的 $0.001。这种精度允许 x402 服务器以美分的分数设定价格。 ### Gas 豁免集成 -[Gas 豁免](/cn/how-to/integrate-gas-waiver)完全消除了交易成本。x402 促成方可以使用 Gas 豁免基础设施提交 `transferWithAuthorization` 调用,而无需向买方或卖方收取 gas 费用。这意味着 Stable 上的 x402 微支付除了付款金额本身之外不产生任何额外开销。 +[Gas 豁免](/cn/how-to/integrate-gas-waiver)完全消除了交易成本。x402 协调方可以使用 Gas 豁免基础设施提交`transferWithAuthorization`调用,而无需向买方或卖方收取 Gas 费用。这意味着 Stable 上的 x402 小额支付除了支付金额本身之外,没有额外开销。 ## 基础设施 ### Semantic Pay -[Semantic Pay](https://x402.semanticpay.io) 为 Stable 提供了一个公共的 x402 促成方。它处理签名验证、链上提交和确认跟踪。在 Stable 上集成 x402 的开发者可以将其中间件指向此端点,而无需运行自己的结算基础设施。 +[Semantic Pay](https://x402.semanticpay.io) 为 Stable 提供了一个公共 x402 协调方。它负责处理签名验证、链上提交和确认跟踪。在 Stable 上集成 x402 的开发人员可以将其中间件指向此端点,而无需运行自己的结算基础设施。 -**促成方端点:** `https://x402.semanticpay.io` +**协调方端点:** `https://x402.semanticpay.io` ### WDK(钱包开发工具包) -为了让 AI 代理自主参与 x402,它们需要能够以编程方式控制的钱包。Tether 的开源 WDK 提供了这一点: +为了使 AI 代理能够自主参与 x402,它们需要可以程序化控制的钱包。Tether 的开源 WDK 提供了以下功能: -- **自我托管**:WDK 使 AI 代理能够在本地生成和存储私钥,而无需依赖中心化的 API 基础设施。 -- **x402 兼容性**:WDK 的 `WalletAccountEvm` 实例原生满足 x402 SDK 所需的客户端签名者接口,使代理能够自动拦截 402 HTTP 响应、签署 ERC-3009 授权并重新提交请求。 +- **自托管**:WDK 使 AI 代理能够在本地生成和存储私钥,而无需依赖中心化 API 基础设施。 +- **x402 兼容性**:WDK 的 `WalletAccountEvm` 实例原生满足 x402 SDK 所需的客户端签名者接口,允许代理自动拦截 402 HTTP 响应,签署 ERC-3009 授权,并重新提交请求。 **另请参阅:** -- [ERC-3009(带授权转账)](/cn/explanation/erc-3009):x402 使用的链上结算标准 +- [ERC-3009(带授权的转账)](/cn/explanation/erc-3009):x402 使用的链上结算标准 - [支付用例](/cn/explanation/payment-use-cases-overview):P2P、订阅、发票和 API 计费模式 - [Gas 豁免](/cn/how-to/integrate-gas-waiver):零成本交易提交 diff --git a/docs/pages/cn/how-to/account-abstraction.mdx b/docs/pages/cn/how-to/account-abstraction.mdx index c5a7212..f3fe942 100644 --- a/docs/pages/cn/how-to/account-abstraction.mdx +++ b/docs/pages/cn/how-to/account-abstraction.mdx @@ -1,39 +1,39 @@ --- source_path: how-to/account-abstraction.mdx -source_sha: 8eaa5c6ea2859611c839ed8d5c8acbe81f18c38a +source_sha: 30e0b565660c81e67967daa2ddf0f0ceae7aa9ef title: "使用 EIP-7702 实现账户抽象" -description: "通过委托给 EIP-7702 智能合约,在现有 EOA 上实现批量支付、支出限额和会话密钥。" +description: "通过将现有 EOA 委托给 EIP-7702 智能合约,实现批量支付、消费限额和会话密钥。" diataxis: "how-to" --- # 使用 EIP-7702 实现账户抽象 -本指南将逐步介绍如何将 EIP-7702 应用于 EOA,并利用委托实现三种模式:批量支付、支出限额和会话密钥。整个过程中,EOA 始终保持其地址和私钥不变。 +本指南将通过 EIP-7702 应用于 EOA,并使用委托实现三种模式:批量支付、消费限额和会话密钥。在此过程中,EOA 保持其地址和私钥不变。 :::note -**概念:** 关于 EIP-7702 在 Stable 上能够实现的功能以及安全注意事项,请参阅 [EIP-7702](/cn/explanation/eip-7702)。 +**概念:** 有关 EIP-7702 在 Stable 上能实现的功能以及安全方面的考量,请参阅[EIP-7702](/cn/explanation/eip-7702)。 ::: -## 前提条件 +## 先决条件 -- 了解 EOA 与智能合约账户的区别(EOA 默认没有代码)。 +- 了解 EOA 与智能合约账户的区别(EOA 默认不包含代码)。 - 熟悉 EVM 交易类型([EIP-2718](https://eips.ethereum.org/EIPS/eip-2718))。 ## 概述 -EIP-7702 引入了一种新的交易类型(`0x04`),该类型携带一个 `authorizationList`。每个授权都指定一个智能合约,EOA 将在该交易中执行该合约的代码。流程如下: +EIP-7702 引入了一种新的交易类型(`0x04`),它携带一个 `authorizationList`。每个授权都指定了一个智能合约,EOA 将在该交易中执行该智能合约的代码。流程如下: -1. **选择或部署委托合约**:一个标准的 Solidity 合约,实现你希望 EOA 使用的逻辑。你可以使用已部署的合约,也可以部署自己的合约。请尽可能使用经过审计的合约。 -2. **签署授权**:EOA 所有者签署一条消息,授权委托合约。 -3. **提交 EIP-7702 交易**:该交易包含授权,EOA 在执行过程中运行委托合约的代码。 +1. **选择或部署委托合约**:一个标准的 Solidity 合约,实现了您希望 EOA 使用的逻辑。您可以使用已部署的合约或部署自己的合约。尽可能使用经过审计的合约。 +2. **签署授权**:EOA 所有者签署一条消息,授权委托合约。 +3. **提交 EIP-7702 交易**:交易包含授权,EOA 在执行期间运行委托的代码。 ## 用例:批量交易 -下面的步骤将使用 `Multicall3` 作为委托合约来演示此流程。`Multicall3` 是一个广泛部署的实用合约,可将多个调用聚合到单个交易中。通过将 `Multicall3` 指定为 EIP-7702 委托,EOA 可以将任意合约交互(代币转账、授权、合约读取或任意组合)批量打包到一个原子交易中。批量支付便是其中一个示例:与其为一次工资发放发送十笔单独的交易,EOA 可以一次性执行所有交易。 +以下步骤将使用 `Multicall3` 作为委托合约来演示此流程。`Multicall3` 是一个广泛部署的实用合约,它将多个调用聚合到一个交易中。通过将 `Multicall3` 指定为 EIP-7702 委托,EOA 可以将任意合约交互(代币转账、批准、合约读取或任意组合)批量处理为一笔原子交易。批量支付就是一个例子:EOA 无需为一次工资支付发送十笔单独的交易,而是可以一次性执行所有交易。 ### 步骤 1:使用 Multicall3 作为委托合约 -`Multicall3` 在 Stable 上部署于 `0xcA11bde05977b3631167028862bE2a173976CA11`。由于它已经部署且被广泛使用,你无需部署自己的委托合约。签署 EIP-7702 授权将授予委托合约对你的 EOA 的完整执行权限。 +`Multicall3` 部署在 Stable 上的 `0xcA11bde05977b3631167028862bE2a173976CA11`。由于它已经部署并且被广泛使用,您无需部署自己的委托。签署 EIP-7702 授权会授予委托对您的 EOA 的完全执行权限。 ```solidity // Multicall3 interface (relevant functions only) @@ -56,7 +56,7 @@ interface IMulticall3 { ### 步骤 2:签署授权 -EOA 所有者签署一个指定委托合约的授权。该授权包含在 EIP-7702 交易中。 +EOA 所有者签署一份授权,指定委托合约。此授权将包含在 EIP-7702 交易中。 ```javascript // config.ts @@ -89,7 +89,7 @@ export async function signAuthorization() { ### 步骤 3:提交 EIP-7702 交易 -将授权与对 `Multicall3.aggregate3` 的调用结合起来。本示例在单个交易中批量执行三笔 USDT0 转账。 +将授权与对 `Multicall3.aggregate3` 的调用结合起来。此示例将三个 USDT0 转账批处理到一个交易中。 ```javascript import { ethers } from "ethers"; @@ -138,11 +138,11 @@ async function main() { Batch transactions executed in tx: 0x... ``` -EOA 通过 `Multicall3.aggregate3` 在单个原子交易中执行所有三个调用。委托会一直持续,直到被显式更改或清除。虽然本示例展示的是批量支付,但同样的模式适用于任意组合的合约调用。 +EOA 通过 `Multicall3.aggregate3` 在一个原子交易中执行所有三个调用。委托将持续存在,直到明确更改或清除。虽然此示例展示了批量支付,但相同的模式适用于任何合约调用组合。 -## 用例:支出限额 +## 用例:消费限额 -委托合约可以在不进行账户迁移的情况下,对 EOA 强制执行每笔交易或每日的限额。 +委托合约可以强制对 EOA 实行每笔交易或每日限额,而无需进行账户迁移。 ```solidity // SPDX-License-Identifier: MIT @@ -185,7 +185,7 @@ contract SpendingLimitExecutor { ## 用例:会话密钥 -会话密钥允许 dApp 在限定的权限范围内代表 EOA 执行交易:一个时间窗口和一组允许的目标合约。这对于那些频繁的链上交互否则需要反复钱包批准的 dApp 非常有用。 +会话密钥允许 dApp 在具有限定权限(时间窗口和允许的目标合约集)的情况下代表 EOA 执行交易。这对于需要频繁链上交互的 dApp 很有用,否则会需要重复的钱包批准。 ```solidity // SPDX-License-Identifier: MIT @@ -254,18 +254,18 @@ contract SessionKeyExecutor { ## 重要注意事项 -- **持久委托**:委托会一直持续,直到 EOA 显式更改或清除它。它不限于单个交易。 -- **Gas 成本**:由于授权处理,EIP-7702 交易的基础 Gas 略高,但在委托批量处理多个调用时可以抵消这部分成本。 -- **使用经过审计的委托**:恶意的委托合约可能会耗尽 EOA 的资产。只委托给经过审计的合约。 +- **持久委托**:委托将一直持续,直到 EOA 明确更改或清除它。它不限于单笔交易。 +- **gas 成本**:EIP-7702 交易由于授权处理,基础 gas 费略高,但当委托批量处理多个调用时,可以抵消这部分成本。 +- **使用经过审计的委托**:恶意的委托合约可能会耗尽 EOA 的资产。仅委托给经过审计的合约。 -## 关键要点 +## 主要收获 -- EIP-7702 允许 EOA 执行智能合约逻辑,而无需迁移到新的账户类型。 -- 在 Stable 上,EIP-7702 可在现有 EOA 上实现批量支付、支出限额和限定范围的会话密钥。 -- 委托会一直持续,直到被显式更改。请始终使用经过审计的委托合约。 +- EIP-7702 允许 EOA 执行智能合约逻辑,而无需迁移到新的账户类型。 +- 在 Stable 上,EIP-7702 使得现有 EOA 能够实现批量支付、消费限额和受限会话密钥。 +- 委托将持续存在,直到明确更改。始终使用经过审计的委托合约。 -## 下一步推荐 +## 接下来推荐 -- [**订阅与收款**](/cn/how-to/subscribe-and-collect) — 使用 SubscriptionManager 将 EIP-7702 应用于周期性订阅支付。 -- [**EIP-7702 概念**](/cn/explanation/eip-7702) — 在上线之前理解委托模型。 -- [**EIP-7702 参考**](/cn/reference/eip-7702-api) — 查阅 `0x04` 交易格式和授权字段。 +- [**订阅与收款**](/cn/how-to/subscribe-and-collect):将 EIP-7702 应用于使用 SubscriptionManager 的定期订阅支付。 +- [**EIP-7702 概念**](/cn/explanation/eip-7702):在发布之前了解委托模型。 +- [**EIP-7702 参考资料**](/cn/reference/eip-7702-api):查找 `0x04` 交易格式和授权字段。 diff --git a/docs/pages/cn/how-to/build-mpp-endpoint.mdx b/docs/pages/cn/how-to/build-mpp-endpoint.mdx index 7dc058e..01c6353 100644 --- a/docs/pages/cn/how-to/build-mpp-endpoint.mdx +++ b/docs/pages/cn/how-to/build-mpp-endpoint.mdx @@ -1,58 +1,58 @@ --- source_path: how-to/build-mpp-endpoint.mdx -source_sha: 6aff0597391159c025c805e5a95e17a1e9373acc -title: "在 Stable 上构建 MPP 端点" -description: "通过针对 viem 编写三个自定义方法钩子,在 Stable 上经由 MPP 的 HTTP 402 流程接受 USDT0 付款。" +source_sha: d7b857d878cd4ce2044c0cb7796cfe8e2a7aae29 +title: "在Stable上构建一个MPP端点" +description: "通过针对viem编写三个自定义方法钩子,在Stable上通过MPP的HTTP 402流程接受USDT0支付。" diataxis: "how-to" --- -# 在 Stable 上构建 MPP 端点 +# 在Stable上构建一个MPP端点 -本指南将逐步介绍如何为 Stable 上的 USDT0 编写自定义 [MPP](/cn/explanation/mpp) 支付方法,并提供一个受 MPP 保护的端点。买方签署一个 [ERC-3009](/cn/explanation/erc-3009) `transferWithAuthorization`,服务器通过 `mppx` 的 `verify()` 钩子对其进行验证,结算则在你控制的单独步骤中完成。 +本指南将指导您在Stable上为USDT0编写一个自定义的[MPP](/cn/explanation/mpp)支付方法,并提供一个MPP门控端点。买方签署一个[ERC-3009](/cn/explanation/erc-3009) `transferWithAuthorization`,服务器通过`mppx`的`verify()`钩子验证它,结算在您控制的单独步骤中进行。 :::note -**概念:** 关于什么是 MPP 以及它与 x402 的关系,请参阅 [机器支付协议(MPP)](/cn/explanation/mpp)。关于 x402 的等价实现,请参阅 [构建按次调用付费 API](/cn/how-to/build-pay-per-call)。 +**概念:** 有关MPP是什么以及它如何与x402相关的信息,请参阅[机器支付协议(MPP)](/cn/explanation/mpp)。有关x402的等效内容,请参阅[构建按次计费API](/cn/how-to/build-pay-per-call)。 ::: :::note -该示例使用 Stable 主网。测试时请使用小额金额。 +本示例使用Stable主网。测试时请使用小额资金。 ::: -## 你将构建的内容 +## 您将构建什么 -一个 HTTP 端点,它返回 `402 Payment Required` 以及一个 MPP `WWW-Authenticate` 挑战,接受 `Authorization` 标头中已签名的凭据,对其进行验证,在 USDT0 上结算 `transferWithAuthorization`,并返回带有 `Payment-Receipt` 标头的响应。 +一个HTTP端点,它返回 `402 Payment Required` 带有 MPP `WWW-Authenticate` 挑战,在 `Authorization` 头中接受签名凭据,验证它,在 USDT0 上结算 `transferWithAuthorization`,并返回带有 `Payment-Receipt` 头的响应。 ```text -step 1. Client: GET /weather (no Authorization header) - Server: 402 Payment Required +步骤 1. 客户端:GET /weather (无Authorization头) + 服务器:402 Payment Required WWW-Authenticate: Payment realm="...", challenges="[...usdt0-stable charge for $0.001...]" -step 2. Client signs an ERC-3009 authorization with their viem account +步骤 2. 客户端使用他们的viem账户签署一个ERC-3009授权 -step 3. Client: GET /weather + Authorization header containing the serialized credential - Server: verify() validates the EIP-712 signature - Server: settle() submits transferWithAuthorization on Stable - (~700ms block confirmation) - Server: 200 OK { weather: "sunny" } +步骤 3. 客户端:GET /weather + 包含序列化凭据的Authorization头 + 服务器:verify()验证EIP-712签名 + 服务器:settle()提交Stable上的transferWithAuthorization + (~700ms 区块确认) + 服务器:200 OK { weather: "sunny" } Payment-Receipt: reference="0x8f3a...", status="success" -step 4. Verify settlement on Stablescan +步骤 4. 在Stablescan上验证结算 https://stablescan.xyz/tx/0x8f3a... ``` -## 前提条件 +## 先决条件 -- 在 Stable 上有一个已注资的 USDT0 钱包。请参阅 [使用水龙头](/cn/how-to/use-faucet) 或 [转移 USDT0](/cn/tutorial/send-usdt0)。 -- 安装了 `mppx`、`viem` 和 `zod` 的 Node 20+。 -- 在 Stable 上有一个卖方账户(一个 EOA)。在默认结算路径下,卖方以 USDT0 支付 gas;[Gas Waiver](#alternative-settle-through-the-gas-waiver) 一节展示了零 gas 的变体。 +- Stable上资金充足的USDT0钱包。请参阅[使用水龙头](/cn/how-to/use-faucet)或[移动USDT0](/cn/tutorial/send-usdt0)。 +- Node 20+,并安装了`mppx`、`viem`和`zod`。 +- Stable上的卖家账户(一个EOA)。对于默认的结算路径,卖家以USDT0支付gas;[Gas豁免](#alternative-settle-through-the-gas-waiver)部分展示了零gas变体。 ```bash npm install mppx viem zod express ``` -## 1. 定义共享 schema +## 1. 定义共享Dapp模式 -`Method.from()` 声明意图以及请求(Challenge)和凭据载荷的 schema。客户端和服务器都导入此定义。 +`Method.from()` 声明了意图以及请求(挑战)和凭据负载的 Dapp 模式。客户端和服务器都导入此定义。 ```typescript // src/method.ts @@ -63,7 +63,7 @@ import { parseUnits } from "viem"; export const USDT0_STABLE = "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"; export const CHAIN_ID = 988; -// Request: the Challenge payload the server sends to the client. +// Request: The Challenge payload the server sends to the client. const zRequest = z.pipe( z.object({ chainId: z.literal(CHAIN_ID), @@ -120,7 +120,7 @@ usdt0Stable.intent === "charge" ## 2. 服务器:验证凭据 -`Method.toServer` 将 `verify()` 接入 `mppx`。该函数接收反序列化后的凭据(挑战 + 载荷),并且必须在证明无效时抛出异常,或者返回一个 `Receipt`。 +`Method.toServer` 将 `verify()` 接入到 `mppx`。该函数接收反序列化的凭据(挑战 + 负载),并且必须在无效证明时抛出错误或返回 `Receipt`。 ```typescript // src/server-method.ts @@ -153,9 +153,9 @@ export const usdt0StableServer = Method.toServer(usdt0Stable, { signature: signature as `0x${string}`, }); - if (!valid) throw new Error("Invalid ERC-3009 signature"); + if (!valid) throw new Error("无效的ERC-3009签名"); - // The Receipt's reference is filled in with the tx hash after settle(). + // Recipt的reference字段将在settle()后被交易哈希填充。 return Receipt.from({ method: usdt0Stable.name, reference: "pending", @@ -176,16 +176,16 @@ export const usdt0StableServer = Method.toServer(usdt0Stable, { ``` :::warning -`verify()` 检查签名,但不检查 nonce 唯一性或授权是否已被花费。链在提交时强制执行这两者:`transferWithAuthorization` 在 nonce 已被使用时会回退。结算步骤会将这些回退转化为服务器可以向客户端展现的错误。 +`verify()` 检查签名,但不检查 nonce 的唯一性或授权是否已消费。链在提交时强制执行这两项:`transferWithAuthorization` 在使用过的 nonce 上将会回滚。结算步骤将这些回滚转化为服务器可以向客户端显示错误。 ::: ## 3. 结算:提交 `transferWithAuthorization` -结算被有意地与 `verify()` 分离。在 `verify()` 返回后,你通过适合你运维模型的任意路径将授权提交到链上。以下是三个选项,按推荐顺序排列。 +结算有意地与 `verify()` 分离。在 `verify()` 返回后,您可以通过适合您运营模型的任何路径提交链上授权。三种选项,按推荐顺序列出。 ### 默认:服务器直接提交 -卖方的 EOA 将带有已签名授权的 `transferWithAuthorization` 提交到 USDT0。卖方以 USDT0(Stable 的原生 gas 代币)支付 gas,因此无需管理单独的 gas 代币余额。 +卖家的 EOA 使用签名的授权将 `transferWithAuthorization` 提交给 USDT0。卖家以 USDT0(Stable 的原生 gas token)支付 gas,因此无需管理单独的 gas token 余额。 ```typescript // src/settle.ts @@ -253,9 +253,9 @@ export async function settleDirect(credential: { { txHash: "0x8f3a1b2c..." } ``` -### 替代方案:通过 Gas Waiver 结算 +### 替代方案:通过 Gas 豁免进行结算 -使用 Stable 的 [Gas Waiver](/cn/how-to/integrate-gas-waiver) 以 `gasPrice = 0` 提交内层交易。卖方仍然签署包装交易,但不支付 gas。需要一个 Waiver Server API 密钥。 +使用 Stable 的[Gas 豁免](/cn/how-to/integrate-gas-waiver)以 `gasPrice = 0` 提交内部交易。卖家仍然签署包装交易,但无需支付 gas 费。需要豁免服务器 API 密钥。 ```typescript // src/settle-waiver.ts @@ -280,7 +280,7 @@ export async function settleViaWaiver( const lines = (await res.text()).trim().split("\n"); const result = JSON.parse(lines[0]); - if (!result.success) throw new Error(`Settle failed: ${result.error?.message}`); + if (!result.success) throw new Error(`结算失败: ${result.error?.message}`); return { txHash: result.txHash }; } ``` @@ -289,17 +289,17 @@ export async function settleViaWaiver( { txHash: "0x8f3a1b2c..." } ``` -关于如何在发布前构建已签名的内层交易(`gasPrice: 0`,已编码的 `transferWithAuthorization` 调用),请参阅 [Gas waiver 协议](/cn/reference/gas-waiver-api)。 +有关如何构建已签名的内部交易(`gasPrice: 0`,编码的 `transferWithAuthorization` 调用)然后再发布的信息,请参阅[Gas 豁免协议](/cn/reference/gas-waiver-api)。 -### 替代方案:交给 x402 facilitator +### 替代方案:移交给x402协调器 -如果你已经运行了 x402 facilitator 集成([Semantic Pay](https://docs.semanticpay.io) 或 [Heurist](https://docs.heurist.ai/x402-products/facilitator)),你可以将其复用为结算目标。向 `/settle` POST 一个 `paymentPayload`;facilitator 会提交链上调用。 +如果您已经运行了x402协调器集成([Semantic Pay](https://docs.semanticpay.io)或[Heurist](https://docs.heurist.ai/x402-products/facilitator)),您可以将其复用为结算目标。向 `/settle` POST 一个 `paymentPayload`;协调器会提交链上调用。 -`paymentPayload` 的确切结构是 x402 中间件内部的,未在线路层面指定。最简单的路径是使用 facilitator 自己的 SDK 来构建载荷,或者坚持使用上面的直接提交路径。facilitator 不需要支持 MPP;它只看到 `transferWithAuthorization` 字段。 +`paymentPayload` 的确切形状是 x402 中间件内部的,未在协议层面指定。最简单的路径是使用协调器自己的 SDK 来构建负载,或者坚持使用上述的直接提交路径。协调器不需要理解 MPP;它只看到 `transferWithAuthorization` 字段。 ## 4. 客户端:签署凭据 -`Method.toClient` 将 `createCredential()` 接入 `mppx`。客户端读取 Challenge,使用代理的 viem 账户签署 EIP-712 授权,并序列化凭据。 +`Method.toClient` 将 `createCredential()` 接入 `mppx`。客户端读取挑战,使用代理的 viem 账户签署 EIP-712 授权,并序列化凭据。 ```typescript // src/client-method.ts @@ -346,9 +346,9 @@ export function createUsdt0StableClient(privateKey: `0x${string}`) { "eyJjaGFsbGVuZ2UiOnsi..." // base64-serialized credential, ~600 bytes ``` -## 5. 将服务器组装起来 +## 5. 将服务器连接起来 -使用 `mppx` 的 Express 中间件来发出 Challenge、解析传入的 `Authorization` 标头、运行 `verify()`、调用你的结算函数,并发出 `Payment-Receipt` 标头。 +使用 `mppx` 的 Express 中间件来发布挑战、解析传入的 `Authorization` 头、运行 `verify()`、调用您的结算函数并发出 `Payment-Receipt` 头。 ```typescript // src/server.ts @@ -392,23 +392,23 @@ app.get( ); app.listen(PORT, () => { - console.log(`MPP server listening on http://localhost:${PORT}`); + console.log(`MPP服务器正在监听 http://localhost:${PORT}`); }); ``` ```text -MPP server listening on http://localhost:4022 +MPP服务器正在监听 http://localhost:4022 ``` -## 6. 端到端运行整个流程 +## 6. 端到端运行流程 -启动服务器,确认 Challenge,运行客户端,并确认结算。 +启动服务器,确认挑战,运行客户端,并确认结算。 :::warning -下一步将在 Stable 主网上结算一笔真实的 USDT0 付款。请使用专用钱包和小额金额。 +下一步将在 Stable 主网上结算一笔真实的 USDT0 支付。请使用专用钱包并小额支付进行测试。 ::: -### 确认 Challenge +### 确认挑战 ```bash curl -i http://localhost:4022/weather @@ -422,7 +422,7 @@ Content-Type: application/json {"error":"Payment required"} ``` -### 发送一个付费请求 +### 发送付费请求 ```typescript // src/client.ts @@ -451,18 +451,18 @@ npx tsx src/client.ts Payment-Receipt: reference="0x8f3a1b2c...", status="success", timestamp="2026-06-01T12:34:56.000Z" ``` -### 在 Stablescan 上验证 +### 在Stablescan上验证 -打开 `https://stablescan.xyz/tx/0x8f3a1b2c...`,确认 `transferWithAuthorization` 已结算到你的 `PAY_TO` 地址。 +打开 `https://stablescan.xyz/tx/0x8f3a1b2c...` 并确认 `transferWithAuthorization` 已结算到您的 `PAY_TO` 地址。 -## 你刚刚完成的内容 +## 您做了什么 -- 以 USDT0 付款,以美元计价,买方一侧无需管理 gas 代币余额。 -- 在客户端到服务器的跳转上使用了 MPP 的 `WWW-Authenticate` / `Authorization` / `Payment-Receipt` 线路格式。 -- 在同一个 HTTP 请求生命周期内(约 700 毫秒的出块时间)使用 `transferWithAuthorization` 在 Stable 上完成了结算。 +- 以美元计价的 USDT0 支付,买方无需管理 gas token 余额。 +- 在客户端-服务器跳跃中使用了 MPP 的 `WWW-Authenticate` / `Authorization` / `Payment-Receipt` 线路格式。 +- 在同一 HTTP 请求生命周期内(~700 毫秒区块时间)通过 Stable 上的 `transferWithAuthorization` 进行结算。 -## 推荐的后续内容 +## 接下来推荐 -- [**MPP 概念**](/cn/explanation/mpp) — 了解 MPP 如何与 x402 关联,以及其他意图是什么样的。 -- [**MPP 会话**](/cn/explanation/mpp-sessions) — 当按请求结算成本过高时,使用链下凭证流式传输微支付。 -- [**Facilitators**](/cn/reference/agentic-facilitators) — 使用 Semantic Pay 或 Heurist 作为结算目标,而不是直接提交。 +- [**MPP概念**](/cn/explanation/mpp):阅读MPP如何与x402相关以及其他意图是什么。 +- [**MPP会话**](/cn/explanation/mpp-sessions):当按请求结算成本过高时,使用链下凭证流式传输小额支付。 +- [**协调器**](/cn/reference/agentic-facilitators):使用 Semantic Pay 或 Heurist 作为结算目标,而不是直接提交。 diff --git a/docs/pages/cn/how-to/build-p2p-payments.mdx b/docs/pages/cn/how-to/build-p2p-payments.mdx index 2fd3d5a..d57da34 100644 --- a/docs/pages/cn/how-to/build-p2p-payments.mdx +++ b/docs/pages/cn/how-to/build-p2p-payments.mdx @@ -1,26 +1,26 @@ --- source_path: how-to/build-p2p-payments.mdx -source_sha: cb21475c28be41c86374be5066e7b1c5c5261c56 +source_sha: 57dc356587b68955bf9eac544e7b2bcf1b337bee title: "学习 P2P 支付" -description: "在 Stable 上构建 P2P 支付应用。创建钱包、查询余额、收发 USDT0,并查询交易历史。" +description: "在 Stable 上构建 P2P 支付应用。创建钱包、查询余额、发送和接收 USDT0,以及查询交易历史。" diataxis: "how-to" --- # 学习 P2P 支付 -本指南将带你在 Stable 上构建一个 P2P 支付应用。该应用处理完整的支付生命周期:发送方直接转账 USDT0,接收方实时检测到入账支付,双方都可以查询各自的交易历史。无论是移动应用、网页结账,还是后端服务,任何钱包或支付界面的架构都与此相同。 +本指南将带领您在 Stable 上构建一个 P2P 支付应用程序。该应用程序处理完整的支付生命周期:发送方直接转移 USDT0,接收方实时检测到入账,双方都可以查询交易历史。与任何钱包或支付界面(无论是移动应用、网页结账还是后端服务)的架构相同。 -无需中间件,无需中介。如需了解概念性概述,请参阅 [P2P 支付](/cn/reference/p2p-payments)。如果想跳过 ABI 相关工作、用几行代码实现可用的 `transfer`,请使用 [Stable SDK](/cn/explanation/sdk-overview)。 +没有中间件,没有中介。有关概念性概述,请参见 [P2P 支付](/cn/reference/p2p-payments)。要跳过 ABI 工作并快速实现可用的 `transfer`,请使用 [Stable SDK](/cn/explanation/sdk-overview)。 -## 你将构建的内容 +## 您将构建什么 -构成一个最小支付应用的五个脚本: +构成最小支付应用程序的五个脚本: -- `wallet.ts` — 创建或恢复钱包。 -- `getBalance.ts` — 查询当前 USDT0 余额。 -- `send.ts` — 向另一个地址发送 USDT0。 -- `receive.ts` — 实时监听入账支付。 -- `history.ts` — 查询某个地址过去的 Transfer 事件。 +- `wallet.ts`: 创建或恢复钱包。 +- `getBalance.ts`: 查询当前的 USDT0 余额。 +- `send.ts`: 将 USDT0 发送到另一个地址。 +- `receive.ts`: 实时监听入账。 +- `history.ts`: 查询某个地址过去的 Transfer 事件。 ### 演示 @@ -39,10 +39,10 @@ step 4. Bob receives payment (real-time event) tx: 0x8f3a...2d41 ``` -## 前置条件 +## 前提条件 - Node.js 20 或更高版本。 -- 一个拥有测试网 USDT0 的私钥(参见[快速开始](/cn/tutorial/quick-start)为钱包注资)。 +- 具有测试网 USDT0 的私钥(请参阅 [快速入门](/cn/tutorial/quick-start) 以资助钱包)。 ## 项目设置 @@ -55,7 +55,7 @@ npm init -y && npm install ethers dotenv added 2 packages, audited 3 packages in 1s ``` -创建一个被所有脚本共享的 `config.ts`: +创建所有脚本共享的 `config.ts`: ```typescript // config.ts @@ -71,24 +71,24 @@ export const provider = new ethers.JsonRpcProvider(STABLE_RPC); ## 1. 创建或恢复钱包 -钱包是从助记词派生出来的密钥对。为新用户生成一个钱包,并返回助记词以便他们备份。回访用户可以用相同的助记词恢复钱包。 +钱包是由助记词派生出的密钥对。为新用户生成一个,并返回助记词,以便他们可以备份。回访用户可以通过相同的助记词恢复他们的钱包。 ```typescript // wallet.ts import { ethers } from "ethers"; import { provider } from "./config"; -/** Create a new wallet for a new user. */ +/** 为新用户创建新钱包。 */ export function createWallet() { const wallet = ethers.Wallet.createRandom(provider); return { wallet, address: wallet.address, - seedPhrase: wallet.mnemonic!.phrase, // display to user for backup + seedPhrase: wallet.mnemonic!.phrase, // 显示给用户备份 }; } -/** Restore a wallet from a seed phrase (returning user). */ +/** 从助记词恢复钱包(回访用户)。 */ export function restoreWallet(seedPhrase: string) { const wallet = ethers.Wallet.fromPhrase(seedPhrase, provider); return { wallet, address: wallet.address }; @@ -110,9 +110,9 @@ Address: 0xAlice...1234 Seed phrase: liberty shoot ... (12 words) ``` -## 2. 查询余额 +## 2. 检查余额 -USDT0 是 Stable 上的原生资产,因此余额查询与以太坊上的 ETH 完全相同。原生余额为 18 位小数,使用 `formatEther` 进行显示。 +USDT0 是 Stable 上的原生资产,因此余额查询的工作方式与以太坊上的 ETH 完全相同。原生余额为 18 位小数,使用 `formatEther` 进行显示。 ```typescript // getBalance.ts @@ -121,7 +121,7 @@ import { provider } from "./config"; export async function getBalance(address: string) { const balance = await provider.getBalance(address); - return ethers.formatEther(balance); // 18 decimals + return ethers.formatEther(balance); // 18 位小数 } if (import.meta.url === `file://${process.argv[1]}`) { @@ -139,9 +139,9 @@ npx tsx getBalance.ts 0xAlice...1234 Balance: 0.01 USDT0 ``` -## 3. 发送支付 +## 3. 发送付款 -发送方直接签名并提交转账。在 Stable 上,USDT0 是原生资产,因此简单的价值转账是最便宜的方式(21,000 gas)。这与任何支付应用中的"发送"功能采用相同的代码路径。 +发送方直接签名并提交转账。在 Stable 上,USDT0 是原生资产,因此简单的价值转账是最便宜的路径(21,000 gas)。这与任何支付应用程序中“发送”的代码路径相同。 ```typescript // send.ts @@ -151,7 +151,7 @@ import { provider } from "./config"; export async function sendPayment( senderKey: string, recipient: string, - amount: string // e.g. "0.001" for 0.001 USDT0 + amount: string // 例如,0.001 USDT0 的“0.001” ) { const wallet = new ethers.Wallet(senderKey, provider); const block = await provider.getBlock("latest"); @@ -161,7 +161,7 @@ export async function sendPayment( to: recipient, value: ethers.parseEther(amount), maxFeePerGas: baseFee * 2n, - maxPriorityFeePerGas: 0n, // always 0 on Stable + maxPriorityFeePerGas: 0n, // 在 Stable 上始终为 0 }); console.log("Payment sent:", tx.hash); @@ -186,9 +186,9 @@ Payment sent: 0x8f3a...2d41 Payment settled ``` -## 4. 实时接收支付 +## 4. 实时接收付款 -接收方监听入账的 `Transfer` 事件。这相当于传统支付应用中的推送通知。在 Stable 上,单槽最终性意味着接收方几乎可以即时看到支付。 +接收方监听入账 `Transfer` 事件。这相当于传统支付应用程序中的推送通知。在 Stable 上,单槽终结性意味着接收方几乎可以立即看到付款。 ```typescript // receive.ts @@ -233,12 +233,12 @@ Payment received: ``` :::note -原生转账(价值转账)同样会在 USDT0 ERC-20 合约上触发一个 `Transfer` 事件,因为在 Stable 上 USDT0 既是原生资产,也是一个 ERC-20 代币。单个事件监听器即可覆盖这两种转账方式。 +原生转账(价值转账)也会在 USDT0 ERC-20 合约上发出 `Transfer` 事件,因为 USDT0 在 Stable 上既是原生资产,又是 ERC-20 代币。一个事件监听器涵盖了两种转账方法。 ::: ## 5. 查询交易历史 -查询过去的 `Transfer` 事件以构建交易历史视图,就像任何支付应用中的银行对账单或交易列表一样。 +查询过去的 `Transfer` 事件以构建交易历史视图,就像任何支付应用程序中的银行对账单或交易列表一样。 ```typescript // history.ts @@ -298,11 +298,11 @@ received 0.01 USDT0 0xFaucet... 0x22b1...3f09 ``` :::warning -扫描大范围的区块(数百万个区块)可能会超时并超过 RPC 速率限制。在生产环境中,请使用 [Stablescan 的 Etherscan 兼容 API](https://stablescan.xyz) 进行分页历史查询——每一笔交易都已被索引。 +扫描大范围块(数百万个块)可能会超时,并超出 RPC 速率限制。对于生产环境,请使用 [Stablescan Etherscan 兼容 API](https://stablescan.xyz) 进行分页历史查询。所有交易都已编入索引。 ::: -## 推荐后续阅读 +## 接下来推荐 -- [**订阅与收款**](/cn/how-to/subscribe-and-collect) — 基于拉取的周期性订阅,使用 EIP-7702 委托。 -- [**使用发票付款**](/cn/how-to/pay-with-invoice) — 使用 ERC-3009 和确定性 nonce 结算发票。 -- [**发送你的第一笔 USDT0**](/cn/tutorial/send-usdt0) — 参考基本的原生转账与 ERC-20 转账流程。 +- [**订阅和收集**](/cn/how-to/subscribe-and-collect):基于拉取的定期订阅与 EIP-7702 委托。 +- [**使用发票支付**](/cn/how-to/pay-with-invoice):使用 ERC-3009 和确定性随机数结算发票。 +- [**发送您的第一个 USDT0**](/cn/tutorial/send-usdt0):参考基本的原生与 ERC-20 转账流程。 diff --git a/docs/pages/cn/how-to/build-pay-per-call.mdx b/docs/pages/cn/how-to/build-pay-per-call.mdx index 289c4db..452c1ef 100644 --- a/docs/pages/cn/how-to/build-pay-per-call.mdx +++ b/docs/pages/cn/how-to/build-pay-per-call.mdx @@ -1,52 +1,52 @@ --- source_path: how-to/build-pay-per-call.mdx -source_sha: c51728a92a4f9ff299c86445d2b6b0f31cbe5d8c -title: "构建按调用付费的 API" -description: "使用 Stable 上的 x402,通过每次请求的 USDT0 支付来将 HTTP 端点货币化。包括服务端设置、客户端集成与支出控制。" +source_sha: 37e3f619a2a824cd05b1ff780d568b1b412d01ad +title: "构建按次计费 API" +description: "使用 Stable 上的 x402,通过每次请求 USDT0 支付,实现 HTTP 端点货币化。服务器设置、客户端集成和支出控制。" diataxis: "how-to" --- -# 构建按调用付费的 API +# 构建按次计费 API -本指南介绍如何使用 x402 将 API 端点货币化。服务端添加支付处理逻辑,客户端按请求付费,结算在 HTTP 生命周期内完成。 +本指南将指导您如何使用 x402 将 API 端点货币化。服务器添加支付处理程序,客户端按请求付费,并在 HTTP 生命周期内完成结算。 :::note -**概念:** 关于 x402 协议及其为何适合 Stable,请参阅 [x402](/cn/explanation/x402)。关于高层用例模型,请参阅 [按调用付费 API](/cn/reference/pay-per-call)。 +**概念:** 有关 x402 协议及其为何适用于 Stable,请参阅 [x402](/cn/explanation/x402)。有关高级用例模型,请参阅 [按次计费 API](/cn/reference/pay-per-call)。 ::: :::note -Semantic 结算方目前仅在主网上运行。本指南中的示例使用 Stable 主网。测试时请使用小额金额。 +Semantic 协调器目前仅在主网运行。本指南中的示例使用 Stable 主网。测试时请使用小额资金。 ::: -## 你将构建的内容 +## 您将构建什么 -一个付费 HTTP API,服务端以 `402 Payment Required` 响应,客户端按请求付费,结算方在 HTTP 生命周期内在链上结算 USDT0。 +一个付费 HTTP API,其中服务器以 `402 Payment Required` 响应,客户端按请求付费,协调器在 HTTP 生命周期内链上结算 USDT0。 ### 演示 ```text -step 1. Client: GET /weather (no payment) - Server: 402 Payment Required +步骤 1. 客户端:GET /weather (未支付) + 服务器:402 Payment Required PAYMENT-REQUIRED: { amount: "1000", asset: USDT0, network: eip155:988 } -step 2. Client signs ERC-3009 authorization +步骤 2. 客户端签署 ERC-3009 授权 -step 3. Client: GET /weather + PAYMENT-SIGNATURE header - Server: forwards to facilitator → transferWithAuthorization settles on-chain - (~700ms block confirmation) - Server: 200 OK { weather: "sunny", temperature: 70 } +步骤 3. 客户端:GET /weather + PAYMENT-SIGNATURE header + 服务器:转发给协调器 → transferWithAuthorization 在链上结算 + (~700ms 区块确认) + 服务器:200 OK { weather: "sunny", temperature: 70 } PAYMENT-SETTLE-RESPONSE: { txHash: "0x8f3a...", paid: "0.001 USDT0" } -step 4. Verify settlement on Stablescan +步骤 4. 在 Stablescan 上验证结算 https://stablescan.xyz/tx/0x8f3a... ``` -## 概览 +## 概述 -**卖方(服务端):** +**卖家(服务器):** ```typescript -// --- Server --- +// --- 服务器 --- app.use(paymentMiddleware({ "GET /weather": { price: { amount: "1000", asset: USDT0 }, @@ -58,13 +58,13 @@ app.use(paymentMiddleware({ }, }, resourceServer)); -// Routes not listed in the config are not gated. +// 配置中未列出的路由不受限制。 ``` -**买方(客户端):** +**买家(客户端):** ```typescript -// --- Client --- +// --- 客户端 --- account = new WalletAccountEvm(seedPhrase, { provider: RPC }); client = new x402Client(); fetchWithPayment = wrapFetchWithPayment(fetch, client); @@ -76,16 +76,16 @@ inferenceResponse = fetchWithPayment("https://api.example.com/inference", { body: JSON.stringify({ prompt: "Hello" }), }); -// For each paid request: -// 1. Initial request returns 402 with PAYMENT-REQUIRED header -// 2. Client signs ERC-3009 authorization with wallet -// 3. Client retries with PAYMENT-SIGNATURE header -// 4. Facilitator settles on-chain, server returns the response +// 对于每个付费请求: +// 1. 初始请求返回 402 和 PAYMENT-REQUIRED 头部 +// 2. 客户端使用钱包签署 ERC-3009 授权 +// 3. 客户端使用 PAYMENT-SIGNATURE 头部重试 +// 4. 协调器在链上结算,服务器返回响应 ``` -## 卖方:设置付费端点 +## 卖家:设置付费端点 -卖方添加 x402 中间件来定义哪些路由需要付费。当请求到达但没有携带支付时,中间件以 `402 Payment Required` 和支付条款响应。当存在有效的支付标头时,中间件将其转发给结算方,由结算方验证签名并在链上结算支付。卖方只需配置价格和收款地址;结算方负责验证和结算。 +卖家添加 x402 中间件来定义哪些路由需要付费。当没有付款的请求到达时,中间件会以 `402 Payment Required` 和付款条款响应。当存在有效的付款头部时,中间件将其转发给协调器,协调器验证签名并在链上结算付款。卖家只需配置价格和收款地址;协调器处理验证和结算。 ```bash npm install express @x402/express @x402/evm @x402/core @@ -93,21 +93,21 @@ npm install express @x402/express @x402/evm @x402/core ### 定价 -每个路由以 USDT0 基本单位(6 位小数)指定支付金额、网络和收款地址。例如,`"1000"` 等于 `$0.001`,`"50000"` 等于 `$0.05`。 +每个路由都指定以 USDT0 基本单位(6 位小数)计价的支付金额、网络和接收资金的地址。例如,`"1000"` 等于 `$0.001`,`"50000"` 等于 `$0.05`。 ```typescript price: { - amount: "1000", // base units (6 decimals) - asset: USDT0_STABLE, // USDT0 contract address - extra: { name: "USDT0", version: "1", decimals: 6 }, // EIP-712 domain info + amount: "1000", // 基本单位 (6 位小数) + asset: USDT0_STABLE, // USDT0 合约地址 + extra: { name: "USDT0", version: "1", decimals: 6 }, // EIP-712 域信息 } ``` -`extra` 字段(`name`、`version`、`decimals`)由买方的客户端用于构建 EIP-712 签名,必须与链上 USDT0 合约相匹配。 +`extra` 字段(`name`、`version`、`decimals`)由买方的客户端用于 EIP-712 签名构建,并且必须与链上 USDT0 合约匹配。 ### 路由配置 -路由使用 `METHOD /path` 格式映射。每个路由指定接受的支付方案、网络、价格和收款地址(`payTo`)。`description` 和 `mimeType` 字段帮助买方和 AI 代理发现该端点提供的内容。未在配置中列出的路由不受限制,行为与普通 Express 路由一致。 +路由使用 `METHOD /path` 格式进行映射。每个路由都指定接受的支付方案、网络、价格以及接收资金的地址 (`payTo`)。`description` 和 `mimeType` 字段帮助买家和 AI 代理发现端点提供的信息。配置中未列出的路由不受限制,其行为类似于正常的 Express 路由。 ```typescript // server.ts @@ -118,7 +118,7 @@ import { HTTPFacilitatorClient } from "@x402/core/server"; const PAY_TO = process.env.PAY_TO_ADDRESS as `0x${string}`; const FACILITATOR_URL = "https://x402.semanticpay.io/"; -const STABLE_NETWORK = "eip155:988"; // Stable Mainnet CAIP-2 ID +const STABLE_NETWORK = "eip155:988"; // Stable 主网 CAIP-2 ID const USDT0_STABLE = "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"; const facilitatorClient = new HTTPFacilitatorClient({ url: FACILITATOR_URL }); @@ -130,7 +130,7 @@ const app = express(); app.use( paymentMiddleware( { - // Example 1: Configure a paid GET route + // 示例 1:配置一个付费 GET 路由 "GET /weather": { accepts: [ { @@ -144,10 +144,10 @@ app.use( payTo: PAY_TO, }, ], - description: "Weather data", + description: "天气数据", mimeType: "application/json", }, - // Example 2: Configure a paid POST route + // 示例 2:配置一个付费 POST 路由 "POST /inference": { accepts: [ { @@ -161,7 +161,7 @@ app.use( payTo: PAY_TO, }, ], - description: "AI inference endpoint", + description: "AI 推理端点", mimeType: "application/json", }, }, @@ -175,30 +175,30 @@ app.get("/weather", (req, res) => { app.post("/inference", (req, res) => { const { prompt } = req.body; - res.json({ result: `Inference result for: ${prompt}` }); + res.json({ result: `推理结果为: ${prompt}` }); }); -// Not listed in the config, so no payment required. +// 未在配置中列出,因此无需支付。 app.get("/health", (req, res) => { res.json({ status: "ok", payTo: PAY_TO }); }); const PORT = process.env.PORT || 4021; app.listen(PORT, () => { - console.log(`Server listening at http://localhost:${PORT}`); - console.log(`GET /health - free`); - console.log(`GET /weather - $0.001 per request`); - console.log(`POST /inference - $0.05 per request`); + console.log(`服务器监听地址 http://localhost:${PORT}`); + console.log(`GET /health - 免费`); + console.log(`GET /weather - 每次请求 $0.001`); + console.log(`POST /inference - 每次请求 $0.05`); }); ``` :::note -x402 还为 Hono(`@x402/hono`)和 Next.js(`@x402/next`)提供了中间件。模式相同:创建结算方客户端、注册 EVM 方案并应用中间件。 +x402 还为 Hono (`@x402/hono`) 和 Next.js (`@x402/next`) 提供了中间件。模式相同:创建协调器客户端,注册 EVM 方案,然后应用中间件。 ::: -## 买方:发起付费请求 +## 买家:发出付费请求 -买方无需经过手动支付流程即可访问付费端点。买方不支付 gas。结算方在链上结算,买方只支付支付要求中指定的确切金额。 +买家无需通过手动支付流程即可访问付费端点。买家无需支付 Gas 费。协调器在链上结算,买家只需支付支付要求中指定的精确金额。 ```bash npm install @x402/fetch @x402/evm @tetherto/wdk-wallet-evm @@ -214,17 +214,17 @@ const account = await new WalletManagerEvm(process.env.SEED_PHRASE!, { provider: "https://rpc.stable.xyz", }).getAccount(0); -console.log("Buyer address:", account.address); +console.log("买家地址:", account.address); -// USDT0 uses 6 decimals. A balance of 1000000 equals 1.00 USDT0. +// USDT0 使用 6 位小数。余额 1000000 等于 1.00 USDT0。 const USDT0_STABLE = "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"; const balance = await account.getTokenBalance(USDT0_STABLE); -console.log("USDT0 balance:", Number(balance) / 1e6, "USDT0"); +console.log("USDT0 余额:", Number(balance) / 1e6, "USDT0"); ``` -### 连接到 x402 并发起付费请求 +### 连接到 x402 并发出付费请求 -`WalletAccountEvm` 满足 x402 所期望的签名者接口,因此可以直接注册为 x402 客户端的签名者。注册后,通过启用 x402 的客户端发送的请求会自动处理 402 支付流程。 +`WalletAccountEvm` 满足 x402 所需的签名者接口,因此可以直接注册为 x402 客户端的签名者。注册后,通过启用 x402 的客户端发送的请求会自动处理 402 支付流程。 ```typescript import { x402Client, wrapFetchWithPayment } from "@x402/fetch"; @@ -236,21 +236,21 @@ const fetchWithPayment = wrapFetchWithPayment(fetch, client); const response = await fetchWithPayment("http://localhost:4021/weather"); const data = await response.json(); -console.log("Response:", data); +console.log("响应:", data); ``` -在底层,`fetchWithPayment` 会拦截 402 响应,解析支付要求(金额、代币、网络、收款方),用 WDK 钱包签署一个 ERC-3009 `transferWithAuthorization`,并使用 `PAYMENT-SIGNATURE` 标头重试请求。 +在底层,`fetchWithPayment` 拦截 402 响应,解析支付要求(金额、代币、网络、接收方),使用 WDK 钱包签署 ERC-3009 `transferWithAuthorization`,并使用 `PAYMENT-SIGNATURE` 头部重试请求。 :::note -如果你更喜欢 Axios,可使用 `@x402/axios` 配合 `wrapAxiosWithPayment` 来获得相同的自动支付处理。 +如果您更喜欢 Axios,请使用 `@x402/axios` 和 `wrapAxiosWithPayment` 进行相同的自动支付处理。 ::: ## 测试支付流程 -启动服务端并验证付费路由和免费路由。 +启动服务器并验证付费和免费路由。 :::warning -此测试流程在 Stable 主网上运行。每次成功的付费请求都会通过托管的结算方结算一笔真实的 USDT0 支付。请仅使用专用钱包和小额金额。 +此测试流程在 Stable 主网运行。每个成功的付费请求都会通过托管协调器结算真实的 USDT0 支付。请仅使用专用钱包和小额资金。 ::: ### 1. 确认 402 响应 @@ -259,7 +259,7 @@ console.log("Response:", data); curl -i http://localhost:4021/weather ``` -响应应为 `402 Payment Required`,并带有包含价格、资产和网络的 `PAYMENT-REQUIRED` 标头。 +响应应为 `402 Payment Required`,并带有包含价格、资产和网络的 `PAYMENT-REQUIRED` 头部。 ### 2. 运行客户端 @@ -267,33 +267,33 @@ curl -i http://localhost:4021/weather npx tsx client.ts ``` -客户端处理完整流程:接收 402、签署授权、携带支付重试并打印响应。 +客户端处理整个周期:接收 402,签署授权,重试并支付,然后打印响应。 ### 3. 读取收据 -在付费请求成功后,买方可以从服务端响应中读取 `PAYMENT-SETTLE-RESPONSE` 标头并解析结算收据。 +成功支付请求后,买方可以从服务器响应中读取 `PAYMENT-SETTLE-RESPONSE` 头部并解析结算收据。 ```typescript -// (continued) client.ts +// (续) client.ts import { x402HTTPClient } from "@x402/fetch"; const httpClient = new x402HTTPClient(client); const receipt = httpClient.getPaymentSettleResponse( (name) => response.headers.get(name), ); -console.log("Payment receipt:", JSON.stringify(receipt, null, 2)); +console.log("支付收据:", JSON.stringify(receipt, null, 2)); ``` -## 在没有实时结算方的情况下测试 +## 不使用实时协调器进行测试 -由于 Semantic 结算方仅支持主网,目前你无法将服务端指向测试网结算方。要在不结算真实支付的情况下迭代服务端逻辑、路由处理程序和中间件行为,可以对结算方客户端进行打桩(stub)。 +由于 Semantic 协调器仅限于主网,因此您目前无法将服务器指向测试网协调器。要在不结算实际支付的情况下迭代服务器逻辑、路由处理程序和中间件行为,请使用模拟协调器客户端。 ```typescript // server.test.ts import { x402ResourceServer } from "@x402/express"; import { ExactEvmScheme } from "@x402/evm/exact/server"; -// Stub facilitator: accepts any signature, returns a fake settlement. +// 模拟协调器:接受任何签名,返回伪造的结算。 const stubFacilitatorClient = { verify: async () => ({ isValid: true, payer: "0xMockPayer" }), settle: async () => ({ @@ -307,26 +307,26 @@ export const testResourceServer = new x402ResourceServer(stubFacilitatorClient a .register("eip155:988", new ExactEvmScheme()); ``` -针对该桩运行单元测试以验证: +针对模拟运行单元测试以验证: -- 402 响应包含正确的 `PAYMENT-REQUIRED` 负载。 -- 带有有效 `PAYMENT-SIGNATURE` 标头的请求能够到达处理程序。 -- 缺失或格式错误标头的请求在处理程序运行前就被拒绝。 +- 402 响应包含正确的 `PAYMENT-REQUIRED` 有效负载。 +- 带有有效 `PAYMENT-SIGNATURE` 头的请求到达处理程序。 +- 缺少或格式错误的头的请求在处理程序运行前被拒绝。 -当你准备好执行真实结算时,切换回 `HTTPFacilitatorClient` 并在主网上使用小额金额运行。 +当您准备好进行真实结算时,请切换回 `HTTPFacilitatorClient` 并在主网上使用小额资金运行。 :::warning -打桩结算仅验证中间件行为。它无法证明你的路由处理程序在真实网络延迟或并发支付下是幂等的。在发布之前,始终要用小额金额在真实主网上完成测试。 +模拟结算仅验证中间件行为。它并不能证明您的路由处理程序在真实网络延迟或并发支付下是幂等的。在发布之前,务必使用小额资金在主网进行实时测试。 ::: -## 进阶:生命周期钩子 +## 高级:生命周期钩子 -x402 提供钩子,可在流程的关键节点拦截并自定义支付处理。例如,服务端可以在验证之前运行逻辑(如检查 API 密钥或订阅者状态),从而为已授权的请求绕过支付,而客户端可以在签名前强制实施支出限制。 +x402 提供了钩子,可以在流程中的关键点拦截和自定义支付处理。例如,服务器可以在验证之前运行逻辑(例如,检查 API 密钥或订阅者状态)以绕过授权请求的支付,客户端可以在签名之前强制执行消费限制。 -完整的钩子参考和示例,请参阅 [x402 生命周期钩子](https://x402.semanticpay.io/docs/hooks)。 +有关完整的钩子参考和示例,请参阅 [x402 生命周期的钩子](https://x402.semanticpay.io/docs/hooks)。 -## 推荐的后续内容 +## 接下来推荐 -- [**x402 概念**](/cn/explanation/x402) — 了解协议及其适用场景。 -- [**ERC-3009**](/cn/explanation/erc-3009) — 回顾 x402 使用的结算标准。 -- [**通过 MCP 服务器付费**](/cn/how-to/pay-with-mcp) — 将此 API 封装为 MCP 工具,以便 AI 客户端可以通过提示词调用它。 +- [**x402 概念**](/cn/explanation/x402):了解协议及其适用范围。 +- [**ERC-3009**](/cn/explanation/erc-3009):回顾 x402 使用的结算标准。 +- [**使用 MCP 服务器支付**](/cn/how-to/pay-with-mcp):将此 API 封装为 MCP 工具,以便 AI 客户端可以通过提示调用它。 diff --git a/docs/pages/cn/how-to/create-wallet.mdx b/docs/pages/cn/how-to/create-wallet.mdx index f8c6e9b..a068361 100644 --- a/docs/pages/cn/how-to/create-wallet.mdx +++ b/docs/pages/cn/how-to/create-wallet.mdx @@ -1,6 +1,6 @@ --- source_path: how-to/create-wallet.mdx -source_sha: 282b1f16baf49a0e39d7df989136218e3727fad2 +source_sha: 0735e9a5c8737cb5606dd4ea1d7406859b371377 title: "创建钱包" description: "使用 ethers.js 或 Tether WDK 生成新的 Stable 钱包,或从助记词恢复钱包。" diataxis: "how-to" @@ -8,19 +8,19 @@ diataxis: "how-to" # 创建钱包 -Stable 钱包是一个符合以太坊标准的密钥对。任何能生成 EVM 账户的钱包库都可以在 Stable 上直接使用,无需修改。本指南展示两种方式:适用于大多数应用的 ethers.js,以及面向需要为代理和支付提供开箱即用自托管层的集成场景的 Tether [WDK(钱包开发工具包)](https://github.com/tetherto/wdk)。 +Stable 钱包是一个以太坊标准的密钥对。任何生成 EVM 账户的钱包库都可以在 Stable 上运行,无需修改。本指南提供了两种路径:对于大多数应用程序使用 ethers.js,对于需要为代理和支付提供开箱即用的自托管层的集成,可以使用 Tether 的 [WDK(钱包开发工具包)](https://github.com/tetherto/wdk)。 :::note -无需注册,也无需进行 Stable 专属的账户设置。钱包可以立即从[测试网水龙头](/cn/how-to/use-faucet)或主网转账接收 USDT0。 +无需注册,无需 Stable 特定账户设置。钱包可以立即从 [测试网水龙头](/cn/how-to/use-faucet) 或主网转账接收 USDT0。 ::: ## 前提条件 - Node.js 20 或更高版本。 -## 方式 1:ethers.js +## 选项 1:ethers.js -安装该库并生成密钥对。 +安装库并生成密钥对。 ```bash npm install ethers @@ -32,17 +32,17 @@ import { ethers } from "ethers"; const provider = new ethers.JsonRpcProvider("https://rpc.testnet.stable.xyz"); -/** Create a new wallet for a new user. */ +/** 为新用户创建新钱包。*/ export function createWallet() { const wallet = ethers.Wallet.createRandom(provider); return { wallet, address: wallet.address, - seedPhrase: wallet.mnemonic!.phrase, // show to the user once for backup + seedPhrase: wallet.mnemonic!.phrase, // 向用户展示一次以进行备份 }; } -/** Restore a wallet from a seed phrase (returning user). */ +/** 从助记词恢复钱包(回访用户)。*/ export function restoreWallet(seedPhrase: string) { const wallet = ethers.Wallet.fromPhrase(seedPhrase, provider); return { wallet, address: wallet.address }; @@ -65,12 +65,12 @@ Seed phrase: liberty shoot ... (12 words) ``` :::warning -在生产环境中,切勿以明文形式记录或存储助记词。请将其加密存储,或使用密钥管理器。`ethers.Wallet.createRandom` 每次调用只返回一次助记词——如果丢失,资金将无法找回。 +切勿在生产环境中明文记录或存储助记词。请对其进行加密存储,或使用秘密管理器。`ethers.Wallet.createRandom` 每次调用返回一次助记词。如果您丢失了助记词,资金将无法恢复。 ::: -## 方式 2:Tether WDK +## 选项 2:Tether WDK -WDK 将密钥派生、签名和交易提交封装到单一接口中。当你希望实现自托管而无需重新实现常见账户流程时,它是正确的选择,并且它能直接与 [x402](/cn/how-to/build-pay-per-call) 集成以实现代理支付。 +WDK 将密钥派生、签名和交易提交包装在一个接口中。当您想要自托管而无需重新实现常见的账户流程时,它是正确的选择,并且它与 [x402](/cn/how-to/build-pay-per-call) 直接集成,用于代理支付。 ```bash npm install @tetherto/wdk @tetherto/wdk-wallet-evm @@ -88,7 +88,7 @@ function initWdk(seedPhrase: string) { }); } -/** Create a new wallet for a new user. */ +/** 为新用户创建新钱包。*/ export async function createWallet() { const seedPhrase = WDK.getRandomSeedPhrase(); const wdk = initWdk(seedPhrase); @@ -96,11 +96,11 @@ export async function createWallet() { return { account, address: await account.getAddress(), - seedPhrase, // show to the user once for backup + seedPhrase, // 向用户展示一次以进行备份 }; } -/** Restore a wallet from a seed phrase (returning user). */ +/** 从助记词恢复钱包(回访用户)。*/ export async function restoreWallet(seedPhrase: string) { const wdk = initWdk(seedPhrase); const account = await wdk.getAccount("stable", 0); @@ -117,19 +117,19 @@ Address: 0xAlice...1234 Seed phrase: liberty shoot ... (12 words) ``` -## 为钱包注资 +## 钱包充值 -在钱包能够进行交易之前,它需要 USDT0 作为 gas。在测试网上,可从水龙头请求: +在钱包可以进行交易之前,它需要 USDT0 作为 gas。在测试网上,可以从水龙头请求: ```bash open https://faucet.stable.xyz ``` -粘贴地址并选择按钮即可接收 1 个测试网 USDT0(足够进行数千次原生转账)。对于主网,可从任何受支持的交易所或桥转入 USDT0;参见[跨链桥接到 Stable](/cn/explanation/usdt0-bridging)。 +粘贴地址并选择按钮以接收 1 个测试网 USDT0(足以进行数千次原生转账)。对于主网,可以从任何受支持的交易所或网桥发送 USDT0;请参阅 [桥接到 Stable](/cn/explanation/usdt0-bridging)。 -## 查询余额 +## 检查余额 -原生 USDT0 使用 18 位小数。原生余额即为支付 gas 所用的余额。 +原生 USDT0 使用 18 位小数。原生余额是用于支付 gas 的。 ```typescript // balance.ts @@ -148,8 +148,8 @@ npx tsx balance.ts Balance: 1.0 USDT0 ``` -## 推荐的后续步骤 +## 接下来推荐 -- [**使用 EIP-7702 进行委托**](/cn/how-to/account-abstraction) — 为该钱包添加批量支付、支出限额和会话密钥。 -- [**发送你的第一笔 USDT0**](/cn/tutorial/send-usdt0) — 在同一余额上进行原生和 ERC-20 转账。 -- [**为测试网钱包注资**](/cn/how-to/use-faucet) — 用于获取更大测试余额的水龙头和 Sepolia 桥接选项。 +- [**使用 EIP-7702 进行委托**](/cn/how-to/account-abstraction):为该钱包添加批量支付、支出限额和会话密钥。 +- [**发送您的第一个 USDT0**](/cn/tutorial/send-usdt0):相同余额上的原生和 ERC-20 转账。 +- [**为测试网钱包充值**](/cn/how-to/use-faucet):用于更多测试余额的水龙头和 Sepolia 网桥选项。 diff --git a/docs/pages/cn/how-to/develop-with-ai.mdx b/docs/pages/cn/how-to/develop-with-ai.mdx index 7091f59..e8fdaa1 100644 --- a/docs/pages/cn/how-to/develop-with-ai.mdx +++ b/docs/pages/cn/how-to/develop-with-ai.mdx @@ -1,22 +1,22 @@ --- source_path: how-to/develop-with-ai.mdx -source_sha: 621ff15f63c34d76a39e5a45a36987add8833dbd +source_sha: 2dca54cdd89b846903b46f9688a1a3367b258907 title: "使用 AI 进行开发" -description: "设置 MCP 服务器、agent skills 和纯文本文档,让 AI 编辑器和编码代理能够直接在 Stable 上构建。" +description: "设置 MCP 服务器、代理技能和纯文本文档,以便 AI 编辑器和编码代理可以直接在 Stable 上进行构建。" diataxis: "how-to" --- -Stable 提供 MCP 服务器、agent skills 和纯文本文档文件,让 AI 编辑器和编码代理能够直接与 Stable 协作。本页介绍如何将每个组件接入你的工作流、为非 MCP AI 工具提供可复制粘贴的上下文块,以及常见任务的入门提示词。 +Stable 提供 MCP 服务器、代理技能和纯文本文档文件,以便 AI 编辑器和编码代理可以直接使用 Stable。本页面介绍如何将每个组件集成到您的工作流中,为非 MCP AI 工具提供可复制粘贴的上下文块,以及常见任务的入门提示。 ## MCP 服务器 -Stable 运行两个 MCP 服务器。**Docs MCP** 在本文档站点中搜索概念、指南、代码片段和合约参考。**Runtime MCP** 与 Stable 链交互,用于余额查询、交易模拟和执行。 +Stable 运行两个 MCP 服务器。**Docs MCP** 在此文档站点中搜索概念、指南、代码片段和合约引用。**Runtime MCP** 与 Stable 链交互,用于余额查询、交易模拟和执行。 -这两个服务器都可以添加到任何兼容 MCP 的客户端。 +两个服务器都可以添加到任何 MCP 兼容客户端。 ### Cursor -打开你的 MCP 配置文件并添加: +打开您的 MCP 配置文件并添加: ```json { @@ -31,7 +31,7 @@ Stable 运行两个 MCP 服务器。**Docs MCP** 在本文档站点中搜索概 } ``` -重启 Cursor。通过询问以下问题进行验证:"How do I send USDT0 on Stable?" +重启 Cursor。通过询问“我如何在 Stable 上发送 USDT0?”进行验证。 ### Claude Code @@ -40,13 +40,13 @@ claude mcp add stable-docs https://docs.stable.xyz/mcp claude mcp add stable-runtime https://runtime.stable.xyz/mcp ``` -通过询问以下问题进行验证:"Search Stable docs for Gas Waiver integration steps." +通过询问“搜索 Stable 文档以获取 Gas 豁免集成步骤。”进行验证。 -## Agent skills +## 代理技能 -Agent skills 是结合了 Docs MCP 和 Runtime MCP 的预定义工作流。当你要求 AI 执行诸如"向三个地址发送 100 USDT0"之类的任务时,该 skill 会处理整个流程:查找相关文档、解析地址和参数、检查余额、模拟交易,并在批准后执行。 +代理技能是预定义的工作流,结合了 Docs MCP 和 Runtime MCP。当您要求 AI 执行“发送 100 USDT0 到三个地址”等任务时,该技能会处理整个序列:查找相关文档、解析地址和参数、检查余额、模拟交易并在批准后执行。 -Skills 以 Claude Code 插件的形式提供。 +技能作为 Claude Code 插件提供。 ### 安装 @@ -54,20 +54,20 @@ Skills 以 Claude Code 插件的形式提供。 claude plugin add stable-xyz/agent-skills ``` -或从 Claude Code 市场安装。 +或者从 Claude Code 市场安装。 -有关完整的 skill 定义和源代码,请参阅 [agent-skills 仓库](https://github.com/stable-xyz/agent-skills)。 +有关完整的技能定义和来源,请参阅 [agent-skills 存储库](https://github.com/stable-xyz/agent-skills)。 ## 纯文本文档 -对于不支持 MCP 的 AI 工具,Stable 文档以静态文本文件的形式提供。 +对于不支持 MCP 的 AI 工具,Stable 文档以静态文本文件形式提供。 | **文件** | **URL** | **内容** | | :--- | :--- | :--- | -| `llms.txt` | [https://docs.stable.xyz/llms.txt](https://docs.stable.xyz/llms.txt) | 带标题和描述的页面索引 | -| `llms-full.txt` | [https://docs.stable.xyz/llms-full.txt](https://docs.stable.xyz/llms-full.txt) | 单个文件中的完整文档 | +| `llms.txt` | [https://docs.stable.xyz/llms.txt](https://docs.stable.xyz/llms.txt) | 包含标题和描述的页面索引 | +| `llms-full.txt` | [https://docs.stable.xyz/llms-full.txt](https://docs.stable.xyz/llms-full.txt) | 单文件完整文档 | -这些文件是静态快照。如需最新内容,请使用 Docs MCP。 +这些文件是静态快照。要获取最新内容,请使用 Docs MCP。 ### Cursor @@ -77,138 +77,137 @@ claude plugin add stable-xyz/agent-skills ### 其他工具 -下载 `llms-full.txt` 并将其包含在你的项目上下文或系统提示词中。 +下载 `llms-full.txt` 并将其包含在您的项目上下文或系统提示中。 ## Stable 上下文块 -将此内容粘贴到任何 AI 聊天或系统提示词的顶部。它为模型提供了首次尝试即可生成正确 Stable 代码所需的一切。 +将其粘贴到任何 AI 聊天或系统提示的顶部。它为模型提供了在第一次尝试时生成正确的 Stable 代码所需的一切。 ````markdown -# Stable chain context +# Stable 链上下文 -Stable is a Layer 1 where USDT0 is the native gas token. Fully EVM-compatible. -All standard EVM tools (Hardhat, Foundry, ethers.js, viem) work unchanged once -you adjust three gas fields (see Behavioral differences below). +Stable 是一个 Layer 1,其中 USDT0 是原生的 gas 代币。与 EVM 完全兼容。 +所有标准 EVM 工具(Hardhat、Foundry、ethers.js、viem)在 +调整三个 gas 字段后(参见下面的行为差异)无需更改即可工作。 -## Network +## 网络 -| Field | Mainnet | Testnet | +| 字段 | 主网 | 测试网 | | :-------------- | :--------------------------------------- | :----------------------------------------- | -| Chain ID | 988 | 2201 | +| 链 ID | 988 | 2201 | | RPC | https://rpc.stable.xyz | https://rpc.testnet.stable.xyz | -| Explorer | https://stablescan.xyz | https://testnet.stablescan.xyz | -| Currency symbol | USDT0 | USDT0 | - -## USDT0 contract addresses - -- Mainnet: 0x779ded0c9e1022225f8e0630b35a9b54be713736 -- Testnet: 0x78cf24370174180738c5b8e352b6d14c83a6c9a9 - -## Behavioral differences from Ethereum - -1. **Gas token is USDT0, not ETH.** The `value` field in native transfers - carries USDT0. Fees are denominated in USDT0. -2. **`maxPriorityFeePerGas` is always 0.** No tip-based ordering. Set it - explicitly to `0n` or validators will reject or ignore tip components. -3. **USDT0 has a dual role**: native asset (18 decimals) AND ERC-20 (6 decimals) - on the same balance. `address(x).balance` reports 18-decimal wei; - `USDT0.balanceOf(x)` reports 6-decimal units. Values may differ by up to - 0.000001 USDT0 due to fractional reconciliation. Never mirror native - balance in an internal variable; always query at payout time. -4. **Transfer events are emitted for native transfers too.** A single Transfer - event listener on the USDT0 ERC-20 contract covers both transfer paths. -5. **Single-slot finality (~700ms).** Once a block is committed, it cannot - be reorged. No need to wait multiple confirmations. -6. **Gas Waiver** lets applications cover gas: user signs with `gasPrice = 0`, - a governance-registered waiver wraps and submits. Contracts must be on - the waiver's AllowedTarget policy. -7. **EIP-7702** is supported for delegating an EOA to a contract (type-4 tx). -8. **Precompile addresses**: Bank `0x...1003`, Distribution `0x...0801`, - Staking `0x...0800`, StableSystem `0x...9999`. - -## Common mistakes to avoid - -- Copying Ethereum priority-fee constants (2 gwei tips, etc.) — has no effect - on Stable and can be rejected by wallets. -- Using `ethers.parseUnits(x, 18)` for ERC-20 USDT0 amounts. ERC-20 uses 6 - decimals; native transfers use 18. -- Mirroring native balance in a `uint256 deposited` variable — USDT0 - allowance-based operations (transferFrom, permit) can reduce a contract's - native balance without invoking its code. -- Sending native or ERC-20 USDT0 to `address(0)` — both revert on Stable. -- Assuming `EXTCODEHASH == 0` means an address is unused. On Stable, - permit-based approvals can change state without incrementing nonce. -- Writing `value: ethers.parseEther(amount, "ether")` and expecting ETH - semantics. That transfer sends USDT0. +| 浏览器 | https://stablescan.xyz | https://testnet.stablescan.xyz | +| 货币符号 | USDT0 | USDT0 | + +## USDT0 合约地址 + +- 主网: 0x779ded0c9e1022225f8e0630b35a9b54be713736 +- 测试网: 0x78cf24370174180738c5b8e352b6d14c83a6c9a9 + +## 与以太坊的行为差异 + +1. **Gas 代币是 USDT0,而不是 ETH。** 原生转账中的 `value` 字段 + 携带 USDT0。费用以 USDT0 计价。 +2. **`maxPriorityFeePerGas` 始终为 0。** 没有基于小费的排序。将其 + 明确设置为 `0n`,否则验证者将拒绝或忽略小费组件。 +3. **USDT0 具有双重作用**:原生资产(18 位小数)和 ERC-20(6 位小数) + 在同一余额上。`address(x).balance` 报告 18 位小数的 wei; + `USDT0.balanceOf(x)` 报告 6 位小数的单位。由于分数协调, + 值可能相差高达 0.000001 USDT0。切勿在内部变量中镜像原生 + 余额;始终在支付时查询。 +4. **原生转账也会发出转账事件。** USDT0 ERC-20 合约上的单个 + Transfer 事件监听器涵盖两种转账路径。 +5. **单槽终结性(约 700ms)。** 一旦区块提交,就无法 + 重组。无需等待多次确认。 +6. **Gas 豁免** 允许应用程序支付 gas:用户使用 `gasPrice = 0` 进行签名, + 由治理注册的豁免包装并提交。合约必须在 + 豁免的 AllowedTarget 策略上。 +7. **EIP-7702** 支持将 EOA 委托给合约(类型 4 交易)。 +8. **预编译地址**:Bank `0x...1003`,Distribution `0x...0801`, + Staking `0x...0800`,StableSystem `0x...9999`。 + +## 常见的错误避免 + +- 复制以太坊优先费用常量(2 gwei 小费等)。这在 Stable 上 + 没有效果,并且可能被钱包拒绝。 +- 为 ERC-20 USDT0 金额使用 `ethers.parseUnits(x, 18)`。ERC-20 使用 6 + 位小数;原生转账使用 18 位小数。 +- 在 `uint256 deposited` 变量中镜像原生余额。USDT0 + 基于授权的操作(transferFrom、permit)可以在不调用合约 + 代码的情况下减少合约的原生余额。 +- 将原生或 ERC-20 USDT0 发送到 `address(0)`。这两种情况在 Stable 上都会回滚。 +- 假设 `EXTCODEHASH == 0` 表示地址未使用。在 Stable 上, + 基于许可的批准可以更改状态而无需增加 nonce。 +- 编写 `value: ethers.parseEther(amount, "ether")` 并期望 ETH + 语义。该转账发送 USDT0。 ```` -## 入门提示词 +## 入门提示 -加载上面的上下文块后,将以下任意提示词复制到你的 AI 编辑器中。 +在加载上面的上下文块后,将以下任何内容复制到您的 AI 编辑器中。 ### 部署合约 ```text -Use Foundry to scaffold a project called `stable-escrow`. Write a minimal -Escrow contract in Solidity ^0.8.24 with deposit() and withdraw(amount) -functions that transfer USDT0 natively. Use address(this).balance for -solvency checks (never mirror the balance in a uint256). Reject -address(0) recipients. Then produce a deployment command using -`forge create` pointed at Stable testnet (RPC https://rpc.testnet.stable.xyz, -chain ID 2201). +使用 Foundry 搭建一个名为 `stable-escrow` 的项目。编写一个最简单的 +Solidity ^0.8.24 托管合约,包含 deposit() 和 withdraw(amount) +函数,这些函数原生转账 USDT0。使用 address(this).balance 进行 +偿付能力检查(切勿在 uint256 中镜像余额)。拒绝 +address(0) 接收者。然后生成一个使用 +`forge create` 命令,指向 Stable 测试网(RPC https://rpc.testnet.stable.xyz, +链 ID 2201)。 ``` ### 发送 USDT0 ```text -Write a TypeScript script using ethers v6 that sends 0.001 USDT0 natively -from the wallet loaded from PRIVATE_KEY. Use base-fee-only EIP-1559 gas -(maxPriorityFeePerGas = 0n, maxFeePerGas = 2 * baseFeePerGas). Target -Stable testnet. Log the tx hash and a Stablescan explorer URL. +编写一个使用 ethers v6 的 TypeScript 脚本,它原生发送 0.001 USDT0 +从 PRIVATE_KEY 加载的钱包中。使用仅基础费用 EIP-1559 gas +(maxPriorityFeePerGas = 0n, maxFeePerGas = 2 * baseFeePerGas)。目标 +Stable 测试网。记录交易哈希和 Stablescan 浏览器 URL。 ``` ### 设置 EIP-7702 委托 ```text -Write a TypeScript script using ethers v6 that: -1. Signs an EIP-7702 authorization delegating my EOA to Multicall3 at - 0xcA11bde05977b3631167028862bE2a173976CA11 on Stable testnet - (chain ID 2201). -2. Sends a type-4 transaction with authorizationList: [signedAuth], - to: wallet.address (self-call), and data that invokes aggregate3() - to batch three USDT0 transfers (100, 200, 150 USDT0 with 6 decimals). -3. Use maxPriorityFeePerGas: 0n. +编写一个使用 ethers v6 的 TypeScript 脚本: +1. 签署一个 EIP-7702 授权,将我的 EOA 委托给 Stable 测试网 + (链 ID 2201) 上的 0xcA11bde05977b3631167028862bE2a173976CA11 的 Multicall3。 +2. 发送一个类型 4 交易,其 authorizationList: [signedAuth], + to: wallet.address (自调用),以及调用 aggregate3() + 以批量处理三个 USDT0 转账(100、200、150 USDT0,6 位小数)的数据。 +3. 使用 maxPriorityFeePerGas: 0n。 ``` ### 构建订阅合约 ```text -Write a SubscriptionManager Solidity contract for EIP-7702 delegation on -Stable. It runs on a subscriber's EOA. Expose: +为 Stable 上的 EIP-7702 委托编写一个 SubscriptionManager Solidity 合约。 +它在订阅者的 EOA 上运行。公开: - subscribe(bytes32 subId, address provider, uint256 amount, uint256 interval) - callable only when msg.sender == address(this) (subscriber on their own EOA). - - collect(bytes32 subId) callable only by the registered provider, only - when block.timestamp >= nextChargeAt; advances nextChargeAt by interval - and transfers USDT0 to the provider. Use IERC20 USDT0 at the testnet - address 0x78cf24370174180738c5b8e352b6d14c83a6c9a9. - - cancelSubscription(bytes32 subId) callable only by the subscriber. -Emit events for SubscriptionCreated, SubscriptionCollected, SubscriptionCancelled. + 只有当 msg.sender == address(this)(订阅者在其自己的 EOA 上)时才可调用。 + - collect(bytes32 subId) 只有注册的提供商可调用,只有 + 当 block.timestamp >= nextChargeAt 时;通过 interval 提前 nextChargeAt + 并将 USDT0 转账给提供商。使用测试网 + 地址 0x78cf24370174180738c5b8e352b6d14c83a6c9a9 的 IERC20 USDT0。 + - cancelSubscription(bytes32 subId) 只有订阅者可调用。 +为 SubscriptionCreated、SubscriptionCollected、SubscriptionCancelled 发出事件。 ``` -### 构建 x402 按调用付费 API +### 构建 x402 按次付费 API ```text -Write an Express server in TypeScript that exposes GET /weather priced -at $0.001 USDT0 (amount: "1000", 6 decimals) using @x402/express, -@x402/evm/exact/server, and HTTPFacilitatorClient pointed at -https://x402.semanticpay.io/. Use Stable mainnet (CAIP-2 eip155:988, -USDT0 at 0x779Ded0c9e1022225f8E0630b35a9b54bE713736). The handler should -return { weather: "sunny", temperature: 70 }. Read PAY_TO_ADDRESS from -env. Print the configured routes on startup. +编写一个用 TypeScript 编写的 Express 服务器,它公开 GET /weather,价格 +为 $0.001 USDT0 (金额: "1000", 6 位小数),使用 @x402/express、 +@x402/evm/exact/server 和 HTTPFacilitatorClient 指向 +https://x402.semanticpay.io/。使用 Stable 主网 (CAIP-2 eip155:988, +USDT0 在 0x779Ded0c9e1022225f8E0630b35a9b54bE713736)。处理程序应 +返回 { weather: "sunny", temperature: 70 }。从 env 中读取 PAY_TO_ADDRESS。 +在启动时打印已配置的路由。 ``` -## 下一步推荐 +## 接下来推荐 -- [**使用 MCP 服务器付费**](/cn/how-to/pay-with-mcp) — 将付费 API 封装为 MCP 工具,使 AI 客户端能够调用并为其付费。 -- [**快速开始**](/cn/tutorial/quick-start) — 将 AI 上下文与五分钟内的首次交易运行配对。 -- [**与 Ethereum 的区别**](/cn/explanation/ethereum-comparison) — 深入了解上下文块中的 gas 和 USDT0 语义。 +- [**使用 MCP 服务器付费**](/cn/how-to/pay-with-mcp):将付费 API 封装为 MCP 工具,以便 AI 客户端可以调用和付费。 +- [**快速开始**](/cn/tutorial/quick-start):结合 AI 上下文,在五分钟内运行第一个交易。 +- [**与以太坊的区别**](/cn/explanation/ethereum-comparison):深入了解上下文块中的 gas 和 USDT0 语义。 diff --git a/docs/pages/cn/how-to/index-contract.mdx b/docs/pages/cn/how-to/index-contract.mdx index 0c54c2a..894d075 100644 --- a/docs/pages/cn/how-to/index-contract.mdx +++ b/docs/pages/cn/how-to/index-contract.mdx @@ -1,22 +1,22 @@ --- source_path: how-to/index-contract.mdx -source_sha: 5293e991b87b99d0da868102a910d03d70bde96b +source_sha: b32b9a67615217f86bfd96c7ff8bb192ee87454b title: "索引合约事件" -description: "使用 ethers.js 的 watchContractEvent 订阅 Stable 上的智能合约事件,并构建实时事件流。" +description: "使用 ethers.js watchContractEvent 在 Stable 上订阅智能合约事件,并构建实时事件流。" diataxis: "how-to" --- # 索引合约事件 -索引将链上事件转化为应用程序可以响应的数据:余额更新、交易历史、UI 通知。本指南展示如何使用 ethers.js 订阅已部署的 Stable 合约的事件,以及如何回填历史事件,这样你就不会遗漏服务离线期间发出的任何事件。 +索引将链上事件转换为你的应用程序可以响应的数据:余额更新、交易历史、UI 通知。本指南介绍如何使用 ethers.js 订阅已部署 Stable 合约的事件,以及如何回填历史事件,以便你的服务脱机时不会错过任何发出的事件。 -## 前置条件 +## 前提条件 -- 在 Stable 测试网或主网上部署的合约。如果你需要一个,请参阅 [部署](/cn/tutorial/smart-contract) 和 [验证](/cn/how-to/verify-contract)。 +- 在 Stable 测试网或主网上部署的合约。如果需要,请参阅[部署](/cn/tutorial/smart-contract)和[验证](/cn/how-to/verify-contract)。 - Node.js 20 或更高版本。 -- 你想要索引的事件的合约地址和 ABI。 +- 合约地址和你想要索引的事件的 ABI。 -## 1. 安装与配置 +## 1. 安装和配置 ```bash npm install ethers @@ -30,7 +30,7 @@ export const STABLE_TESTNET_RPC = "https://rpc.testnet.stable.xyz"; export const STABLE_TESTNET_WS = "wss://rpc.testnet.stable.xyz"; export const CONTRACT_ADDRESS = "0xDeployedContractAddress"; -// Minimal ABI: only the events you want to index. +// 最小 ABI:仅包含你想要索引的事件。 export const CONTRACT_ABI = [ "event NumberUpdated(address indexed caller, uint256 oldValue, uint256 newValue)", ]; @@ -38,7 +38,7 @@ export const CONTRACT_ABI = [ ## 2. 订阅实时事件 -使用 WebSocket provider,这样你就能在验证者最终确认每个区块后立即收到事件。WebSocket 避免了轮询开销,并使通知延迟接近区块时间(在 Stable 上约 0.7 秒)。 +使用 WebSocket 提供程序,以便在验证者最终确定每个区块后立即接收事件。WebSocket 避免了轮询开销,并将通知延迟保持在接近区块时间(Stable 上约为 0.7 秒)。 ```typescript // watchLive.ts @@ -74,11 +74,11 @@ NumberUpdated: block: 1284371 ``` -当调用者调用你的合约时,事件会实时到达。 +事件会随着调用者调用你的合约而实时到达。 ## 3. 回填历史事件 -当服务启动时,你通常需要补上离线期间发出的事件。使用带区块范围的 `queryFilter`。 +当服务启动时,通常需要追溯其脱机期间发出的事件。使用带有块范围的 `queryFilter`。 ```typescript // backfill.ts @@ -89,7 +89,7 @@ const provider = new ethers.JsonRpcProvider(STABLE_TESTNET_RPC); const contract = new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, provider); const latest = await provider.getBlockNumber(); -const fromBlock = Math.max(0, latest - 10_000); // last ~10k blocks +const fromBlock = Math.max(0, latest - 10_000); // 最后约 1万 个区块 const events = await contract.queryFilter( contract.filters.NumberUpdated(), @@ -121,12 +121,12 @@ Backfilled 3 events from block 1282351 to 1284371 ``` :::warning -过宽的区块范围(数百万个区块)可能超出 RPC 速率限制并导致超时。对于生产环境的索引器,请按 10k 区块窗口分页,或使用 [Stablescan 的 Etherscan 兼容 API](/cn/how-to/build-p2p-payments#transaction-history) 进行已索引的历史查询。 +广范围区块(数百万个区块)可能会超出 RPC 速率限制并导致超时。对于生产索引器,请按 1 万个区块的窗口进行分页,或使用 [Stablescan 兼容 Etherscan 的 API](/cn/how-to/build-p2p-payments#transaction-history) 进行索引的历史查询。 ::: -## 4. 按索引参数过滤事件 +## 4. 按索引参数筛选事件 -带有 `indexed` 参数的事件(如上面的 `caller`)可以在服务端进行过滤。传入过滤值,而不是读取每个事件后在应用中过滤。 +带有 `indexed` 参数(如上文的 `caller`)的事件可以在服务器端进行筛选。传递筛选值,而不是读取每个事件并在你的应用程序中进行筛选。 ```typescript // watchUser.ts @@ -157,7 +157,7 @@ Watching NumberUpdated for 0x1234...abcd... ## 处理连接断开 -WebSocket 连接可能会断开。对于生产环境的索引器,请实现重连逻辑,以免遗漏事件。 +WebSocket 连接可能会断开。对于生产索引器,请实现重新连接逻辑,以免错过事件。 ```typescript // resilientWatch.ts @@ -187,8 +187,8 @@ function setupWatcher() { setupWatcher(); ``` -## 后续推荐 +## 接下来建议 -- [**追踪解绑完成**](/cn/how-to/track-unbonding) — 索引协议发出的系统交易事件(解绑完成)。 -- [**构建 P2P 支付应用**](/cn/how-to/build-p2p-payments) — 将索引应用于 USDT0 Transfer 事件并构建支付历史视图。 -- [**JSON-RPC 参考**](/cn/reference/json-rpc-api) — 查看 Stable 支持哪些 `eth_getLogs` 及相关方法。 +- [**跟踪解绑完成情况**](/cn/how-to/track-unbonding):索引协议发出的系统交易事件(解绑完成情况)。 +- [**构建 P2P 支付应用程序**](/cn/how-to/build-p2p-payments):应用索引到 USDT0 Transfer 事件并构建支付历史视图。 +- [**JSON-RPC 参考**](/cn/reference/json-rpc-api):查看 Stable 支持哪些 `eth_getLogs` 和相关方法。 diff --git a/docs/pages/cn/how-to/index-validator-data.mdx b/docs/pages/cn/how-to/index-validator-data.mdx index 284b50b..b16e525 100644 --- a/docs/pages/cn/how-to/index-validator-data.mdx +++ b/docs/pages/cn/how-to/index-validator-data.mdx @@ -1,46 +1,46 @@ --- source_path: how-to/index-validator-data.mdx -source_sha: c61d0583cb63d1cacdebaa8d836bd6c30e3a66eb -title: "索引验证者数据" -description: "直接从 Stable 预编译合约和事件日志读取验证者身份、加入日期、质押、佣金、在线率和投票历史,无需运行 stabled。" +source_sha: 87a9f18c6cafd38834304736db22ff3c0297f2ce +title: "索引验证器数据" +description: "直接从 Stable 预编译和事件日志中读取验证器身份、加入日期、质押、佣金、正常运行时间和投票历史,无需运行 stabled。" diataxis: "how-to" --- -# 索引验证者数据 +# 索引验证器数据 -验证者数据存储在链上,可通过标准 EVM JSON-RPC 读取。你通过 staking、slashing 和 governance 预编译合约查询当前状态,并从它们的事件日志重建历史。这意味着索引器或分析平台可以通过 `eth_call` 和 `eth_getLogs` 读取所需的一切,无需访问节点的 `stabled` CLI 或 Cosmos REST。 +验证器数据存储在链上,可通过标准 EVM JSON-RPC 读取。您可以通过质押、惩罚和治理预编译查询当前状态,并从其事件日志中重建历史。这意味着索引器或分析平台可以通过 `eth_call` 和 `eth_getLogs` 读取所需的一切,而无需访问节点的 `stabled` CLI 或 Cosmos REST。 :::note -**概念:** 关于 staking 模块跟踪的内容以及委托的工作原理,请参阅 [Staking 模块](/cn/explanation/staking-module)。关于每个方法的输入和输出,请参阅 [Staking 预编译参考](/cn/reference/staking-module-api)。 +**概念:** 有关质押模块跟踪的内容以及委托如何运作,请参阅[质押模块](/cn/explanation/staking-module)。有关每个方法的输入和输出,请参阅[质押预编译参考](/cn/reference/staking-module-api)。 ::: ## 每个数据点的来源 | **数据点** | **来源** | **如何读取** | | :--- | :--- | :--- | -| 验证者名称、身份、网站 | Staking 预编译 `validators()` | `description.moniker` 及相关字段 | -| 质押(已绑定代币) | Staking 预编译 `validators()` | `tokens` 字段 | -| 佣金 | Staking 预编译 `validators()` | `commission` 字段 | -| 质押随时间的变化 | Staking 预编译事件 | `Delegate`、`Unbond`、`Redelegate` 日志 | -| 加入日期 | Staking 预编译事件 | `CreateValidator` 日志 → 区块时间戳 | -| 在线率 | Slashing 预编译 `getSigningInfos()` | `(signedBlocksWindow − missedBlocksCounter) / signedBlocksWindow` | -| 投票历史(汇总) | Gov 预编译 `getTallyResult()` | 每个提案的计票 | -| 投票历史(按验证者) | Gov 预编译事件 | `Vote`、`VoteWeighted` 日志,voter = operator 地址 | +| 验证器名称、身份、网站 | 质押预编译 `validators()` | `description.moniker` 和相关字段 | +| 质押(绑定代币) | 质押预编译 `validators()` | `tokens` 字段 | +| 佣金 | 质押预编译 `validators()` | `commission` 字段 | +| 质押随时间变化 | 质押预编译事件 | `Delegate`, `Unbond`, `Redelegate` 日志 | +| 加入日期 | 质押预编译事件 | `CreateValidator` 日志 → 块时间戳 | +| 正常运行时间 | 惩罚预编译 `getSigningInfos()` | `(signedBlocksWindow − missedBlocksCounter) / signedBlocksWindow` | +| 投票历史(聚合) | 治理预编译 `getTallyResult()` | 每一项提案的计票结果 | +| 投票历史(按验证器) | 治理预编译事件 | `Vote`, `VoteWeighted` 日志,投票者 = 运营者地址 | ## 预编译地址 | **模块** | **地址** | **用途** | | :--- | :--- | :--- | -| Staking | `0x0000000000000000000000000000000000000800` | 验证者集合、质押、佣金、委托事件 | -| Distribution | `0x0000000000000000000000000000000000000801` | 奖励和佣金提取 | -| Gov | `0x0000000000000000000000000000000000000805` | 提案、计票和投票日志 | -| Slashing | `0x0000000000000000000000000000000000000806` | 签名信息和在线率 | +| 质押 | `0x0000000000000000000000000000000000000800` | 验证器集合、质押、佣金、委托事件 | +| 分发 | `0x0000000000000000000000000000000000000801` | 奖励和佣金提款 | +| 治理 | `0x0000000000000000000000000000000000000805` | 提案、计票和投票日志 | +| 惩罚 | `0x0000000000000000000000000000000000000806` | 签名信息和正常运行时间 | -在 `https://rpc.stable.xyz` 连接到主网(Chain ID `988`)。关于端点和限制,请参阅 [主网信息](/cn/reference/mainnet-information)。 +连接到主网(链 ID `988`),地址为 `https://rpc.stable.xyz`。有关端点和限制,请参阅[主网信息](/cn/reference/mainnet-information)。 -## 验证者名称、质押和佣金 +## 验证器名称、质押和佣金 -在 staking 预编译上调用 `validators()` 以读取当前的验证者集合。传入绑定状态进行过滤(例如 `BOND_STATUS_BONDED`)。每个条目都暴露验证者的 `description`(包括 `moniker`)、`tokens`(已绑定质押)和 `commission`。 +调用质押预编译上的 `validators()` 来读取当前验证器集。传入绑定状态进行过滤(例如 `BOND_STATUS_BONDED`)。每个条目都显示验证器的 `description`(包括 `moniker`)、`tokens`(绑定的质押)和 `commission`。 ```typescript // validators.ts @@ -70,11 +70,11 @@ StableNode-01 4500000000000000000000000 50000000000000000 StableNode-02 3900000000000000000000000 100000000000000000 ``` -`tokens` 和 `commission` 值缩放为 18 位小数。将 `commission` 除以 1e18 即可得到分数形式的费率(例如 `0.05` 表示 5%)。关于完整的 `Validator` 结构体和 `BOND_STATUS_*` 值,请参阅 [Staking 预编译参考](/cn/reference/staking-module-api#validators)。 +`tokens` 和 `commission` 的值按 18 位小数进行缩放。将 `commission` 除以 1e18 可获得费率分数(例如 `0.05` 为 5%)。有关完整的 `Validator` 结构和 `BOND_STATUS_*` 值,请参阅[质押预编译参考](/cn/reference/staking-module-api#validators)。 -## 质押随时间的变化 +## 质押随时间变化 -`validators()` 返回一个快照。要跟踪质押的变动,请索引 staking 预编译的委托事件。`Delegate`、`Unbond` 和 `Redelegate` 携带索引的 `validatorAddr` 和 `amount`,因此你可以将每一次质押变化归因到某个验证者和区块。 +`validators()` 返回一个快照。要跟踪质押的变化,请索引质押预编译的委托事件。`Delegate`、`Unbond` 和 `Redelegate` 带有索引的 `validatorAddr` 和 `amount`,因此您可以将每个质押变化归因于验证器和区块。 ```typescript // stakeChanges.ts @@ -96,11 +96,11 @@ console.log(`${logs.length} delegations indexed`); 1842 delegations indexed ``` -`Unbond` 和 `Redelegate` 遵循相同的结构,并额外携带 `completionTime`。关于确切的签名,请参阅 staking 参考的 [事件部分](/cn/reference/staking-module-api#events)。 +`Unbond` 和 `Redelegate` 遵循相同的结构,并且额外带有 `completionTime`。有关确切的签名,请参阅质押参考的[事件部分](/cn/reference/staking-module-api#events)。 ## 加入日期 -验证者的加入日期是其 `CreateValidator` 事件的区块时间戳。该事件按验证者地址索引,因此你可以过滤单个验证者或扫描整个集合,然后用 `eth_getBlockByNumber` 将每个日志的 `blockNumber` 解析为时间戳。 +验证器的加入日期是其 `CreateValidator` 事件的区块时间戳。该事件按验证器地址索引,因此您可以筛选单个验证器或扫描完整集合,然后使用 `eth_getBlockByNumber` 将每个日志的 `blockNumber` 解析为时间戳。 ```typescript // joinDate.ts @@ -125,26 +125,26 @@ for (const log of logs) { ``` :::warning -创世验证者没有 `CreateValidator` 事件。它们是在创世区块中创建的,而非通过交易,因此不存在日志。将它们的加入日期视为链的创世时间:**2025-10-29**。为所有在创世后加入的验证者索引 `CreateValidator`,并从创世验证者列表回填创世集合。 +创世验证器没有 `CreateValidator` 事件。它们是在创世区块中创建的,而不是通过交易创建的,因此不存在日志。将它们的加入日期视为链的创世日期:**2025-10-29**。索引在创世之后加入的每个人的 `CreateValidator`,并从创世验证器列表中回填创世集。 ::: -## 在线率 +## 正常运行时间 -使用 `getSigningInfos()` 从 slashing 预编译(`0x...806`)读取签名信息。每条记录报告 `signedBlocksWindow`(滑动窗口的大小)和 `missedBlocksCounter`(窗口内错过的区块)。按如下方式计算在线率: +使用 `getSigningInfos()` 从惩罚预编译 (`0x...806`) 读取签名信息。每条记录报告 `signedBlocksWindow`(滑动窗口的大小)和 `missedBlocksCounter`(窗口内错过的区块)。计算正常运行时间为: ```text -uptime = (signedBlocksWindow − missedBlocksCounter) / signedBlocksWindow +正常运行时间 = (signedBlocksWindow − missedBlocksCounter) / signedBlocksWindow ``` -`signedBlocksWindow` 为 `10000`、`missedBlocksCounter` 为 `25` 的验证者在窗口内的在线率为 99.75%。这是一个滚动数值,而非终身在线率。要跟踪在线率历史,请按固定间隔对计数器进行快照并存储每次读数。 +一个 `signedBlocksWindow` 为 `10000` 且 `missedBlocksCounter` 为 `25` 的验证器在窗口内的正常运行时间为 99.75%。这是一个滚动数字,而不是生命周期正常运行时间。要跟踪正常运行时间历史记录,请按固定间隔对计数器进行快照并存储每次读取。 :::note -slashing 预编译遵循 Cosmos EVM `x/slashing` 接口。其地址列在 [系统模块预编译表](/cn/how-to/use-system-modules#whats-exposed) 中。请从链的预编译接口生成确切的方法 ABI。 +惩罚预编译遵循 Cosmos EVM `x/slashing` 接口。其地址列在[系统模块预编译表](/cn/how-to/use-system-modules#whats-exposed)中。从链的预编译接口生成确切的方法 ABI。 ::: ## 投票历史 -治理数据有两层。对于提案的汇总结果,请在 gov 预编译(`0x...805`)上调用 `getTallyResult()`。对于谁投了什么票,请索引 `Vote` 和 `VoteWeighted` 事件日志。这些日志中的投票者地址是验证者的 operator 地址,因此你可以直接将投票关联到验证者。 +治理数据分为两层。对于提案的聚合结果,在治理预编译 (`0x...805`) 上调用 `getTallyResult()`。对于谁投了什么票,索引 `Vote` 和 `VoteWeighted` 事件日志。这些日志中的投票者地址是验证器的运营者地址,因此您可以直接将投票与验证器关联起来。 ```typescript // votes.ts @@ -168,15 +168,15 @@ console.log(`${logs.length} votes indexed across all proposals`); 38 votes indexed across all proposals ``` -迄今为止的每个提案(提案 #1 到 #7)都已确认有实时投票日志。当你只需要每个提案的最终计数时,使用 `getTallyResult()`;当你需要每个验证者的记录时,使用事件日志。 +实时投票日志确认了迄今为止的所有提案(提案 #1 到 #7)。当您只需要每项提案的最终计票结果时,请使用 `getTallyResult()`,当您需要每个验证器的记录时,请使用事件日志。 :::note -gov 预编译遵循 Cosmos EVM `x/gov` 接口。其地址列在 [系统模块预编译表](/cn/how-to/use-system-modules#whats-exposed) 中。请从链的预编译接口生成确切的方法 ABI 和 `VoteOption` 枚举。 +治理预编译遵循 Cosmos EVM `x/gov` 接口。其地址列在[系统模块预编译表](/cn/how-to/use-system-modules#whats-exposed)中。从链的预编译接口生成确切的方法 ABI 和 `VoteOption` 枚举。 ::: -## 推荐的后续步骤 +## 接下来推荐 -- [**Staking 预编译参考**](/cn/reference/staking-module-api) — 查找完整的 validators()、委托方法和事件签名。 -- [**创建验证者**](/cn/how-to/run-validator) — 将已同步的节点注册为验证者,使其出现在上述数据中。 -- [**索引器和分析**](/cn/reference/indexers) — 浏览已经提供标准化 Stable 数据的索引提供商。 -- [**主网信息**](/cn/reference/mainnet-information) — 在开始索引之前获取 Chain ID、RPC 端点和速率限制。 +- [**质押预编译参考**](/cn/reference/staking-module-api):查找完整的 validators()、委托方法和事件签名。 +- [**创建验证器**](/cn/how-to/run-validator):将同步节点注册为验证器,以便它出现在上述数据中。 +- [**索引器和分析**](/cn/reference/indexers):浏览已经提供标准化 Stable 数据的索引提供商。 +- [**主网信息**](/cn/reference/mainnet-information):在开始索引之前获取链 ID、RPC 端点和费率限制。 diff --git a/docs/pages/cn/how-to/integrate-gas-waiver.mdx b/docs/pages/cn/how-to/integrate-gas-waiver.mdx index 319b0bd..d0921df 100644 --- a/docs/pages/cn/how-to/integrate-gas-waiver.mdx +++ b/docs/pages/cn/how-to/integrate-gas-waiver.mdx @@ -1,25 +1,25 @@ --- source_path: how-to/integrate-gas-waiver.mdx -source_sha: 95a46a35ec56b9f823fb443aeb2693a9b0248e18 -title: "启用免 Gas 交易" -description: "集成 Stable Gas Waiver,通过向 Waiver Server API 提交已签名的 InnerTx 载荷来启用免 Gas 交易。" +source_sha: eaaf45d02173e1ce6279849d803d73014dbb7696 +title: "启用免Gas交易" +description: "通过向豁免服务器 API 提交已签名的 InnerTx 有效负载来集成 Stable Gas Waiver,以启用免 Gas 交易。" diataxis: "how-to" --- -# 启用免 Gas 交易 +# 启用免Gas交易 -Gas Waiver 可在 Stable 上实现免 Gas 交易。借助 Gas Waiver,应用程序代表用户支付 Gas 费用,因此用户无需持有 USDT0 即可与合约进行交互。 +Gas Waiver 可以在 Stable 上启用免 Gas 交易。通过 Gas Waiver,应用程序可以代表用户支付 Gas 费用,因此用户无需持有 USDT0 即可与合约进行交互。 -本指南介绍如何通过 Waiver Server API 进行集成。 +本指南涵盖了通过豁免服务器 API 进行的集成。 :::note -**概念:** 关于 Gas Waiver 是什么、为何存在以及治理授权的豁免如何运作,请参阅 [Gas 豁免](/cn/explanation/gas-waiver)。关于完整的协议规范(包装交易格式、标记地址、执行语义、安全模型),请参阅 [Gas 豁免协议](/cn/reference/gas-waiver-api)。 +**概念:** 有关 Gas Waiver 是什么、它为何存在以及治理授权豁免如何运作的信息,请参阅[Gas waiver](/cn/explanation/gas-waiver)。有关完整的协议规范(包装器交易格式、标记地址、执行语义、安全模型),请参阅[Gas waiver protocol](/cn/reference/gas-waiver-api)。 ::: -## 前置条件 +## 前提条件 -- 由 Stable 团队签发的 Waiver Server API 密钥 -- 目标合约地址必须已在豁免的 `AllowedTarget` 策略中注册 +- 由 Stable 团队颁发的 Waiver Server API 密钥 +- 目标合约地址必须在豁免的 `AllowedTarget` 策略中注册 ## Waiver Server @@ -34,13 +34,13 @@ Gas Waiver 可在 Stable 上实现免 Gas 交易。借助 Gas Waiver,应用程 集成流程分为三个步骤: -1. **构建 InnerTx**:用户签署一笔 `gasPrice = 0` 的交易。 +1. **构建 InnerTx**:用户使用 `gasPrice = 0` 签署交易。 2. **提交到 Waiver Server**:将已签名的交易提交到 Waiver Server API。 -3. **处理响应**:waiver server 包装并广播交易。处理流式返回的结果,并向用户展示交易哈希。 +3. **处理响应**:豁免服务器封装并广播交易。处理流式结果并将交易哈希显示给用户。 ## 步骤 1:创建用户的 InnerTx -用户签署一笔 `gasPrice = 0` 的标准交易。`to` 地址和方法选择器必须被豁免的 `AllowedTarget` 策略所允许。 +用户使用 `gasPrice = 0` 签署标准交易。`to` 地址和方法选择器必须得到豁免的 `AllowedTarget` 策略的允许。 ```typescript // config.ts @@ -88,7 +88,7 @@ const signedInnerTx = await userWallet.signTransaction(innerTx); ``` :::warning -`gasPrice` 必须为 `0`。如果非零,waiver server 将拒绝该交易。 +`gasPrice` 必须为 `0`。如果它不为零,豁免服务器将拒绝该交易。 ::: ## 步骤 2:提交到 Waiver Server @@ -112,7 +112,7 @@ const response = await fetch(`${CONFIG.WAIVER_SERVER}/v1/submit`, { ### 批量提交 -你可以在单次请求中提交多笔已签名的交易: +您可以在单个请求中提交多个已签名的交易: ```typescript body: JSON.stringify({ @@ -120,11 +120,11 @@ body: JSON.stringify({ }) ``` -每个结果行都包含一个 `index` 字段,对应交易在数组中的位置。 +每个结果行都包含一个 `index` 字段,对应于交易在数组中的位置。 ## 步骤 3:处理响应 -响应以 NDJSON(以换行符分隔的 JSON)形式流式返回。每一行对应一笔已提交的交易。 +响应以 NDJSON(换行符分隔的 JSON)流式传输。每行对应一个已提交的交易。 ```typescript const reader = response.body.getReader(); @@ -160,28 +160,28 @@ while (true) { ## 错误代码 -| **代码** | **说明** | +| **代码** | **描述** | | :--- | :--- | -| `PARSE_ERROR` | 解析交易失败 | -| `INVALID_REQUEST` | 请求体格式错误 | +| `PARSE_ERROR` | 无法解析交易 | +| `INVALID_REQUEST` | 请求正文格式错误 | | `BATCH_SIZE_EXCEEDED` | 批量大小超出允许的最大值 | -| `VALIDATION_FAILED` | 交易验证失败(例如:签名无效、目标不被允许) | -| `BROADCAST_FAILED` | 广播到链上失败 | +| `VALIDATION_FAILED` | 交易验证失败(例如,签名无效,不允许的目标) | +| `BROADCAST_FAILED` | 无法广播到链上 | | `RATE_LIMITED` | 超出速率限制 | | `QUEUE_FULL` | 服务器队列已满 | | `TIMEOUT` | 请求超时 | -## API 参考 +## API参考 ### GET `/v1/health` -健康检查端点。认证:无需。 +健康检查端点。认证:无。 ### POST `/v1/submit` 提交一批已签名的内部交易。认证:必需(Bearer)。 -**请求体:** +**请求正文:** ```json { @@ -189,21 +189,21 @@ while (true) { } ``` -响应以 NDJSON 形式流式返回。每一行对应一笔已提交交易的索引。 +响应以 NDJSON 形式流式传输。每行对应一个已提交的交易索引。 ### GET `/v1/submit` 用于流式提交的 WebSocket 接口。认证:必需(Bearer)。 -## 关键要点 +## 主要收获 -- Gas Waiver 是一种服务端集成:你的后端将已签名的用户交易提交到 Waiver Server。用户从不直接与 Waiver Server 交互。 -- 用户始终签署 InnerTx,从而保持签名的完整性。豁免方无法修改用户的交易。 -- 目标合约必须位于豁免的 `AllowedTarget` 列表中。 +- Gas Waiver 是一种服务器端集成:您的后端将已签名的用户交易提交到 Waiver Server。用户从不直接与 Waiver Server 交互。 +- 用户始终签署 InnerTx,以保持签名的完整性。豁免无法修改用户的交易。 +- 目标合约必须在豁免的 `AllowedTarget` 列表中。 -## 后续推荐 +## 下一步建议 -- [**零 Gas 交易**](/cn/how-to/zero-gas-transactions) — 查看以演示为核心的流程,以及如何在收据中验证零 Gas。 -- [**自托管 Gas Waiver**](/cn/how-to/self-hosted-gas-waiver) — 在不使用托管 API 的情况下运行你自己的豁免服务。 -- [**Gas 豁免协议**](/cn/reference/gas-waiver-api) — 完整的包装交易规范和治理模型。 -- [**Stable SDK**](/cn/explanation/sdk-overview) — 使用类型化客户端来签署用户交易,随后将其提交到 Waiver Server。 +- [**零 Gas 交易**](/cn/how-to/zero-gas-transactions):查看以演示为中心的流程以及如何验证收据上的零 Gas。 +- [**自托管 Gas Waiver**](/cn/how-to/self-hosted-gas-waiver):运行您自己的豁免,无需托管 API。 +- [**Gas Waiver 协议**](/cn/reference/gas-waiver-api):完整的包装器交易规范和治理模型。 +- [**Stable SDK**](/cn/explanation/sdk-overview):使用类型化客户端签署用户交易,然后将其提交到 Waiver Server。 diff --git a/docs/pages/cn/how-to/pay-with-invoice.mdx b/docs/pages/cn/how-to/pay-with-invoice.mdx index 691f711..e07fae9 100644 --- a/docs/pages/cn/how-to/pay-with-invoice.mdx +++ b/docs/pages/cn/how-to/pay-with-invoice.mdx @@ -1,22 +1,22 @@ --- source_path: how-to/pay-with-invoice.mdx -source_sha: 7c09e8018dbc151950875e9df186903fe8674032 -title: "使用发票付款" -description: "在 Stable 上使用 ERC-3009 结算发票,nonce 由发票元数据确定性派生。通过链上事件进行对账。" +source_sha: b7c9e4ad00713067eaea4c312ff14a82656e23bb +title: "发票支付" +description: "使用 ERC-3009 在 Stable 上结算发票,其中确定性随机数来源于发票元数据。通过链上事件进行对账。" diataxis: "how-to" --- -# 使用发票付款 +# 发票支付 -本指南演示如何使用 [ERC-3009](/cn/explanation/erc-3009) 在链上结算发票,其中 nonce 由发票元数据确定性派生。该 nonce 将每笔付款与其发票关联起来,并防止重复付款。 +本指南将介绍如何使用 [ERC-3009](/cn/explanation/erc-3009) 在链上结算发票,其中确定性随机数来源于发票元数据。该随机数将每次支付与发票关联起来,并防止重复支付。 :::note -**概念:** 关于发票结算模型以及与传统 B2B 开票方式的比较,请参阅[发票结算](/cn/reference/invoices)。 +**概念:** 有关发票结算模型以及与传统 B2B 发票的比较,请参见 [发票结算](/cn/reference/invoices)。 ::: -## 你将构建的内容 +## 您将构建什么 -一个完整的发票生命周期:买方在链下签署一个 ERC-3009 授权,供应商将其提交到链上,对账过程通过确定性 nonce 将产生的 `AuthorizationUsed` 事件匹配回发票。 +一个完整的发票生命周期:买方在链下签署 ERC-3009 授权,供应商在链上提交,对账将生成的 `AuthorizationUsed` 事件通过确定性随机数与发票匹配。 ### 演示 @@ -40,11 +40,11 @@ step 4. Reconciliation ERP: marked PAID at block 1284371 ``` -## 概览 +## 概述 **买方:** -``` +```text ─── Buyer ─────────────────────────────────────────── nonce = getInvoiceNonce(invoice) authorization = { from: buyer, to: vendor, value: amount, nonce, ... } @@ -59,7 +59,7 @@ usdt0.transferWithAuthorization(authorization, signature) **供应商:** -``` +```text ─── Vendor ────────────────────────────────────────── // If Option B: submit transferWithAuthorization using the buyer's signature @@ -110,9 +110,9 @@ export interface Invoice { } ``` -## 步骤 1:生成确定性 nonce +## 步骤 1:生成一个确定性随机数 -买方和供应商都可以根据发票元数据独立计算出相同的 nonce。无需外部注册表。 +买方和供应商都可以从发票元数据中独立计算出相同的随机数。无需外部注册表。 ```typescript // nonce.ts @@ -148,7 +148,7 @@ const nonce = getInvoiceNonce(invoice); ## 步骤 2:签署授权(买方) -买方使用步骤 1 中的确定性 nonce 签署一个 ERC-3009 的 `transferWithAuthorization`。 +买方使用步骤 1 中的确定性随机数签署 ERC-3009 `transferWithAuthorization`。 ```typescript // sign-invoice.ts @@ -188,11 +188,11 @@ async function signInvoiceAuthorization(invoice: Invoice) { ## 步骤 3:提交交易 -根据由谁提交,有两种选择。 +根据提交者的不同,有两种选择。 ### 选项 A:买方提交 -买方直接提交 `transferWithAuthorization` 交易并支付 gas。当买方需要控制付款执行的时间和方式时使用此选项,例如当买方的会计系统需要将 tx hash 与内部审批流程绑定时。 +买方直接提交 `transferWithAuthorization` 交易并支付 gas。当买方控制支付的执行时间和方式时使用此方法,例如当买方的会计系统需要与内部审批流程关联的交易哈希时。 ```typescript // pay.ts @@ -234,7 +234,7 @@ async function payInvoice( ### 选项 B:供应商提交 -买方通过 API、电子邮件或任何渠道将 `{authorization, signature}` 发送给供应商。供应商(或协助方)代表买方提交交易,因此买方无需管理 gas。当供应商需要在同一请求流程内获得同步确认时使用此选项。 +买方通过 API、电子邮件或任何渠道将 `{authorization, signature}` 发送给供应商。供应商(或促成者)代表买方提交交易,因此买方无需管理 Gas。当供应商需要在同一请求流程中进行同步确认时使用此方法。 ```typescript // settle.ts @@ -273,12 +273,12 @@ async function settleInvoice( } ``` -## 步骤 4:通过链上事件对账(供应商) +## 步骤 4:通过链上事件进行对账(供应商) -无论由谁提交交易,每笔发票付款都会发出一个携带确定性 nonce 的 `AuthorizationUsed` 事件。供应商监听该事件并通过 nonce 将其匹配到待处理的发票。由于 nonce 是从发票元数据派生的,因此匹配是精确的。 +无论谁提交了交易,每次发票支付都会发出一个 `AuthorizationUsed` 事件,其中包含确定性随机数。供应商监听此事件,并通过随机数将其与待处理发票进行匹配。由于随机数来源于发票元数据,因此匹配是精确的。 :::note -通过 nonce 匹配可以识别哪张发票已付款,但供应商还应验证同一交易中的 `Transfer` 事件,以确认正确的金额已发送给正确的收款人。下面的代码包含了此项验证。 +通过随机数匹配可以确定支付了哪张发票,但供应商还应验证同一交易中的 `Transfer` 事件,以确认已将正确金额发送给正确接收方。下面的代码包括此验证。 ::: ```typescript @@ -359,19 +359,19 @@ Invoice INV-2026-001234 PAID settled at block: 1284371 ``` -## 处理失败的付款 +## 处理失败的支付 -已提交的 `transferWithAuthorization` 可能因多种原因而回滚。检测并向供应商或买方呈现每种原因,以便重试或关闭发票。 +提交的 `transferWithAuthorization` 可能会因多种原因而回滚。检测并向供应商或买方报告每个原因,以便可以重试或关闭发票。 -| **回滚原因** | **起因** | **恢复方法** | +| **回滚原因** | **原因** | **恢复** | | :--- | :--- | :--- | -| `FiatTokenV2: invalid signature` | 签名与授权字段不匹配。 | 要求买方在发票数据不变的情况下重新签署。 | -| `FiatTokenV2: authorization is used or canceled` | nonce 已被消耗(重复提交)或买方取消了该授权。 | 将发票标记为已付款;通过 nonce 查找原始交易。 | -| `FiatTokenV2: authorization is not yet valid` | 在 `validAfter` 之前提交。 | 等待至 `validAfter` 或签发新的授权。 | -| `FiatTokenV2: authorization is expired` | 在 `validBefore` 之后提交。 | 签发一个具有更长时间窗口的新授权。 | -| `FiatTokenV2: transfer amount exceeds balance` | 买方的 USDT0 余额不足。 | 通知买方为钱包充值,然后用相同的签名重试。 | +| `FiatTokenV2: invalid signature` | 签名与授权字段不匹配。 | 要求买方使用未更改的发票数据重新签名。 | +| `FiatTokenV2: authorization is used or canceled` | 随机数已被使用(重复提交)或买方已取消。 | 将发票标记为已支付;通过随机数查找原始交易。 | +| `FiatTokenV2: authorization is not yet valid` | 在 `validAfter` 之前提交。 | 等待 `validAfter` 或签发新的授权。 | +| `FiatTokenV2: authorization is expired` | 在 `validBefore` 之后提交。 | 签发新的授权,并延长有效期。 | +| `FiatTokenV2: transfer amount exceeds balance` | 买方的 USDT0 余额不足。 | 通知买方充值钱包,然后重试同一签名。 | -捕获回滚并在重试前对其分类。 +在重试之前捕获回滚并对其进行分类。 ```typescript // retry.ts @@ -406,11 +406,11 @@ async function submitWithRetry( ``` :::warning -切勿在未对错误进行分类的情况下重试失败的提交。对已回滚的 transferWithAuthorization 进行盲目重试,可能会在买方充值后通过验证,而这可能与买方的最新意图不符。 +切勿在未对错误进行分类的情况下重试失败的提交。对已回滚的 `transferWithAuthorization` 进行盲目重试,可能会在买方充值余额后通过验证,这可能与买方的最新意图不符。 ::: ## 接下来推荐 -- [**发票结算概念**](/cn/reference/invoices) — 了解确定性 nonce 的对账模型。 -- [**ERC-3009**](/cn/explanation/erc-3009) — 回顾此流程背后的签名授权标准。 -- [**启用免 gas 交易**](/cn/how-to/integrate-gas-waiver) — 与 Gas Waiver 结合,从结算路径中消除 gas。 +- [**发票结算概念**](/cn/reference/invoices):了解确定性随机数对账模型。 +- [**ERC-3009**](/cn/explanation/erc-3009):回顾此流程背后的签名授权标准。 +- [**启用免 Gas 交易**](/cn/how-to/integrate-gas-waiver):结合 Gas Waiver 以消除结算路径中的 Gas。 diff --git a/docs/pages/cn/how-to/pay-with-mcp.mdx b/docs/pages/cn/how-to/pay-with-mcp.mdx index 7f057d5..142fc09 100644 --- a/docs/pages/cn/how-to/pay-with-mcp.mdx +++ b/docs/pages/cn/how-to/pay-with-mcp.mdx @@ -1,46 +1,46 @@ --- source_path: how-to/pay-with-mcp.mdx -source_sha: 355c978d02f66d687a3bee1cb0f49dc3558381a9 -title: "通过 MCP 服务器付款" -description: "通过 MCP 服务器将启用 x402 的 API 连接到 AI 客户端。用户通过提示词为 API 调用付费,无需直接管理钱包或支付流程。" +source_sha: bdf458199e0866324d1f3d08253609bea9b2236f +title: "使用 MCP 服务器支付" +description: "通过 MCP 服务器将启用 x402 的 API 连接到 AI 客户端。用户通过提示为 API 调用付费,而无需直接管理钱包或支付流程。" diataxis: "how-to" --- -# 通过 MCP 服务器付款 +# 使用 MCP 服务器支付 -本指南展示如何将启用 x402 的 API 桥接到 [MCP](https://modelcontextprotocol.io) 工具,使 AI 客户端能够通过自然语言提示词调用并为其付费。它基于 [构建按调用付费 API](/cn/how-to/build-pay-per-call) 中的服务器构建。 +本指南展示了如何将启用 x402 的 API 桥接到 [MCP](https://modelcontextprotocol.io) 工具,以便 AI 客户端可以通过自然语言提示调用并支付它们。它基于 [构建按次付费 API](/cn/how-to/build-pay-per-call) 中的服务器。 -## 你将构建的内容 +## 您将构建什么 -一个将 x402 付费端点封装为工具的 MCP 服务器。AI 客户端输入自然语言提示词,每次工具调用都会触发一次付费的 x402 请求,结算可在 Stablescan 上查看。用户永远不会看到钱包提示。 +一个 MCP 服务器,它将支持 x402 付费的端点封装为工具。AI 客户端输入自然语言提示,每次工具调用都会触发付费的 x402 请求,并且结算可在 Stablescan 上查看。用户永远不会看到钱包提示。 ### 演示 ```text -step 1. User in Claude: "Pull financials for ACME Corp and assess credit risk." +步骤 1. Claude 中的用户:"提取 ACME Corp 的财务数据并评估信用风险。" -step 2. Client calls get_company_financials("ACME") - → MCP handler: fetchWithPayment("/financials?ticker=ACME") - → 402 Payment Required → sign ERC-3009 → retry - → Facilitator settles $0.01 USDT0 on-chain - → tx: 0x8f3a...aaaa +步骤 2. 客户端调用 get_company_financials("ACME") + → MCP 处理程序:fetchWithPayment("/financials?ticker=ACME") + → 402 Payment Required → 签署 ERC-3009 → 重试 + → 协调器链上结算 $0.01 USDT0 + → 交易:0x8f3a...aaaa → 200 OK { revenue, debt_ratio, cash_flow } -step 3. Client calls assess_credit_risk(financials) - → MCP handler: fetchWithPayment("/credit-risk", POST) - → Facilitator settles $0.05 USDT0 on-chain - → tx: 0x9bc4...bbbb +步骤 3. 客户端调用 assess_credit_risk(financials) + → MCP 处理程序:fetchWithPayment("/credit-risk", POST) + → 协调器链上结算 $0.05 USDT0 + → 交易:0x9bc4...bbbb → 200 OK { score: 72, rating: "moderate" } -step 4. Claude responds: - "ACME Corp has a credit risk score of 72 (moderate). Revenue is stable - but debt-to-equity ratio is elevated at 1.8x..." +步骤 4. Claude 回答: + "ACME Corp 的信用风险评分为 72(中等)。收入稳定, + 但债股比率升至 1.8 倍..." ``` -两个 `tx` 值均可在 [https://stablescan.xyz](https://stablescan.xyz) 上查看。 +两个 `tx` 值都可以在 [https://stablescan.xyz](https://stablescan.xyz) 上看到。 :::note -**为代理钱包注资**:MCP 服务器使用你控制的助记词来签署支付。在启动服务器之前,请为该钱包在主网上注入 USDT0。至少 `$0.10` 的余额可以支付多次付费调用;`$1.00` 足以进行长时间测试。需要时,可以使用标准的 USDT0 转账向该钱包地址充值。 +**代理钱包资金**:MCP 服务器使用您控制的助记词签署付款。在启动服务器之前,请将该钱包与主网上的 USDT0 资金同步。至少 `$0.10` 的余额足以支付多次付费调用;`$1.00` 足以进行长时间测试。根据需要使用标准 USDT0 转账到钱包地址进行充值。 ::: ## 概述 @@ -49,7 +49,7 @@ step 4. Claude responds: ```typescript // --- MCP Server --- -// Bridge x402-enabled APIs to MCP tools +// 将启用 x402 的 API 桥接到 MCP 工具 tools = { "get_company_financials": { handler: (ticker) => @@ -67,30 +67,30 @@ tools = { **用户(通过 AI 客户端):** -``` -─── AI Client ─────────────────────────────────────── -User: "Pull financials for ACME Corp and assess their credit risk." - -Client calls get_company_financials tool - → MCP server sends x402 paid request - → Facilitator settles USDT0 on-chain - → API returns financial data - -Client calls assess_credit_risk tool with the result - → MCP server sends x402 paid request - → Facilitator settles USDT0 on-chain - → API returns risk assessment - → Client responds with the combined result +```text +─── AI 客户端 ───────────────────────────────── +用户:"提取 ACME Corp 的财务数据并评估其信用风险。" + +客户端调用 get_company_financials 工具 + → MCP 服务器发送 x402 付费请求 + → 协调器链上结算 USDT0 + → API 返回财务数据 + +客户端使用结果调用 assess_credit_risk 工具 + → MCP 服务器发送 x402 付费请求 + → 协调器链上结算 USDT0 + → API 返回风险评估 + → 客户端回复合并结果 ``` -## 前提条件 +## 先决条件 -- 一个正在运行的 x402 服务器(参见 [构建按调用付费 API](/cn/how-to/build-pay-per-call))。 -- 一个兼容 MCP 的 AI 客户端(Claude Desktop、Claude Code 等)。 +- 运行中的 x402 服务器(请参阅 [构建按次付费 API](/cn/how-to/build-pay-per-call))。 +- 兼容 MCP 的 AI 客户端(Claude Desktop、Claude Code 等)。 -## 第 1 步:创建 MCP 服务器 +## 步骤 1:创建 MCP 服务器 -MCP 服务器充当 AI 客户端与启用 x402 的 API 之间的桥梁。每个工具使用 x402 客户端 SDK 发起付费请求并返回结果。 +MCP 服务器充当 AI 客户端和支持 x402 的 API 之间的桥梁。每个工具都使用 x402 客户端 SDK 发送付费请求并返回结果。 ```bash npm install @modelcontextprotocol/sdk @x402/fetch @x402/evm @tetherto/wdk-wallet-evm @@ -105,7 +105,7 @@ import { x402Client, wrapFetchWithPayment } from "@x402/fetch"; import { registerExactEvmScheme } from "@x402/evm/exact/client"; import { z } from "zod"; -// --- Wallet and x402 client --- +// --- 钱包和 x402 客户端 --- const account = await new WalletManagerEvm(process.env.SEED_PHRASE!, { provider: "https://rpc.stable.xyz", }).getAccount(0); @@ -114,10 +114,10 @@ const client = new x402Client(); registerExactEvmScheme(client, { signer: account }); const fetchWithPayment = wrapFetchWithPayment(fetch, client); -// --- x402 API base URL --- +// --- x402 API 基础 URL --- const API_BASE = process.env.API_BASE || "http://localhost:4021"; -// --- MCP server --- +// --- MCP 服务器 --- const server = new McpServer({ name: "x402-payments", version: "1.0.0", @@ -125,8 +125,8 @@ const server = new McpServer({ server.tool( "get_company_financials", - "Get company financial data by ticker (paid endpoint, $0.01 per call)", - { ticker: z.string().describe("Company ticker symbol (e.g. ACME)") }, + "通过股票代码获取公司财务数据(付费端点,每次调用 $0.01)", + { ticker: z.string().describe("公司股票代码 (例如 ACME)") }, async ({ ticker }) => { const response = await fetchWithPayment(`${API_BASE}/financials?ticker=${ticker}`); const data = await response.json(); @@ -136,8 +136,8 @@ server.tool( server.tool( "assess_credit_risk", - "Assess credit risk from financial data (paid endpoint, $0.05 per call)", - { financials: z.string().describe("JSON string of company financial data") }, + "根据财务数据评估信用风险(付费端点,每次调用 $0.05)", + { financials: z.string().describe("公司财务数据的 JSON 字符串") }, async ({ financials }) => { const response = await fetchWithPayment(`${API_BASE}/credit-risk`, { method: "POST", @@ -151,30 +151,30 @@ server.tool( server.tool( "check_balance", - "Check the USDT0 balance of the payment wallet", + "检查支付钱包的 USDT0 余额", {}, async () => { const USDT0_STABLE = "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"; const balance = await account.getTokenBalance(USDT0_STABLE); const formatted = (Number(balance) / 1e6).toFixed(2); return { - content: [{ type: "text", text: `Wallet balance: ${formatted} USDT0` }], + content: [{ type: "text", text: `钱包余额:${formatted} USDT0` }], }; }, ); -// --- Start --- +// --- 启动 --- const transport = new StdioServerTransport(); await server.connect(transport); ``` -每个工具处理程序都会调用 `fetchWithPayment`,它会自动处理完整的 x402 支付流程。AI 客户端只能看到工具名称、描述和参数。 +每个工具处理程序都会调用 `fetchWithPayment`,它会自动处理完整的 x402 支付周期。AI 客户端只看到工具名称、描述和参数。 -## 第 2 步:配置你的 AI 客户端 +## 步骤 2:配置您的 AI 客户端 -将 MCP 服务器添加到你的 AI 客户端配置中。 +将 MCP 服务器添加到您的 AI 客户端配置中。 -**Claude Desktop**(`claude_desktop_config.json`): +**Claude Desktop** (`claude_desktop_config.json`): ```json { @@ -183,7 +183,7 @@ await server.connect(transport); "command": "npx", "args": ["tsx", "/path/to/mcp-server.ts"], "env": { - "SEED_PHRASE": "your seed phrase here", + "SEED_PHRASE": "您的助记词", "API_BASE": "https://api.example.com" } } @@ -191,51 +191,51 @@ await server.connect(transport); } ``` -**Claude Code:** +**Claude Code:** ```bash claude mcp add x402-payments -- npx tsx /path/to/mcp-server.ts ``` -配置完成后,重启你的 AI 客户端。这些工具应该会出现在可用工具列表中。 +配置后,重启您的 AI 客户端。工具应该出现在可用工具列表中。 :::warning -MCP 配置中的助记词控制着真实资金。请使用你的操作系统密钥链或密钥管理器安全地存储它,而不是放在明文配置文件中。 +MCP 配置中的助记词控制着真实的资金。请使用您的操作系统密钥链或秘密管理器安全地存储它,而不是以纯文本配置文件形式。 ::: -## 第 3 步:输入提示词并使用 +## 步骤 3:输入提示并使用它 -配置完成后,AI 客户端可以通过用户的提示词调用付费 API: +配置后,AI 客户端可以通过用户的提示调用付费 API: -**用户:**"拉取 ACME Corp 的财务数据并评估他们的信用风险。" +**用户:**"提取 ACME Corp 的财务数据并评估其信用风险。" -1. 客户端调用 `get_company_financials("ACME")`:通过 x402 支付 $0.01。返回营收、负债率、现金流等。 +1. 客户端调用 `get_company_financials("ACME")`:通过 x402 支付 $0.01。返回收入、负债率、现金流等。 2. 客户端调用 `assess_credit_risk(financials)`:通过 x402 支付 $0.05。返回风险评分、评级、关键因素。 -3. 客户端响应:"ACME Corp 的信用风险评分为 72(中等)。营收稳定,但负债权益比偏高,为 1.8 倍……" +3. 客户端回复:"ACME Corp 的信用风险评分为 72(中等)。收入稳定,但债股比率升至 1.8 倍..." -各个工具也可以单独使用: +单个工具也可以独立工作: -- "拉取 ACME Corp 的财务数据" 调用 `get_company_financials`($0.01)。 -- "评估这些数据的信用风险" 调用 `assess_credit_risk`($0.05)。 -- "我还剩多少 USDT0?" 调用 `check_balance`。 +- "提取 ACME Corp 的财务数据" 调用 `get_company_financials` ($0.01)。 +- "评估此数据的信用风险" 调用 `assess_credit_risk` ($0.05)。 +- "我还有多少 USDT0?" 调用 `check_balance`。 -用户不会与钱包、签名或支付流程交互。MCP 服务器会透明地为每次工具调用处理支付。 +用户无需与钱包、签名或支付流程进行交互。MCP 服务器透明地处理每个工具调用的支付。 -## 支出控制 +## 消费控制 -为防止意外支出,请考虑为 MCP 服务器添加控制措施。 +为防止意外消费,请考虑向 MCP 服务器添加控制。 ```typescript -const MAX_PER_CALL = 100_000; // $0.10 in base units -const MAX_PER_SESSION = 5_000_000; // $5.00 in base units +const MAX_PER_CALL = 100_000; // 以基本单位计 $0.10 +const MAX_PER_SESSION = 5_000_000; // 以基本单位计 $5.00 let sessionSpent = 0n; function checkSpendingLimit(amount: bigint) { if (amount > BigInt(MAX_PER_CALL)) { - throw new Error(`Amount exceeds per-call limit of $${MAX_PER_CALL / 1e6}`); + throw new Error(`金额超出单次调用上限 $${MAX_PER_CALL / 1e6}`); } if (sessionSpent + amount > BigInt(MAX_PER_SESSION)) { - throw new Error(`Session spending limit of $${MAX_PER_SESSION / 1e6} reached`); + throw new Error(`会话消费上限 $${MAX_PER_SESSION / 1e6} 已达到`); } sessionSpent += amount; } @@ -245,6 +245,6 @@ function checkSpendingLimit(amount: bigint) { ## 接下来推荐 -- [**构建按调用付费 API**](/cn/how-to/build-pay-per-call) — 设置此 MCP 服务器所桥接的 x402 服务器。 -- [**x402 概念**](/cn/explanation/x402) — 了解这些支付背后的结算协议。 -- [**使用 AI 开发**](/cn/how-to/develop-with-ai) — 将 Stable 的文档和运行时 MCP 服务器接入同一个 AI 客户端。 +- [**构建按次付费 API**](/cn/how-to/build-pay-per-call):设置此 MCP 服务器桥接的 x402 服务器。 +- [**x402 概念**](/cn/explanation/x402):回顾这些支付背后的结算协议。 +- [**使用 AI 开发**](/cn/how-to/develop-with-ai):将 Stable 的文档和运行时 MCP 服务器连接到同一个 AI 客户端。 diff --git a/docs/pages/cn/how-to/production-readiness.mdx b/docs/pages/cn/how-to/production-readiness.mdx index a32dce6..0c50d07 100644 --- a/docs/pages/cn/how-to/production-readiness.mdx +++ b/docs/pages/cn/how-to/production-readiness.mdx @@ -1,30 +1,30 @@ --- source_path: how-to/production-readiness.mdx -source_sha: 4789a197ff1efd758012e442307c58c105ac716a -title: "生产环境就绪" -description: "在部署到主网之前验证集成:安全性、可靠性、运维以及问题升级渠道。" +source_sha: 99ec4061509a9a91f28a5a835a51015abb204503 +title: "生产可用性" +description: "在发布到主网之前验证集成:安全性、可靠性、操作以及如何上报问题。" diataxis: "how-to" --- -# 生产环境就绪 +# 生产可用性 -在从测试网切换到主网之前,请逐一完成下面的每个部分。 +在从测试网切换到主网之前,请完成下面列出的所有章节。 -## 启动前准备 +## 发布前 -- **网络目标。** 你的应用读取的是主网值,而非测试网:chain ID `988`、RPC `https://rpc.stable.xyz`、浏览器 `https://stablescan.xyz`。完整配置见 [连接](/cn/reference/connect)。 -- **合约已验证。** 已部署的合约在 [stablescan.xyz](https://stablescan.xyz) 上完成验证,以便用户和合作伙伴可以检查它们。 -- **主网资金路径。** 你有一套书面记录的方式,让生产钱包获取 USDT0:直接获取、通过 LayerZero 跨链或托管方。水龙头仅限测试网。 -- **环境隔离。** 密钥、RPC 凭据和签名路径在测试网和主网之间相互隔离。 +- **网络目标。** 您的应用程序读取的是主网值,而非测试网:链 ID `988`,RPC `https://rpc.stable.xyz`,浏览器 `https://stablescan.xyz`。完整配置请参见[连接](/cn/reference/connect)。 +- **合约已验证。** 已部署的合约已在 [stablescan.xyz](https://stablescan.xyz) 上验证,以便用户和合作伙伴可以检查它们。 +- **主网资金路径。** 您有记录的生产钱包获取 USDT0 的方式:直接获取、通过 LayerZero 桥接或通过托管人。水龙头仅适用于测试网。 +- **环境隔离。** 密钥、RPC 凭据和签名路径在测试网和主网之间是分离的。 ## 安全检查 -USDT0 的双重角色行为打破了一些从以太坊沿用而来的假设。下面每一项都应当验证。完整列表见 [迁移检查清单](/cn/explanation/usdt0-behavior)。 +USDT0 的双重角色行为打破了从以太坊移植过来的一些假设。下面的每个项目都应该进行验证。完整列表请参见[迁移清单](/cn/explanation/usdt0-behavior)。 -**偿付能力检查读取真实的原生余额,而非镜像值。** +**偿付能力检查读取的是真实的原生余额,而非镜像。** :::warning -在内部变量中跟踪已存入的原生价值是不安全的。外部的 `USDT0.transferFrom` 调用可以在不触发任何合约代码的情况下耗尽合约的原生余额。 +在内部变量中跟踪存入的原生值是不安全的。外部 `USDT0.transferFrom` 调用可以在不调用任何合约代码的情况下耗尽合约的原生余额。 ::: ```solidity @@ -38,12 +38,12 @@ function withdraw() external { } ``` -**基于授权额度的耗尽路径已被测试覆盖。** 每条 `approve` / `transferFrom` / `permit` 路径都有一项试图耗尽合约原生余额的测试。 +**基于授权的耗尽路径已通过测试覆盖。** 每个 `approve` / `transferFrom` / `permit` 路径都有一个尝试耗尽合约原生余额的测试。 -**向零地址的转账在调用前被拒绝。** +**在调用之前拒绝零地址转账。** :::warning -在 Stable 上,向 `address(0)` 进行的原生转账和 ERC-20 转账都会回滚。请显式校验接收方,否则你的交易将失败。 +向 `address(0)` 进行的原生和 ERC-20 转账在 Stable 上都会回滚。明确验证接收方,否则您的交易将失败。 ::: ```solidity @@ -51,30 +51,30 @@ require(recipient != address(0), "zero address recipient"); payable(recipient).call{value: amount}(""); ``` -**地址重用检测不依赖于 `EXTCODEHASH`。** 基于 permit 的授权会在不增加 nonce 的情况下改变原生余额,因此 `EXTCODEHASH` 可能在零哈希和空哈希之间来回波动。请改用显式跟踪。 +**地址复用检测不依赖于 `EXTCODEHASH`。** 基于许可的批准会在不增加 nonce 的情况下更改原生余额,因此 `EXTCODEHASH` 可以在零哈希和空哈希之间振荡。请改用显式跟踪。 ## 性能与可靠性 -- **RPC 冗余。** 生产流量有故障切换方案。第三方提供商列于 [RPC 提供商](/cn/reference/rpc-providers)。 -- **Gas 估算。** 交易将 `maxPriorityFeePerGas` 设为 `0`,并根据当前的基础费用计算 `maxFeePerGas`。参见 [Gas 定价](/cn/reference/gas-pricing-api)。 -- **出块时间。** 区块大约每 0.7 秒产生一个,并具有单槽最终性。轮询间隔和确认阈值应根据这一节奏进行调整。 -- **重试。** 瞬时 RPC 错误应以幂等方式重试。对于涉及资金的敏感流程,应在下游状态变更之前通过收据或日志验证交易已被打包。 +- **RPC 冗余。** 生产流量有一个故障转移计划。第三方提供商列在 [RPC 提供商](/cn/reference/rpc-providers)中。 +- **Gas 估算。** 交易将 `maxPriorityFeePerGas` 设置为 `0`,并根据当前基本费用计算 `maxFeePerGas`。请参阅 [Gas 定价](/cn/reference/gas-pricing-api)。 +- **出块时间。** 大约每 0.7 秒出块一次,并具有单槽终结性。查询间隔和确认阈值已根据此节奏进行调整。 +- **重试。** 瞬时 RPC 错误会幂等地重试。对于金融敏感的流程,在下游状态更改之前,通过收据或日志验证包含情况。 -## 运维归属 +## 运营所有权 -- **监控。** 如果你运行自己的节点,告警会监视出块、对等节点健康状况和 RPC 延迟;参见 [监控](/cn/how-to/monitor-node)。如果你使用第三方 RPC,请跟踪提供商的 SLA 和故障切换遥测数据。 -- **升级。** 协议版本发布会被跟踪,以便节点运营者能够安排升级;参见 [主网版本历史](/cn/reference/mainnet-version-history)。 -- **运行手册。** 针对合约暂停、密钥轮换和 RPC 提供商切换都有回滚流程。 +- **监控。** 如果您运行自己的节点,警报会监控出块、对等健康状况和 RPC 延迟;请参阅[监控](/cn/how-to/monitor-node)。如果您使用第三方 RPC,请跟踪提供商的 SLA 和故障转移遥测。 +- **升级。** 协议发布会被跟踪,以便节点运营商可以安排升级;请参阅[主网版本历史](/cn/reference/mainnet-version-history)。 +- **运行手册。** 存在用于合约暂停、密钥轮换和 RPC 提供商切换的回滚程序。 -## 支持与升级 +## 支持与上报 -- [开发者协助](/cn/reference/developer-assistance):常见问题和参考指引。 +- [开发者协助](/cn/reference/developer-assistance):常见问题解答和参考指向。 - [Discord](https://discord.gg/stablexyz):社区支持和协议更新。 -- `bizdev@stable.xyz`:合作与集成洽谈。 +- `bizdev@stable.xyz`:合作和集成交流。 -## 推荐后续阅读 +## 推荐阅读 -- [**USDT0 行为**](/cn/explanation/usdt0-behavior) — 阅读完整的迁移检查清单和合约设计要求。 -- [**主网信息**](/cn/reference/mainnet-information) — 查看主网链参数和版本历史。 -- [**RPC 提供商**](/cn/reference/rpc-providers) — 选择第三方 RPC 提供商以实现冗余。 -- [**监控**](/cn/how-to/monitor-node) — 为出块和 RPC 健康状况接入指标和告警。 +- [**USDT0 行为**](/cn/explanation/usdt0-behavior):阅读完整的迁移清单和合约设计要求。 +- [**主网信息**](/cn/reference/mainnet-information):检查主网链参数和版本历史。 +- [**RPC 提供商**](/cn/reference/rpc-providers):选择第三方 RPC 提供商以实现冗余。 +- [**监控**](/cn/how-to/monitor-node):连接用于出块和 RPC 健康状况的指标和警报。 diff --git a/docs/pages/cn/how-to/run-validator.mdx b/docs/pages/cn/how-to/run-validator.mdx index 112c77f..26d6513 100644 --- a/docs/pages/cn/how-to/run-validator.mdx +++ b/docs/pages/cn/how-to/run-validator.mdx @@ -1,25 +1,25 @@ --- source_path: how-to/run-validator.mdx -source_sha: 2ce47d3b037076ab9550319f91845149a6b98f83 -title: "创建验证者" -description: "将已同步的 Stable 节点提升为活跃验证者:准备密钥、通过质押预编译合约注册、验证并进行自委托。" +source_sha: d00aabfde18ce379eb65d00c6fc12306a7c631a5 +title: "创建验证人" +description: "将同步的 Stable 节点提升为活跃验证人:准备密钥,在质押预编译中注册,验证,并自委托。" diataxis: "how-to" --- -验证者是已在链上注册并绑定了质押的同步全节点。你需要先安装并同步节点,然后通过在质押预编译合约(`0x0000000000000000000000000000000000000800`)上调用 `createValidator` 来注册它。本页介绍注册步骤。关于节点本身,请参阅[安装节点](/cn/how-to/install-node)和[节点配置](/cn/reference/node-configuration)。 +验证人是一个已同步的全节点,它已经在链上注册并绑定了质押。您首先安装并同步节点,然后通过调用质押预编译 (`0x0000000000000000000000000000000000000800`) 上的 `createValidator` 来注册它。本页介绍注册步骤。有关节点本身的信息,请参阅[安装节点](/cn/how-to/install-node)和[节点配置](/cn/reference/node-configuration)。 :::warning -请在节点完全同步后再进行注册。验证者在尚未追上进度时就签名,可能会双重签名并被永久移出验证者集合(被 tombstone)。在开始前,请在 `config.toml` 中将 `double_sign_check_height` 设置为 `2` 或更高(参见[节点配置](/cn/reference/node-configuration#consensus-configuration))。将其设置为 `1` 不会执行任何检查。 +仅在您的节点完全同步后才注册。如果验证人在未赶上之前签名,可能会导致双重签名并被永久地从集合中删除(石碑化)。在开始之前,在 `config.toml` 中将 `double_sign_check_height = 2` 或更高(参阅[节点配置](/cn/reference/node-configuration#consensus-configuration))。将其设置为 `1` 不执行检查。 ::: -## 前置条件 +## 先决条件 -- 主网(Chain ID `988`)上一个完全同步的全节点。参见[安装节点](/cn/how-to/install-node)。 -- 在 `~/.stabled/config/config.toml` 中将 `double_sign_check_height` 设置为 `2` 或更高。 -- 已安装 [Foundry](https://book.getfoundry.sh/),用于 `cast`,以调用预编译合约。 -- 你的验证者 EVM 地址上已存入质押金额(以 USDT0 计)。 +- 主网(链 ID `988`)上一个完全同步的全节点。参阅[安装节点](/cn/how-to/install-node)。 +- `~/.stabled/config/config.toml` 中 `double_sign_check_height` 设置为 `2` 或更高。 +- 已安装 [Foundry](https://book.getfoundry.sh/) 以使用 `cast` 调用预编译。 +- 您的验证人的 EVM 地址上已存入质押金额,以 USDT0 计。 -在继续之前,请确认节点已追上进度。`catching_up` 必须为 `false`。 +在继续之前,请确认节点已赶上。`catching_up` 必须为 `false`。 ```bash curl -s localhost:26657/status | jq '.result.sync_info.catching_up' @@ -29,54 +29,54 @@ curl -s localhost:26657/status | jq '.result.sync_info.catching_up' false ``` -## 步骤 1:准备验证者密钥 +## 步骤 1:准备验证人密钥 -创建操作员账户,然后读取 `createValidator` 所需的两个值:共识公钥(base64)和验证者的 EVM 地址。 +创建操作员账户,然后读取 `createValidator` 所需的两个值:共识公钥(base64)和验证人的 EVM 地址。 ```bash -# Create the validator operator account +# 创建验证人操作员账户 stabled keys add validator -# Consensus public key (base64) — save this +# 共识公钥 (base64) — 保存此值 stabled comet show-validator | jq .key -# Derive the validator's EVM address (0x form) +# 派生验证人的 EVM 地址 (0x 形式) stabled keys parse $(stabled keys show validator -a) ``` ```text "AbCd...base64PubKey...==" # ... -# then, evm address is 0xCAEA59C7476C87D0FF6BE6F04DA207601D5BE7D0 +# 然后,evm 地址是 0xCAEA59C7476C87D0FF6BE6F04DA207601D5BE7D0 ``` :::warning -将 `~/.stabled/config/priv_validator_key.json` 离线备份,并且绝不要用同一密钥运行两个节点。两个实例用同一密钥签名即为双重签名,会导致永久性削减(slash)。 +将 `~/.stabled/config/priv_validator_key.json` 离线备份,切勿使用相同的密钥运行两个节点。两个实例使用一个密钥进行签名会导致双重签名,并导致永久削减。 ::: ## 步骤 2:设置环境 ```bash -# Staking precompile contract address +# 质押预编译合约地址 export STAKING_ADDRESS="0x0000000000000000000000000000000000000800" -# Mainnet EVM RPC +# 主网 EVM RPC export RPC_URL="https://rpc.stable.xyz" -# Your operator private key and validator EVM address +# 您的操作员私钥和验证人 EVM 地址 export PRIVATE_KEY="your_private_key_here" export VALIDATOR_ADDRESS="0xYourValidatorAddress" -# Consensus pubkey from Step 1 +# 步骤 1 中的共识公钥 export PUBKEY="AbCd...base64PubKey...==" -# Self-delegation amount in wei (18 decimals). 1000000000000000000 = 1 token +# 自委托金额,以 wei 为单位(18 位小数)。1000000000000000000 = 1 token export AMOUNT="1000000000000000000" ``` -## 步骤 3:创建验证者 +## 步骤 3:创建验证人 -在质押预编译合约上调用 `createValidator`。该函数接受一个 `description` 元组、一个 `commissionRates` 元组、最小自委托额、验证者地址、共识公钥以及绑定金额。使用 `cast` 进行编码并发送。 +调用质押预编译上的 `createValidator`。该函数接受一个 `description` 元组,一个 `commissionRates` 元组,最小自委托,验证人地址,共识公钥和绑定金额。使用 `cast` 对其进行编码和发送。 ```bash # createValidator( @@ -101,30 +101,30 @@ transactionHash 0x4f...c2 status 1 (success) ``` -佣金元组为 `(rate, maxRate, maxChangeRate)`,每个值均缩放为 18 位小数。该示例设置了 10% 的费率(`100000000000000000`)、20% 的上限以及 1% 的每日最大变动幅度。`maxRate` 和 `maxChangeRate` 在创建时即固定,之后无法修改。调用成功会发出一个 `CreateValidator` 事件。每个字段的详情请参阅[质押预编译参考](/cn/reference/staking-module-api#createvalidator)。 +佣金元组是 `(rate, maxRate, maxChangeRate)`,每个都按 18 位小数缩放。示例设置 10% 的费率 (`100000000000000000`),20% 的上限和 1% 的每日最大变化。`maxRate` 和 `maxChangeRate` 在创建时固定,以后无法编辑。成功的调用会发出 `CreateValidator` 事件。有关每个字段的详细信息,请参阅[质押预编译参考](/cn/reference/staking-module-api#createvalidator)。 ## 步骤 4:验证 -通过从质押预编译合约读回验证者记录,确认验证者已注册并绑定,然后检查它是否正在签名区块。 +通过从质押预编译中读取您的验证人,然后检查它是否正在签名区块,来确认验证人已注册并绑定。 ```bash -# Read your validator's on-chain record +# 读取您的验证人链上记录 cast call "$STAKING_ADDRESS" \ "validator(address)" "$VALIDATOR_ADDRESS" \ --rpc-url "$RPC_URL" -# Confirm the node reports validator info +# 确认节点报告验证人信息 curl -s localhost:26657/status | jq '.result.validator_info' ``` ```text -# validator() returns the moniker, tokens, commission, and a bonded status (3) -# validator_info shows your consensus address with non-zero voting power +# validator() 返回标识、代币、佣金和绑定状态 (3) +# validator_info 显示您的共识地址和非零投票权 ``` ## 添加自委托 -要在创建后向自己的验证者绑定更多质押,请在同一个预编译合约上调用 `delegate`。 +要在创建后向您自己的验证人绑定更多质押,请在相同的预编译上调用 `delegate`。 ```bash cast send "$STAKING_ADDRESS" \ @@ -138,17 +138,17 @@ cast send "$STAKING_ADDRESS" \ status 1 (success) ``` -## 注册之后 +## 注册后 -保持验证者健康并为网络升级做好准备: +保持验证人健康并为网络升级做好准备: -- **使用 Prometheus 和 Grafana 监控栈监控签名和漏块情况**,详见[监控节点](/cn/how-to/monitor-node)。 -- **自动化升级**,这样你就不会错过升级高度。参见[安装节点](/cn/how-to/install-node#cosmovisor-setup-recommended-for-automatic-upgrades)中的 Cosmovisor 设置和[升级节点](/cn/how-to/upgrade-node)。 -- **诊断问题**(不同步、不签名),参见[节点故障排查](/cn/how-to/troubleshoot-node)。 +- 使用 [监控节点](/cn/how-to/monitor-node) 中的 Prometheus 和 Grafana 堆栈**监控签名和未出块**。 +- **自动化升级**,以免错过升级高度。请参阅 [安装节点](/cn/how-to/install-node#cosmovisor-setup-recommended-for-automatic-upgrades) 中的 Cosmovisor 设置和 [升级节点](/cn/how-to/upgrade-node)。 +- 使用 [故障排除节点](/cn/how-to/troubleshoot-node) **诊断问题**(未同步,未签名)。 -## 推荐的后续步骤 +## 接下来推荐 -- [**质押预编译参考**](/cn/reference/staking-module-api) — 查阅完整的 createValidator、delegate 和 editValidator 签名及结构体。 -- [**节点配置**](/cn/reference/node-configuration) — 在注册前设置 double_sign_check_height 及其他对验证者至关重要的配置。 -- [**监控节点**](/cn/how-to/monitor-node) — 跟踪签名、漏块和资源使用情况,以便在削减发生前发现问题。 -- [**索引验证者数据**](/cn/how-to/index-validator-data) — 在验证者上线后,从链上读取其质押、在线率和投票历史。 +- [**质押预编译参考**](/cn/reference/staking-module-api):查找完整的 createValidator、delegate 和 editValidator 签名和结构。 +- [**节点配置**](/cn/reference/node-configuration):在注册之前设置 double_sign_check_height 和其他对验证人至关重要的配置。 +- [**监控节点**](/cn/how-to/monitor-node):跟踪签名、未出块和资源使用情况,以便在削减之前发现问题。 +- [**索引验证人数据**](/cn/how-to/index-validator-data):一旦验证人上线,在链上读取其质押、正常运行时间和投票历史。 diff --git a/docs/pages/cn/how-to/sdk-with-viem.mdx b/docs/pages/cn/how-to/sdk-with-viem.mdx index e58da60..9066af8 100644 --- a/docs/pages/cn/how-to/sdk-with-viem.mdx +++ b/docs/pages/cn/how-to/sdk-with-viem.mdx @@ -1,20 +1,20 @@ --- source_path: how-to/sdk-with-viem.mdx -source_sha: c80565f060bd79708a5811def2e3b67fa2cedab9 -title: "搭配 viem 使用 SDK" -description: "通过三种方式使用 @stablechain/sdk 签名:私钥 Account、浏览器 Transport,或预先构建的 viem WalletClient。" +source_sha: 48be50a291feef6843b9074ab105a81c375d5845 +title: "将 SDK 与 viem 结合使用" +description: "通过三种方式使用 @stablechain/sdk 进行签名:私钥账户、浏览器传输或预构建的 viem WalletClient。" diataxis: "how-to" --- -# 搭配 viem 使用 SDK +# 将 SDK 与 viem 结合使用 -`@stablechain/sdk` 基于 viem 构建。`createStable` 接受三种签名模式,你可以根据代码运行的位置选择其一:服务端使用私钥、浏览器端使用用户钱包,或使用你已经构建好的 `WalletClient`(例如在 wagmi 应用中)。 +`@stablechain/sdk` 基于 viem 构建。`createStable` 接受三种签名模式,您可以根据代码运行环境进行选择:在服务器端使用私钥,在浏览器端使用用户钱包,或者使用您已经构建的 `WalletClient`(例如,在 wagmi 应用程序中)。 -本指南将端到端地展示每种模式。 +本指南将演示每种模式的端到端实现。 -## 服务端:私钥 `Account` +## 服务器端:私钥 `Account` -使用 viem 的 `privateKeyToAccount`,通过后端持有的私钥进行签名。 +使用 viem 中的 `privateKeyToAccount` 函数,通过后端持有的私钥进行签名。 ```ts import "dotenv/config"; @@ -43,7 +43,7 @@ console.log(txHash); ## 浏览器端:来自钱包的 `Transport` -将 `custom(window.ethereum)`(或任意 EIP-1193 provider)作为 `transport` 传入。SDK 会构建 `WalletClient` 并从 provider 读取签名者地址。 +将 `custom(window.ethereum)`(或任何 EIP-1193 provider)作为 `transport` 传递。SDK 会构建 `WalletClient` 并从 provider 读取签名者地址。 ```ts import { createStable, Network } from "@stablechain/sdk"; @@ -68,12 +68,12 @@ const { txHash } = await stable.transfer({ ``` :::warning -`transfer`、`bridge` 和 `swap` 会调用 `switchChain` 将钱包切换到正确的网络。如果用户拒绝,SDK 会抛出带有 `phase: "switch_chain"` 的 `StableTransactionError`。请捕获它并向用户提供重试选项。 +`transfer`、`bridge` 和 `swap` 会调用 `switchChain` 将钱包切换到正确的网络。如果用户拒绝,SDK 会抛出 `StableTransactionError` 并带有 `phase: "switch_chain"` 字段。请捕获此错误并向用户显示重试选项。 ::: -## 自带 `WalletClient` +## 引入您自己的 `WalletClient` -当你已经拥有一个 `WalletClient`(例如来自 wagmi 或自定义签名器)时,可以直接传入。它的优先级高于 `account` 和 `transport`。 +当您已经拥有一个 `WalletClient`(例如,来自 wagmi 或自定义签名器)时,可以直接传递它。它会优先于 `account` 和 `transport`。 ```ts import { createStable, Network } from "@stablechain/sdk"; @@ -101,14 +101,14 @@ const { txHash } = await stable.transfer({ from, to: "0xRecipient", amount: 5 }) ## 选择一种模式 -| **模式** | **适用场景** | +| **模式** | **何时使用** | | :--- | :--- | -| `account` | 后端服务、脚本、代理——任何你持有私钥的地方。 | -| `transport` | 浏览器应用,用户通过 MetaMask 或不依赖 wagmi 的自定义流程签名。 | -| `walletClient` | 你已经拥有配置好的 `WalletClient`(wagmi、RainbowKit、ConnectKit)。 | +| `account` | 后端服务、脚本、代理,任何您持有私钥的地方。 | +| `transport` | 浏览器应用程序,用户通过 MetaMask 或无 wagmi 的自定义流程进行签名。 | +| `walletClient` | 您已经有一个配置好的 `WalletClient` (wagmi、RainbowKit、ConnectKit)。 | -## 推荐的后续步骤 +## 接下来推荐 -- [**搭配 wagmi 使用**](/cn/how-to/sdk-with-wagmi) — 通过 wagmi hooks 将 SDK 接入 React 应用。 -- [**SDK 参考**](/cn/reference/sdk) — 每个配置字段、方法、枚举和错误类。 -- [**SDK 快速入门**](/cn/tutorial/sdk-quickstart) — 在测试网上运行你的第一笔转账、跨链和兑换。 +- [**与 wagmi 结合使用**](/cn/how-to/sdk-with-wagmi):通过 wagmi 钩子将 SDK 集成到 React 应用程序中。 +- [**SDK 参考**](/cn/reference/sdk):所有配置字段、方法、枚举和错误类。 +- [**SDK 快速入门**](/cn/tutorial/sdk-quickstart):在测试网上运行您的第一个转账、桥接和兑换。 diff --git a/docs/pages/cn/how-to/sdk-with-wagmi.mdx b/docs/pages/cn/how-to/sdk-with-wagmi.mdx index c571942..d9c06ab 100644 --- a/docs/pages/cn/how-to/sdk-with-wagmi.mdx +++ b/docs/pages/cn/how-to/sdk-with-wagmi.mdx @@ -1,20 +1,20 @@ --- source_path: how-to/sdk-with-wagmi.mdx -source_sha: d3266e146435bf079104ad0d84f274096f220701 -title: "在 wagmi 中使用 SDK" -description: "使用 wagmi 的 useWalletClient、useAccount 和 useChainId hooks,将 @stablechain/sdk 接入 React 应用。" +source_sha: 396745c5590db9fb3f8b0677d67b69579aeeb55a +title: "将 SDK 与 wagmi 结合使用" +description: "将 @stablechain/sdk 引入 React 应用中,使用 wagmi 的 useWalletClient, useAccount, 和 useChainId 钩子。" diataxis: "how-to" --- -# 在 wagmi 中使用 SDK +# 将 SDK 与 wagmi 结合使用 -`createStable` 接受一个 viem `WalletClient`,而这正是 wagmi 的 `useWalletClient` 所返回的内容。你像往常一样通过 wagmi 连接钱包,然后在钱包客户端发生变化时记忆化一个 `StableClient`。 +`createStable` 接受一个 viem `WalletClient`,这正是 wagmi 的 `useWalletClient` 返回的。您像往常一样通过 wagmi 连接钱包,然后在钱包客户端更改时记忆一个 `StableClient`。 -本指南假设你使用 wagmi v2 和 `@tanstack/react-query`。 +本指南假设使用 wagmi v2 和 `@tanstack/react-query`。 ## 1. 配置 wagmi -将 Stable 添加到 wagmi 配置中。viem 为两个网络都提供了链定义。 +将 Stable 添加到 wagmi 配置中。viem 提供了两个网络的链定义。 ```ts import { http, createConfig } from "wagmi"; @@ -35,9 +35,9 @@ export const wagmiConfig = createConfig({ WagmiConfig { chains: [988, 2201], connectors: [injected] } ``` -## 2. 构建一个返回 `StableClient` 的 hook +## 2. 构建一个返回 `StableClient` 的 Hook -针对当前的 `WalletClient` 记忆化一个 `StableClient`。当钱包客户端标识发生变化时重新创建它。 +针对当前的 `WalletClient` 记忆一个 `StableClient`。当钱包客户端的身份发生变化时重新创建它。 ```tsx import { useMemo } from "react"; @@ -55,7 +55,7 @@ export function useStable(network: Network = Network.Mainnet): StableClient | nu ``` :::warning -在用户连接之前,`useWalletClient()` 返回 `undefined`。在调用 SDK 方法之前务必进行守卫检查,否则解构得到的 `walletClient` 将为假值,`createStable` 将没有签名者。 +`useWalletClient()` 在用户连接之前返回 `undefined`。在调用 SDK 方法之前务必进行防御性检查,否则解构的 `walletClient` 将为假值,并且 `createStable` 将没有签名者。 ::: ## 3. 在组件中使用它 @@ -82,7 +82,7 @@ export function PayButton() { return ( ); } @@ -92,9 +92,9 @@ export function PayButton() { Sent: 0x8f3a...2d41 ``` -## 4. 在 React 中进行桥接和兑换 +## 4. 从 React 执行桥接和兑换 -同一个 `stable` 实例可处理桥接和兑换。在 effect 或 `useQuery` 中获取报价,然后在点击时执行。 +同一个 `stable` 实例处理桥接和兑换。在 effect 或 `useQuery` 中获取报价,然后点击执行。 ```tsx const stable = useStable(Network.Mainnet); @@ -123,11 +123,11 @@ const onSwap = async () => { ``` :::note -使用 `useQuery` 缓存报价效果很好:将 `quoteSwap` / `quoteBridge` 作为查询函数传入,并将缓存的 `quote` 转发给 `swap` / `bridge`。当提供了报价时,SDK 会跳过其内部的报价调用。 +使用 `useQuery` 缓存报价效果很好:将 `quoteSwap` / `quoteBridge` 作为查询函数传递,并将缓存的 `quote` 转发到 `swap` / `bridge`。当提供了报价时,SDK 会跳过其内部的报价调用。 ::: -## 推荐的下一步 +## 下一步建议 -- [**SDK 参考**](/cn/reference/sdk) — 每个方法、配置字段和错误类。 -- [**与 viem 一起使用**](/cn/how-to/sdk-with-viem) — 并排比较三种签名模式。 -- [**SDK 快速入门**](/cn/tutorial/sdk-quickstart) — 在测试网上运行你的第一笔转账、桥接和兑换。 +- [**SDK 参考**](/cn/reference/sdk):每个方法、配置字段和错误类。 +- [**与 viem 结合使用**](/cn/how-to/sdk-with-viem):并排比较三种签名模式。 +- [**SDK 快速入门**](/cn/tutorial/sdk-quickstart):在测试网上运行您的首次转账、桥接和兑换。 diff --git a/docs/pages/cn/how-to/self-hosted-gas-waiver.mdx b/docs/pages/cn/how-to/self-hosted-gas-waiver.mdx index e8fe2af..c427ede 100644 --- a/docs/pages/cn/how-to/self-hosted-gas-waiver.mdx +++ b/docs/pages/cn/how-to/self-hosted-gas-waiver.mdx @@ -1,39 +1,38 @@ --- source_path: how-to/self-hosted-gas-waiver.mdx -source_sha: 60e5bccdb2641ffd0f4c1184d8dfb6e642990c73 -title: "自托管 gas 豁免" -description: "在 Stable 上运行你自己的 gas 豁免。通过治理注册豁免地址、构造包装交易,并直接广播,无需使用托管的 Waiver Server API。" +source_sha: c054baff79a39314af7a4aaa087bd4525dfc7f12 +title: "自托管燃气费代付" +description: "在 Stable 上运行您自己的燃气费代付服务。通过治理注册代付地址,构建封装器交易,然后无需托管服务器即可广播它们。" diataxis: "how-to" --- +# 自托管燃气费代付 -# 自托管 gas 豁免 +自托管燃气费代付让您可以操作自己的代付基础设施,而不是使用托管的Waiver Server API。您通过链上治理注册一个代付地址,然后直接向网络广播封装器交易。 -自托管 Gas 豁免让你可以运营自己的豁免基础设施,而不必使用托管的 Waiver Server API。你通过链上治理注册一个豁免地址,然后直接向网络广播包装交易。 - -本指南涵盖注册豁免地址、收集已签名的用户交易、构造包装交易并广播它们。 +本指南涵盖注册代付地址、收集已签名的用户交易、构建封装器交易以及广播它们。 :::note -**概念:** 关于 Gas 豁免是什么以及为何存在,参见 [Gas 豁免](/cn/explanation/gas-waiver)。关于完整的协议规范(包装交易机制、授权、策略检查、执行语义、安全模型),参见 [Gas 豁免协议](/cn/reference/gas-waiver-api)。 +**概念:** 关于燃气费代付是什么以及它为什么存在,请参阅[燃气费代付](/cn/explanation/gas-waiver)。有关完整的协议规范(封装器交易机制、授权、策略检查、执行语义、安全模型),请参阅[燃气费代付协议](/cn/reference/gas-waiver-api)。 ::: -关于托管的 Waiver Server API 集成路径,参见 [启用免 gas 交易](/cn/how-to/integrate-gas-waiver)。 +有关托管Waiver Server API集成路径,请参阅[启用免燃气费交易](/cn/how-to/integrate-gas-waiver)。 -## 前置条件 +## 先决条件 -- 通过验证者治理在链上注册的豁免地址。 -- 为你的目标合约配置的 `AllowedTarget` 策略。 +- 一个通过验证者治理在链上注册的代付地址。 +- 为您的目标合约配置了`AllowedTarget`策略。 -## 概述 +## 概览 自托管流程: -1. **从用户收集已签名的 InnerTx**,其 `gasPrice = 0`。 -2. **构造 WrapperTx**:对 InnerTx 进行 RLP 编码,并将其包装在一笔发送到 marker 地址的交易中。 -3. **广播** WrapperTx,通过 `eth_sendRawTransaction`。 +1. **收集已签名的 InnerTx**,其中用户的`gasPrice = 0`。 +2. **构建 WrapperTx**:RLP 编码 InnerTx 并将其封装在发送到标记地址的交易中。 +3. **通过 `eth_sendRawTransaction` 广播** WrapperTx。 ## 步骤 1:收集用户的 InnerTx -用户签名一笔 `gasPrice = 0` 的交易。`to` 地址和方法选择器必须匹配你豁免的 `AllowedTarget` 策略。 +用户签署一个`gasPrice = 0`的交易。`to`地址和方法选择器必须与您的代付的`AllowedTarget`策略匹配。 ```typescript // config.ts @@ -82,9 +81,9 @@ const innerTx = { const signedInnerTx = await userWallet.signTransaction(innerTx); ``` -## 步骤 2:构造 WrapperTx +## 步骤 2:构建 WrapperTx -对已签名的 InnerTx 进行 RLP 编码,并将其包装在一笔发送到 marker 地址的交易中。`gasLimit` 必须同时覆盖内部执行和包装开销。 +RLP 编码已签名的 InnerTx 并将其封装在发送到标记地址的交易中。`gasLimit`必须覆盖内部执行和封装开销。 ```typescript // constructWrapper.ts @@ -110,7 +109,7 @@ const signedWrapperTx = await waiverWallet.signTransaction(wrapperTx); ``` :::warning -`InnerTx.gasPrice` 和 `WrapperTx.gasPrice` 都必须为 `0`。`WrapperTx.value` 也必须为 `0`。如果其中任何条件不满足,验证者将拒绝该交易。 +`InnerTx.gasPrice`和`WrapperTx.gasPrice`都必须为`0`。`WrapperTx.value`也必须为`0`。如果这些条件中的任何一个不满足,验证者将拒绝该交易。 ::: ## 步骤 3:广播 @@ -131,14 +130,14 @@ Wrapper tx broadcast: 0x... Confirmed: true ``` -## 关键要点 +## 主要收获 -- 自托管豁免需要一个通过链上验证者治理注册的豁免地址。 -- WrapperTx 被发送到 marker 地址(`0x...f333`),并以 RLP 编码的 InnerTx 作为数据。 -- InnerTx 和 WrapperTx 都必须满足 `gasPrice = 0` 和 `value = 0`。 +- 自托管代付需要通过链上验证者治理注册一个代付地址。 +- WrapperTx 会发送到标记地址 (`0x...f333`),数据为 RLP 编码的 InnerTx。 +- InnerTx 和 WrapperTx 的 `gasPrice` 都必须为 `0`,且 `value` 也必须为 `0`。 -## 下一步推荐 +## 下一步建议 -- [**Gas 豁免概念**](/cn/explanation/gas-waiver) — 在运行你自己的豁免之前理解其机制。 -- [**Gas 豁免协议**](/cn/reference/gas-waiver-api) — 参考完整的协议规范,了解 marker 路由、授权和执行语义。 -- [**启用免 gas 交易**](/cn/how-to/integrate-gas-waiver) — 使用托管的 Waiver Server API,而不是自托管。 +- [**燃气费代付概念**](/cn/explanation/gas-waiver):在您自行运行之前,了解其机制。 +- [**燃气费代付协议**](/cn/reference/gas-waiver-api):参考完整的协议规范,了解标记路由、授权和执行语义。 +- [**启用免燃气费交易**](/cn/how-to/integrate-gas-waiver):使用托管的 Waiver Server API,而不是自行托管。 diff --git a/docs/pages/cn/how-to/subscribe-and-collect.mdx b/docs/pages/cn/how-to/subscribe-and-collect.mdx index a41b2e0..91257ec 100644 --- a/docs/pages/cn/how-to/subscribe-and-collect.mdx +++ b/docs/pages/cn/how-to/subscribe-and-collect.mdx @@ -1,22 +1,22 @@ --- source_path: how-to/subscribe-and-collect.mdx -source_sha: c1fe3d6efad8671b22584ae67ffc3cdbf929337d +source_sha: a381dc34ff14359750a205ac7aca9d960486455a title: "订阅与收款" -description: "使用 EIP-7702 委托在 Stable 上构建基于拉取的订阅支付。设置订阅者授权并自动执行计费周期的收款。" +description: "使用 EIP-7702 委托在 Stable 上构建拉式订阅支付。设置订阅者授权并自动化账单周期收款。" diataxis: "how-to" --- # 订阅与收款 -本指南将引导你构建一个订阅支付系统,订阅者只需授权一次,服务提供方便可在每个计费周期通过 EIP-7702 账户抽象自动收款。 +本指南将介绍如何构建一个订阅支付系统,其中订阅者只需授权一次,服务提供商即可通过 EIP-7702 账户抽象在每个账单周期自动收款。 :::note -**概念:** 关于订阅模型、权衡取舍以及与卡片预存计费的比较,请参阅[订阅计费](/cn/reference/subscriptions)。 +**概念:** 有关订阅模式、权衡以及与持卡计费的比较,请参阅[订阅计费](/cn/reference/subscriptions)。 ::: -## 你将构建的内容 +## 您将构建什么 -一个完整的订阅生命周期:订阅者委托并订阅一次,提供方按计划收款(展示第二个周期以证明重复行为),订阅者取消订阅。 +一个完整的订阅生命周期:订阅者委托并订阅一次,提供商按计划收款(显示第二个周期以证明重复行为),然后订阅者取消。 ### 演示 @@ -46,7 +46,7 @@ step 5. Subscriber cancels **订阅者:** -``` +```text ─── Subscriber ─────────────────────────────────────── // One-time setup: delegate EOA to the subscription contract signAuthorization(delegateContract) @@ -59,9 +59,9 @@ sendTransaction({ to: self, data: subscribe(subscriptionId, provider, amount, in sendTransaction({ to: self, data: cancelSubscription(subscriptionId) }) ``` -**服务提供方:** +**服务提供商:** -``` +```text ─── Service Provider ──────────────────────────────── // Each billing cycle: collect payment from subscriber's EOA // The delegate contract verifies caller, billing schedule, and amount @@ -73,13 +73,13 @@ sendTransaction({ to: subscriberEOA, data: collect(subscriptionId) }) ## 委托合约 -订阅计费的工作原理是将订阅者的 EOA 委托给一个执行计费条款的合约。通过 EIP-7702,订阅者的账户临时获得合约逻辑,使得服务提供方能够在每个计费周期收款,而无需订阅者每次都签名。 +订阅计费通过将订阅者的 EOA 委托给一个强制执行计费条款的合约来工作。通过 EIP-7702,订阅者的账户暂时获得合约逻辑,允许服务提供商在每个计费周期收款,而无需订阅者每次都签名。 -你可以使用现有的已部署合约,也可以部署自己的合约。下面的示例是一个最小化的 `SubscriptionManager` 合约,支持三种操作: +您可以使用已部署的现有合约或部署您自己的合约。下面的示例是一个最小的 `SubscriptionManager` 合约,它支持三种操作: -- `subscribe`:为某个 `subscriptionId` 注册计费条款。 -- `collect`:提供方为该 `subscriptionId` 拉取下一笔计划付款。 -- `cancelSubscription`:订阅者撤销某个特定订阅。 +- `subscribe`:为 `subscriptionId` 注册计费条款。 +- `collect`:提供商为该 `subscriptionId` 拉取下一个预定付款。 +- `cancelSubscription`:订阅者撤销特定订阅。 ```solidity // SPDX-License-Identifier: MIT @@ -180,7 +180,7 @@ contract SubscriptionManager { ``` :::note -此合约作为参考实现提供,仅用于测试目的。委托合约对订阅者的 EOA 拥有完全的执行权限,因此在生产环境中,请使用经过审计和验证的合约。有关 EIP-7702 委托和安全性的更多背景信息,请参阅 [EIP-7702](/cn/explanation/eip-7702)。 +此合约作为测试参考实现提供。委托合约对订阅者的 EOA 拥有完全执行权限,因此在生产环境中,请使用经过审计和验证的合约。有关 EIP-7702 委托和安全性的更多背景信息,请参阅 [EIP-7702](/cn/explanation/eip-7702)。 ::: ## 配置 @@ -198,9 +198,9 @@ export const provider = new ethers.JsonRpcProvider(STABLE_TESTNET_RPC); export const subscriberWallet = new ethers.Wallet(process.env.SUBSCRIBER_KEY!, provider); ``` -## 步骤 1:委托订阅者的 EOA(EIP-7702) +## 步骤 1:委托订阅者的 EOA (EIP-7702) -订阅者签署一个 EIP-7702 授权,将其 EOA 委托给 `SubscriptionManager`。此后,订阅者的 EOA 将执行委托合约的逻辑。 +订阅者签署 EIP-7702 授权,将其 EOA 委托给 `SubscriptionManager`。在此之后,订阅者的 EOA 将执行委托合约的逻辑。 ```typescript // delegate.ts @@ -235,7 +235,7 @@ Delegation tx: 0x7702...aaaa ## 步骤 2:注册订阅(订阅者) -订阅者在自己的 EOA 上调用 `subscribe()`。由于 EOA 已被委托,此操作将执行 `SubscriptionManager.subscribe`。 +订阅者在其自己的 EOA 上调用 `subscribe()`。由于 EOA 已被委托,这将执行 `SubscriptionManager.subscribe`。 ```typescript // subscribe.ts @@ -281,9 +281,9 @@ Subscription registered, tx: 0xabcd...1234 Subscription ID: 0xfedc...9876 ``` -## 步骤 3:收取付款(服务提供方) +## 步骤 3:收款(服务提供商) -每个计费周期,服务提供方在订阅者的 EOA 上调用 `collect(subscriptionId)`。委托逻辑在转移 USDT0 之前会验证调用者、计费计划和金额。 +每个账单周期,服务提供商在订阅者的 EOA 上调用 `collect(subscriptionId)`。委托逻辑在转账 USDT0 之前验证调用者、计费计划和金额。 ```typescript // collect.ts @@ -322,11 +322,11 @@ Payment collected, tx: 0x8f3a...2d41 Gas used: 52000 ``` -在 Stable 上,一次 `collect()` 调用大约消耗 **50k-55k gas**(21k 基础 + 7702 委托开销 + ERC-20 `transfer`)。按 1 gwei 基础费用计算,提供方每个计费周期支付的费用约为 `0.000050 USDT0`。 +`collect()` 调用在 Stable 上大约需要 **50k-55k gas**(21k 基础 gas + 7702 委托开销 + ERC-20 `transfer`)。在 1 gwei 的基础费用下,每个计费周期提供商支付的费用约为 `0.000050 USDT0`。 ## 步骤 4:取消订阅(订阅者) -订阅者在自己的 EOA 上调用 `cancelSubscription(subscriptionId)`,以撤销该特定订阅的计费权限。 +订阅者在其自己的 EOA 上调用 `cancelSubscription(subscriptionId)` 以撤销该特定订阅的计费访问权限。 ```typescript // cancel.ts @@ -359,33 +359,33 @@ Subscription cancelled, tx: 0xdef0...5678 ## 安全模型 -订阅者授权委托合约从其 EOA 中拉取资金。请准确了解该授权涵盖的范围以及如何限制风险敞口。 +订阅者正在授权委托合约从其 EOA 中提取资金。精确了解该授权涵盖的内容以及如何限制风险敞口。 -**订阅者授权的内容。** 通过委托给 `SubscriptionManager`,订阅者授予该合约逻辑对其 EOA 的完全执行权限。委托方只能在其代码所设定的条件下转移资金:调用者是已注册的提供方、间隔时间已过、金额与已存储的订阅相匹配。它无法转移到其他地址或绕过间隔检查,因为合约代码不允许这些操作。 +**订阅者正在授权什么。** 通过委托给 `SubscriptionManager`,订阅者授予合约逻辑对其 EOA 的完全执行权限。委托只能在符合编码条件的情况下转移资金:调用者是注册的提供商,间隔已过,金额与存储的订阅匹配。它不能转移到其他地址或绕过间隔检查,因为合约代码不允许这些操作。 -**需要缓解的失败模式。** +**需要缓解的故障模式。** -- **恶意委托升级**:如果 `SubscriptionManager` 是一个其实现可被管理员更改的代理合约,那么该授权实际上信任了该管理员。仅委托给不可变的合约或具有透明、时间锁定升级的代理合约。 -- **提供方被攻破**:如果提供方的密钥泄露,攻击者可在每个周期金额的上限内提前收款。订阅者应为每个订阅设置 `spendingLimit`,并监控未经授权的 `SubscriptionCollected` 事件。 -- **委托替换**:使用不同的委托方再次订阅会清除订阅状态。请使用模块化委托方,在单一委托下支持多种功能(订阅、批量支付、支出限额),而不是每个功能使用一个委托方。 -- **可重放签名**:所有签名都使用与订阅者 EOA 绑定的 EIP-7702 nonce,因此它们无法跨链或跨委托重放。 +- **恶意委托合约升级**:如果 `SubscriptionManager` 是一个代理,其实现可以通过管理员更改,那么授权实际上信任该管理员。只委托给不可变合约或具有透明、时间锁定升级的代理。 +- **提供商泄露**:如果提供商的密钥泄露,攻击者可以提前收取费用,最高可达每个周期的金额。订阅者应为每个订阅设置 `spendingLimit` 并监控未经授权的 `SubscriptionCollected` 事件。 +- **委托替换**:使用不同的委托再次订阅会清除订阅状态。使用支持多个功能(订阅、批量支付、支出限制)的模块化委托,而不是每个功能使用一个委托。 +- **可重放签名**:所有签名都使用绑定到订阅者 EOA 的 EIP-7702 随机数,因此它们不能跨链或跨委托重放。 **推荐的防护措施。** -- 在生产环境使用前审计委托合约。 -- 相对于订阅者的余额,保持每个订阅的金额较小。 -- 监控 `SubscriptionCreated` / `SubscriptionCollected` 事件并向订阅者展示。 -- 为订阅者提供清晰的"取消"界面,在其自己的 EOA 上调用 `cancelSubscription(subscriptionId)`。 +- 在生产使用前审计委托合约。 +- 将每个订阅的金额保持在订阅者余额的较小比例。 +- 监控 `SubscriptionCreated` / `SubscriptionCollected` 事件并将其显示给订阅者。 +- 提供订阅者清晰的“取消”UI,在其自己的 EOA 上调用 `cancelSubscription(subscriptionId)`。 -## 重要注意事项 +## 重要考虑事项 -- **持久委托**:EIP-7702 委托会持续存在,直到订阅者明确更改或清除它。无需每个计费周期重新委托。 -- **每个 EOA 单一委托**:如果订阅者之后委托给不同的合约,订阅委托逻辑将被替换,收款将失败。请使用模块化委托合约,在单一委托下支持多种功能(订阅、批量支付、支出限额、会话密钥)。 -- **计划行为**:此示例在每次成功收款时将 `nextChargeAt` 推进一个间隔。如果已经过去了多个计费周期,重复的 `collect()` 调用可以逐个周期追赶。如果你的产品需要不同的策略,请扩展该逻辑。 -- **使用经过审计的委托方**:仅委托给已经过审计的合约。 +- **持久委托**:EIP-7702 委托将一直存在,直到订阅者明确更改或清除它。每个计费周期无需重新委托。 +- **每个 EOA 的单一委托**:如果订阅者以后委托给不同的合约,订阅委托逻辑将被替换,并且收款将失败。使用支持多个功能(订阅、批量支付、支出限制、会话密钥)的模块化委托合约,所有这些功能都在一个委托下。 +- **计划行为**:此示例在每次成功收款时将 `nextChargeAt` 增加一个间隔。如果已经过去不止一个计费周期,则重复的 `collect()` 调用可以一次赶上一个周期。如果您的产品需要不同的策略,请扩展逻辑。 +- **使用经过审计的委托合约**:仅委托给经过审计的合约。 -## 下一步推荐 +## 接下来推荐 -- [**订阅计费概念**](/cn/reference/subscriptions) — 了解基于拉取的计费模型。 -- [**账户抽象**](/cn/how-to/account-abstraction) — 了解批量支付、支出限额和会话密钥如何在单一委托下组合。 -- [**EIP-7702 概念**](/cn/explanation/eip-7702) — 回顾使这一切成为可能的委托模型。 +- [**订阅计费概念**](/cn/reference/subscriptions):了解拉式计费模型。 +- [**账户抽象**](/cn/how-to/account-abstraction):了解批量支付、支出限制和会话密钥如何在单个委托下结合使用。 +- [**EIP-7702 概念**](/cn/explanation/eip-7702):回顾使这成为可能的委托模型。 diff --git a/docs/pages/cn/how-to/track-unbonding.mdx b/docs/pages/cn/how-to/track-unbonding.mdx index fc5ee4f..ce34826 100644 --- a/docs/pages/cn/how-to/track-unbonding.mdx +++ b/docs/pages/cn/how-to/track-unbonding.mdx @@ -1,30 +1,30 @@ --- source_path: how-to/track-unbonding.mdx -source_sha: 33d66c8fbb264a445f511902164794ff3796e785 -title: "追踪解绑完成" -description: "通过系统交易订阅 StableSystem 预编译合约发出的 UnbondingCompleted 事件。按用户或验证人筛选,查询历史事件。" +source_sha: 5c4d430a5edb73996ba773710b260c58025a04d8 +title: "跟踪解除质押完成情况" +description: "通过系统交易订阅 StableSystem 预编译合约发出的 UnbondingCompleted 事件。按用户或验证者进行筛选,查询历史事件。" diataxis: "how-to" --- -# 追踪解绑完成 +# 跟踪解除质押完成情况 -当解绑周期完成时,协议会通过系统交易,借助 `StableSystem` 预编译合约(`0x0000000000000000000000000000000000009999`)发出 `UnbondingCompleted` 事件。这使得 dApp 能够实时通知用户并更新余额,而无需运行自定义索引器或轮询 REST 端点。 +当解除质押期完成时,协议会通过系统交易,通过 `StableSystem` 预编译合约(`0x0000000000000000000000000000000000009999`)发出一个 `UnbondingCompleted` 事件。这允许 dApp 实时通知用户并更新余额,而无需运行自定义索引器或轮询 REST 端点。 :::note -**概念:** 关于系统交易如何将 SDK 层事件桥接到 EVM 以及其重要性,请参阅 [系统交易](/cn/explanation/system-transactions)。 +**概念:** 有关系统交易如何将 SDK 层事件桥接到 EVM 以及其重要性,请参阅[系统交易](/cn/explanation/system-transactions)。 ::: -## 前置条件 +## 前提条件 -- 了解 [系统交易](/cn/explanation/system-transactions)。 -- 熟悉 [质押](/cn/explanation/staking-module),特别是 `undelegate` 和解绑流程。 -- 具备使用标准 web3 库(例如 [ethers.js](https://docs.ethers.org/) v6)订阅和筛选合约事件的经验。 +- 了解[系统交易](/cn/explanation/system-transactions)。 +- 熟悉[质押](/cn/explanation/staking-module),特别是 `undelegate` 和解除质押过程。 +- 有使用标准 web3 库(例如 [ethers.js](https://docs.ethers.org/) v6)进行合约事件订阅和过滤的经验。 ## 概述 -- **设置合约实例**:为 StableSystem 预编译合约创建一个合约实例。 -- **在应用中处理事件**:根据应用逻辑订阅实时事件或查询历史数据。 -- **处理连接问题**:为持久化的 WebSocket 订阅实现重连逻辑。 +- **设置合约实例**:为 StableSystem 预编译合约创建合约实例。 +- **在你的应用程序中处理事件**:根据你的应用程序逻辑订阅实时事件或查询历史数据。 +- **处理连接问题**:为持久的 WebSocket 订阅实现重新连接逻辑。 ## 步骤 1:设置合约实例 @@ -49,13 +49,13 @@ export const stableSystem = new ethers.Contract( ); ``` -## 步骤 2:在应用中处理事件 +## 步骤 2:在你的应用程序中处理事件 -根据应用逻辑订阅实时事件、查询历史数据,或两者兼有。 +根据你的应用程序逻辑,订阅实时事件、查询历史数据或两者兼而有之。 ### 实时订阅 -订阅 `UnbondingCompleted` 事件,以便在任何解绑完成时获得实时通知。这对于触发余额更新、发送通知或刷新仪表盘统计数据很有用。 +订阅 `UnbondingCompleted` 事件以获取任何解除质押完成时的实时通知。这对于触发余额更新、发送通知或刷新仪表板统计数据非常有用。 ```typescript // subscribeBasic.ts @@ -73,7 +73,7 @@ stableSystem.on("UnbondingCompleted", (delegator, validator, amount, event) => { ### 按用户筛选 -如果只想接收特定委托人地址的事件,请使用已索引的事件参数创建一个筛选器。 +要仅接收特定委托人地址的事件,请使用索引事件参数创建过滤器。 ```typescript // subscribeByUser.ts @@ -86,12 +86,12 @@ const filter = stableSystem.filters.UnbondingCompleted(userAddress); stableSystem.on(filter, (delegator, validator, amount, event) => { refreshUserBalance(userAddress); showNotification( - `Your unbonding of ${ethers.formatEther(amount)} tokens completed!` + `您的 ${ethers.formatEther(amount)} 代币的解除质押已完成!` ); }); ``` -### 按验证人筛选 +### 按验证者筛选 ```typescript // subscribeByValidator.ts @@ -110,7 +110,7 @@ stableSystem.on(validatorFilter, (delegator, validator, amount) => { ### 历史查询 -如果你的 dApp 需要展示过去解绑完成的历史记录,请使用带区块范围的事件筛选器查询历史事件。 +如果你的 dApp 需要显示过去解除质押完成的历史记录,请使用带有区块范围的事件过滤器查询历史事件。 ```typescript // queryHistory.ts @@ -144,25 +144,25 @@ const history = await getUnbondingHistory( ## 步骤 3:处理连接问题 -事件订阅依赖于持久化的 WebSocket 连接。请为生产环境的 dApp 实现重连逻辑。 +事件订阅依赖于持久的 WebSocket 连接。为生产 dApp 实现重新连接逻辑。 ```typescript // subscribeWithReconnection.ts -import { ethers } from "ethers"; +import { ethers } = "ethers"; import { STABLE_SYSTEM_ADDRESS, STABLE_SYSTEM_ABI } from "./config"; let reconnectAttempts = 0; const MAX_RECONNECT_ATTEMPTS = 5; function handleUnbonding(delegator: string, validator: string, amount: bigint) { - console.log("Unbonding completed:", { delegator, validator, amount }); + console.log("解除质押完成:", { delegator, validator, amount }); } function setupEventListener() { const wsProvider = new ethers.WebSocketProvider("wss://rpc.testnet.stable.xyz"); wsProvider.on("error", (error) => { - console.error("Provider error:", error); + console.error("提供者错误:", error); if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) { reconnectAttempts++; setTimeout(() => setupEventListener(), 5000); @@ -181,8 +181,8 @@ function setupEventListener() { setupEventListener(); ``` -## 后续推荐 +## 下一步推荐 -- [**系统交易概念**](/cn/explanation/system-transactions) — 了解协议层事件如何到达 EVM。 -- [**质押模块概念**](/cn/explanation/staking-module) — 回顾委托和解绑流程。 -- [**质押预编译参考**](/cn/reference/staking-module-api) — 查找触发此处所追踪事件的方法。 +- [**系统交易概念**](/cn/explanation/system-transactions):了解协议级别的事件如何到达 EVM。 +- [**质押模块概念**](/cn/explanation/staking-module):回顾委托和解除质押流程。 +- [**质押预编译参考**](/cn/reference/staking-module-api):查找触发此处跟踪的事件的方法。 diff --git a/docs/pages/cn/how-to/troubleshoot-node.mdx b/docs/pages/cn/how-to/troubleshoot-node.mdx index 541dbd2..669de11 100755 --- a/docs/pages/cn/how-to/troubleshoot-node.mdx +++ b/docs/pages/cn/how-to/troubleshoot-node.mdx @@ -1,12 +1,12 @@ --- source_path: how-to/troubleshoot-node.mdx -source_sha: f4b7701fdfef056c1aa8bd46ae494c7f6d73d775 -title: 故障排查指南 -description: "针对常见 Stable 节点连接、同步和性能问题的诊断脚本与解决方案。" +source_sha: 138c5c2eb1a61666718ce625d0553a298a454c03 +title: 故障排除指南 +description: "用于解决 Stable 节点常见连接、同步和性能问题的诊断脚本和解决方案。" diataxis: "how-to" --- -本综合指南帮助诊断和解决 Stable 节点的常见问题。 +本综合指南旨在帮助诊断和解决 Stable 节点常见问题。 ## 快速诊断 @@ -19,56 +19,56 @@ diataxis: "how-to" # Set service name (default: stable) export SERVICE_NAME=stable -echo "=== Stable Node Diagnostics ===" -echo "Timestamp: $(date)" +echo "=== Stable 节点诊断 ===" +echo "时间戳: $(date)" echo "" -# 1. Service Status -echo "1. SERVICE STATUS:" +# 1. 服务状态 +echo "1. 服务状态:" systemctl status ${SERVICE_NAME} --no-pager | head -10 -# 2. Sync Status -echo -e "\n2. SYNC STATUS:" -curl -s localhost:26657/status | jq '.result.sync_info' 2>/dev/null || echo "RPC not responding" +# 2. 同步状态 +echo -e "\n2. 同步状态:" +curl -s localhost:26657/status | jq '.result.sync_info' 2>/dev/null || echo "RPC 未响应" -# 3. Peer Connections -echo -e "\n3. PEER COUNT:" -curl -s localhost:26657/net_info | jq '.result.n_peers' 2>/dev/null || echo "Cannot get peer info" +# 3. 对等连接 +echo -e "\n3. 对等节点数量:" +curl -s localhost:26657/net_info | jq '.result.n_peers' 2>/dev/null || echo "无法获取对等节点信息" -# 4. Recent Errors -echo -e "\n4. RECENT ERRORS (last 20):" +# 4. 最近错误 +echo -e "\n4. 最近错误 (最近 20 条):" sudo journalctl -u ${SERVICE_NAME} --since "1 hour ago" | grep -i error | tail -20 -# 5. System Resources -echo -e "\n5. SYSTEM RESOURCES:" +# 5. 系统资源 +echo -e "\n5. 系统资源:" df -h / | grep -v Filesystem free -h | grep Mem top -bn1 | grep "load average" -# 6. Port Status -echo -e "\n6. PORT STATUS:" -ss -tulpn | grep ${SERVICE_NAME} || echo "No ${SERVICE_NAME} ports found" +# 6. 端口状态 +echo -e "\n6. 端口状态:" +ss -tulpn | grep ${SERVICE_NAME} || echo "未找到 ${SERVICE_NAME} 端口" -echo -e "\n=== Diagnostics Complete ===" +echo -e "\n=== 诊断完成 ===" ``` -## 常见问题与解决方案 +## 常见问题及解决方案 ### 节点无法启动 #### 问题:找不到二进制文件 **错误信息:** -``` +```text stabled: command not found ``` **解决方案:** ```bash -# Check if binary exists +# 检查二进制文件是否存在 ls -la /usr/bin/stabled -# If missing, reinstall (use arm64 if needed) +# 如果缺失,重新安装 (如果需要使用 arm64) wget https://stable-data-dist.s3.us-east-1.amazonaws.com/testnet/binary/stabled-0.7.2-linux-amd64-testnet.tar.gz tar -xvzf stabled-0.7.2-linux-amd64-testnet.tar.gz sudo mv stabled /usr/bin/ @@ -78,16 +78,16 @@ sudo chmod +x /usr/bin/stabled #### 问题:权限被拒绝 **错误信息:** -``` +```text Error: open /home/user/.stabled/config/config.toml: permission denied ``` **解决方案:** ```bash -# Fix ownership +# 修复所有权 sudo chown -R $USER:$USER ~/.stabled/ -# Fix permissions +# 修复权限 chmod 700 ~/.stabled/ chmod 600 ~/.stabled/config/*.json chmod 644 ~/.stabled/config/*.toml @@ -96,19 +96,19 @@ chmod 644 ~/.stabled/config/*.toml #### 问题:地址已被占用 **错误信息:** -``` +```text Error: listen tcp 0.0.0.0:26657: bind: address already in use ``` **解决方案:** ```bash -# Find process using port +# 查找使用端口的进程 sudo lsof -i :26657 -# Kill the process +# 终止该进程 sudo kill -9 -# Or change port in config +# 或者在配置中更改端口 sed -i 's/laddr = "tcp:\/\/0.0.0.0:26657"/laddr = "tcp:\/\/0.0.0.0:26658"/' ~/.stabled/config/config.toml ``` @@ -117,52 +117,52 @@ sed -i 's/laddr = "tcp:\/\/0.0.0.0:26657"/laddr = "tcp:\/\/0.0.0.0:26658"/' ~/.s #### 问题:节点卡在某个高度 **症状:** -- 区块高度不增加 -- 超过 1 分钟没有新区块 +- 块高不增加 +- 超过 1 分钟没有新块 **解决方案:** ```bash -# 1. Check peers +# 1. 检查对等节点 curl localhost:26657/net_info | jq '.result.n_peers' -# If no peers, add persistent peers +# 如果没有对等节点,添加持久对等节点 echo "persistent_peers = \"5ed0f977a26ccf290e184e364fb04e268ef16430@37.187.147.27:26656,128accd3e8ee379bfdf54560c21345451c7048c7@37.187.147.22:26656\"" >> ~/.stabled/config/config.toml -# 2. Reset and resync +# 2. 重置并重新同步 sudo systemctl stop ${SERVICE_NAME} stabled comet unsafe-reset-all --keep-addr-book sudo systemctl start ${SERVICE_NAME} -# 3. Use snapshot (see Snapshots guide) +# 3. 使用快照 (参见快照指南) ``` -#### 问题:"wrong Block.Header.AppHash" 错误 +#### 问题:"`wrong Block.Header.AppHash`" 错误 **错误信息:** -``` +```text panic: Wrong Block.Header.AppHash. Expected XXXX, got YYYY ``` **解决方案:** ```bash -# This indicates state corruption - rollback to previous block +# 这表示状态损坏 - 回滚到前一个块 sudo systemctl stop ${SERVICE_NAME} -# Rollback one block +# 回滚一个块 stabled rollback -# Restart node +# 重启节点 sudo systemctl start ${SERVICE_NAME} -# If rollback doesn't work, restore from snapshot -# Backup important files +# 如果回滚无效,从快照恢复 +# 备份重要文件 cp ~/.stabled/config/priv_validator_key.json ~/backup/ cp ~/.stabled/config/node_key.json ~/backup/ -# Reset state +# 重置状态 stabled comet unsafe-reset-all -# Restore from snapshot +# 从快照恢复 wget https://stable-data-dist.s3.us-east-1.amazonaws.com/testnet/snapshots/snapshot.tar.lz4 tar -I lz4 -xf snapshot.tar.lz4 -C ~/.stabled/ @@ -172,15 +172,15 @@ sudo systemctl start ${SERVICE_NAME} #### 问题:同步速度慢 **症状:** -- 每分钟少于 100 个区块 +- 每分钟少于 100 个块 - CPU/磁盘使用率高 **解决方案:** ```bash -# 1. Check disk I/O +# 1. 检查磁盘 I/O iostat -x 1 5 -# 2. Optimize configuration +# 2. 优化配置 cat >> ~/.stabled/config/config.toml <> ~/.stabled/config/config.toml < db_dump.txt -# 4. If repair fails, resync +# 4. 如果修复失败,重新同步 rm -rf ~/.stabled/data -# Restore from snapshot +# 从快照恢复 -# 5. Start node +# 5. 启动节点 sudo systemctl start ${SERVICE_NAME} ``` -#### 问题:"too many open files" +#### 问题:"打开文件过多" **错误信息:** -``` +```text accept: too many open files ``` **解决方案:** ```bash -# 1. Check current limits +# 1. 检查当前限制 ulimit -n -# 2. Increase limits +# 2. 增加限制 echo "* soft nofile 65535" | sudo tee -a /etc/security/limits.conf echo "* hard nofile 65535" | sudo tee -a /etc/security/limits.conf -# 3. Update systemd service +# 3. 更新 systemd 服务 sudo sed -i '/\[Service\]/a LimitNOFILE=65535' /etc/systemd/system/stabled.service -# 4. Reload and restart +# 4. 重新加载和重启 sudo systemctl daemon-reload sudo systemctl restart ${SERVICE_NAME} ``` ### 内存问题 -#### 问题:内存不足(OOM)导致进程被杀 +#### 问题:内存不足 (OOM) 终止 **症状:** -``` +```text stabled.service: Main process exited, code=killed, status=9/KILL ``` **解决方案:** ```bash -# 1. Check memory usage +# 1. 检查内存使用情况 free -h dmesg | grep -i "killed process" -# 2. Add swap space +# 2. 添加交换空间 sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab -# 3. Optimize memory usage +# 3. 优化内存使用 cat >> ~/.stabled/config/app.toml < $OUTPUT_DIR/system.txt df -h >> $OUTPUT_DIR/system.txt free -h >> $OUTPUT_DIR/system.txt -# Service status +# 服务状态 systemctl status ${SERVICE_NAME} --no-pager > $OUTPUT_DIR/service-status.txt -# Recent logs +# 最近日志 sudo journalctl -u ${SERVICE_NAME} --since "1 hour ago" > $OUTPUT_DIR/recent-logs.txt -# Config files (remove sensitive data) +# 配置文件 (删除敏感数据) grep -v "priv" ~/.stabled/config/config.toml > $OUTPUT_DIR/config.toml grep -v "priv" ~/.stabled/config/app.toml > $OUTPUT_DIR/app.toml -# Node status +# 节点状态 curl -s localhost:26657/status > $OUTPUT_DIR/node-status.json 2>/dev/null -# Create archive +# 创建归档 tar -czf $OUTPUT_DIR.tar.gz $OUTPUT_DIR/ -echo "Debug info collected: $OUTPUT_DIR.tar.gz" -echo "Share this file when requesting support" +echo "调试信息已收集: $OUTPUT_DIR.tar.gz" +echo "请求支持时请共享此文件" ``` ## 后续步骤 -- 查看[监控设置](/cn/how-to/monitor-node)以预防问题 -- 查看[升级指南](/cn/how-to/upgrade-node)了解特定版本的问题 +- 查看 [监控设置](/cn/how-to/monitor-node) 以预防问题 +- 检查 [升级指南](/cn/how-to/upgrade-node) 以了解特定版本问题 diff --git a/docs/pages/cn/how-to/use-system-modules.mdx b/docs/pages/cn/how-to/use-system-modules.mdx index 64082c5..09382f3 100644 --- a/docs/pages/cn/how-to/use-system-modules.mdx +++ b/docs/pages/cn/how-to/use-system-modules.mdx @@ -1,44 +1,44 @@ --- source_path: how-to/use-system-modules.mdx -source_sha: 20a3d686672800eb94c39601d0f332f12eff44cb +source_sha: cfd6ec43ac3c766ae5fdb7d0007a1cb6671ad955 title: "使用系统模块" -description: "通过最小化 ABI 和可运行的示例,从 Solidity 和 ethers.js 调用 Stable 的 Bank、Distribution 和 Staking 预编译合约。" +description: "通过最少的 ABI 和工作示例,从 Solidity 和 ethers.js 调用 Stable 的银行、分配和质押预编译。" diataxis: "how-to" --- # 使用系统模块 -Stable 通过位于固定地址的**预编译合约(precompiled contracts)**暴露协议层的结算逻辑。这些预编译合约让 EVM 代码可以调用 Stable SDK 模块(质押、奖励分发、STABLE 代币操作),而无需重新实现它们。由于它们运行在协议层,因此比等价的 Solidity 实现显著更省 gas。 +Stable 通过固定地址的**预编译合约**公开协议级结算逻辑。预编译合约允许 EVM 代码调用 Stable SDK 模块(质押、奖励分配、STABLE 代币操作),而无需重新实现它们。由于它们在协议级别运行,因此比同等的 Solidity 实现效率更高,消耗的 Gas 更少。 -本指南展示了如何同时从 Solidity 和 ethers.js 调用预编译合约,以及何时应该使用它而非普通合约。 +本指南介绍了如何从 Solidity 和 ethers.js 调用预编译合约,以及何时使用预编译合约而不是常规合约。 :::note -**概念**:关于系统模块的作用以及它们为何是预编译合约,请参阅[系统模块](/cn/explanation/system-modules-overview)。关于各模块的方法签名和事件,请参阅[系统模块参考](/cn/reference/system-modules-api-overview)。 +**概念**:有关系统模块的功能和为何它们是预编译合约,请参阅[系统模块概述](/cn/explanation/system-modules-overview)。有关每个模块的方法签名和事件,请参阅[系统模块参考](/cn/reference/system-modules-api-overview)。 ::: -## 暴露了哪些内容 +## 开放的功能 -| **模块** | **预编译地址** | **用途** | +| **模块** | **预编译合约地址** | **用途** | | :--- | :--- | :--- | -| Bank | `0x0000000000000000000000000000000000001003` | STABLE 代币转账和余额操作 | -| Distribution | `0x0000000000000000000000000000000000000801` | 领取质押奖励、奖励查询、佣金管理 | -| Staking | `0x0000000000000000000000000000000000000800` | 委托、解除委托、重新委托、验证人查询 | -| Gov | `0x0000000000000000000000000000000000000805` | 提案、计票结果和链上投票记录 | -| Slashing | `0x0000000000000000000000000000000000000806` | 验证人签名信息和在线时长 | -| StableSystem | `0x0000000000000000000000000000000000009999` | 为系统交易(解绑完成)发出 EVM 事件 | +| Bank (银行) | `0x0000000000000000000000000000000000001003` | STABLE 代币转账和余额操作 | +| Distribution (分配) | `0x0000000000000000000000000000000000000801` | 领取质押奖励、奖励查询、佣金管理 | +| Staking (质押) | `0x0000000000000000000000000000000000000800` | 委托、解除委托、重新委托、验证者查询 | +| Gov (治理) | `0x0000000000000000000000000000000000000805` | 提案、计票结果和链上投票记录 | +| Slashing (罚没) | `0x0000000000000000000000000000000000000806` | 验证者签名信息和正常运行时间 | +| StableSystem | `0x0000000000000000000000000000000000009999` | 系统交易的 EVM 事件 emission(解除绑定完成) | -以上所有内容都可以从任何 EVM 合约或链下客户端调用。这些地址是固定的,在主网和测试网上完全相同。 +所有这些都可以从任何 EVM 合约或链下客户端调用。这些地址是稳定的,在主网和测试网上都相同。 -## 何时调用预编译合约 vs 普通合约 +## 何时调用预编译合约与常规合约 -- **使用预编译合约**:当操作对应于某个 Stable SDK 模块时,例如质押、奖励分发、STABLE 代币操作。调用预编译合约既更便宜,也是触发协议层行为的唯一方式。 -- **使用普通合约**:当操作属于应用逻辑时,例如托管、定价、访问控制。如果你需要自定义授权或验证,可将预编译合约的调用封装在你自己的合约中。 +- **在以下情况下使用预编译合约**:当操作映射到 Stable SDK 模块时:质押、奖励分配、STABLE 代币操作。调用预编译合约更便宜,并且是触发协议级行为的唯一方式。 +- **在以下情况下使用常规合约**:当操作是应用程序逻辑时:托管、定价、访问控制。如果您需要自定义授权或验证,请将预编译合约调用包装在您自己的合约中。 -预编译合约并不是应用合约的替代品。它们是进入底层协议的稳定接口。 +预编译合约不能替代应用程序合约。它们是底层协议的稳定接口。 ## 从 Solidity 调用 -为你需要的方法声明一个接口,然后像调用已部署合约一样调用预编译合约。 +为所需方法声明一个接口,然后像调用已部署合约一样调用预编译合约。 ```solidity // SPDX-License-Identifier: MIT @@ -87,15 +87,15 @@ contract StakingHelper { } ``` -使用 Foundry 或 Hardhat 编译并部署。预编译地址被固化到合约的常量槽中,因此部署后无需额外配置。 +使用 Foundry 或 Hardhat 编译和部署。预编译合约地址在合约中固定不变,因此部署后无需任何额外配置。 ```solidity -// SAFE: precompile address is fixed on Stable and never changes. +// SAFE: 预编译合约地址在 Stable 上固定且永不改变。 ``` ## 从 ethers.js 调用 -对于链下客户端,将同样的接口声明为最小化 ABI,并实例化一个指向预编译地址的合约。 +对于链下客户端,声明相同的接口作为最小 ABI,并实例化指向预编译地址的合约。 ```typescript // queryDelegation.ts @@ -133,9 +133,9 @@ Delegation balance: 1000.0 STABLE ## 订阅系统交易事件 -某些 Stable SDK 操作(例如解绑完成)本身不会自然地发出 EVM 事件。Stable 通过**系统交易(system transactions)**来填补这一空白:由验证人生成的交易会调用 `StableSystem` 预编译合约,在下一个区块中发出标准的 EVM 事件。 +一些 Stable SDK 操作(例如解除绑定完成)不会自然地发出 EVM 事件。Stable 通过**系统交易**弥补了这一空白:验证者生成的交易调用 `StableSystem` 预编译合约,以便在下一个区块期间发出标准 EVM 事件。 -要监听 `UnbondingCompleted`,请像监听任何 ERC-20 `Transfer` 一样,在该预编译地址上进行订阅。 +要监视 `UnbondingCompleted`,请像监听 ERC-20 `Transfer` 事件一样订阅预编译合约地址。 ```typescript // watchUnbonding.ts @@ -173,19 +173,19 @@ Amount: 100.0 STABLE Tx: 0x12ab... ``` -关于完整的系统交易机制以及按用户筛选 / 历史查询的模式,请参阅[追踪解绑完成](/cn/how-to/track-unbonding)。 +有关完整的系统交易机制以及按用户筛选/历史查询模式,请参阅[跟踪解除绑定完成情况](/cn/how-to/track-unbonding)。 ## 各模块参考 -每个预编译合约的完整方法列表、事件和授权规则都在其对应的参考页面中。 +每个预编译合约的完整方法列表、事件和授权规则都可以在其参考页面中找到。 -- [Bank 预编译合约](/cn/reference/bank-module-api):STABLE 代币转账和供应量查询。 -- [Distribution 预编译合约](/cn/reference/distribution-module-api):奖励领取和佣金。 -- [Staking 预编译合约](/cn/reference/staking-module-api):委托、解除委托、重新委托、验证人查询。 +- [银行预编译合约](/cn/reference/bank-module-api):STABLE 代币转账和供应查询。 +- [分配预编译合约](/cn/reference/distribution-module-api):奖励领取和佣金。 +- [质押预编译合约](/cn/reference/staking-module-api):委托、解除委托、重新委托、验证者查询。 - [系统交易](/cn/reference/system-transactions-api):StableSystem 事件格式和授权。 -## 推荐的后续阅读 +## 下一步建议 -- [**追踪解绑完成**](/cn/how-to/track-unbonding) — 订阅通过 StableSystem 预编译合约发出的 UnbondingCompleted 事件。 -- [**系统模块参考**](/cn/reference/system-modules-api-overview) — 直接查看各模块的 ABI、方法签名和事件结构。 -- [**系统模块概念**](/cn/explanation/system-modules-overview) — 理解 Stable 为何通过预编译合约暴露 SDK 模块。 +- [**跟踪解除绑定完成情况**](/cn/how-to/track-unbonding):订阅通过 StableSystem 预编译合约发出的 `UnbondingCompleted` 事件。 +- [**系统模块参考**](/cn/reference/system-modules-api-overview):跳转到各模块的 ABI、方法签名和事件模式。 +- [**系统模块概念**](/cn/explanation/system-modules-overview):了解 Stable 为什么通过预编译合约公开 SDK 模块。 diff --git a/docs/pages/cn/how-to/verify-contract.mdx b/docs/pages/cn/how-to/verify-contract.mdx index 6d59b63..9e32d1f 100644 --- a/docs/pages/cn/how-to/verify-contract.mdx +++ b/docs/pages/cn/how-to/verify-contract.mdx @@ -1,24 +1,24 @@ --- source_path: how-to/verify-contract.mdx -source_sha: 830fdc192d492e9e07e95fd6c0cf3bde9df9d2cd +source_sha: 6cc73e10bb88685960bc61fa08f4942073bc61bc title: "验证智能合约" -description: "使用 forge verify-contract 在 Stablescan 上验证你的 Stable 合约源代码,让用户可以读取并与之交互。" +description: "使用 forge verify-contract 在 Stablescan 上验证您的 Stable 合约源代码,以便用户可以读取和与其交互。" diataxis: "how-to" --- # 验证智能合约 -验证会将合约的源代码上传到区块浏览器,并证明它编译后与已部署的字节码一致。一旦完成验证,用户就可以在 Stablescan 上读取状态、调用函数并审计源代码,而无需重新托管你的代码。本指南将带你完成在 Stable 上验证由 Foundry 部署的合约。 +验证会将您的合约源代码上传到区块浏览器,并证明其编译为已部署的字节码。验证后,用户无需重新托管您的代码,即可在 Stablescan 上读取状态、调用函数和审计源代码。本指南将介绍如何在 Stable 上验证 Foundry 部署的合约。 -## 前置条件 +## 先决条件 -- 一个已部署在 Stable 测试网或主网上的合约。如果你尚未部署,请参阅[部署智能合约](/cn/tutorial/smart-contract)。 -- 已安装 Foundry(PATH 中可使用 `forge`)。 +- 已在 Stable 测试网或主网上部署的合约。如果您尚未部署,请参阅[部署智能合约](/cn/tutorial/smart-contract)。 +- 已安装 Foundry(`forge` 在您的 PATH 中可用)。 - 来自 `forge create` 输出的已部署合约地址。 -## 1. 确认已部署的地址 +## 1. 确认已部署地址 -确保你拥有之前部署时的 `Deployed to` 地址。在[部署智能合约](/cn/tutorial/smart-contract)流程中,这是 `forge create` 之后打印出的值。 +确保您拥有之前部署的“部署到”地址。在[部署智能合约](/cn/tutorial/smart-contract)流程中,这是 `forge create` 后打印的值。 ```bash cast code 0xDeployedContractAddress --rpc-url https://rpc.testnet.stable.xyz | head -c 20 @@ -28,11 +28,11 @@ cast code 0xDeployedContractAddress --rpc-url https://rpc.testnet.stable.xyz | h 0x6080604052600436... ``` -非空的字节码确认该合约已部署在该地址。 +非空字节码确认合约已部署在该地址。 ## 2. 运行 forge verify-contract -Foundry 的验证流程会将你的源代码提交给 Stablescan 验证器。 +Foundry 的验证流程将您的源代码提交给 Stablescan 验证器。 ```bash forge verify-contract \ @@ -58,30 +58,30 @@ Details: `Pass - Verified` Contract successfully verified ``` -`--watch` 会阻塞直到验证完成,这样你就无需轮询。在主网上,将 chain ID 换成 `988`,验证器 URL 换成 `https://stablescan.xyz/api`。 +`--watch` 会一直阻塞直到验证完成,这样您就不需要轮询。在主网上,将链 ID 更改为 `988`,验证器 URL 更改为 `https://stablescan.xyz/api`。 :::note -**构造函数参数**:如果你的合约接受构造函数参数,请在命令中添加 `--constructor-args $(cast abi-encode "constructor(uint256,address)" 42 0xSomeAddress)`。如果没有这个标志,任何带有非空构造函数的合约都会验证失败。 +**构造函数参数**:如果您的合约接受构造函数参数,请将 `--constructor-args $(cast abi-encode "constructor(uint256,address)" 42 0xSomeAddress)` 添加到命令中。如果没有此标志,任何带有非空构造函数的合约都将验证失败。 ::: ## 3. 在 Stablescan 上确认验证 -在浏览器中打开合约页面。 +在浏览器上打开合约页面。 ```text https://testnet.stablescan.xyz/address/0xDeployedContractAddress ``` -此时 **Contract** 标签页应该会显示源代码、一个绿色的 "Verified" 徽章以及完整的 ABI。用户可以在 **Read Contract** 下读取状态,并在 **Write Contract** 下发送交易。 +**合约**选项卡现在应该显示源代码,一个绿色的“已验证”徽章,以及完整的 ABI。用户可以在**读取合约**下读取状态,并在**写入合约**下发送交易。 -## 故障排查 +## 故障排除 -- **"Bytecode does not match"**:你的源代码编译出的字节码与已部署的不同。最常见的原因是 Solidity 版本或优化器设置不匹配。显式传入 `--compiler-version` 和 `--optimizer-runs` 以匹配你的 `foundry.toml`。 -- **"GUID not found"**:验证器尚未注册你的提交。使用 `--watch` 重新运行,或手动检查响应中打印的 URL。 -- **合约使用了库**:为每个链接的库添加 `--libraries src/Lib.sol:Lib:0xDeployedLibAddress`。 +- **“字节码不匹配”**:您的源代码编译成与已部署代码不同的字节码。这通常是由于 Solidity 版本或优化器设置不匹配造成的。明确传递 `--compiler-version` 和 `--optimizer-runs` 以匹配您的 `foundry.toml`。 +- **“GU ID 未找到”**:验证器尚未注册您的提交。使用 `--watch` 重新运行或手动检查响应中打印的 URL。 +- **合约使用库**:为每个链接的库添加 `--libraries src/Lib.sol:Lib:0xDeployedLibAddress`。 -## 推荐的后续步骤 +## 下一步推荐 -- [**索引合约事件**](/cn/how-to/index-contract) — 使用 ethers.js 订阅链上事件并构建实时事件流。 -- [**部署智能合约**](/cn/tutorial/smart-contract) — 搭建一个全新的 Foundry 项目并部署到 Stable 测试网。 -- [**JSON-RPC 参考**](/cn/reference/json-rpc-api) — 查看 Stable 支持哪些 `eth_*` 方法用于链上交互。 +- [**索引合约事件**](/cn/how-to/index-contract):使用 ethers.js 订阅链上事件并构建实时事件流。 +- [**部署智能合约**](/cn/tutorial/smart-contract):搭建一个新的 Foundry 项目并部署到 Stable 测试网。 +- [**JSON-RPC 参考**](/cn/reference/json-rpc-api):查看 Stable 支持哪些 `eth_*` 方法用于链上交互。 diff --git a/docs/pages/cn/how-to/work-with-usdt-gas.mdx b/docs/pages/cn/how-to/work-with-usdt-gas.mdx index dd15cdb..0b53cf4 100644 --- a/docs/pages/cn/how-to/work-with-usdt-gas.mdx +++ b/docs/pages/cn/how-to/work-with-usdt-gas.mdx @@ -1,34 +1,34 @@ --- source_path: how-to/work-with-usdt-gas.mdx -source_sha: 8b0a60e8fdc7a504803325125750cc39877974d5 -title: "将 USDT0 作为 gas 使用" -description: "将以太坊交易构建迁移到 Stable:将优先费设为零,以 USDT0 读取 baseFee,并以 USDT0 计价 value。" +source_sha: ec41da713b012d64269926acdd594bc6255cd981 +title: "将 USDT0 作为 Gas 进行操作" +description: "将以太坊交易结构移植到 Stable:将优先费用设置为零,以 USDT0 读取基本费用,并以 USDT0 计价。" diataxis: "how-to" --- -# 将 USDT0 作为 gas 使用 +# 将 USDT0 作为 Gas 进行操作 -在 Stable 上,USDT0 既是链的原生资产,也是一种 ERC-20 代币。gas 代币是 USDT0,而不是单独的原生资产。只要调整三件事,标准的以太坊 gas 估算就能正常工作:`maxPriorityFeePerGas` 始终为 `0`、`baseFee` 以 USDT0 计价,以及原生转账中的 `value` 字段携带的是 USDT0(而非 ETH)。 +在 Stable 上,USDT0 既是链的原生资产,也是 ERC-20 代币。Gas 代币是 USDT0,而不是单独的原生资产。标准以太坊 Gas 估算工作原理如下,但您需要调整三点:`maxPriorityFeePerGas` 始终为 `0`,`baseFee` 以 USDT0 计价,并且原生转账中的 `value` 字段承载 USDT0(而不是 ETH)。 -本指南展示如何在 Stable 上正确构建交易,以及在迁移以太坊代码时需要改动什么。 +本指南展示了如何在 Stable 上正确构建交易以及移植以太坊代码时需要更改的内容。 ## 与以太坊相比的变化 | **字段** | **以太坊** | **Stable** | | :--- | :--- | :--- | | Gas 代币 | ETH | USDT0 | -| `maxPriorityFeePerGas` | 用于排序 | 忽略(设为 `0`) | +| `maxPriorityFeePerGas` | 用于排序 | 忽略(设置为 `0`) | | `baseFeePerGas` | 以 ETH 计价 | 以 USDT0 计价 | -| `value`(原生转账) | 转移 ETH | 转移 USDT0 | +| `value`(原生转账) | 转账 ETH | 转账 USDT0 | | EIP-1559 交易格式 | 支持 | 支持 | -| `eth_estimateGas`、`eth_gasPrice` | 支持 | 支持 | +| `eth_estimateGas`, `eth_gasPrice` | 支持 | 支持 | | `eth_maxPriorityFeePerGas` | 返回小费 | 返回 `0` | -由于交易格式没有变化,现有的 ethers.js、viem、Hardhat 和 Foundry 代码无需改动即可在 Stable 上运行。区别在于你如何*计算* gas 字段,而不是如何对它们进行编码。 +因为交易格式不变,所以现有的 ethers.js、viem、Hardhat 和 Foundry 代码可以在 Stable 上运行而无需更改。区别在于您如何*计算* Gas 字段,而不是如何编码它们。 ## 构建交易 -获取 base fee,将 `maxPriorityFeePerGas` 设为 `0`,并将 base fee 翻倍作为安全余量。 +获取基本费用,将 `maxPriorityFeePerGas` 设置为 `0`,并将基本费用加倍作为安全余量。 ```typescript // sendNative.ts @@ -67,11 +67,11 @@ Gas used: 21000 Effective gas price: 1000000000 (USDT0 wei-equivalent) ``` -有效 gas 价格是一个以 USDT0 计价的值。在 `1 gwei` 时,一笔 21,000 gas 的原生转账大约花费 `0.000021` USDT0。 +有效 Gas 价格是以 USDT0 计价的值。以 `1 gwei` 计算,21,000 Gas 的原生转账大约需要 `0.000021` USDT0。 -## 以 USDT0 估算 gas 成本 +## 估算 USDT0 中的 Gas 成本 -`eth_estimateGas` 和 `eth_gasPrice` 的行为与以太坊完全相同。由于 USDT0 是 gas 代币,结果已经以 USDT0 计价。 +`eth_estimateGas` 和 `eth_gasPrice` 的行为与以太坊完全相同。结果已经是 USDT0,因为它是 Gas 代币。 ```typescript // estimate.ts @@ -98,23 +98,23 @@ Estimated fee: 0.000021 USDT0 ``` :::warning -`eth_maxPriorityFeePerGas` 在 Stable 上始终返回 `0`。如果你的钱包或 SDK 将 RPC 返回的优先费加在 base fee 之上,它仍然有效,但显示单独小费的费用界面将显示 `0`,应当隐藏。 +`eth_maxPriorityFeePerGas` 在 Stable 上始终返回 `0`。如果您的钱包或 SDK 在基本费用之上添加了 RPC 返回的优先费用,它仍然有效,但显示单独小费的费用界面将显示 `0`,应将其隐藏。 ::: ## 工具配置 -- **Hardhat / Foundry**:无需特殊配置。标准 EVM 设置即可工作。如果你的配置显式设置了优先费,请将其设为 `0`。 -- **钱包**:隐藏或禁用优先小费的输入字段。显示它会产生误导,因为该值对排序或打包没有任何影响。 -- **监控**:费用分析仪表板不应绘制优先费图表。它们在 Stable 上始终为零。 +- **Hardhat / Foundry**:无需特殊配置。标准 EVM 设置即可。如果您的配置明确设置了优先费用,请将其设置为 `0`。 +- **钱包**:隐藏或禁用优先小费输入字段。显示它具有误导性,因为该值对排序或包含没有影响。 +- **监控**:费用分析仪表板不应绘制优先费用图表。它们在 Stable 上始终为零。 -## 从以太坊迁移时的常见错误 +## 从以太坊移植时常见的错误 -- **应用以 ETH 计价的小费**:从以太坊复制优先费常量并不会带来更快的打包。Stable 仅按 base fee 对交易排序。 -- **将 `value` 当作 ETH**:原生转账的 `value` 是 USDT0。不要通过 ETH/USD 价格进行换算。 -- **硬编码费用上限**:应根据实时的 `baseFeePerGas` 设置 `maxFeePerGas`(例如 `baseFee * 2`),而不是固定值,这样当 base fee 上升时交易才不会卡住。 +- **应用以 ETH 计价的小费**:复制以太坊的优先费用常量不会导致更快的包含。Stable 仅按基本费用对交易进行排序。 +- **将 `value` 视为 ETH**:原生转账的 `value` 是 USDT0。不要通过 ETH/USD 价格进行转换。 +- **硬编码费用上限**:从实时 `baseFeePerGas`(例如 `baseFee * 2`)设置 `maxFeePerGas`,而不是固定值,这样当基本费用上涨时交易不会停滞。 -## 下一步推荐 +## 推荐阅读 -- [**Gas 定价参考**](/cn/reference/gas-pricing-api) — 完整的 base-fee 模型、EIP-1559 格式以及 `eth_*` 方法行为。 -- [**零 gas 交易**](/cn/how-to/zero-gas-transactions) — 让应用通过 Gas 豁免来承担 gas。 -- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior) — 余额对账以及针对 USDT0 双重角色的合约设计。 +- [**Gas 定价参考**](/cn/reference/gas-pricing-api):完整的基本费用模型、EIP-1559 格式以及 `eth_*` 方法行为。 +- [**零 Gas 交易**](/cn/how-to/zero-gas-transactions):允许应用程序通过 Gas Waivers 支付 Gas。 +- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior):USDT0 双重角色的余额核对和合约设计。 diff --git a/docs/pages/cn/how-to/zero-gas-transactions.mdx b/docs/pages/cn/how-to/zero-gas-transactions.mdx index c059d9b..dea977d 100644 --- a/docs/pages/cn/how-to/zero-gas-transactions.mdx +++ b/docs/pages/cn/how-to/zero-gas-transactions.mdx @@ -1,56 +1,56 @@ --- source_path: how-to/zero-gas-transactions.mdx -source_sha: 169da924be4764e0ff38c2b0af2e580ed4508070 -title: "零 gas 交易" -description: "使用 Stable 的 Gas Waiver 发送一笔不需要用户支付 gas 的 USDT0 转账,并验证收据显示费用为零。" +source_sha: e339e4b5be06cdca1384f6b51ea54df697194698 +title: "零 Gas 交易" +description: "使用 Stable 的 Gas Waiver 发送一笔用户无需支付 Gas 的 USDT0 转账,并验证收据是否显示零费用。" diataxis: "how-to" --- -# 零 gas 交易 +# 零 Gas 交易 -Gas Waiver 让应用程序可以代表用户承担 gas 费用。用户使用 `gasPrice = 0` 签署一笔交易,由治理注册的 waiver 将其包装,验证者以零成本为用户执行该调用。本指南将带你完成一笔符合条件的转账,展示如何验证 gas 已被豁免,并解释 waiver 涵盖与不涵盖的范围。 +Gas Waiver 允许应用程序代表用户支付 Gas。用户使用 `gasPrice = 0` 签署交易,经治理注册的豁免机制会封装该交易,验证者将以零成本为用户执行调用。本指南将引导您完成一笔符合条件的转账,展示如何验证 Gas 是否已被豁免,并解释豁免所涵盖和不涵盖的范围。 :::note -**概念**:关于包装交易机制、授权模型和安全保证,请参阅 [Gas waiver](/cn/explanation/gas-waiver) 和 [Gas waiver 协议参考](/cn/reference/gas-waiver-api)。 +**概念**:有关封装交易机制、授权模型和安全保证,请参阅[Gas 豁免](/cn/explanation/gas-waiver)和[Gas 豁免协议参考](/cn/reference/gas-waiver-api)。 ::: -## 你将构建的内容 +## 您将构建什么 -一个两脚本流程,通过托管的 Waiver Server 提交一笔 USDT0 转账,获取收据,并确认 `gasPrice = 0`。 +一个包含两个脚本的流程,通过托管的 Waiver Server 提交 USDT0 转账,获取收据,并确认 `gasPrice = 0`。 ### 演示 ```text -step 1. Connect wallet, balance displayed as 0.01 USDT0 +步骤 1. 连接钱包,余额显示 0.01 USDT0 -step 2. Send transaction via Gas Waiver → [Run] +步骤 2. 通过 Gas Waiver 发送交易 → [运行] -step 3. Result - tx: 0x8f3a...2d41 - Gas fee paid by you: 0.000000 USDT0 - Balance after: 0.01 USDT0 +步骤 3. 结果 + 交易哈希: 0x8f3a...2d41 + 您支付的 Gas 费用: 0.000000 USDT0 + 交易后余额: 0.01 USDT0 ``` -## waiver 何时生效 +## 豁免适用情况 -当以下所有条件均满足时,交易符合条件: +当以下所有条件都满足时,交易才符合条件: - 用户使用 `gasPrice = 0` 签署内部交易。 -- 提交者是治理注册的 waiver 地址。 -- 目标 `to` 地址和方法选择器位于 waiver 的 `AllowedTarget` 策略中。 -- 包装交易发送到标记地址 `0x000000000000000000000000000000000000f333`,且 `value = 0` 和 `gasPrice = 0`。 +- 提交者是经过治理注册的豁免地址。 +- 目标 `to` 地址和方法选择器位于豁免的 `AllowedTarget` 策略中。 +- 封装交易发送到标记地址 `0x000000000000000000000000000000000000f333`,且 `value = 0` 和 `gasPrice = 0`。 -如果其中任何一项不满足,验证者将拒绝该包装交易,不执行内部调用。未列入 `AllowedTarget` 的合约调用不在涵盖范围内。无法进行任意的自助 waiver;每个 waiver 都必须通过验证者治理注册。 +如果其中任何一个失败,验证者将拒绝封装交易,而不执行内部调用。未在 `AllowedTarget` 中列出的合约调用不受涵盖。任意的自助豁免是不可能的;每个豁免都必须通过验证者治理进行注册。 -## 前置条件 +## 先决条件 -- Waiver Server 的 API 密钥,由 Stable 团队签发。 -- 已在 waiver 的 `AllowedTarget` 策略上注册的目标合约地址和方法选择器。 -- 一个测试网上的用户钱包,无需 USDT0 用于支付 gas。 +- Stable 团队颁发的 Waiver Server API 密钥。 +- 目标合约地址和方法选择器已在豁免的 `AllowedTarget` 策略上注册。 +- 测试网上拥有用户钱包,无需 USDT0 用于 Gas。 ## 步骤 1:签署符合条件的 InnerTx -用户使用 `gasPrice = 0` 签署一笔标准交易。在本示例中,该调用是一笔 USDT0 `transfer`,这是应用程序承担 gas 流程中常见的 `AllowedTarget`。 +用户使用 `gasPrice = 0` 签署标准交易。在此示例中,调用是 USDT0 `transfer`,这是应用程序涵盖的 Gas 流的常见 `AllowedTarget`。 ```typescript // config.ts @@ -113,12 +113,12 @@ Signed InnerTx: 0xf8a8...c1 ``` :::warning -`gasPrice` 必须为 `0`。非零值会导致 waiver 服务器拒绝提交,验证者拒绝包装交易。 +`gasPrice` 必须为 `0`。非零值会导致豁免服务器拒绝提交,并导致验证者拒绝封装交易。 ::: ## 步骤 2:通过 Waiver Server 提交 -Waiver Server 会包装已签署的内部交易并广播。你需要一个服务器签发的 API 密钥。 +Waiver Server 会封装签名的内部交易并广播它。您需要一个服务器颁发的 API 密钥。 ```typescript // submit.ts @@ -162,9 +162,9 @@ npx tsx submit.ts tx confirmed: 0x8f3a...2d41 ``` -## 步骤 3:验证收据显示零 gas +## 步骤 3:验证收据显示零 Gas -获取收据并确认 `effectiveGasPrice` 为 0。这就是用户未支付任何 gas 的密码学证明。 +获取收据并确认 `effectiveGasPrice` 为 0。这是用户未支付 Gas 的加密证据。 ```typescript // verify.ts @@ -192,18 +192,18 @@ Effective gas price: 0 Gas fee paid: 0 USDT0 (wei-equivalent) ``` -`effectiveGasPrice` 为 `0` 确认了该交易在已注册的 waiver 下执行,且用户未被收费。 +`effectiveGasPrice` 为 `0` 确认交易是在已注册的豁免下执行的,并且未向用户收取费用。 ## Gas Waiver 不涵盖的范围 -- **`AllowedTarget` 之外的合约**:任意合约调用不在涵盖范围内。每个目标都通过治理按 waiver 进行限定。 -- **用户提交的包装交易**:如果用户直接提交到 `0x...f333`,将会失败。只有已注册的 waiver 地址才能进行包装。 -- **费用提取**:验证者不接受内部交易或包装交易上任何非零的 `gasPrice`。 +- **`AllowedTarget` 之外的合约**:任意合约调用不在此列。每个目标都通过治理按豁免范围确定。 +- **用户提交的封装交易**:如果用户直接提交给 `0x...f333`,则会失败。只有注册的豁免地址才能进行封装。 +- **费用提取**:验证者不接受内部或封装交易中的非零 `gasPrice`。 -关于完整的策略模型和按 waiver 的范围规则,请参阅 [Gas waiver 协议](/cn/reference/gas-waiver-api)。 +有关完整的策略模型和每个豁免的范围规则,请参阅[Gas 豁免协议](/cn/reference/gas-waiver-api)。 -## 推荐的后续步骤 +## 下一步建议 -- [**集成 Waiver Server**](/cn/how-to/integrate-gas-waiver) — 完整的 API 参考、批量提交、错误码和 NDJSON 流式传输。 -- [**自托管 Gas Waiver**](/cn/how-to/self-hosted-gas-waiver) — 注册你自己的 waiver 地址,无需托管 API 即可广播包装交易。 -- [**Gas waiver 协议**](/cn/reference/gas-waiver-api) — 阅读完整规范:标记路由、包装格式、治理控制。 +- [**集成 Waiver Server**](/cn/how-to/integrate-gas-waiver):完整的 API 参考、批量提交、错误代码和 NDJSON 流。 +- [**自托管 Gas Waiver**](/cn/how-to/self-hosted-gas-waiver):注册您自己的豁免地址,无需托管 API 即可广播封装交易。 +- [**Gas 豁免协议**](/cn/reference/gas-waiver-api):阅读完整规范:标记路由、封装格式、治理控制。 diff --git a/docs/pages/cn/index.mdx b/docs/pages/cn/index.mdx index 7778d29..fa696db 100755 --- a/docs/pages/cn/index.mdx +++ b/docs/pages/cn/index.mdx @@ -1,34 +1,34 @@ --- source_path: index.mdx -source_sha: 4f3855b4d75c262f0f87dc286a2dce4c7b7ba36a +source_sha: 1245c6893961ce66cd4dd228ab22312760d5f5b4 title: "集成 Stable" -description: "选择你正在构建的功能。下面的每条路径都能在几分钟内引导你完成一份可在测试网运行的指南。" +description: "选择您要构建的功能。每条路径都会在几分钟内引导您完成测试网上的可运行指南。" diataxis: "explanation" --- # 集成 Stable -Stable 是一个 Layer 1,其中 USDT0 既是原生 gas 代币,也是一种 ERC-20。单槽最终性、亚秒级出块时间,以及完整的 EVM 兼容性。你只需带上你的钱包、助记词和 USDT0。 +Stable 是一个 Layer 1,其中 USDT0 既是原生 Gas 代币,也是 ERC-20。单槽确定性,亚秒级区块时间,并完全兼容 EVM。您只需携带您的钱包、助记词和 USDT0。 -选择你正在构建的功能。下面的每条路径都能在几分钟内引导你完成一份可在测试网运行的指南。 +选择您要构建的功能。下面每条路径都会在几分钟内引导您完成测试网上的可运行指南。 -## 选择你的路径 +## 选择您的路径 -- [**账户**](/cn/explanation/accounts-overview) — 钱包、EIP-7702 委托、会话密钥和支出限额。一流地支持用户账户和代理账户。 -- [**支付**](/cn/explanation/payments-overview) — 发送 USDT0,构建 P2P 钱包、周期性订阅、发票结算以及按调用付费的 API。 -- [**合约**](/cn/explanation/contracts-overview) — 部署、验证和索引合约。从 Solidity 调用 Bank、Distribution 和 Staking 预编译合约。 -- [**AI / 代理**](/cn/explanation/agent-settlement) — 将 MCP 服务器和代理技能接入 AI 编辑器。为自主代理按请求为 API 定价。 -- [**基础设施**](/cn/explanation/integrate-overview) — Gas 豁免服务、生态系统提供商(桥、预言机、出入金通道)、网络信息和节点运维。 -- [**学习**](/cn/explanation/learn-overview) — 架构、USDT0 行为、用例叙述,以及 Ethereum 到 Stable 的参考资料。 +- [**账户**](/cn/explanation/accounts-overview):钱包、EIP-7702 委托、会话密钥和消费限额。对用户和代理账户的一流支持。 +- [**支付**](/cn/explanation/payments-overview):发送 USDT0、构建 P2P 钱包、定期订阅、发票结算和按次付费 API。 +- [**合约**](/cn/explanation/contracts-overview):部署、验证和索引合约。从 Solidity 调用 Bank、Distribution 和 Staking 预编译。 +- [**AI / 代理**](/cn/explanation/agent-settlement):将 MCP 服务器和代理技能连接到 AI 编辑器。为自主代理按请求定价 API。 +- [**基础设施**](/cn/explanation/integrate-overview):Gas 豁免服务、生态系统提供商(桥接、预言机、坡道)、网络信息和节点操作。 +- [**学习**](/cn/explanation/learn-overview):架构、USDT0 行为、用例叙述以及 Ethereum 到 Stable 的参考。 -## 五分钟上手 +## 五分钟快速开始 -- [**快速开始**](/cn/tutorial/quick-start) — 连接、从水龙头为钱包注资,并原生发送 0.001 USDT0。 -- [**连接到 Stable**](/cn/reference/connect) — 链 ID、RPC 端点、水龙头和区块浏览器。 -- [**与 Ethereum 的区别**](/cn/explanation/ethereum-comparison) — 从 Ethereum 移植时哪些保持不变、哪些会改变。 +- [**快速开始**](/cn/tutorial/quick-start):连接、从水龙头获取资金,并原生发送 0.001 USDT0。 +- [**连接到 Stable**](/cn/reference/connect):链 ID、RPC 端点、水龙头和区块浏览器。 +- [**与以太坊的区别**](/cn/explanation/ethereum-comparison):从以太坊移植时哪些保持不变,哪些发生变化。 -## 其他内容 +## 其他所有内容 -- **网络状态与版本**:[测试网](/cn/reference/testnet-information) · [主网](/cn/reference/mainnet-information) · [版本历史](/cn/reference/testnet-version-history)。 -- **代币经济学与路线图**:[STABLE 代币经济学](/cn/reference/tokenomics) · [技术路线图](/cn/explanation/technical-roadmap)。 -- **常见问题**:[开发者常见问题](/cn/reference/faq) · [开发者支持](/cn/reference/developer-assistance)。 +- **网络状态和版本**:[测试网](/cn/reference/testnet-information) · [主网](/cn/reference/mainnet-information) · [版本历史](/cn/reference/testnet-version-history)。 +- **代币经济学和路线图**:[STABLE 代币经济学](/cn/reference/tokenomics) · [技术路线图](/cn/explanation/technical-roadmap)。 +- **常见问题**:[开发者常见问题](/cn/reference/faq) · [开发者协助](/cn/reference/developer-assistance)。 diff --git a/docs/pages/cn/reference/connect.mdx b/docs/pages/cn/reference/connect.mdx index 0cc923b..ad41bee 100644 --- a/docs/pages/cn/reference/connect.mdx +++ b/docs/pages/cn/reference/connect.mdx @@ -1,13 +1,11 @@ --- source_path: reference/connect.mdx -source_sha: ae01c8773f19829d94bf98e624e9fd6797ae283b +source_sha: 5499fbd8e32bd54d6d35e5b87182919c7eadd9a3 title: "连接" description: "Stable 的主网和测试网链 ID、RPC 端点、区块浏览器和水龙头。" diataxis: "reference" --- -import { AddToMetaMask } from '../../../components/AddToMetaMask' - # 连接 本页面汇总了连接到 Stable 所需的网络详细信息。 @@ -16,8 +14,8 @@ import { AddToMetaMask } from '../../../components/AddToMetaMask' | **字段** | **值** | | :--- | :--- | -| 网络名称 | Stable Mainnet | -| Chain ID | `988` | +| 网络名称 | Stable 主网 | +| 链 ID | `988` | | 货币符号 | USDT0 | | EVM JSON-RPC | `https://rpc.stable.xyz` | | WebSocket | `wss://rpc.stable.xyz` | @@ -27,43 +25,37 @@ import { AddToMetaMask } from '../../../components/AddToMetaMask' | **字段** | **值** | | :--- | :--- | -| 网络名称 | Stable Testnet | -| Chain ID | `2201` | +| 网络名称 | Stable 测试网 | +| 链 ID | `2201` | | 货币符号 | USDT0 | | EVM JSON-RPC | `https://rpc.testnet.stable.xyz` | | WebSocket | `wss://rpc.testnet.stable.xyz` | | 区块浏览器 | [https://testnet.stablescan.xyz](https://testnet.stablescan.xyz) | -有关第三方 RPC 提供商,请参阅 [RPC 提供商](/cn/reference/rpc-providers)。如需为你预先接入这些端点的类型化客户端,请参阅 [Stable SDK](/cn/explanation/sdk-overview)。 +有关第三方 RPC 提供商,请参阅 [RPC 提供商](/cn/reference/rpc-providers)。有关为您连接这些端点的类型化客户端,请参阅 [Stable SDK](/cn/explanation/sdk-overview)。 ## 速率限制 -公共 RPC 端点(`https://rpc.stable.xyz` 和 `https://rpc.testnet.stable.xyz`)的速率限制为**每个 IP 每 10 秒 1,000 次请求**。超过限制的请求将返回 `HTTP 429`。 +公共 RPC 端点(`https://rpc.stable.xyz` 和 `https://rpc.testnet.stable.xyz`)的速率限制为**每 10 秒每个 IP 1,000 个请求**。超出限制的请求将返回 `HTTP 429`。 -如需更高的吞吐量,请使用[第三方 RPC 提供商](/cn/reference/rpc-providers)。 +若要获得更高的吞吐量,请使用[第三方 RPC 提供商](/cn/reference/rpc-providers)。 :::note -USDT0 作为原生 gas 代币时使用 **18 位小数**(由 `address(x).balance` 返回),作为 ERC-20 代币时使用 **6 位小数**(由 `USDT0.balanceOf(x)` 返回)。这两个接口操作的是同一个底层余额。viem 和 ethers.js 等库报告 18 位小数,因为它们读取的是原生 gas 代币。有关如何协调精度差异的详细信息,请参阅 [USDT0 在 Stable 上的行为](/cn/explanation/usdt0-behavior)。 +USDT0 作为原生 gas 代币(由 `address(x).balance` 返回)使用 **18 位小数**,作为 ERC-20 代币(由 `USDT0.balanceOf(x)` 返回)使用 **6 位小数**。这两个接口对相同的底层余额进行操作。像 viem 和 ethers.js 这样的库报告 18 位小数,因为它们读取的是原生 gas 代币。有关精度差距如何协调的详细信息,请参阅 [Stable 上的 USDT0 行为](/cn/explanation/usdt0-behavior)。 ::: -## 将 Stable 添加到你的钱包 - -如果你使用 MetaMask(或其他注入式 EVM 钱包),只需一键即可添加 Stable。该按钮会调用 `wallet_addEthereumChain`,因此你的钱包会提示你确认下方的网络详细信息。由于 USDT0 是原生 gas 代币,一旦添加网络,你的余额就会自动显示,无需单独导入代币。 - - - -你也可以从 [Chainlist](https://chainlist.org/?search=Stable) 添加 Stable:搜索 "Stable",连接你的钱包,然后点击 **Add to MetaMask**。 +## 将 Stable 添加到您的钱包 -如需改为手动添加 Stable,请打开钱包的网络设置并输入上方表格中的值。必填字段为: +要手动添加 Stable,请打开浏览器钱包的网络设置并输入上表中的值。所需字段为: - **网络名称** - **RPC URL**(EVM JSON-RPC 端点) -- **Chain ID** +- **链 ID** - **货币符号**:`USDT0` ## 验证连接 -通过查询链 ID 来确认你的 RPC 端点是否可访问: +通过查询链 ID 确认您的 RPC 端点可访问: ```bash cast chain-id --rpc-url https://rpc.stable.xyz @@ -87,8 +79,8 @@ cast chain-id --rpc-url https://rpc.testnet.stable.xyz 2201 ``` -## 推荐的后续步骤 +## 接下来推荐 -- [**快速开始**](/cn/tutorial/quick-start):在五分钟内发送你的第一笔测试网交易。 -- [**获取测试网 USDT0**](/cn/how-to/use-faucet):从水龙头为钱包注资,或从 Sepolia 跨链。 -- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior):在针对余额编写代码之前,了解 18/6 位小数的双重角色。 +- [**快速入门**](/cn/tutorial/quick-start):在五分钟内发送您的第一个测试网交易。 +- [**获取测试网 USDT0**](/cn/how-to/use-faucet):从水龙头为钱包注资或从 Sepolia 桥接。 +- [**Stable 上的 USDT0 行为**](/cn/explanation/usdt0-behavior):在您针对余额编写代码之前,请了解 18/6 位小数的双重作用。 diff --git a/docs/pages/cn/reference/developer-assistance.mdx b/docs/pages/cn/reference/developer-assistance.mdx index 1140a79..26400ac 100755 --- a/docs/pages/cn/reference/developer-assistance.mdx +++ b/docs/pages/cn/reference/developer-assistance.mdx @@ -1,33 +1,49 @@ --- source_path: reference/developer-assistance.mdx -source_sha: 740d84fb64ee73630cea7e1fc648dfa8ceea5b19 -title: 开发者支持 -description: 快速获取帮助、官方交流渠道与关键资源。 +source_sha: 2e55049566daa5a3f782c7ca3acee94096762402 +title: 开发者协助 +description: 快速获取帮助、官方沟通渠道以及在 Stable 上进行开发的关键参考位置。 +diataxis: "reference" --- -# 开发者支持 +# 开发者协助 -### 常见问题(FAQ) +## 常见问题解答 -- 如何连接 Stable 网络? - - 使用标准 JSON-RPC 即可,与常见 EVM 工具兼容。 -- 交易费用使用哪种货币? - - 所有交易费用以 USDT0 支付。 -- Stable 是否支持账户抽象? - - 支持。EIP-7702 允许 EOA 临时具备智能账户行为。 -- 如何查看交易结果? - - 通过余额查询、合约状态或事件日志。 -- 如何为 Stable 编写智能合约? - - 使用标准 EVM 工具(如 Solidity + JSON-RPC 库)。 +一个不断增长的以开发者为中心的问题集合,涵盖以下主题: -完整 FAQ 请见文档。 +- 如何连接到 Stable 网络? + - 您可以使用与常见 EVM 工具兼容的标准 JSON-RPC 请求与网络进行交互。 +- 交易费用使用什么货币? + - 您需要支付 USDT0 作为交易费用。除了标准基础 gas 价格外,无需额外的费用参数。 +- 在哪里可以追踪更新? + - 发布和变更日志会告知所有协议和面向开发者的变更。 +- Stable 是否支持账户抽象? + - 是的。EIP-7702 允许 EOA 临时以智能账户行为运行。 + - 请参阅 [EIP-7702 参考](/cn/reference/eip-7702-api)和[账户抽象操作指南](/cn/how-to/account-abstraction)。 +- 在哪里可以看到我的交易结果? + - 一旦包含在区块中,结果可以通过以下方式查看: + - 余额读取 + - 合约状态查询 + - 日志和发出的事件 +- 如何为 Stable 构建智能合约? + - 您可以使用标准的 EVM 开发者工作流,例如: + - 基于 Solidity 的合约 + - JSON-RPC 库与网络交互 + +随着公测网使用过程中常见问题的出现,此页面将不断扩展。 ## 支持渠道 -开发者可直接与 Stable 团队联系以获取技术支持。 +您可以直接与 Stable 团队联系以获得技术协助。 + +- **Discord**:加入开发者频道:https://discord.gg/stablexyz +- **问题报告**:公共仓库开放后将提供说明 -- Discord(开发者频道): https://discord.gg/stablexyz -- 问题反馈: 将会在github repo开放后提供 +社区平台可用后将更新支持联系方式。 -技术支持联系方式将在社区平台上线后持续更新。 +## 下一步推荐 +- [**快速入门**](/cn/tutorial/quick-start):在五分钟内完成您的第一个测试网交易。 +- [**生产就绪**](/cn/how-to/production-readiness):在发布到主网之前验证集成。 +- [**常见问题**](/cn/reference/faq):关于链 ID、端点和入门的常见解答。 diff --git a/docs/pages/cn/reference/eip-7702-api.mdx b/docs/pages/cn/reference/eip-7702-api.mdx index 5078096..e90b816 100644 --- a/docs/pages/cn/reference/eip-7702-api.mdx +++ b/docs/pages/cn/reference/eip-7702-api.mdx @@ -1,6 +1,6 @@ --- source_path: reference/eip-7702-api.mdx -source_sha: ed9c7f3d8305826eb401d45116a49d3adf2cd3f6 +source_sha: e14a186b9b5e856dc39965a4b8358d407e18dcbd title: "EIP-7702" description: "Stable 对 EIP-7702 的支持。EOA 可以将其账户代码设置为现有的智能合约,从而实现批量支付、消费限额和会话密钥。" diataxis: "reference" @@ -8,15 +8,15 @@ diataxis: "reference" # EIP-7702 -Stable 支持 **EIP-7702**,它允许 EOA 将其账户代码设置为现有的智能合约。EOA 在执行委托方逻辑的同时保留其原始地址和私钥。 +Stable 支持 **EIP-7702**,它允许 EOA 将其账户代码设置为现有的智能合约。EOA 保持其原始地址和私钥,同时执行委托的逻辑。 :::note -**概念:** 关于 EIP-7702 在 Stable 上的作用、委托模型以及安全注意事项,请参阅 [EIP-7702](/cn/explanation/eip-7702)。完整规范请参阅 [EIP-7702 规范](https://eips.ethereum.org/EIPS/eip-7702)。 +**概念:** 有关 EIP-7702 在 Stable 上实现的功能、委托模型和安全注意事项,请参阅 [EIP-7702](/cn/explanation/eip-7702)。有关完整规范,请参阅 [EIP-7702 规范](https://eips.ethereum.org/EIPS/eip-7702)。 ::: ## 交易格式 -EIP-7702 使用交易类型 `0x04`,并带有 `authorizationList` 字段。每个授权都指定一个委托合约,EOA 在该交易中执行其代码。 +EIP-7702 使用交易类型 `0x04` 和一个 `authorizationList` 字段。每次授权都指定一个委托合约,EOA 将为该交易执行该合约的代码。 ```typescript { @@ -29,21 +29,21 @@ EIP-7702 使用交易类型 `0x04`,并带有 `authorizationList` 字段。每 } ``` -该授权包含: +授权包含: - `chainId`:必须与目标链匹配。 - `address`:委托合约地址。 -- `nonce`:授权 nonce(与交易 nonce 分开)。 +- `nonce`:授权随机数(与交易随机数分开)。 支持 EIP-7702 的钱包和库会自动处理授权格式。 -## 工具链 +## 工具 -- **ethers.js**:`wallet.signAuthorization({ chainId, address, nonce })` 生成已签名的授权,用于包含在 `authorizationList` 中。 -- **viem**:使用带有 walletClient 的 `signAuthorization`,然后将结果传递给 `sendTransaction`。 -- **Hardhat / Foundry**:当你的工具链版本支持 Pectra 硬分叉时,标准的 EIP-7702 交易格式即可使用。 +- **ethers.js**:`wallet.signAuthorization({ chainId, address, nonce })` 生成已签名的授权,以便包含在 `authorizationList` 中。 +- **viem**:使用 `signAuthorization` 和 `walletClient`,然后将结果传递给 `sendTransaction`。 +- **Hardhat / Foundry**:当您的工具链版本支持 Pectra 硬分叉时,标准的 EIP-7702 交易格式即可使用。 -## 后续推荐 +## 接下来推荐 -- [**EIP-7702 概念**](/cn/explanation/eip-7702) — 了解委托模型及何时使用它。 -- [**账户抽象(EIP-7702)**](/cn/reference/eip-7702-api) — 逐步实现批量支付、消费限额和会话密钥。 +- [**EIP-7702 概念**](/cn/explanation/eip-7702):了解委托模型以及何时使用它。 +- [**账户抽象 (EIP-7702)**](/cn/reference/eip-7702-api):逐步实施批量支付、消费限额和会话密钥。 diff --git a/docs/pages/cn/reference/faq.mdx b/docs/pages/cn/reference/faq.mdx index a90f81d..53da55e 100755 --- a/docs/pages/cn/reference/faq.mdx +++ b/docs/pages/cn/reference/faq.mdx @@ -1,50 +1,75 @@ --- source_path: reference/faq.mdx -source_sha: 8bc0e6b7823c072b4f7c5dd26e280584966f7493 +source_sha: 348b72ccef22f764866c7d7b5395ae60c4e9f159 title: "常见问题" -description: "关于 Stable 设计、USDT 集成、可扩展性方案与技术特性的常见问题解答。" +description: "快速解答常见的入门问题:Stable 是什么、如何开始、与以太坊有何不同,以及在哪里可以找到更深入的文档。" +diataxis: "reference" --- # 常见问题 -## 常规问题 +## 入门 -**什么是 Stable?** +**Stable 是什么?** -Stable 是一个高性能区块链,致力于成为 USDT 的专属区块链,重新定义 USDT 在全球范围内的流通方式。 +一个 Layer 1,其中 USDT0 是原生的 gas 代币和结算资产。标准的 EVM 工具可以不变地工作。 -**Stable 与其他区块链有何不同?** +**Stable 适合谁?** -Stable 专为 USDT 打造的高性能网络,具备多种 USDT 专属功能,包括使用 USDT 作为原生 gas、为企业级应用预留专属区块空间和聚合转账功能,所有这些都建立在高度可扩展的架构之上。 +三种开发者画像:转移 USDT0 的支付和钱包团队、部署到 EVM 的智能合约开发者,以及运行节点或 RPC 的基础设施团队。[学习概述](/cn/explanation/learn-overview)为每条路径提供了一个卡片。 -## 技术特性 +**我应该从哪里开始:支付、合约、AI/代理,还是基础设施?** -**Stable 采用什么方法来提升可扩展性?** +- 转移 USDT0 或构建支付流程 → [支付](/cn/explanation/payments-overview)。 +- 部署合约 → [合约](/cn/explanation/contracts-overview)。 +- 连接 AI 编辑器或构建代理支付服务 → [代理结算](/cn/explanation/agent-settlement)。 +- 运行节点或为用户支付 gas → [基础设施](/cn/explanation/integrate-overview)。 -Stable 采用全栈式优化方案,从状态数据库、执行层、共识机制到 针对 USDT 的特定优化,对区块链上的交易的生命周期的每个阶段都进行了优化。 +如果您还没有连接到测试网,请从[快速开始](/cn/tutorial/quick-start)入手。 -**Stable 是否可以通过未来的共识升级至 DAG 共识机制?** +## 技术方面 -可以。与 Narwhal 和 Tusk 不同,它们无法与 StableBFT 直接兼容,而 Autobahn 提供了 PBFT-on-DAG 架构,可以与 Stable 的共识层更自然地集成。 +**Stable 是否兼容 EVM?** -**Stable 是否兼容 EVM?其他 EVM 生态的 dApp 能否迁移到Stable?** +是的。Solidity、Vyper、Foundry、Hardhat、ethers、viem,以及 `eth_*` JSON-RPC 方法都可以不变地工作。有四种行为与以太坊不同。请参阅[与以太坊的区别](/cn/explanation/ethereum-comparison)。 -Stable 完全兼容 EVM,用户和开发者可以无缝使用现有的以太坊合约、工具和钱包与Stable进行交互。 +**为什么 USDT0 是 gas 代币?** -## USDT 特性 +这样您就可以用您正在交易的资产支付费用。无需资助第二种代币,并且费用始终以稳定币计价。该协议还通过保证区块空间和传输聚合来优化 USDT0 密集型工作负载;请参阅[核心概念](/cn/explanation/core-concepts)。 -**如何在 Stable 上获取 USDT0?** +**如何获取 USDT0?** -得益于 USDT0 的 OFT 标准,用户可以通过 LayerZero 轻松地将其他网络的 USDT0 跨链转移到 Stable。 +- **测试网:** 使用 [faucet.stable.xyz](https://faucet.stable.xyz) 上的水龙头,或从以太坊 Sepolia 桥接测试 USDT。请参阅[获取测试网 USDT0](/cn/how-to/use-faucet) 中的演练。 +- **主网:** 通过 LayerZero 从其他链桥接 USDT0,或通过交易所或托管人获取。 -**Stable 还有哪些 USDT 专属的独特功能?** +**我从以太坊移植合约时会有哪些变化?** -即将上线的功能包括: +大多数合约部署时不需要更改。如果适用,有三件事需要修复: -- **企业专用区块空间**:允许机构用户在网络拥堵时依然获得可预测的延迟和成本。 -- **USDT 转账聚合器**:可高效地打包多个 USDT0 转账交易,提高吞吐量并降低成本。 -- **保密转账**:在符合监管要求的前提下保护交易金额隐私的功能。 +- 不要在内部变量中镜像原生余额。`transferFrom` 可以在不调用合约的情况下耗尽原生余额。 +- 不要转移到 `address(0)`。原生和 ERC-20 转移到零地址都会回滚。 +- 不要依赖 `EXTCODEHASH` 进行地址重用检测。基于许可的批准会改变原生余额而不增加 nonce。 -**什么是 Stable Pay?** +完整检查表:[Stable 上的 USDT0 行为](/cn/explanation/usdt0-behavior)。 -Stable Pay为用户提供简洁、友好的使用体验,并具备 DeFi 的强大能力。它既适合初学者,也适合有经验的加密用户。新用户可通过社交登录轻松上手,而现有传统区块链钱包的用户也可使用原有方式使用Stable。Stable Pay支持网页与移动端使用,确保用户随时随地安全访问其数字资产。 +## 资源 + +**我在哪里可以找到代币经济学、路线图和架构?** + +- [代币经济学](/cn/reference/tokenomics):STABLE 供应、分配和归属。 +- [技术路线图](/cn/explanation/technical-roadmap):分阶段优化计划。 +- [技术概述](/cn/explanation/tech-overview):StableBFT、Stable EVM、StableDB 和 RPC 设计。 +- [USDT 特定功能](/cn/explanation/usdt-features-overview):关于 gas、区块空间、聚合和机密传输的详细信息。 + +**我可以在哪里获得帮助?** + +- [开发者协助](/cn/reference/developer-assistance):常见问题和参考指针。 +- [Discord](https://discord.gg/stablexyz):社区支持和协议更新。 +- `bizdev@stable.xyz`:合作和集成咨询。 + +## 下一步建议 + +- [**快速开始**](/cn/tutorial/quick-start):在测试网发送第一笔交易。 +- [**核心概念**](/cn/explanation/core-concepts):在构建之前学习你需要了解的四个核心概念。 +- [**学习概述**](/cn/explanation/learn-overview):选择适合您正在构建的文档路径。 +- [**生产就绪**](/cn/how-to/production-readiness):在发布到主网之前验证集成。 diff --git a/docs/pages/cn/reference/gas-pricing-api.mdx b/docs/pages/cn/reference/gas-pricing-api.mdx index 089fcd5..43cb833 100644 --- a/docs/pages/cn/reference/gas-pricing-api.mdx +++ b/docs/pages/cn/reference/gas-pricing-api.mdx @@ -1,22 +1,22 @@ --- source_path: reference/gas-pricing-api.mdx -source_sha: 9355a785da7466f7714460ce6e1ea80e95c4f55c -title: "Gas 定价参考" -description: "针对 Stable 的单组件费用模型构建交易、估算 gas 并配置工具链。" +source_sha: 54bf228a3df7b32d8dc92f632372ba1adbd7bcce +title: "Gas 资费参考" +description: "根据 Stable 的单组件费用模型构建交易、估算 gas 并配置工具。" diataxis: "reference" --- -# Gas 定价参考 +# Gas 资费参考 -Stable 上的交易构建、gas 估算和工具链配置。 +Stable 的交易构建、gas 估算和工具配置。 :::note -**概念:** 关于 Stable 为何使用单组件费用模型以及它与 Ethereum 的对比,请参阅 [Gas 定价](/cn/explanation/gas-pricing)。 +**概念:** 有关 Stable 为何使用单组件费用模型以及它与以太坊的比较,请参阅[Gas 资费](/cn/explanation/gas-pricing)。 ::: ## 交易构建 -在 Stable 上构建交易时,将 `maxPriorityFeePerGas` 设置为 `0`。客户端应从最新区块获取最新的 base fee,并在计算 `maxFeePerGas` 时加入安全余量。 +在 Stable 上构建交易时,将 `maxPriorityFeePerGas` 设置为 `0`。客户端应从最新块中获取最新的基本费用,并在计算 `maxFeePerGas` 时包含安全边际。 ```javascript // ethers.js v6 @@ -35,12 +35,12 @@ const tx = await wallet.sendTransaction({ ``` ```text -Native USDT0 transfer confirmed. Fee ≈ 0.0000021 USDT0 at baseFee = 1 gwei. +原生 USDT0 转账已确认。当 baseFee = 1 gwei 时,费用 ≈ 0.0000021 USDT0。 ``` ## Gas 估算 -像在 Ethereum 上一样使用 `eth_estimateGas` 和 `eth_gasPrice`。关键区别在于 `eth_maxPriorityFeePerGas` 将始终返回 `0`。 +像在以太坊上一样使用 `eth_estimateGas` 和 `eth_gasPrice`。关键区别在于 `eth_maxPriorityFeePerGas` 将始终返回 `0`。 ```javascript const gasPrice = await provider.send("eth_gasPrice", []); @@ -52,14 +52,14 @@ const gasEstimate = await provider.estimateGas({ const estimatedFeeInUSDT0 = gasPrice * gasEstimate; ``` -## 工具链配置 +## 工具配置 -- **Hardhat / Foundry**:无需特殊配置;标准的 EVM 设置即可工作。如果你的配置显式设置了 priority fee,请将其设置为 `0`。 -- **钱包**:隐藏或禁用 priority tip 输入字段。显示它可能会让用户困惑,因为该值不起作用。 -- **监控**:费用分析仪表板不应跟踪 priority fee。它们将始终为零。 +- **Hardhat / Foundry**:无需特殊配置;标准 EVM 设置即可。如果您的配置明确设置了优先费用,请将其设置为 `0`。 +- **钱包**:隐藏或禁用优先小费输入字段。显示它可能会混淆用户,因为该值无效。 +- **监控**:费用分析仪表板不应跟踪优先费用。它们将始终为零。 -## 推荐后续阅读 +## 下一步建议 -- [**Gas 定价概念**](/cn/explanation/gas-pricing) — 理解 Stable 为何使用单组件费用模型。 -- [**Ethereum 对比**](/cn/explanation/ethereum-comparison) — 了解从 Ethereum 移植时会遇到的所有行为差异。 -- [**JSON-RPC API**](/cn/reference/json-rpc-api) — 参考 Stable 提供的 `eth_*` 方法。 +- [**Gas 资费概念**](/cn/explanation/gas-pricing):了解 Stable 为何使用单组件费用模型。 +- [**以太坊比较**](/cn/explanation/ethereum-comparison):查看从以太坊移植时会遇到的所有行为差异。 +- [**JSON-RPC API**](/cn/reference/json-rpc-api):参考 Stable 公开的 `eth_*` 方法。 diff --git a/docs/pages/cn/reference/gas-waiver-api.mdx b/docs/pages/cn/reference/gas-waiver-api.mdx index 32e31ce..2e2d757 100644 --- a/docs/pages/cn/reference/gas-waiver-api.mdx +++ b/docs/pages/cn/reference/gas-waiver-api.mdx @@ -1,98 +1,98 @@ --- source_path: reference/gas-waiver-api.mdx -source_sha: 92a2fff1dc4c0731b7b98573203aa468600dd6d8 -title: "Gas 豁免协议" -description: "Gas 豁免的协议级规范:交易格式、标记路由、治理控制以及 Waiver Server API。" +source_sha: 73af0a88040bca94925046ff388ccc018e9be11b +title: "燃气费减免协议" +description: "燃气费减免的协议级规范:交易格式、标记路由、治理控制和减免服务器 API。" diataxis: "reference" --- -# Gas 豁免协议 +# 燃气费减免协议 -本文档规定了 Gas 豁免机制:交易格式、标记路由、治理控制以及 Waiver Server API。 +本文档详细说明了燃气费减免机制:交易格式、标记路由、治理控制和减免服务器 API。 :::note -**概念:** 关于 Gas 豁免是什么以及它为何存在,请参阅 [Gas 豁免](/cn/explanation/gas-waiver)。关于针对托管 Waiver Server 的操作集成指南,请参阅 [启用免 Gas 交易](/cn/how-to/integrate-gas-waiver)。 +**概念:** 有关燃气费减免是什么以及它存在的原因,请参阅[燃气费减免](/cn/explanation/gas-waiver)。有关与托管的减免服务器集成的操作指南,请参阅[启用免燃气费交易](/cn/how-to/integrate-gas-waiver)。 ::: ## 摘要 -Gas 豁免通过允许一小组经治理批准的地址(“waivers”)提交 `gasPrice = 0` 的交易,从而在 Stable 上实现面向最终用户的免 Gas 交易。Stable 目前运营一项 waiver 服务(“Waiver Server”),你可以与其集成,以在无需实现特定于协议的封装逻辑的情况下提供免 Gas 的用户体验。 +燃气费减免通过允许一小部分经治理批准的地址(“减免方”)提交 `gasPrice = 0` 的交易,从而在 Stable 上实现无燃气费的最终用户交易。Stable 目前运营着一个减免服务(“减免服务器”),您可以与之集成以提供无燃气费的用户体验,而无需实现协议特定的包装器逻辑。 ## 范围 本规范涵盖: -- gas 豁免交易的协议级规则 -- 封装交易机制和标记地址 -- 治理控制的授权与允许的目标 -- 用于提交已签名用户交易的 Waiver Server 接口 +- 免燃气费交易的协议级规则 +- 包装器交易机制和标记地址 +- 治理控制的授权和允许的目标 +- 用于提交签名用户交易的减免服务器接口 ## 定义 -- **Waiver**:通过验证者治理在链上注册的以太坊地址,被授权提交 gas 豁免交易。 -- **InnerTx**:最终用户签名的、`gasPrice = 0` 的交易。 -- **WrapperTx**:由 waiver 签名的交易,将用户的 `InnerTx` 传输到链上并授权执行。 -- **Marker address(标记地址)**:用于识别 waiver 封装交易的哨兵地址:`0x000000000000000000000000000000000000f333`。 -- **AllowedTarget**:将 waiver 限制为特定合约地址和方法选择器的策略。 +- **减免方(Waiver)**:通过验证者治理在链上注册的以太坊地址,被授权提交免燃气费交易。 +- **InnerTx**:最终用户签名的交易,`gasPrice = 0`。 +- **WrapperTx**:由减免方签名的一笔交易,将用户的 `InnerTx` 传输到链上并授权执行。 +- **标记地址(Marker address)**:用于识别减免包装器交易的哨兵地址:`0x000000000000000000000000000000000000f333`。 +- **允许目标(AllowedTarget)**:限制减免方到特定合约地址和方法选择器的策略。 ## 概述 -Gas 豁免使用封装交易模式: +燃气费减免使用包装器交易模式: -1. 用户签名一笔 `gasPrice = 0` 的 `InnerTx`。 -2. waiver 将 `InnerTx` 封装为 `WrapperTx` 并广播。 -3. 验证者检测标记交易,验证 waiver 授权和策略约束,然后执行内嵌的 `InnerTx`。 +1. 用户用 `gasPrice = 0` 签署一个 `InnerTx`。 +2. 减免方将 `InnerTx` 包装到 `WrapperTx` 中并广播。 +3. 验证者检测标记交易,验证减免方的授权和策略约束,然后执行嵌入的 `InnerTx`。 -Stable 运营一项 waiver 服务(Waiver Server),它在链上注册为经授权的 waiver。你与 Waiver Server API 集成以提交已签名的 `InnerTx` 载荷。 +Stable 运营着一个减免服务(减免服务器),该服务在链上注册为授权减免方。您可以通过减免服务器 API 提交已签名的 `InnerTx` 有效负载。 ## 协议规范 ### 标记地址路由 -当且仅当满足以下条件时,交易才被视为 waiver 封装交易: +当且仅当发生以下情况时,交易才被视为减免包装器交易: - `to == 0x000000000000000000000000000000000000f333`。 -协议将交易的 `data` 字段解释为编码后的内部交易载荷,并使用下面的 waiver 验证规则对其进行处理。 +协议将交易的 `data` 字段解释为编码的内部交易有效负载,并使用下面的减免验证规则进行处理。 -### 授权与策略检查 +### 授权和策略检查 -对于每个候选封装交易,验证者必须强制执行: +对于每个候选包装器交易,验证者必须强制执行: -1. **Waiver 授权** - - `WrapperTx.from` 必须是通过治理在链上注册的 waiver 地址。 -2. **Gas 豁免** +1. **减免方授权** + - `WrapperTx.from` 必须是通过治理在链上注册的减免地址。 +2. **燃气费减免** - `WrapperTx.gasPrice` 必须等于 `0`。 - `InnerTx.gasPrice` 必须等于 `0`。 -3. **目标允许列表** - - `InnerTx.to` 以及从 `InnerTx.data` 中提取的方法选择器必须被 waiver 的 `AllowedTarget` 策略允许。 -4. **Value 限制** +3. **目标白名单** + - `InnerTx.to` 以及从 `InnerTx.data` 中提取的方法选择器必须由减免方的 `AllowedTarget` 策略允许。 +4. **价值限制** - `WrapperTx.value` 必须等于 `0`。 -如果任何检查失败,验证者将拒绝封装交易,且不执行内部交易。 +如果任何检查失败,验证者将拒绝包装器交易,并且不执行内部交易。 ### 执行语义 -如果所有检查均通过: +如果所有检查都通过: -1. 协议以用户身份执行 `InnerTx`,保留用户的 `from`、`nonce` 和调用语义。 -2. Gas 计费由 waiver 机制处理:用户不支付 gas,且根据该功能的定义,waiver 交易使用 `gasPrice = 0`。 -3. 封装交易必须提供足够的 `gasLimit` 以覆盖 `InnerTx` 的执行(包括解封装和验证的开销)。 +1. 协议以用户的身份执行 `InnerTx`,保留用户的 `from`、`nonce` 和调用语义。 +2. 燃气费核算由减免机制处理:用户不支付燃气费,并且根据该功能的定义,减免交易使用 `gasPrice = 0`。 +3. 包装器交易必须提供足够的 `gasLimit` 来覆盖 `InnerTx` 的执行(包括解包和验证的开销)。 ## 交易格式 ### WrapperTx -封装交易由 waiver 签名并发送到标记地址。 +包装器交易由减免方签名并发送到标记地址。 ```javascript WrapperTx { from: waiver_address, to: 0x000000000000000000000000000000000000f333, - value: 0, // must be zero - data: RLP(InnerTx), // RLP-encoded inner transaction - gasPrice: 0, // must be zero - gasLimit: sufficient_for_inner, // must cover inner execution + overhead + value: 0, // 必须为零 + data: RLP(InnerTx), // RLP 编码的内部交易 + gasPrice: 0, // 必须为零 + gasLimit: sufficient_for_inner, // 必须覆盖内部执行 + 开销 nonce: waiver_nonce } ``` @@ -107,7 +107,7 @@ InnerTx { to: target_contract, value: value, data: call_data, - gasPrice: 0, // must be zero + gasPrice: 0, // 必须为零 gasLimit: execution_gas, nonce: user_nonce } @@ -115,54 +115,54 @@ InnerTx { ## 治理控制的访问 -Waiver 授权由验证者治理在链上管理。 +减免授权由验证者治理在链上控制。 治理控制提供: -- 可审查的 waiver 地址授权 -- waiver 注册和更新的链上透明度 +- 对减免地址的可审查授权 +- 减免注册和更新的链上透明度 - 撤销能力 -- 通过 `AllowedTarget` 进行的按 waiver 范围限定 +- 通过 `AllowedTarget` 进行的每个减免方的范围界定 ## 安全模型 ### 最终用户签名完整性 -用户签名 `InnerTx`。waiver 无法在不使签名失效的情况下修改内部交易载荷。你仍必须确保用户仅签名预期的交易载荷。 +用户签署 `InnerTx`。减免方无法修改内部交易有效负载而使其签名失效。您仍然必须确保用户仅签署预期的交易有效负载。 ### 信任边界 -如果合作伙伴通过 Waiver Server 路由提交,则 Gas 豁免会引入一个服务依赖: +如果合作伙伴通过减免服务器路由提交内容,燃气费减免会引入服务依赖: -- 服务的可用性会影响提交免 Gas 交易的能力。 -- 授权仍保留在链上;只有已注册的 waiver 地址才能产生有效的封装提交。 +- 服务的可用性影响提交无燃气费交易的能力。 +- 授权保留在链上;只有注册的减免地址才能生成有效的包装器提交。 ## 集成 -你通过以下方式集成: +您可以通过以下方式集成: -1. 从用户处收集已签名的 `InnerTx`(`gasPrice = 0`)。 -2. 将已签名的内部交易提交到 Waiver Server API。 -3. 处理流式返回的结果并向最终用户展示交易哈希。 +1. 从用户收集签名的 `InnerTx`(`gasPrice = 0`)。 +2. 将签名的内部交易提交给减免服务器 API。 +3. 处理流式结果并将交易哈希显示给最终用户。 -## Waiver server +## 减免服务器 ### 概述 -Waiver Server 将已签名的用户 `InnerTx` 载荷封装并广播为经 waiver 授权的封装交易。你无需构造封装交易或运营 waiver 地址。 +减免服务器将签名的用户 `InnerTx` 有效负载包装并广播为减免方授权的包装器交易。您无需构建包装器交易或操作减免地址。 -### 端点和基础 URL +### 端点和基本 URL -基础 URL: +基本 URL: -- 主网:TBD +- 主网:待定 - 测试网:`https://waiver.testnet.stable.xyz` -### 认证 +### 身份验证 -除健康检查外,所有端点都需要 bearer token 认证: +除健康检查外的所有端点都需要 bearer token 身份验证: -``` +```text Authorization: Bearer ``` @@ -172,13 +172,13 @@ Authorization: Bearer 健康检查端点。 -认证:无。 +身份验证:无。 #### POST `/v1/submit` -提交一批已签名的内部交易。 +提交一批签名的内部交易。 -认证:必需(`Bearer`)。 +身份验证:必需(`Bearer`)。 请求体: @@ -188,7 +188,7 @@ Authorization: Bearer } ``` -响应以 NDJSON(换行分隔的 JSON)流式返回。每一行对应一个已提交交易的索引。 +响应以 NDJSON(换行符分隔的 JSON)流式传输。每行对应于一个已提交的交易索引。 示例: @@ -201,7 +201,7 @@ Authorization: Bearer 用于流式提交的 WebSocket 接口。 -认证:必需(`Bearer`)。 +身份验证:必需(`Bearer`)。 ### 集成示例 @@ -238,7 +238,7 @@ async function submitGaslessTransaction(signedInnerTxHex, apiKey) { ### 创建用户 InnerTx -你负责构造一个 `gasPrice = 0` 的 `InnerTx`,然后收集用户签名。 +您负责构建 `gasPrice = 0` 的 `InnerTx`,然后收集用户签名。 示例: @@ -250,29 +250,29 @@ async function createInnerTx(userWallet, contractAddress, callData, nonce) { to: contractAddress, data: callData, value: value, - gasPrice: 0, // must be 0 for waiver + gasPrice: 0, // 减免必须为 0 gasLimit: 100000, nonce: nonce, - chainId: 2201, // 988 for mainnet, 2201 for testnet + chainId: 2201, // 主网为 988,测试网为 2201 }; return await userWallet.signTransaction(innerTx); } ``` -### 错误码 +### 错误代码 - `PARSE_ERROR`:解析交易失败 - `INVALID_REQUEST`:请求体格式错误 - `BATCH_SIZE_EXCEEDED`:批量大小超过允许的最大值 - `VALIDATION_FAILED`:交易验证失败 -- `BROADCAST_FAILED`:广播到链上失败 -- `RATE_LIMITED`:超出速率限制 +- `BROADCAST_FAILED`:广播到链失败 +- `RATE_LIMITED`:速率限制超出 - `QUEUE_FULL`:服务器队列已满 - `TIMEOUT`:请求超时 -## 推荐的后续内容 +## 下一步推荐 -- [**零 Gas 交易**](/cn/how-to/zero-gas-transactions) — 以演示为重点的操作演练,附带显示零 Gas 费用的收据。 -- [**启用免 Gas 交易**](/cn/how-to/integrate-gas-waiver) — 完整的托管 API 集成指南,包含批量提交和错误处理。 -- [**自托管 Gas 豁免**](/cn/how-to/self-hosted-gas-waiver) — 在不使用托管 API 的情况下运行你自己的 waiver 基础设施。 +- [**零燃气费交易**](/cn/how-to/zero-gas-transactions):演示为主的演练,包含显示零燃气费的收据。 +- [**启用免燃气费交易**](/cn/how-to/integrate-gas-waiver):完整的托管 API 集成指南,包含批量提交和错误处理。 +- [**自托管燃气费减免**](/cn/how-to/self-hosted-gas-waiver):无需托管 API,运行您自己的燃气费减免基础设施。 diff --git a/docs/pages/cn/reference/invoices.mdx b/docs/pages/cn/reference/invoices.mdx index 2c7a875..4eb2cc8 100644 --- a/docs/pages/cn/reference/invoices.mdx +++ b/docs/pages/cn/reference/invoices.mdx @@ -1,52 +1,52 @@ --- source_path: reference/invoices.mdx -source_sha: 7e3a42da7db359e387c7b973b03c1248dde7baa2 +source_sha: 39c34da4d80dcbcd49a25e21d22d8039202a418e title: "结算发票" -description: "在 Stable 上使用 ERC-3009,通过从发票元数据派生的确定性 nonce 结算发票,实现自动对账。" +description: "Stable 使用 ERC-3009 结算发票,其中确定性随机数源自发票元数据,用于自动对账。" diataxis: "reference" --- # 结算发票 -每张发票都映射到一个唯一的、确定性的 nonce,该 nonce 派生自发票元数据:发票编号、交易方、金额和到期日。此 nonce 通过 [ERC-3009](/cn/explanation/erc-3009) 驱动结算,并创建一个不可变的收据,可与现有会计系统进行对账。 +每张发票都映射到一个唯一的、确定性的随机数,该随机数源自发票元数据:发票编号、各方、金额和到期日。此随机数通过 [ERC-3009](/cn/explanation/erc-3009) 驱动结算,并创建不可变的收据,可与现有会计系统进行对账。 ## 工作原理 -买方和供应商各自独立地从相同的发票元数据计算出相同的 nonce。无需外部注册表来协调付款。 +买方和供应商都从相同的发票元数据独立计算相同的随机数。无需外部注册机构来协调支付。 -nonce 是确定性派生的: +随机数是确定性派生的: -``` +```text nonce = keccak256(invoiceNumber, vendor, buyer, amount, dueDate) ``` -当买方使用此 nonce 签署 ERC-3009 授权时,链上结算事件即可作为防篡改的付款收据。 +当买方使用此随机数签署 ERC-3009 授权时,链上结算事件将作为防篡改支付收据。 ### 结算流程 -1. **签发发票**:供应商创建一张具有唯一编号、金额和到期日的发票。 -2. **计算 nonce**:双方各自独立地从发票元数据派生出相同的 nonce。 -3. **买方签名**:买方使用确定性 nonce 在链下签署 ERC-3009 授权。`validBefore` 字段可设置为到期日加上一段宽限期。 +1. **开具发票**:供应商创建具有唯一编号、金额和到期日的发票。 +2. **计算随机数**:双方独立地从发票元数据中派生相同的随机数。 +3. **买方签名**:买方使用确定性随机数在链下签署 ERC-3009 授权。`validBefore` 字段可以设置为到期日加上宽限期。 4. **结算**:买方或供应商在链上提交 `transferWithAuthorization`。结算在一秒内确认。 -5. **对账**:发出的 `AuthorizationUsed` 事件包含该 nonce,将链上结算与确切的发票关联起来。同一交易中的 `Transfer` 事件验证发送方、接收方和金额。 +5. **对账**:发出的 `AuthorizationUsed` 事件包含随机数,将链上结算与确切的发票关联起来。同一交易中的 `Transfer` 事件验证发送方、接收方和金额。 -### 防止重复付款 +### 防止双重支付 -nonce 在付款时于链上被消耗。同一张发票无法被结算两次;使用已使用过的 nonce 重新提交授权将会被回退。 +支付后,随机数在链上消耗。同一张发票不能结算两次;重新提交带有已使用随机数的授权将导致操作回滚。 -## 有何不同 +## 独特之处 -传统的 B2B 发票涉及银行电汇(1–5 个工作日)、人工对账,并且没有与发票本身绑定的加密付款凭证。借助确定性 nonce,链上付款是自我记录的:nonce 将结算与确切的发票关联起来,区块链事件日志提供了不可变的审计追踪。 +传统的 B2B 发票涉及银行电汇(1-5 个工作日)、手动对账,并且没有与发票本身绑定的加密支付证明。通过确定性随机数,链上支付是自文档化的:随机数将结算与确切的发票关联起来,区块链事件日志提供了不可变的审计追踪。 -| **方面** | **传统方式(银行电汇)** | **Stable(ERC-3009)** | +| **方面** | **传统(银行电汇)** | **Stable (ERC-3009)** | | :--- | :--- | :--- | -| 结算 | 1–5 个工作日 | 1 秒以内 | -| 对账 | 人工与银行对账单匹配 | `AuthorizationUsed` 事件将付款与发票 nonce 关联 | -| 付款凭证 | 银行确认函 | 链上交易,以加密方式与发票关联 | -| 中间方 | 代理银行 | 无 | -| 手续费 | 电汇费用($15–45)+ 外汇点差 | ~0.00021 USDT0(使用 Gas Waiver 时为 0) | +| 结算 | 1-5 个工作日 | 1 秒内 | +| 对账 | 根据银行对账单手动匹配 | `AuthorizationUsed` 事件将支付与发票随机数关联 | +| 支付证明 | 银行确认函 | 链上交易,以加密方式链接到发票 | +| 中介 | 代理银行 | 无 | +| 费用 | 电汇费用(15-45 美元)+ 外汇差价 | 约 0.00021 USDT0(或使用 Gas Waiver 为 0) | **另请参阅:** -- [ERC-3009(带授权转账)](/cn/explanation/erc-3009) +- [ERC-3009 (Transfer With Authorization)](/cn/explanation/erc-3009) - [Gas Waiver](/cn/how-to/integrate-gas-waiver) diff --git a/docs/pages/cn/reference/json-rpc-api.mdx b/docs/pages/cn/reference/json-rpc-api.mdx index 0aa0557..0858591 100755 --- a/docs/pages/cn/reference/json-rpc-api.mdx +++ b/docs/pages/cn/reference/json-rpc-api.mdx @@ -1,15 +1,16 @@ --- source_path: reference/json-rpc-api.mdx -source_sha: 1b6ce25dd5d0c90be028f78f97179a32c2c70a39 +source_sha: 838e9e92455c9c3acac3d94e4afcf7d7d907ef25 title: JSON-RPC API -description: "Stable 支持的 eth、net、web3 和 debug 命名空间 JSON-RPC API 方法列表。" +description: "Stable 上 eth、net、web3 和 debug 命名空间中支持的 JSON-RPC API 方法。" +diataxis: "reference" --- # JSON-RPC API ## eth_namespace -| API | support | +| API | 支持 | |--------------------------------------------|---------| | eth_syncing | ✅ | | eth_gasPrice | ✅ | @@ -66,7 +67,7 @@ description: "Stable 支持的 eth、net、web3 和 debug 命名空间 JSON-RPC | eth_getLogs | ✅ | ## debug_namespace -| API | support | +| API | 支持 | |-----------------------------------|---------| | debug_accountRange | ❌ | | debug_backtraceAt | ❌ | @@ -106,7 +107,7 @@ description: "Stable 支持的 eth、net、web3 和 debug 命名空间 JSON-RPC | debug_startCPUProfile | ✅ | | debug_startGoTrace | ✅ | | debug_stopCPUProfile | ✅ | -| debug_stopGoTrace | ✅ | +| debug_stopGoTrace | ✅ H | debug_storageRangeAt | ❌ | | debug_traceBadBlock | ❌ | | debug_traceBlock | ❌ | @@ -121,3 +122,9 @@ description: "Stable 支持的 eth、net、web3 和 debug 命名空间 JSON-RPC | debug_writeBlockProfile | ✅ | | debug_writeMemProfile | ✅ | | debug_writeMutexProfile | ✅ | + +## 下一步建议 + +- [**Gas 定价参考**](/cn/reference/gas-pricing-api):根据 Stable 的仅基础费模型构建 EIP-1559 交易。 +- [**EIP-7702 参考**](/cn/reference/eip-7702-api):使用 `authorizationList` 字段构建类型 4 交易。 +- [**系统模块参考**](/cn/reference/system-modules-api-overview):在固定的预编译地址调用 Bank、Distribution 和 Staking。 diff --git a/docs/pages/cn/reference/sdk.mdx b/docs/pages/cn/reference/sdk.mdx index 19fe5df..242b9a1 100644 --- a/docs/pages/cn/reference/sdk.mdx +++ b/docs/pages/cn/reference/sdk.mdx @@ -1,14 +1,14 @@ --- source_path: reference/sdk.mdx -source_sha: 77de6350f7056346c43e1b5ca5da572df7f4b7ae +source_sha: 64d437cfd1ea8f5c39da592e6dfad6bb6ab8b3bf title: "SDK 参考" -description: "Complete reference for @stablechain/sdk: createStable, StableClient methods, enums, chain configs, and error classes." +description: "@stablechain/sdk 的完整参考:createStable、StableClient 方法、枚举、链配置和错误类。" diataxis: "reference" --- # SDK 参考 -`@stablechain/sdk` 的完整功能。如需操作指南,请参阅 [SDK 快速开始](/cn/tutorial/sdk-quickstart)。 +`@stablechain/sdk` 的完整概览。有关详细介绍,请参阅 [SDK 快速入门](/cn/tutorial/sdk-quickstart)。 ## 安装 @@ -20,11 +20,11 @@ npm install @stablechain/sdk viem added 2 packages, audited 3 packages in 2s ``` -`viem >= 2.0.0` 是一个 peer dependency。 +`viem >= 2.0.0` 是对等依赖。 ## `createStable(config)` -构造一个 `StableClient`。返回一个对象,其方法列在 [`StableClient`](#stableclient) 下。 +构造一个 `StableClient`。返回一个包含 [`StableClient`](#stableclient) 中列出的方法的对象。 ```ts import { createStable, Network } from "@stablechain/sdk"; @@ -42,9 +42,9 @@ StableClient { transfer, quoteBridge, bridge, quoteSwap, swap } | :--- | :--- | :--- | :--- | | `network` | `Network` | `Network.Mainnet` | 目标网络。 | | `rpc` | `string` | `network` 的公共 RPC | RPC 覆盖。 | -| `account` | `viem.Account` | | 服务端签名者(例如 `privateKeyToAccount`)。 | -| `transport` | `viem.Transport` | | 浏览器钱包传输(例如 `custom(window.ethereum)`)。 | -| `walletClient` | `viem.WalletClient` | | 预构建的钱包客户端。优先级高于 `account` 和 `transport`。 | +| `account` | `viem.Account` | | 服务器端签名器(例如 `privateKeyToAccount`)。 | +| `transport` | `viem.Transport` | | 浏览器钱包传输(例如 `custom(window.ethereum)`)。 | +| `walletClient` | `viem.WalletClient` | | 预构建的钱包客户端。优先于 `account` 和 `transport`。 | 请提供 `account`、`transport` 或 `walletClient` 中的一个。 @@ -52,7 +52,7 @@ StableClient { transfer, quoteBridge, bridge, quoteSwap, swap } ### `transfer(params)` -在 Stable 上发送原生 USDT0 或任意 ERC-20。会将钱包切换到 Stable 链,在缺失时从链上获取代币精度,并等待回执。 +在 Stable 上发送原生 USDT0 或任何 ERC-20。切换钱包到 Stable 链,在缺失时链上获取代币小数位数,并等待回执。 ```ts const { txHash } = await stable.transfer({ @@ -70,15 +70,15 @@ const { txHash } = await stable.transfer({ | :--- | :--- | :--- | | `from` | `string` | 发送方地址。 | | `to` | `string` | 接收方地址。 | -| `amount` | `number` | 人类可读的金额。 | -| `token` | `string?` | ERC-20 合约地址。原生 USDT0 时省略。 | -| `tokenDecimals` | `number?` | 精度。省略时从链上获取。 | +| `amount` | `number` | 人类可读金额。 | +| `token` | `string?` | ERC-20 合约地址。原生 USDT0 则省略。 | +| `tokenDecimals` | `number?` | 小数位数。省略时从链上获取。 | -返回 `OperationResult`(`{ txHash, toAmount? }`)。 +返回 `OperationResult` (`{ txHash, toAmount? }`)。 ### `quoteBridge(params)` -预览一次跨链桥接。只读 —— 无需签名,无需 gas。 +桥接预览。只读。无签名,无 gas。 ```ts const quote = await stable.quoteBridge({ @@ -98,7 +98,7 @@ const quote = await stable.quoteBridge({ ### `bridge(params)` -跨链桥接代币。SDK 会自动选择路由:USDT0 → USDT0 使用 LayerZero,其他情况使用 LI.FI。传入预先获取的 `quote` 可跳过内部的报价调用。 +跨链桥接代币。SDK 选择路由:USDT0 → USDT0 使用 LayerZero,其他使用 LI.FI。传入预取的 `quote` 可跳过内部引用调用。 ```ts const { txHash } = await stable.bridge({ ...bridgeParams, quote }); @@ -114,14 +114,14 @@ const { txHash } = await stable.bridge({ ...bridgeParams, quote }); | `toChain` | `Chain` | 目标链。 | | `fromToken` | `string` | 源代币合约地址。 | | `toToken` | `string` | 目标代币合约地址。 | -| `amount` | `number` | 人类可读的金额。 | -| `fromDecimals` | `number?` | 源代币精度。默认为 `6`。 | +| `amount` | `number` | 人类可读金额。 | +| `fromDecimals` | `number?` | 源代币小数位数。默认为 `6`。 | | `recipient` | `string?` | 目标地址。默认为签名者。 | -| `quote` | `BridgeQuote?` | 预先获取的报价。跳过内部报价调用。 | +| `quote` | `BridgeQuote?` | 预取的报价。跳过内部报价调用。 | ### `quoteSwap(params)` -在 Stable 上获取 LI.FI 兑换报价。返回一个预构建的交易请求和授权地址。 +获取 Stable 上的 LI.FI 交换报价。返回预构建的交易请求和批准地址。 ```ts const quote = await stable.quoteSwap({ @@ -138,7 +138,7 @@ const quote = await stable.quoteSwap({ ### `swap(params)` -通过 LI.FI 在 Stable 上兑换代币。自动处理 ERC-20 授权,并在需要时切换钱包所在的链。 +通过 LI.FI 在 Stable 上交换代币。自动处理 ERC-20 批准,并在需要时切换钱包的链。 ```ts const { txHash, toAmount } = await stable.swap({ ...swapParams, quote }); @@ -150,27 +150,27 @@ const { txHash, toAmount } = await stable.swap({ ...swapParams, quote }); | **参数** | **类型** | **默认值** | **描述** | | :--- | :--- | :--- | :--- | -| `fromToken` | `string` | | 源代币地址。 | -| `toToken` | `string` | | 目标代币地址。 | -| `amount` | `number` | | 人类可读的金额。 | -| `fromDecimals` | `number?` | `6` | 源代币精度。 | -| `toAddress` | `string?` | 签名者 | 接收方地址。 | -| `quote` | `SwapQuote?` | | 预先获取的报价。跳过 LI.FI 调用。 | +| `fromToken` | `string` | | 源代币地址。 | +| `toToken` | `string` | | 目标代币地址。 | +| `amount` | `number` | | 人类可读金额。 | +| `fromDecimals` | `number?` | `6` | 源代币小数位数。 | +| `toAddress` | `string?` | signer | 接收方地址。 | +| `quote` | `SwapQuote?` | | 预取的报价。跳过 LI.FI 调用。 | ## 枚举 ### `Network` -| **值** | **Chain ID** | +| **值** | **链 ID** | | :--- | :--- | | `Network.Mainnet` | 988 | | `Network.Testnet` | 2201 | ### `Chain` -由 `quoteBridge` 和 `bridge` 使用。每一项都有对应的 `CHAIN_CONFIGS` 条目。 +由 `quoteBridge` 和 `bridge` 使用。每个条目都有相应的 `CHAIN_CONFIGS` 条目。 -| **枚举** | **网络** | **Chain ID** | +| **枚举** | **网络** | **链 ID** | | :--- | :--- | :--- | | `Chain.Sepolia` | Ethereum Sepolia | 11155111 | | `Chain.StableTestnet` | Stable Testnet | 2201 | @@ -186,7 +186,7 @@ const { txHash, toAmount } = await stable.swap({ ...swapParams, quote }); ## `CHAIN_CONFIGS` -以 `Chain` 枚举为键的 `Partial>`。每一项都暴露 `id`、`rpc`、`usdt` 和 `decimals`。当你需要某条受支持链上的规范 USDT 地址而又不想硬编码时,可以使用它。 +由 `Chain` 枚举键入的 `Partial>`。每个条目都公开 `id`、`rpc`、`usdt` 和 `decimals`。当您需要支持链上的规范 USDT 地址而无需硬编码时使用。 ```ts import { CHAIN_CONFIGS, Chain } from "@stablechain/sdk"; @@ -200,13 +200,13 @@ console.log(CHAIN_CONFIGS[Chain.Stable]); ## 错误 -所有 SDK 错误都继承自 `StableError`,而后者继承自 viem 的 `BaseError`。错误携带结构化的元数据,因此你可以基于 `error.name` 或 `instanceof` 进行分支处理。 +所有 SDK 错误都扩展了 `StableError`,后者又扩展了 viem 的 `BaseError`。错误携带结构化元数据,因此您可以根据 `error.name` 或 `instanceof` 进行分支。 -| **类** | **抛出时机** | **有用的字段** | +| **类** | **抛出条件** | **有用字段** | | :--- | :--- | :--- | -| `StableValidationError` | 参数验证失败(地址错误、金额非有限值、不支持的链)。 | `field`、`value` | -| `StableQuoteError` | 向 LI.FI 发起的报价请求失败。 | `provider`、`httpStatus`、`providerCode`、`body` | -| `StableTransactionError` | 链上步骤失败:切换链、授权、发送或回滚。 | `phase`、`txHash`、`chainId`、`revertReason` | +| `StableValidationError` | 参数验证失败(地址错误、非有限金额、不支持的链)。 | `field`, `value` | +| `StableQuoteError` | 向 LI.FI 发出的报价请求失败。 | `provider`, `httpStatus`, `providerCode`, `body` | +| `StableTransactionError` | 链上步骤失败:链切换、批准、发送或回滚。 | `phase`, `txHash`, `chainId`, `revertReason` | | `StableNetworkError` | 底层 HTTP/RPC 调用失败。 | `url` | ```ts @@ -216,7 +216,7 @@ try { await stable.transfer({ from, to, amount: 1 }); } catch (err) { if (err instanceof StableTransactionError && err.phase === "switch_chain") { - // user rejected the chain switch + // 用户拒绝了链切换 } throw err; } @@ -228,8 +228,8 @@ StableTransactionError: transfer: wallet rejected or failed to switch to chain 9 Chain ID: 988 ``` -## 推荐的后续步骤 +## 建议下一步 -- [**SDK 快速开始**](/cn/tutorial/sdk-quickstart) —— 安装 SDK 并在测试网上运行你的第一笔转账。 -- [**与 viem 一起使用**](/cn/how-to/sdk-with-viem) —— 在私钥、浏览器钱包和预构建签名者之间切换。 -- [**与 wagmi 一起使用**](/cn/how-to/sdk-with-wagmi) —— 通过 hooks 将 SDK 接入 React 应用。 +- [**SDK 快速入门**](/cn/tutorial/sdk-quickstart):安装 SDK 并在测试网上运行您的首次传输。 +- [**与 viem 结合使用**](/cn/how-to/sdk-with-viem):在私钥、浏览器钱包和预构建的签名器之间切换。 +- [**与 wagmi 结合使用**](/cn/how-to/sdk-with-wagmi):使用挂钩将 SDK 连接到 React 应用程序。 diff --git a/docs/pages/cn/resources/brand-kit.mdx b/docs/pages/cn/resources/brand-kit.mdx index 59c2f95..be6a214 100755 --- a/docs/pages/cn/resources/brand-kit.mdx +++ b/docs/pages/cn/resources/brand-kit.mdx @@ -1,12 +1,13 @@ --- source_path: resources/brand-kit.mdx -source_sha: df4ff065c6969109cea93c5217b43a2f1ee1e573 -title: "Brand Kit" -description: "供项目与传播使用的 Stable 品牌套件,包含 Logo 与色彩规范。" +source_sha: 668023711259b32b450e229eaa7f0f808795f146 +title: "品牌资料" +description: "Stable 的品牌资料,包含标志和调色板,用于项目和通信中的一致使用。" +diataxis: "reference" --- -# Brand Kit +# 品牌资料 -您可以在下方找到 Stable 的Brand Kit,其中包含标志的多种格式版本和配色方案。本工具包旨在帮助您在项目或传播中使用 Stable 品牌时保持一致性。 +Stable 品牌资料包含多种格式的标志和官方调色板。使用此资料可在所有项目和通信中保持 Stable 品牌的一致性。 -[前往 Stable 品牌资源库](https://www.stable.xyz/brand-kit) +[打开 Stable 品牌资料](https://www.stable.xyz/brand-kit) diff --git a/docs/pages/cn/tutorial/bridge-usdt0.mdx b/docs/pages/cn/tutorial/bridge-usdt0.mdx index 6cc2276..a7dbee0 100644 --- a/docs/pages/cn/tutorial/bridge-usdt0.mdx +++ b/docs/pages/cn/tutorial/bridge-usdt0.mdx @@ -1,28 +1,28 @@ --- source_path: tutorial/bridge-usdt0.mdx -source_sha: 401984b7572b9f0b7ee12064bf18768f17849e60 -title: "将 USDT0 跨链桥接到 Stable" -description: "一份分步教程,介绍如何使用 LayerZero 的 OFT 协议将 USDT0 从 Ethereum Sepolia 桥接到 Stable Testnet。" +source_sha: 975772bc0a56943603358f10eeb56b45d01a2d24 +title: "将 USDT0 桥接到 Stable" +description: "一个分步教程,使用 LayerZero 的 OFT 协议将 USDT0 从以太坊 Sepolia 桥接到 Stable 测试网。" type: "tutorial" diataxis: "tutorial" --- -# 将 USDT0 跨链桥接到 Stable +# 将 USDT0 桥接到 Stable -在本教程中,你将使用 TypeScript 和 ethers v6 以编程方式将 USDT0 从 Ethereum Sepolia 桥接到 Stable Testnet。你将逐步构建这个脚本,每一步添加一个函数。 +在本教程中,您将使用 TypeScript 和 ethers v6 通过编程方式将 USDT0 从以太坊 Sepolia 桥接到 Stable 测试网。您将逐步构建脚本,每一步添加一个函数。 -本教程使用 OFT Mesh 路径。Sepolia 上的 OFT Adapter 锁定你的代币,LayerZero 的双 DVN 验证确认消息,然后在 Stable 上铸造 USDT0。要全面了解其工作原理,请参阅[桥接到 Stable](/cn/explanation/usdt0-bridging)。 +本教程使用 OFT Mesh 路径。Sepolia 上的 OFT 适配器锁定您的代币,LayerZero 的双 DVN 验证确认消息,然后在 Stable 上铸造 USDT0。有关其工作原理的完整说明,请参阅[桥接到 Stable](/cn/explanation/usdt0-bridging)。 :::note -想要更少的代码行数吗?[Stable SDK](/cn/explanation/sdk-overview) 暴露了 `quoteBridge` 和 `bridge`,并会为你选择路由(LayerZero 或 LI.FI)。 +想要更少的代码行?[Stable SDK](/cn/explanation/sdk-overview) 公开了 `quoteBridge` 和 `bridge`,并为您选择路由(LayerZero 或 LI.FI)。 ::: -## 前置条件 +## 先决条件 -- Node.js 18.0.0 或更高版本(使用 `node --version` 验证) -- 一个你掌控私钥的 Sepolia 钱包(切勿使用持有真实资金的私钥) -- 用于支付 gas 的 SepoliaETH(从 [sepoliafaucet.com](https://sepoliafaucet.com) 或 [faucets.chain.link/sepolia](https://faucets.chain.link/sepolia) 获取) -- 对在终端中运行脚本有基本的了解 +- Node.js 18.0.0 或更高版本(通过 `node --version` 验证) +- 一个由您控制私钥的 Sepolia 钱包(切勿使用持有真实资金的私钥) +- 用于 gas 的 SepoliaETH(可以从 [sepoliafaucet.com](https://sepoliafaucet.com) 或 [faucets.chain.link/sepolia](https://faucets.chain.link/sepolia) 获取) +- 对从终端运行脚本有基本了解 --- @@ -35,7 +35,7 @@ npm install ethers@6 @layerzerolabs/lz-v2-utilities npm install -D tsx ``` -你的 `package.json` 应包含: +您的 `package.json` 应包含: ```json { @@ -54,23 +54,23 @@ npm install -D tsx } ``` -## 2. 配置你的环境 +## 2. 配置您的环境 -创建一个包含你的凭据的 `.env` 文件: +创建 `.env` 文件并包含您的凭据: ```bash PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE SEPOLIA_RPC_URL=https://rpc.sepolia.org ``` -对于 `SEPOLIA_RPC_URL`,以下任何一个都可用: -- 公共节点:`https://rpc.sepolia.org` 或 `https://ethereum-sepolia-rpc.publicnode.com` +对于 `SEPOLIA_RPC_URL`,以下任何一项均可: +- 公共:`https://rpc.sepolia.org` 或 `https://ethereum-sepolia-rpc.publicnode.com` - Alchemy:`https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY` - Infura:`https://sepolia.infura.io/v3/YOUR_KEY` -## 3. 搭建脚本骨架 +## 3. 构建脚本 -创建 `bridge.ts`,包含导入、配置和一个 `main` 函数。你将在接下来的步骤中向该文件添加函数,并从 `main` 中调用它们。 +创建 `bridge.ts` 文件,其中包含导入、配置和一个 `main` 函数。您将在以下步骤中向此文件添加函数,并从 `main` 调用它们。 ```ts import { ethers, Contract, Wallet, JsonRpcProvider } from "ethers"; @@ -126,21 +126,21 @@ main().catch((err) => { ## 4. 在 Sepolia 上铸造测试 USDT0 -Sepolia 上的测试 USDT0 合约暴露了一个公开的 `mint` 函数。将以下函数添加到 `bridge.ts` 中 `main` 的上方: +Sepolia 上的测试 USDT0 合约公开了一个公共 `mint` 函数。将以下函数添加到 `bridge.ts` 中 `main` 函数的上方: ```ts async function mint(usdt0: Contract, receiver: string, amount: bigint) { - console.log(`Minting ${ethers.formatEther(amount)} USDT0 on Sepolia...`); + console.log(`在 Sepolia 上铸造 ${ethers.formatEther(amount)} USDT0...`); const tx = await usdt0.mint(receiver, amount); await tx.wait(); - console.log(`Mint tx: ${tx.hash} confirmed`); + console.log(`铸造交易: ${tx.hash} 已确认`); const balance = await usdt0.balanceOf(receiver); - console.log(`USDT0 balance: ${ethers.formatEther(balance)}`); + console.log(`USDT0 余额: ${ethers.formatEther(balance)}`); } ``` -然后从 `main` 中调用它: +然后从 `main` 调用它: ```ts await mint(usdt0, wallet.address, amount); @@ -154,44 +154,44 @@ npx tsx --env-file=.env bridge.ts --- -**检查点:** 铸造确认后,你应该会看到日志中记录了一个非零的 USDT0 余额。 +**检查点:** 您应该看到铸造确认后记录的非零 USDT0 余额。 --- -## 5. 授权 OFT Adapter +## 5. 批准 OFT 适配器 -在 OFT Adapter 能够转移你的代币之前,它需要一个 ERC-20 授权额度。将此函数添加到 `main` 上方: +在 OFT 适配器移动您的代币之前,它需要一个 ERC-20 授权。将此函数添加到 `main` 上方: ```ts async function approve(usdt0: Contract, spender: string, owner: string, amount: bigint) { - console.log("Approving OFT Adapter..."); + console.log("正在批准 OFT 适配器..."); const tx = await usdt0.approve(spender, amount); await tx.wait(); - console.log(`Approve tx: ${tx.hash} confirmed`); + console.log(`批准交易: ${tx.hash} 已确认`); const allowance = await usdt0.allowance(owner, spender); - console.log(`Allowance: ${ethers.formatEther(allowance)}`); + console.log(`授权金额: ${ethers.formatEther(allowance)}`); } ``` -在 `main` 中 `mint` 之后添加调用: +在 `main` 中的 `mint` 之后添加调用: ```ts // await mint(usdt0, wallet.address, amount); await approve(usdt0, SEPOLIA_OFT_ADAPTER, wallet.address, amount); ``` -运行脚本。如果你已经在上一次运行中获得了代币,可以注释掉 `await mint(...)` 调用。 +运行脚本。如果之前运行已获得代币,您可以注释掉 `await mint(...)` 调用。 --- -**检查点:** 授权确认后,脚本应记录一个非零的授权额度。 +**检查点:** 批准确认后,脚本应记录非零授权金额。 --- ## 6. 报价费用并发送桥接交易 -`quoteSend` 调用返回以 SepoliaETH 计价的 LayerZero 消息费用,你需要将其作为 `msg.value` 传递给 `send`。将此函数添加到 `main` 上方: +`quoteSend` 调用返回 SepoliaETH 中的 LayerZero 消息费用,您将其作为 `msg.value` 传递给 `send`。将此函数添加到 `main` 上方: ```ts async function send(oftAdapter: Contract, receiver: string, amount: bigint) { @@ -207,23 +207,23 @@ async function send(oftAdapter: Contract, receiver: string, amount: bigint) { oftCmd: "0x", }; - console.log("Quoting bridge fee..."); + console.log("正在报价桥接费用..."); const feeResult = await oftAdapter.quoteSend(sendParams, false); const fee = { nativeFee: feeResult.nativeFee, lzTokenFee: feeResult.lzTokenFee }; - console.log(`Bridge fee: ${ethers.formatEther(fee.nativeFee)} ETH`); + console.log(`桥接费用: ${ethers.formatEther(fee.nativeFee)} ETH`); - console.log("Sending bridge transaction..."); + console.log("正在发送桥接交易..."); const tx = await oftAdapter.send(sendParams, fee, receiver, { value: fee.nativeFee, }); await tx.wait(); - console.log(`Bridge tx: ${tx.hash} confirmed`); + console.log(`桥接交易: ${tx.hash} 已确认`); console.log(`Sepolia Etherscan: https://sepolia.etherscan.io/tx/${tx.hash}`); console.log(`LayerZero Scan: https://testnet.layerzeroscan.com/tx/${tx.hash}`); } ``` -在 `main` 中 `approve` 之后添加调用: +在 `main` 中的 `approve` 之后添加调用: ```ts // await mint(usdt0, wallet.address, amount); @@ -231,13 +231,13 @@ async function send(oftAdapter: Contract, receiver: string, amount: bigint) { await send(oftAdapter, wallet.address, amount); ``` -## 7. 验证到达 Stable Testnet +## 7. 验证在 Stable 测试网上的到账 -发送后,脚本可以轮询 Stable Testnet RPC,直到代币到达。将此函数添加到 `main` 上方: +发送后,脚本可以轮询 Stable 测试网 RPC 直到代币到达。将此函数添加到 `main` 上方: ```ts async function verify(receiver: string) { - console.log("Waiting for DVN verification (~2 minutes)..."); + console.log("等待 DVN 验证 (~2 分钟)..."); const stableProvider = new JsonRpcProvider("https://rpc.testnet.stable.xyz"); const stableUsdt0 = new Contract(STABLE_USDT0, ["function balanceOf(address) view returns (uint256)"], stableProvider); @@ -247,18 +247,18 @@ async function verify(receiver: string) { await new Promise((r) => setTimeout(r, 5000)); const current: bigint = await stableUsdt0.balanceOf(receiver); if (current > before) { - console.log(`\nUSDT0 on Stable: ${ethers.formatEther(current)}`); - console.log(`Explorer: https://testnet.stablescan.xyz/address/${receiver}`); + console.log(`\nStable 上的 USDT0: ${ethers.formatEther(current)}`); + console.log(`浏览器: https://testnet.stablescan.xyz/address/${receiver}`); return; } process.stdout.write("."); } - console.log("\nTokens have not arrived yet. Check manually:"); - console.log(`Explorer: https://testnet.stablescan.xyz/address/${receiver}`); + console.log("\n代币尚未到账。请手动检查:"); + console.log(`浏览器: https://testnet.stablescan.xyz/address/${receiver}`); } ``` -在 `main` 中 `send` 之后添加调用: +在 `main` 中的 `send` 之后添加调用: ```ts // await mint(usdt0, wallet.address, amount); @@ -267,9 +267,9 @@ async function verify(receiver: string) { await verify(wallet.address); ``` -## 8. 运行完整的桥接流程 +## 8. 运行完整的桥接 -你的 `main` 函数现在应该如下所示: +您的 `main` 函数现在应该看起来像这样: ```ts async function main() { @@ -296,9 +296,9 @@ npx tsx --env-file=.env bridge.ts --- -**检查点:** 你应该会看到类似这样的输出: +**检查点:** 您应该看到如下输出: -``` +```text Minting 1.0 USDT0 on Sepolia... Mint tx: 0x3a1f...c9d2 confirmed USDT0 balance: 1.0 @@ -316,23 +316,23 @@ Waiting for DVN verification (~2 minutes)... USDT0 on Stable: 1.0 ``` -你也可以在 [Stable Testnet 浏览器](https://testnet.stablescan.xyz)上搜索你的钱包地址,以确认铸造事件。 +您还可以搜索您的钱包地址在[Stable 测试网浏览器](https://testnet.stablescan.xyz)上,以确认铸币事件。 --- -## 你所构建的内容 +## 您已构建的内容 -你已将 USDT0 从 Ethereum Sepolia 桥接到了 Stable Testnet。现在你知道如何: +您已将 USDT0 从以太坊 Sepolia 桥接到 Stable 测试网。您现在知道如何: -- 使用合约的公开 `mint` 函数在 Sepolia 上铸造测试 USDT0 -- 授权 OFT Adapter 代表你花费 ERC-20 代币 -- 使用 32 字节地址编码和执行器选项构造 LayerZero `sendParams` +- 使用合约的公共 `mint` 函数在 Sepolia 上铸造测试 USDT0 +- 批准 OFT 适配器代表您花费 ERC-20 代币 +- 使用 32 字节地址编码和执行器选项构建 LayerZero `sendParams` - 在提交资金之前使用 `quoteSend` 报价跨链消息费用 -- 使用 `send` 执行跨链代币转移,并在目标链上确认送达 -- 使用 Stable 的 RPC(`https://rpc.testnet.stable.xyz`,chain ID `2201`)和 Stablescan 验证链上状态 +- 执行跨链代币转移,并确认在目标链上交付 +- 使用 Stable 的 RPC (`https://rpc.testnet.stable.xyz`,链 ID `2201`) 和 Stablescan 验证链上状态 -## 推荐的后续步骤 +## 下一步推荐 -- [**发送你的第一笔 USDT0**](/cn/tutorial/send-usdt0) — 使用桥接得到的 USDT0 进行原生转账和 ERC-20 转账。 -- [**桥接到 Stable**](/cn/explanation/usdt0-bridging) — 深入了解 OFT Mesh 与 Legacy Mesh 的机制。 -- [**测试网信息**](/cn/reference/testnet-information) — 完整的网络参数、RPC 端点和水龙头详情。 +- [**发送您的第一个 USDT0**](/cn/tutorial/send-usdt0):使用桥接的 USDT0 进行原生和 ERC-20 转移。 +- [**桥接到 Stable**](/cn/explanation/usdt0-bridging):深入了解 OFT Mesh 与 Legacy Mesh 机制。 +- [**测试网信息**](/cn/reference/testnet-information):完整的网络参数、RPC 端点和水龙头详细信息。 diff --git a/docs/pages/cn/tutorial/quick-start.mdx b/docs/pages/cn/tutorial/quick-start.mdx index 983f580..6accd37 100755 --- a/docs/pages/cn/tutorial/quick-start.mdx +++ b/docs/pages/cn/tutorial/quick-start.mdx @@ -1,25 +1,25 @@ --- source_path: tutorial/quick-start.mdx -source_sha: ac60005c171579369156d04b03a48434c2e6bbba -title: "快速开始" -description: "连接到 Stable 测试网,从水龙头为钱包注资,并发送你的第一笔 USDT0 交易" +source_sha: f3a60f028fff5319841801dd9508ebb86d37069f +title: "快速入门" +description: "连接到 Stable 测试网,通过水龙头资助钱包,并发送您的第一个 USDT0 交易" diataxis: "tutorial" --- -# 快速开始 +# 快速入门 -你只需要 Node.js、一些来自水龙头的 USDT0 以及一个私钥。Stable 使用 USDT0 作为其 gas 代币,因此你只需要 USDT0 即可进行交易。无需单独为某种 gas 资产注资。 +您只需要 Node.js、一些来自水龙头的 USDT0 和一个私钥。Stable 使用 USDT0 作为其 Gas 代币,因此您只需 USDT0 即可进行交易。无需资助单独的 Gas 资产。 :::note -更喜欢类型化的客户端?[Stable SDK](/cn/explanation/sdk-overview) 封装了 viem,并提供 `transfer`、`bridge` 和 `swap` 方法,让你省去手动处理 ABI 和小数位的工作。 +偏好类型化客户端?[Stable SDK](/cn/explanation/sdk-overview) 通过 `transfer`、`bridge` 和 `swap` 方法封装了 viem,因此您可以跳过手动 ABI 和小数处理。 ::: -## 前置条件 +## 前提条件 - Node.js 20 或更高版本 -- 一个你掌控的私钥(一个全新的测试密钥即可) +- 您控制的一个私钥(一个新的测试密钥即可) -## 1. 安装与配置 +## 1. 安装和配置 创建一个项目,安装 `ethers`,并保存测试网配置。 @@ -32,7 +32,7 @@ npm init -y && npm install ethers added 1 package, audited 2 packages in 1s ``` -将你的私钥保存到 `.env`: +将您的私钥保存到 `.env`: ```bash echo "PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE" > .env @@ -52,9 +52,9 @@ export const provider = new ethers.JsonRpcProvider(STABLE_TESTNET_RPC); export const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider); ``` -## 2. 为钱包注资 +## 2. 资助钱包 -打印你的地址,然后从水龙头申请测试网 USDT0。 +打印您的地址,然后从水龙头请求测试网 USDT0。 ```typescript // address.ts @@ -71,19 +71,19 @@ npx tsx address.ts Wallet address: 0x1234...abcd ``` -前往 [https://faucet.stable.xyz](https://faucet.stable.xyz),粘贴地址,并选择按钮以接收测试网 USDT0。水龙头会发送 1 USDT0,足以进行数千次原生转账。 +访问 [https://faucet.stable.xyz](https://faucet.stable.xyz),粘贴地址,然后选择按钮以接收测试网 USDT0。水龙头发送 1 USDT0,足以进行数千次原生转账。 -## 3. 发送你的第一笔交易 +## 3. 发送您的第一笔交易 -原生发送 0.001 USDT0。在 Stable 上,USDT0 是原生资产,因此简单的价值转账是最便宜的方式(21,000 gas)。 +原生发送 0.001 USDT0。在 Stable 上,USDT0 是原生资产,因此简单的价值转账是最便宜的路径(21,000 gas)。 ```typescript // send.ts import { ethers } from "ethers"; import { provider, wallet } from "./config"; -const recipient = "0xRecipientAddress"; // replace with any address -const amount = ethers.parseEther("0.001"); // 0.001 USDT0 (18 decimals, native) +const recipient = "0xRecipientAddress"; // 替换为任意地址 +const amount = ethers.parseEther("0.001"); // 0.001 USDT0 (18 位小数,原生) const block = await provider.getBlock("latest"); const baseFee = block!.baseFeePerGas!; @@ -92,7 +92,7 @@ const tx = await wallet.sendTransaction({ to: recipient, value: amount, maxFeePerGas: baseFee * 2n, - maxPriorityFeePerGas: 0n, // always 0 on Stable + maxPriorityFeePerGas: 0n, // 在 Stable 上始终为 0 }); const receipt = await tx.wait(1); @@ -109,14 +109,14 @@ Tx: 0x8f3a...2d41 Explorer: https://testnet.stablescan.xyz/tx/0x8f3a...2d41 ``` -打开浏览器链接以确认该交易。出块时间大约为 0.7 秒,因此它应该已经最终确认。 +打开浏览器链接以确认交易。出块时间约为 0.7 秒,因此它应该已经最终确定。 :::warning -`maxPriorityFeePerGas` 会被 Stable 忽略,并且必须设置为 `0`。请参阅 [Gas 定价](/cn/reference/gas-pricing-api),了解仅基于 base-fee 的模型如何改变交易构造。 +`maxPriorityFeePerGas` 被 Stable 忽略,并且必须设置为 `0`。有关仅基础费用模型如何改变交易构造,请参阅[Gas 定价](/cn/reference/gas-pricing-api)。 ::: ## 接下来去哪里 -- [**部署智能合约**](/cn/tutorial/smart-contract) — 搭建一个 Foundry 项目并部署到 Stable 测试网。 -- [**构建支付应用**](/cn/how-to/build-p2p-payments) — 创建钱包,发送、接收并查询支付历史。 -- [**使用 AI 进行开发**](/cn/how-to/develop-with-ai) — 将 MCP 服务器和 agent 技能接入你的 AI 编辑器。 +- [**部署智能合约**](/cn/tutorial/smart-contract):搭建 Foundry 项目并部署到 Stable 测试网。 +- [**构建支付应用程序**](/cn/how-to/build-p2p-payments):创建钱包,发送、接收和查询支付历史记录。 +- [**使用 AI 进行开发**](/cn/how-to/develop-with-ai):将 MCP 服务器和代理技能连接到您的 AI 编辑器。 diff --git a/docs/pages/cn/tutorial/sdk-quickstart.mdx b/docs/pages/cn/tutorial/sdk-quickstart.mdx index 489b246..46535db 100644 --- a/docs/pages/cn/tutorial/sdk-quickstart.mdx +++ b/docs/pages/cn/tutorial/sdk-quickstart.mdx @@ -1,23 +1,23 @@ --- source_path: tutorial/sdk-quickstart.mdx -source_sha: 7f6797e29245d890cb46a01da0c772ffc797b252 -title: "SDK 快速开始" -description: "安装 Stable SDK,在测试网上发送你的第一笔 USDT0 转账,并预览跨链桥和兑换报价。" +source_sha: 24bdfc4340389e06e1cb06ee6a7f3e1939940c97 +title: "SDK 快速入门" +description: "安装 Stable SDK,在测试网上发送第一个 USDT0 转账,并预览桥接和互换报价。" diataxis: "tutorial" --- -# SDK 快速开始 +# SDK 快速入门 -你将安装 `@stablechain/sdk`,创建一个由私钥签名的客户端,在 Stable Testnet 上发送一笔 USDT0 转账,并获取跨链桥和兑换报价。总耗时约五分钟。 +你将安装 `@stablechain/sdk`,使用私钥创建客户端,在 Stable 测试网上发送 USDT0 转账,并获取桥接和互换报价。总耗时:大约五分钟。 :::note -Stable 使用 USDT0 作为 gas 代币。你只需要测试网 USDT0 即可进行交易——无需另外充值单独的原生资产。 +Stable 使用 USDT0 作为 Gas 代币。你只需要测试网 USDT0 即可进行交易。无需为单独的原生资产充值。 ::: ## 前提条件 - Node.js 20 或更高版本 -- 一个持有测试网 USDT0 的测试私钥。参见 [为你的测试网钱包充值](/cn/how-to/use-faucet)。 +- 一个包含测试网 USDT0 的测试私钥。请参阅[为你的测试网钱包充值](/cn/how-to/use-faucet)。 ## 1. 安装 @@ -59,7 +59,7 @@ console.log("Signer:", account.address); Signer: 0xYourAddress ``` -`createStable` 接受三种签名模式:`account`(服务端,如上所示)、`transport`(通过 `custom(window.ethereum)` 的浏览器钱包),或 `walletClient`(预先构建的 viem `WalletClient`)。三种方式的完整说明请参见 [将 SDK 与 viem 一起使用](/cn/how-to/sdk-with-viem)。 +`createStable` 接受三种签名模式:`account`(服务器端,如上所示)、`transport`(通过 `custom(window.ethereum)` 进行浏览器钱包签名)或 `walletClient`(预构建的 viem `WalletClient`)。有关所有三种模式的详细信息,请参阅[将 SDK 与 viem 结合使用](/cn/how-to/sdk-with-viem)。 ## 3. 发送 USDT0 转账 @@ -75,7 +75,7 @@ const { txHash } = await stable.transfer({ console.log("Transfer:", txHash); ``` -运行它: +运行: ```bash npx tsx index.ts @@ -86,11 +86,11 @@ Signer: 0xYourAddress Transfer: 0x8f3a...2d41 ``` -在[测试网浏览器](https://testnet.stablescan.xyz)上打开该哈希以确认。 +在 [testnet explorer](https://testnet.stablescan.xyz) 上打开哈希以确认。 -## 4. 获取跨链桥报价 +## 4. 报价桥接 -将 USDT0 从 Ethereum Sepolia 跨链桥接到 Stable Testnet。`quoteBridge` 是一个只读调用——无需签名,无需 gas: +将 USDT0 从 Ethereum Sepolia 桥接到 Stable Testnet。`quoteBridge` 是一个只读调用,无需签名和 Gas 费用: ```ts import { Chain } from "@stablechain/sdk"; @@ -110,11 +110,11 @@ console.log("Bridge quote:", bridgeQuote); Bridge quote: { toAmount: 0.999812 } ``` -将报价传入 `stable.bridge({ ...params, quote })` 以执行。SDK 为 USDT0 → USDT0 路由选择 LayerZero,其他所有情况则选择 LI.FI。 +将报价传递给 `stable.bridge({ ...params, quote })` 以执行。SDK 会为 USDT0 → USDT0 路由选择 LayerZero,并为其他所有路由选择 LI.FI。 -## 5. 获取兑换报价 +## 5. 报价互换 -兑换通过 LI.FI 在 Stable 上运行。报价返回预期输出和一个预先构建的交易: +互换在 Stable 上通过 LI.FI 运行。报价返回预期输出和预构建的交易: ```ts const swapQuote = await stable.quoteSwap({ @@ -131,10 +131,10 @@ console.log("You'll receive:", swapQuote.toAmount, "USDT0"); You'll receive: 0.998 USDT0 ``` -调用 `stable.swap({ ...params, quote: swapQuote })` 以执行。ERC-20 来源的授权由内部处理。 +调用 `stable.swap({ ...params, quote: swapQuote })` 以执行。ERC-20 源的批准是在内部处理的。 -## 后续推荐 +## 接下来推荐 -- [**SDK 参考**](/cn/reference/sdk) — 每个参数、返回类型和错误类。 -- [**与 viem 一起使用**](/cn/how-to/sdk-with-viem) — 在私钥、浏览器钱包和预先构建的 `WalletClient` 签名之间切换。 -- [**与 wagmi 一起使用**](/cn/how-to/sdk-with-wagmi) — 使用 wagmi hooks 将 SDK 接入 React 应用。 +- [**SDK 参考**](/cn/reference/sdk):每个参数、返回类型和错误类。 +- [**与 viem 结合使用**](/cn/how-to/sdk-with-viem):在私钥、浏览器钱包和预构建的 `WalletClient` 签名之间切换。 +- [**与 wagmi 结合使用**](/cn/how-to/sdk-with-wagmi):使用 wagmi 钩子将 SDK 连接到 React 应用。 diff --git a/docs/pages/cn/tutorial/send-usdt0.mdx b/docs/pages/cn/tutorial/send-usdt0.mdx index 4e6b879..a0c0c5e 100644 --- a/docs/pages/cn/tutorial/send-usdt0.mdx +++ b/docs/pages/cn/tutorial/send-usdt0.mdx @@ -1,53 +1,53 @@ --- source_path: tutorial/send-usdt0.mdx -source_sha: 1fff06b2bb41a34bd51591c23054ad451815f05e -title: "发送你的第一笔 USDT0" -description: "在 Stable 上以原生转账和 ERC-20 转账两种方式发送 USDT0,并验证它们使用的是同一个余额。" +source_sha: d631d3ab8138addcd0cd58e30ac907fe503a5d04 +title: "发送第一笔 USDT0" +description: "在 Stable 上以原生转账和 ERC-20 转账的方式发送 USDT0,并验证两者操作的是同一个余额。" diataxis: "tutorial" --- -# 发送你的第一笔 USDT0 +# 发送第一笔 USDT0 -在 Stable 上,USDT0 既是链的原生资产,也是一个 ERC-20 代币。这意味着 `approve`、`transferFrom` 和 `permit` 在标准价值转账之外仍然完全可用,并且这两条路径都从同一个底层余额中转移资金。 +在 Stable 上,USDT0 既是链的原生资产,也是一种 ERC-20 代币。这意味着 `approve`、`transferFrom` 和 `permit` 完全可用,同时支持标准的价值转账,并且这两种方式都从同一个底层余额中转移资金。 -本页将引导你通过这两条路径发送 USDT0,并确认它们都从同一个余额中扣款。 +本页面将引导您通过这两种方式发送 USDT0,并确认它们都从一个余额中提取。 :::note -更喜欢使用带类型的客户端?[Stable SDK](/cn/explanation/sdk-overview) 提供了一个统一的 `transfer({ to, amount, token? })`,它涵盖了两条路径,在链上处理小数位,并为你切换钱包所在的链。 +喜欢类型化的客户端?[Stable SDK](/cn/explanation/sdk-overview) 暴露了一个单独的 `transfer({ to, amount, token? })` 方法,它支持这两种方式,处理链上小数,并为您切换钱包的链。 ::: :::note -**18 位与 6 位小数**:原生 USDT0 使用 18 位小数(标准 EVM 精度),而 ERC-20 接口报告 6 位小数(标准 USDT 精度)。两者反映的是同一个余额,因此由于小数对账,`address(x).balance` 和 `USDT0.balanceOf(x)` 可能相差最多 0.000001 USDT0。请参阅 [USDT0 在 Stable 上的行为](/cn/explanation/usdt0-behavior)。 +**18 位小数与 6 位小数**:原生 USDT0 使用 18 位小数(标准 EVM 精度),而 ERC-20 接口报告 6 位小数(标准 USDT 精度)。两者都反映相同的余额,因此 `address(x).balance` 和 `USDT0.balanceOf(x)` 可能会因小数协调而相差最多 0.000001 USDT0。请参阅 [USDT0 在 Stable 上的行为](/cn/explanation/usdt0-behavior)。 ::: -## 你将构建什么 +## 您将构建什么 -一个两脚本流程:以原生转账方式发送 0.001 USDT0,以 ERC-20 转账方式发送 0.001 USDT0,并打印两个余额。 +一个两步脚本流,以原生转账的方式发送 0.001 USDT0,以 ERC-20 转账的方式发送 0.001 USDT0,并打印两种余额。 ### 演示 ```text -step 1. Connect wallet → balance displayed +步骤 1. 连接钱包 → 显示余额 0.01 USDT0 -step 2. Send 0.001 USDT0 (choose native or ERC-20 transfer) +步骤 2. 发送 0.001 USDT0(选择原生转账或 ERC-20 转账) -step 3. Result - Sent: 0.001 USDT0 - Gas fee: 0.000021 USDT0 - Native balance: 0.008979 USDT0 - ERC-20 balance: 0.008979 USDT0 +步骤 3. 结果 + 发送: 0.001 USDT0 + 手续费: 0.000021 USDT0 + 原生余额: 0.008979 USDT0 + ERC-20 余额: 0.008979 USDT0 ``` -## 前提条件 +## 先决条件 - Node.js 20 或更高版本 -- 一个持有测试网 USDT0 的私钥。请参阅[快速开始](/cn/tutorial/quick-start)为钱包充值。 +- 带有测试网 USDT0 的私钥。请参阅[快速入门](/cn/tutorial/quick-start)以资助钱包。 **USDT0 合约地址** -- 主网:`0x779ded0c9e1022225f8e0630b35a9b54be713736` -- 测试网:`0x78cf24370174180738c5b8e352b6d14c83a6c9a9` +- 主网: `0x779ded0c9e1022225f8e0630b35a9b54be713736` +- 测试网: `0x78cf24370174180738c5b8e352b6d14c83a6c9a9` ## 设置 @@ -64,9 +64,9 @@ export const provider = new ethers.JsonRpcProvider(STABLE_TESTNET_RPC); export const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider); ``` -## 选项 1(推荐):以原生转账方式发送 +## 选项 1 (推荐):作为原生转账发送 -原生转账的工作方式与在以太坊上发送 ETH 相同。`value` 字段携带 USDT0 数量。一次原生转账仅消耗 21,000 gas,是发送 USDT0 最便宜的方式。 +原生转账的工作方式与在以太坊上发送 ETH 相同。`value` 字段携带 USDT0 金额。原生转账仅需 21,000 gas, 是发送 USDT0 最便宜的方式。 ```typescript // sendNative.ts @@ -98,9 +98,9 @@ npx tsx sendNative.ts Native transfer tx: 0x8f3a...2d41 ``` -## 选项 2:以 ERC-20 转账方式发送 +## 选项 2:作为 ERC-20 转账发送 -USDT0 也可以作为 ERC-20 转账发送。这会从同一个余额中扣款,但使用 6 位小数精度的 ERC-20 接口。 +USDT0 也可以作为 ERC-20 转账发送。这会从相同的余额中扣除,但使用 6 位小数精度的 ERC-20 接口。 ```typescript // sendERC20.ts @@ -129,7 +129,7 @@ ERC-20 transfer tx: 0xa2b1...77c0 ## 验证统一余额 -在任一种转账之后,查询两个余额以确认它们来自同一来源。 +在任何一种转账之后,查询两种余额以确认它们来自于同一来源。 ```typescript // balances.ts @@ -151,14 +151,14 @@ npx tsx balances.ts ``` ```text -Native balance: 0.008979 USDT0 -ERC-20 balance: 0.008979 USDT0 +原生余额: 0.008979 USDT0 +ERC-20 余额: 0.008979 USDT0 ``` -这两个值代表的是同一个余额。由于[小数余额对账](/cn/explanation/usdt0-behavior#balance-reconciliation),它们可能相差最多 0.000001 USDT0。 +这两个值代表相同的余额。它们之间可能存在高达 0.000001 USDT0 的差异,这是由于[小数余额协调](/cn/explanation/usdt0-behavior#balance-reconciliation)造成的。 -## 推荐的下一步 +## 下一步推荐 -- [**零 gas 交易**](/cn/how-to/zero-gas-transactions) — 通过豁免服务支付 gas 费来发送 USDT0。 -- [**构建 P2P 支付应用**](/cn/how-to/build-p2p-payments) — 创建钱包、发送、接收并查询支付历史。 -- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior) — 了解双角色余额对账和合约设计。 +- [**零 Gas 费交易**](/cn/how-to/zero-gas-transactions):使用豁免服务支付 Gas 费来发送 USDT0。 +- [**构建 P2P 支付应用**](/cn/how-to/build-p2p-payments):创建钱包、发送、接收并查询支付历史。 +- [**USDT0 在 Stable 上的行为**](/cn/explanation/usdt0-behavior):了解双重角色余额协调和合约设计。 diff --git a/docs/pages/cn/tutorial/smart-contract.mdx b/docs/pages/cn/tutorial/smart-contract.mdx index 7347f03..f0acd02 100644 --- a/docs/pages/cn/tutorial/smart-contract.mdx +++ b/docs/pages/cn/tutorial/smart-contract.mdx @@ -1,34 +1,34 @@ --- source_path: tutorial/smart-contract.mdx -source_sha: 55828da2370736b531a7427f6a8d2aeac3e6fe48 +source_sha: c0e4ec8dbb55d2a0f3067fe66608accef1c88fa6 title: "部署智能合约" -description: "搭建 Foundry 项目,用 USDT0 为钱包充值,将合约部署到 Stable 测试网,并在链上验证它。" +description: "搭建 Foundry 项目,使用 USDT0 为钱包注资,将合约部署到 Stable 测试网,并在链上进行验证。" diataxis: "tutorial" --- # 部署智能合约 -在本教程中,你将向 Stable 测试网部署一个简单的智能合约,并从链上读取其状态。在此过程中,你将了解 Stable 网络的配置方式、USDT0 如何作为 gas 代币运作,以及如何将标准 EVM 工具指向 Stable。 +在本教程中,你将把一个简单的智能合约部署到 Stable 测试网,并从链上读取其状态。在此过程中,你将了解 Stable 网络的配置方式、USDT0 作为 Gas 代币的工作原理,以及如何将标准 EVM 工具指向 Stable。 -本教程假设你对 Solidity 和类 Unix 终端有基本了解。无需任何 Stable 经验。 +本教程假设你对 Solidity 和类 Unix 终端有基本的了解。无需事先了解 Stable。 ## 你将构建什么 -一个全新的 Foundry 项目,包含示例 `Counter` 合约,部署到 Stable 测试网,并进行一次状态变更调用和一次读取调用。 +一个全新的 Foundry 项目,包含示例 `Counter` 合约,部署到 Stable 测试网,进行一次状态更改调用和一次读取调用。 ### 演示 ```text -step 1. Scaffold Foundry project → stable-hello/ +step 1. 搭建 Foundry 项目 → stable-hello/ -step 2. Configure testnet +step 2. 配置测试网 RPC: https://rpc.testnet.stable.xyz Chain ID: 2201 -step 3. Fund wallet from faucet (1 USDT0) +step 3. 从水龙头为钱包注资 (1 USDT0) step 4. forge create Counter - Deployed to: 0xContract... + 部署到: 0xContract... step 5. cast send Counter.setNumber(42) @@ -36,25 +36,25 @@ step 6. cast call Counter.number() → 42 ``` -## 前置条件 +## 前提条件 -- 已安装 [Foundry](https://book.getfoundry.sh/getting-started/installation)(`forge`、`cast` 和 `anvil` 已在你的 PATH 中可用) -- 一个你掌控私钥的钱包(使用新的测试密钥即可;切勿使用持有真实资金的密钥在测试网上操作) -- 可访问测试网 RPC 和水龙头的网络连接 +- [Foundry](https://book.getfoundry.sh/getting-started/installation) 已安装(`forge`、`cast` 和 `anvil` 可在你的 PATH 中找到) +- 一个你拥有私钥的钱包(新的测试密钥即可;切勿在测试网中使用持有真实资金的密钥) +- 能访问测试网 RPC 和水龙头的互联网连接 --- -## 1. 创建一个新的 Foundry 项目 +## 1. 创建新的 Foundry 项目 -运行以下命令搭建一个全新项目: +运行以下命令搭建新项目: ```bash forge init stable-hello && cd stable-hello ``` -Foundry 会创建一个 `src/` 目录,其中包含一个示例 `Counter.sol` 合约和一个匹配的测试文件。你将原样部署此合约。目标是让一些真实的东西上链,而不是编写新颖的 Solidity。 +Foundry 会创建一个 `src/` 目录,其中包含示例 `Counter.sol` 合约和匹配的测试文件。你将按原样部署此合约。目标是在链上实现真实功能,而不是编写新颖的 Solidity 代码。 -## 2. 查看你将要部署的合约 +## 2. 审查你正在部署的合约 打开 `src/Counter.sol`。它包含两个函数: @@ -75,7 +75,7 @@ contract Counter { } ``` -`number` 是一个存储在链上的公开状态变量。`increment()` 和 `setNumber()` 是更改它的两种方式。读取 `number` 不需要 gas。它是一次免费的 `eth_call`。 +`number` 是存储在链上的公共状态变量。`increment()` 和 `setNumber()` 是更改它的两种方式。读取 `number` 不消耗 Gas。它是一个免费的 `eth_call`。 ## 3. 配置 Stable 测试网 @@ -85,24 +85,24 @@ contract Counter { touch .env ``` -添加以下内容,并将占位符替换为你的实际私钥: +添加以下内容,将占位符替换为你的实际私钥: ```bash PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE ``` -接下来,打开 `foundry.toml` 并将 Stable 测试网添加为一个命名的网络配置。在现有的 `[profile.default]` 部分下方追加此代码块: +接下来,打开 `foundry.toml`,并将 Stable 测试网添加为命名网络配置文件。将其追加到现有的 `[profile.default]` 部分下方: ```toml [rpc_endpoints] stable_testnet = "https://rpc.testnet.stable.xyz" ``` -这告诉 Foundry 当你以 `stable_testnet` 为目标时将交易发送到哪里。Stable 兼容 EVM,因此不需要其他配置。 +这会告诉 Foundry,当你针对 `stable_testnet` 时,交易应发送到何处。Stable 兼容 EVM,因此无需其他配置。 --- -**检查点:** 确认你的 RPC 端点可访问: +**检查点:**确认你的 RPC 端点可访问: ```bash cast chain-id --rpc-url https://rpc.testnet.stable.xyz @@ -110,46 +110,46 @@ cast chain-id --rpc-url https://rpc.testnet.stable.xyz 预期输出: -``` +```text 2201 ``` -链 ID `2201` 是 Stable 测试网。如果你看到这个数字,说明你的机器可以访问该网络。 +链 ID `2201` 是 Stable Testnet。如果你看到此数字,则你的机器可以访问该网络。 --- ## 4. 获取你的钱包地址 -从你的私钥派生出部署者地址,以便知道要为哪个账户充值: +从你的私钥派生你的部署者地址,以便你知道要为哪个账户注资: ```bash source .env cast wallet address $PRIVATE_KEY ``` -复制打印出来的地址。你将在下一步中用到它。 +复制打印出的地址。你在下一步中需要它。 -## 5. 用 USDT0 为钱包充值 +## 5. 使用 USDT0 为你的钱包注资 -Stable 使用 **USDT0** 作为其 gas 代币。你用于支付商品和服务的同一种资产被直接用于支付计算费用。没有次要的原生代币。 +Stable 使用 **USDT0** 作为其 Gas 代币。你用于支付商品和服务的相同资产直接用于支付计算费用。没有二级原生代币。 访问测试网水龙头并请求资金: -``` +```text https://faucet.stable.xyz ``` -粘贴上一步中的地址。水龙头会向你的钱包发送 1 USDT0,足以部署并与多个合约交互。 +粘贴上一步中的地址。水龙头会向你的钱包发送 1 USDT0,这足以部署并与多个合约交互。 --- -**检查点:** 确认你的余额已到账: +**检查点:**确认你的余额已到账: ```bash cast balance $PRIVATE_KEY --rpc-url https://rpc.testnet.stable.xyz ``` -你应该会看到一个非零的值。如果余额仍为 `0`,请等待几秒钟并重新运行。Stable 大约每 0.7 秒产生一个新区块,因此资金会很快结算。 +你应该会看到一个非零值。如果余额仍然是 `0`,请等待几秒钟并重新运行。Stable 大约每 0.7 秒生成一个新块,因此资金很快就会结算。 --- @@ -165,27 +165,27 @@ forge create src/Counter.sol:Counter \ --broadcast ``` -Foundry 会编译合约,广播一笔部署交易,并等待回执。由于出块时间约为 0.7 秒,这只需片刻。 +Foundry 编译合约,广播部署交易,并等待收据。由于出块时间约为 0.7 秒,因此这只需片刻。 --- -**检查点:** 输出应如下所示: +**检查点:**输出应如下所示: -``` -[⠒] Compiling... -No files changed, compilation skipped -Deployer: 0xYourAddress -Deployed to: 0xSomeContractAddress -Transaction hash: 0xSomeTxHash +```text +[⠒] 正在编译... +没有文件更改,跳过编译 +部署者:0xYourAddress +部署到:0xSomeContractAddress +交易哈希:0xSomeTxHash ``` -复制 `Deployed to` 地址。你将在接下来的两个步骤中用到它。 +复制 `Deployed to` 地址。你在接下来的两个步骤中需要它。 --- ## 7. 调用写入函数 -现在调用 `setNumber()` 在链上存储一个值: +现在调用 `setNumber()` 以在链上存储一个值: ```bash cast send 0xSomeContractAddress "setNumber(uint256)" 42 \ @@ -193,11 +193,11 @@ cast send 0xSomeContractAddress "setNumber(uint256)" 42 \ --private-key $PRIVATE_KEY ``` -这会发送一笔交易。你需要为这次状态变更支付一笔少量的 USDT0 费用。值 `42` 现在存储在 Stable 测试网上的 `number` 变量中。 +这会发送一笔交易。你正在支付少量的 USDT0 费用来进行状态更改。值 `42` 现在存储在 Stable 测试网上的 `number` 变量中。 -## 8. 从链上读取状态 +## 8. 从链中读取状态 -调用 `number()` 读回该值。这是一次免费的读取,没有交易也没有 gas: +调用 `number()` 以读回该值。这是一个免费读取,无需交易,也无需 Gas: ```bash cast call 0xSomeContractAddress "number()(uint256)" \ @@ -206,35 +206,35 @@ cast call 0xSomeContractAddress "number()(uint256)" \ 预期输出: -``` +```text 42 ``` -你刚刚向 Stable 测试网写入并从中读取数据。这次往返——部署、写入、读取——是 EVM 开发的核心循环,它在这里的运作方式与任何其他 EVM 链完全相同。 +你刚刚写入并读取了 Stable 测试网。往返(部署、写入、读取)是 EVM 开发的核心循环,它在这里的运行方式与任何其他 EVM 链完全相同。 ## 9. 在 Stablescan 上检查你的部署 打开 Stable 测试网区块浏览器并粘贴你的合约地址: -``` +```text https://testnet.stablescan.xyz ``` -你将看到你的部署交易以及你所做的 `setNumber` 调用。Stablescan 是检查链上状态、验证合约源代码以及读取 Stable 上交易历史的标准工具。 +你将看到你的部署交易和你进行的 `setNumber` 调用。Stablescan 是检查链上状态、验证合约源代码以及读取 Stable 上的交易历史记录的规范工具。 --- -## 你已经构建了什么 +## 你构建了什么 -你部署了一个合约,发送了一笔状态变更交易,并读取了链上状态——全部在 Stable 测试网上完成。你现在知道如何: +你部署了一个合约,发送了一笔状态更改交易,并在 Stable 测试网上读取了链上状态。你现在知道如何: -- 配置 Foundry(或任何 EVM 工具链)使用标准 RPC 端点以 Stable 为目标 -- 使用 USDT0 水龙头为钱包充值 -- 使用 USDT0 作为 gas 代币支付交易费用 +- 配置 Foundry(或任何 EVM 工具链),使用标准 RPC 端点定位 Stable +- 使用 USDT0 水龙头为钱包注资 +- 使用 USDT0 作为 Gas 代币支付交易费用 - 在 Stablescan 上检查你的工作 -## 推荐的后续步骤 +## 接下来的推荐 -- [**验证合约**](/cn/how-to/verify-contract) —— 将你的源代码上传到 Stablescan,以便用户可以阅读并与之交互。 -- [**索引合约事件**](/cn/how-to/index-contract) —— 使用 ethers.js 订阅事件并回填历史日志。 -- [**Gas 定价参考**](/cn/reference/gas-pricing-api) —— 了解以 USDT0 计价的费用是如何计算的。 +- [**验证合约**](/cn/how-to/verify-contract):将你的源代码上传到 Stablescan,以便用户可以读取并与它交互。 +- [**索引合约事件**](/cn/how-to/index-contract):使用 ethers.js 订阅事件并回填历史日志。 +- [**Gas 定价参考**](/cn/reference/gas-pricing-api):了解 USDT0 计费的费用是如何计算的。 diff --git a/docs/pages/en/explanation/accounts-guides.mdx b/docs/pages/en/explanation/accounts-guides.mdx index cf8f431..a227a66 100755 --- a/docs/pages/en/explanation/accounts-guides.mdx +++ b/docs/pages/en/explanation/accounts-guides.mdx @@ -10,15 +10,15 @@ Every guide, concept, and reference under the Accounts tab, grouped by what you' ## Set up a wallet -- [**Create a wallet**](/en/how-to/create-wallet) — Generate a new key pair or restore from a seed phrase using ethers.js or the Tether WDK. -- [**Agent wallets**](/en/reference/agentic-wallets) — Self-custodied wallets for AI agents — how they differ from user wallets. +- [**Create a wallet**](/en/how-to/create-wallet): Generate a new key pair or restore from a seed phrase using ethers.js or the Tether WDK. +- [**Agent wallets**](/en/reference/agentic-wallets): Self-custodied wallets for AI agents (how they differ from user wallets). ## Delegate the account (EIP-7702) -- [**EIP-7702 concept**](/en/explanation/eip-7702) — What EIP-7702 enables on Stable and the security model. -- [**Account abstraction how-to**](/en/how-to/account-abstraction) — Apply EIP-7702 to batch payments, spending limits, and session keys. +- [**EIP-7702 concept**](/en/explanation/eip-7702): What EIP-7702 enables on Stable and the security model. +- [**Account abstraction how-to**](/en/how-to/account-abstraction): Apply EIP-7702 to batch payments, spending limits, and session keys. ## Reference -- [**EIP-7702 API**](/en/reference/eip-7702-api) — Type-4 transaction format and the authorization list. -- [**Subscribe and collect**](/en/how-to/subscribe-and-collect) — Apply an EIP-7702 delegate to a subscription payment flow (cross-listed). +- [**EIP-7702 API**](/en/reference/eip-7702-api): Type-4 transaction format and the authorization list. +- [**Subscribe and collect**](/en/how-to/subscribe-and-collect): Apply an EIP-7702 delegate to a subscription payment flow (cross-listed). diff --git a/docs/pages/en/explanation/accounts-overview.mdx b/docs/pages/en/explanation/accounts-overview.mdx index f1de0ee..a61b405 100755 --- a/docs/pages/en/explanation/accounts-overview.mdx +++ b/docs/pages/en/explanation/accounts-overview.mdx @@ -24,12 +24,12 @@ An account on Stable is a standard Ethereum EOA that can optionally execute smar ## Start here -- [**Create a wallet**](/en/how-to/create-wallet) — Generate or restore a wallet with ethers.js or the Tether WDK. -- [**Delegate with EIP-7702**](/en/how-to/account-abstraction) — Apply batch payments, spending limits, and session keys to an existing EOA. -- [**Stable SDK**](/en/explanation/sdk-overview) — Use the typed client to sign and send transactions from any account. +- [**Create a wallet**](/en/how-to/create-wallet): Generate or restore a wallet with ethers.js or the Tether WDK. +- [**Delegate with EIP-7702**](/en/how-to/account-abstraction): Apply batch payments, spending limits, and session keys to an existing EOA. +- [**Stable SDK**](/en/explanation/sdk-overview): Use the typed client to sign and send transactions from any account. ## Next recommended -- [**Accounts guide index**](/en/explanation/accounts-guides) — Jump to the full list of account guides and references. -- [**EIP-7702 concept**](/en/explanation/eip-7702) — Why delegation works without account migration. -- [**Subscribe and collect**](/en/how-to/subscribe-and-collect) — Apply the Accounts model to a recurring payment flow. +- [**Accounts guide index**](/en/explanation/accounts-guides): Jump to the full list of account guides and references. +- [**EIP-7702 concept**](/en/explanation/eip-7702): Why delegation works without account migration. +- [**Subscribe and collect**](/en/how-to/subscribe-and-collect): Apply the Accounts model to a recurring payment flow. diff --git a/docs/pages/en/explanation/agent-settlement.mdx b/docs/pages/en/explanation/agent-settlement.mdx index 161a49c..1cf4364 100755 --- a/docs/pages/en/explanation/agent-settlement.mdx +++ b/docs/pages/en/explanation/agent-settlement.mdx @@ -43,13 +43,13 @@ agent (client) ──HTTP──▶ resource server ──signed payment── ## Start here -- [**Build a pay-per-call API**](/en/how-to/build-pay-per-call) — Stand up an x402-gated endpoint and settle a real USDT0 payment in the request. -- [**Build an MPP endpoint on Stable**](/en/how-to/build-mpp-endpoint) — Write the three MPP custom-method hooks for USDT0 and settle on Stable. -- [**Develop with AI**](/en/how-to/develop-with-ai) — Wire Docs MCP and Runtime MCP into your AI editor and paste the Stable context block. -- [**Pay with an MCP server**](/en/how-to/pay-with-mcp) — Expose x402-paid APIs as MCP tools an agent can call through natural-language prompts. +- [**Build a pay-per-call API**](/en/how-to/build-pay-per-call): Stand up an x402-gated endpoint and settle a real USDT0 payment in the request. +- [**Build an MPP endpoint on Stable**](/en/how-to/build-mpp-endpoint): Write the three MPP custom-method hooks for USDT0 and settle on Stable. +- [**Develop with AI**](/en/how-to/develop-with-ai): Wire Docs MCP and Runtime MCP into your AI editor and paste the Stable context block. +- [**Pay with an MCP server**](/en/how-to/pay-with-mcp): Expose x402-paid APIs as MCP tools an agent can call through natural-language prompts. ## Next recommended -- [**x402 in depth**](/en/explanation/x402) — Read how the HTTP payment protocol works end to end on Stable. -- [**MPP**](/en/explanation/mpp) — The broader IETF-track standard that x402 belongs to. -- [**Facilitators**](/en/reference/agentic-facilitators) — See which facilitators already settle USDT0 payments on Stable. +- [**x402 in depth**](/en/explanation/x402): Read how the HTTP payment protocol works end to end on Stable. +- [**MPP**](/en/explanation/mpp): The broader IETF-track standard that x402 belongs to. +- [**Facilitators**](/en/reference/agentic-facilitators): See which facilitators already settle USDT0 payments on Stable. diff --git a/docs/pages/en/explanation/ai-agents-guides.mdx b/docs/pages/en/explanation/ai-agents-guides.mdx index feec6b3..0e67810 100755 --- a/docs/pages/en/explanation/ai-agents-guides.mdx +++ b/docs/pages/en/explanation/ai-agents-guides.mdx @@ -10,21 +10,21 @@ Every guide, concept, and reference under the AI/Agents tab, grouped by what you ## Equip an AI editor -- [**Develop with AI**](/en/how-to/develop-with-ai) — Install Docs MCP, Runtime MCP, agent skills, and paste the Stable context block. -- [**Create an agent wallet**](/en/how-to/create-wallet) — Self-custodied key via WDK — the foundation for agent payments. +- [**Develop with AI**](/en/how-to/develop-with-ai): Install Docs MCP, Runtime MCP, agent skills, and paste the Stable context block. +- [**Create an agent wallet**](/en/how-to/create-wallet): Self-custodied key via WDK, the foundation for agent payments. ## Monetise and consume services -- [**Build a pay-per-call API**](/en/how-to/build-pay-per-call) — Price any HTTP endpoint per request in USDT0 with x402 middleware. -- [**Pay with an MCP server**](/en/how-to/pay-with-mcp) — Wrap x402-paid APIs as MCP tools so an AI client calls and pays for them. +- [**Build a pay-per-call API**](/en/how-to/build-pay-per-call): Price any HTTP endpoint per request in USDT0 with x402 middleware. +- [**Pay with an MCP server**](/en/how-to/pay-with-mcp): Wrap x402-paid APIs as MCP tools so an AI client calls and pays for them. ## Reference -- [**Agentic facilitators**](/en/reference/agentic-facilitators) — Settlement services for agent-to-agent commerce on Stable. -- [**Agent wallets**](/en/reference/agentic-wallets) — Wallet specs for autonomous agent use. +- [**Agentic facilitators**](/en/reference/agentic-facilitators): Settlement services for agent-to-agent commerce on Stable. +- [**Agent wallets**](/en/reference/agentic-wallets): Wallet specs for autonomous agent use. ## Foundation concepts -- [**x402 (HTTP-native payments)**](/en/explanation/x402) — The HTTP protocol agents use to pay per request. -- [**MPP**](/en/explanation/mpp) — The broader IETF-track standard that x402 belongs to, with sessions and multi-rail support. -- [**ERC-3009**](/en/explanation/erc-3009) — The signed-authorization standard x402 settles through. +- [**x402 (HTTP-native payments)**](/en/explanation/x402): The HTTP protocol agents use to pay per request. +- [**MPP**](/en/explanation/mpp): The broader IETF-track standard that x402 belongs to, with sessions and multi-rail support. +- [**ERC-3009**](/en/explanation/erc-3009): The signed-authorization standard x402 settles through. diff --git a/docs/pages/en/explanation/autobahn.mdx b/docs/pages/en/explanation/autobahn.mdx index 166db38..ed268ab 100755 --- a/docs/pages/en/explanation/autobahn.mdx +++ b/docs/pages/en/explanation/autobahn.mdx @@ -77,5 +77,5 @@ For more technical deep-dives and details, refer to: ## Next recommended -- [**Consensus**](/en/explanation/consensus) — Return to StableBFT, the consensus implementation that Autobahn evolves. -- [**Finality**](/en/explanation/finality) — Use Stable's single-slot finality when building against the RPC. +- [**Consensus**](/en/explanation/consensus): Return to StableBFT, the consensus implementation that Autobahn evolves. +- [**Finality**](/en/explanation/finality): Use Stable's single-slot finality when building against the RPC. diff --git a/docs/pages/en/explanation/bank-module.mdx b/docs/pages/en/explanation/bank-module.mdx index 95cf49e..c19264a 100755 --- a/docs/pages/en/explanation/bank-module.mdx +++ b/docs/pages/en/explanation/bank-module.mdx @@ -37,6 +37,6 @@ The full method signatures, event payloads, and authorization flow are in the [B ## Next recommended -- [**Bank precompile reference**](/en/reference/bank-module-api) — Call `transfer`, `approve`, `mint`, `burn`, and read events. -- [**System modules overview**](/en/explanation/system-modules-overview) — Return to the full list of precompile-exposed modules. -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand the dual-role asset model the bank module manages. +- [**Bank precompile reference**](/en/reference/bank-module-api): Call `transfer`, `approve`, `mint`, `burn`, and read events. +- [**System modules overview**](/en/explanation/system-modules-overview): Return to the full list of precompile-exposed modules. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand the dual-role asset model the bank module manages. diff --git a/docs/pages/en/explanation/bridge-security.mdx b/docs/pages/en/explanation/bridge-security.mdx index f1e67d6..1566bfa 100755 --- a/docs/pages/en/explanation/bridge-security.mdx +++ b/docs/pages/en/explanation/bridge-security.mdx @@ -43,6 +43,6 @@ Application surfaces routing through partner bridges should communicate this cle ## Next recommended -- [**Bridging USDT0 to Stable**](/en/explanation/usdt0-bridging) — See how USDT0 reaches Stable through the OFT Mesh and Legacy Mesh. -- [**Bridge providers and addresses**](/en/reference/bridges) — Reference contract addresses, DVN operators, and supported bridge providers. -- [**LayerZero DVN documentation**](https://docs.layerzero.network/v2/concepts/protocol/security-stack-dvns) — Read LayerZero's spec for required and optional DVN verification. +- [**Bridging USDT0 to Stable**](/en/explanation/usdt0-bridging): See how USDT0 reaches Stable through the OFT Mesh and Legacy Mesh. +- [**Bridge providers and addresses**](/en/reference/bridges): Reference contract addresses, DVN operators, and supported bridge providers. +- [**LayerZero DVN documentation**](https://docs.layerzero.network/v2/concepts/protocol/security-stack-dvns): Read LayerZero's spec for required and optional DVN verification. diff --git a/docs/pages/en/explanation/build-overview.mdx b/docs/pages/en/explanation/build-overview.mdx index 3a41b9e..4b19d1f 100755 --- a/docs/pages/en/explanation/build-overview.mdx +++ b/docs/pages/en/explanation/build-overview.mdx @@ -10,14 +10,14 @@ New to Stable? Run the [Quick start](/en/tutorial/quick-start) first. It takes f ## Explore -- [**Accounts**](/en/explanation/accounts-overview) — Create wallets, delegate EOAs with EIP-7702, and scope session keys for users and agents. -- [**Payments**](/en/explanation/payments-overview) — Send USDT0, build P2P and subscription flows, settle invoices with ERC-3009, and price APIs with x402. -- [**Contracts**](/en/explanation/contracts-overview) — Deploy, verify, and index Solidity contracts, and call Bank / Distribution / Staking precompiles. -- [**AI and agents**](/en/explanation/agent-settlement) — Wire MCP servers into AI clients and expose x402-paid tools agents can call through prompts. +- [**Accounts**](/en/explanation/accounts-overview): Create wallets, delegate EOAs with EIP-7702, and scope session keys for users and agents. +- [**Payments**](/en/explanation/payments-overview): Send USDT0, build P2P and subscription flows, settle invoices with ERC-3009, and price APIs with x402. +- [**Contracts**](/en/explanation/contracts-overview): Deploy, verify, and index Solidity contracts, and call Bank / Distribution / Staking precompiles. +- [**AI and agents**](/en/explanation/agent-settlement): Wire MCP servers into AI clients and expose x402-paid tools agents can call through prompts. ## Start here -- [**Quick start**](/en/tutorial/quick-start) — Connect to testnet, fund a wallet, and send your first USDT0 transaction. -- [**Send your first USDT0**](/en/tutorial/send-usdt0) — Native and ERC-20 transfers on the same balance, with TypeScript examples. -- [**Deploy a smart contract**](/en/tutorial/smart-contract) — Scaffold Foundry, configure Stable, and deploy the Counter contract. -- [**Stable SDK**](/en/explanation/sdk-overview) — Use the typed TypeScript client for transfer, bridge, and swap on Stable. +- [**Quick start**](/en/tutorial/quick-start): Connect to testnet, fund a wallet, and send your first USDT0 transaction. +- [**Send your first USDT0**](/en/tutorial/send-usdt0): Native and ERC-20 transfers on the same balance, with TypeScript examples. +- [**Deploy a smart contract**](/en/tutorial/smart-contract): Scaffold Foundry, configure Stable, and deploy the Counter contract. +- [**Stable SDK**](/en/explanation/sdk-overview): Use the typed TypeScript client for transfer, bridge, and swap on Stable. diff --git a/docs/pages/en/explanation/confidential-transfer.mdx b/docs/pages/en/explanation/confidential-transfer.mdx index 162fe40..44b9b00 100755 --- a/docs/pages/en/explanation/confidential-transfer.mdx +++ b/docs/pages/en/explanation/confidential-transfer.mdx @@ -53,6 +53,6 @@ Confidential Transfer is in development. See [Roadmap](/en/explanation/technical ## Next recommended -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand the asset model confidential transfers shield. -- [**Flow of funds**](/en/explanation/flow-of-funds) — See where confidentiality fits in the end-to-end payment lifecycle. -- [**Roadmap**](/en/explanation/technical-roadmap) — Track when confidential transfer ships. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand the asset model confidential transfers shield. +- [**Flow of funds**](/en/explanation/flow-of-funds): See where confidentiality fits in the end-to-end payment lifecycle. +- [**Roadmap**](/en/explanation/technical-roadmap): Track when confidential transfer ships. diff --git a/docs/pages/en/explanation/consensus.mdx b/docs/pages/en/explanation/consensus.mdx index e1ddd03..c3243c1 100755 --- a/docs/pages/en/explanation/consensus.mdx +++ b/docs/pages/en/explanation/consensus.mdx @@ -35,6 +35,6 @@ This advanced consensus design supports much higher throughput based on the inte ## Next recommended -- [**Autobahn**](/en/explanation/autobahn) — Read the protocol paper that underpins StableBFT's DAG-based upgrade path. -- [**Execution**](/en/explanation/execution) — See how blocks move from consensus into parallel execution. -- [**Finality**](/en/explanation/finality) — Apply Stable's single-slot finality when building against the RPC. +- [**Autobahn**](/en/explanation/autobahn): Read the protocol paper that underpins StableBFT's DAG-based upgrade path. +- [**Execution**](/en/explanation/execution): See how blocks move from consensus into parallel execution. +- [**Finality**](/en/explanation/finality): Apply Stable's single-slot finality when building against the RPC. diff --git a/docs/pages/en/explanation/contracts-guides.mdx b/docs/pages/en/explanation/contracts-guides.mdx index d11a9b3..9399f7e 100755 --- a/docs/pages/en/explanation/contracts-guides.mdx +++ b/docs/pages/en/explanation/contracts-guides.mdx @@ -10,21 +10,21 @@ Every guide, concept, and reference under the Contracts tab, grouped by what you ## Build and ship a contract -- [**Deploy**](/en/tutorial/smart-contract) — Scaffold a Foundry project and deploy Counter to Stable testnet. -- [**Verify**](/en/how-to/verify-contract) — Upload source to Stablescan so users can read and call your contract. -- [**Index events**](/en/how-to/index-contract) — Build a live event stream with ethers.js, plus historical backfill. +- [**Deploy**](/en/tutorial/smart-contract): Scaffold a Foundry project and deploy Counter to Stable testnet. +- [**Verify**](/en/how-to/verify-contract): Upload source to Stablescan so users can read and call your contract. +- [**Index events**](/en/how-to/index-contract): Build a live event stream with ethers.js, plus historical backfill. ## Call system modules -- [**Use system modules**](/en/how-to/use-system-modules) — Call Bank, Distribution, and Staking precompiles from Solidity or ethers.js. -- [**Track unbonding completions**](/en/how-to/track-unbonding) — Subscribe to the UnbondingCompleted event emitted via the StableSystem precompile. +- [**Use system modules**](/en/how-to/use-system-modules): Call Bank, Distribution, and Staking precompiles from Solidity or ethers.js. +- [**Track unbonding completions**](/en/how-to/track-unbonding): Subscribe to the UnbondingCompleted event emitted via the StableSystem precompile. ## Reference -- [**System modules reference**](/en/reference/system-modules-api-overview) — Precompile addresses and per-module ABI pointers. -- [**JSON-RPC API**](/en/reference/json-rpc-api) — Supported `eth_*`, `net_*`, `web3_*`, and `debug_*` methods. +- [**System modules reference**](/en/reference/system-modules-api-overview): Precompile addresses and per-module ABI pointers. +- [**JSON-RPC API**](/en/reference/json-rpc-api): Supported `eth_*`, `net_*`, `web3_*`, and `debug_*` methods. ## Foundation concepts -- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior) — Dual-role balance, reconciliation events, and contract design rules. -- [**Difference from Ethereum**](/en/explanation/ethereum-comparison) — Gas token, finality, priority tips, and EVM compatibility. +- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior): Dual-role balance, reconciliation events, and contract design rules. +- [**Difference from Ethereum**](/en/explanation/ethereum-comparison): Gas token, finality, priority tips, and EVM compatibility. diff --git a/docs/pages/en/explanation/contracts-overview.mdx b/docs/pages/en/explanation/contracts-overview.mdx index 4b2c800..d004e6f 100755 --- a/docs/pages/en/explanation/contracts-overview.mdx +++ b/docs/pages/en/explanation/contracts-overview.mdx @@ -18,17 +18,17 @@ Stable is fully EVM-compatible. Solidity, Vyper, Hardhat, Foundry, ethers.js, an ## How Stable differs - **USDT0 is the gas token.** `maxPriorityFeePerGas` must be `0`. The `value` field in native transfers carries USDT0, not ETH. See [Work with USDT0 as gas](/en/how-to/work-with-usdt-gas). -- **USDT0 has a dual role.** Contracts that hold native USDT0 can have their balance changed by ERC-20 `transferFrom` or `permit` — never mirror native balance in a `uint256`. See [USDT0 behavior on Stable](/en/explanation/usdt0-behavior). +- **USDT0 has a dual role.** Contracts that hold native USDT0 can have their balance changed by ERC-20 `transferFrom` or `permit`. Never mirror native balance in a `uint256`. See [USDT0 behavior on Stable](/en/explanation/usdt0-behavior). - **Precompile addresses are fixed across testnet and mainnet.** Burn them into your contract as constants. ## Start here -- [**Deploy**](/en/tutorial/smart-contract) — Scaffold Foundry, configure Stable, and deploy Counter. -- [**Verify**](/en/how-to/verify-contract) — Upload source to Stablescan with forge verify-contract. -- [**Index**](/en/how-to/index-contract) — Subscribe to events with ethers.js and backfill historical logs. +- [**Deploy**](/en/tutorial/smart-contract): Scaffold Foundry, configure Stable, and deploy Counter. +- [**Verify**](/en/how-to/verify-contract): Upload source to Stablescan with forge verify-contract. +- [**Index**](/en/how-to/index-contract): Subscribe to events with ethers.js and backfill historical logs. ## Next recommended -- [**Contracts guide index**](/en/explanation/contracts-guides) — Full list of contract guides, precompile references, and system module ABIs. -- [**Use system modules**](/en/how-to/use-system-modules) — Call Bank / Distribution / Staking from Solidity and ethers.js. -- [**JSON-RPC reference**](/en/reference/json-rpc-api) — Which `eth_*` and `debug_*` methods Stable supports. +- [**Contracts guide index**](/en/explanation/contracts-guides): Full list of contract guides, precompile references, and system module ABIs. +- [**Use system modules**](/en/how-to/use-system-modules): Call Bank / Distribution / Staking from Solidity and ethers.js. +- [**JSON-RPC reference**](/en/reference/json-rpc-api): Which `eth_*` and `debug_*` methods Stable supports. diff --git a/docs/pages/en/explanation/core-concepts.mdx b/docs/pages/en/explanation/core-concepts.mdx index 7400248..97f2155 100755 --- a/docs/pages/en/explanation/core-concepts.mdx +++ b/docs/pages/en/explanation/core-concepts.mdx @@ -87,7 +87,7 @@ Read more: [Confidential transfer](/en/explanation/confidential-transfer). ## Next recommended -- [**Quick start**](/en/tutorial/quick-start) — Connect to testnet and send a first transaction. -- [**USDT0 behavior**](/en/explanation/usdt0-behavior) — Port a contract to Stable without hitting dual-role gotchas. -- [**Gas pricing**](/en/reference/gas-pricing-api) — Construct transactions correctly on Stable's fee model. -- [**Production readiness**](/en/how-to/production-readiness) — Validate an integration before shipping to mainnet. +- [**Quick start**](/en/tutorial/quick-start): Connect to testnet and send a first transaction. +- [**USDT0 behavior**](/en/explanation/usdt0-behavior): Port a contract to Stable without hitting dual-role gotchas. +- [**Gas pricing**](/en/reference/gas-pricing-api): Construct transactions correctly on Stable's fee model. +- [**Production readiness**](/en/how-to/production-readiness): Validate an integration before shipping to mainnet. diff --git a/docs/pages/en/explanation/core-optimization-overview.mdx b/docs/pages/en/explanation/core-optimization-overview.mdx index 64589b2..29de6d4 100755 --- a/docs/pages/en/explanation/core-optimization-overview.mdx +++ b/docs/pages/en/explanation/core-optimization-overview.mdx @@ -22,7 +22,7 @@ The following pages describe how Stable upgrades each layer of its architecture ## Next recommended -- [**Consensus**](/en/explanation/consensus) — Learn how StableBFT extends CometBFT for high throughput and low latency. -- [**Execution**](/en/explanation/execution) — See how Stable EVM runs transactions in parallel with Block-STM and Optimistic Block Processing. -- [**Storage (StableDB)**](/en/explanation/stable-db) — Understand how decoupled state commitment and memory-mapped storage remove the disk I/O bottleneck. -- [**High performance RPC**](/en/explanation/high-performance-rpc) — Understand the split-path RPC architecture separating reads from writes. +- [**Consensus**](/en/explanation/consensus): Learn how StableBFT extends CometBFT for high throughput and low latency. +- [**Execution**](/en/explanation/execution): See how Stable EVM runs transactions in parallel with Block-STM and Optimistic Block Processing. +- [**Storage (StableDB)**](/en/explanation/stable-db): Understand how decoupled state commitment and memory-mapped storage remove the disk I/O bottleneck. +- [**High performance RPC**](/en/explanation/high-performance-rpc): Understand the split-path RPC architecture separating reads from writes. diff --git a/docs/pages/en/explanation/distribution-module.mdx b/docs/pages/en/explanation/distribution-module.mdx index 704e0b6..b4b638c 100755 --- a/docs/pages/en/explanation/distribution-module.mdx +++ b/docs/pages/en/explanation/distribution-module.mdx @@ -31,6 +31,6 @@ Full method signatures, input/output types, and emitted events are in the [Distr ## Next recommended -- [**Distribution precompile reference**](/en/reference/distribution-module-api) — Call `withdrawDelegatorRewards`, set withdraw addresses, and read reward balances. -- [**Staking module**](/en/explanation/staking-module) — See how delegation (the source of these rewards) works. -- [**System transactions**](/en/explanation/system-transactions) — Learn how unbonding completions reach the EVM as events. +- [**Distribution precompile reference**](/en/reference/distribution-module-api): Call `withdrawDelegatorRewards`, set withdraw addresses, and read reward balances. +- [**Staking module**](/en/explanation/staking-module): See how delegation (the source of these rewards) works. +- [**System transactions**](/en/explanation/system-transactions): Learn how unbonding completions reach the EVM as events. diff --git a/docs/pages/en/explanation/eip-7702.mdx b/docs/pages/en/explanation/eip-7702.mdx index 0abc92a..599d3ed 100755 --- a/docs/pages/en/explanation/eip-7702.mdx +++ b/docs/pages/en/explanation/eip-7702.mdx @@ -46,6 +46,6 @@ After submission, the EOA's account code is set to the delegate. Subsequent tran ## Next recommended -- [**Account Abstraction (EIP-7702)**](/en/reference/eip-7702-api) — Implement batch payments, spending limits, and session keys against a delegate contract. -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand the gas model that EIP-7702 transactions run on. -- [**Gas waiver**](/en/explanation/gas-waiver) — Compare delegation to gas-waived flows where an application pays the user's gas instead. +- [**Account Abstraction (EIP-7702)**](/en/reference/eip-7702-api): Implement batch payments, spending limits, and session keys against a delegate contract. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand the gas model that EIP-7702 transactions run on. +- [**Gas waiver**](/en/explanation/gas-waiver): Compare delegation to gas-waived flows where an application pays the user's gas instead. diff --git a/docs/pages/en/explanation/erc-3009.mdx b/docs/pages/en/explanation/erc-3009.mdx index a3574e3..355aa51 100755 --- a/docs/pages/en/explanation/erc-3009.mdx +++ b/docs/pages/en/explanation/erc-3009.mdx @@ -1,6 +1,6 @@ --- title: "Settle with signed authorizations" -description: "ERC-3009 allows a token holder to authorize a transfer by signing a message, without calling the contract directly. The settlement mechanism behind x402 payments on Stable." +description: "Authorize a token transfer by signing a message, with no direct contract call. ERC-3009 is the settlement mechanism behind x402 payments on Stable." diataxis: "explanation" --- diff --git a/docs/pages/en/explanation/ethereum-comparison.mdx b/docs/pages/en/explanation/ethereum-comparison.mdx index 725ca98..899ef03 100755 --- a/docs/pages/en/explanation/ethereum-comparison.mdx +++ b/docs/pages/en/explanation/ethereum-comparison.mdx @@ -74,6 +74,6 @@ USDT0 functions as both the native gas token and an ERC-20 token. This introduce ## Next recommended -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand the asset model that replaces ETH for gas. -- [**Gas pricing**](/en/explanation/gas-pricing) — Review the single-component fee model in detail. -- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior) — Audit contracts for dual-role asset semantics, allowance safety, and `EXTCODEHASH` behavior. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand the asset model that replaces ETH for gas. +- [**Gas pricing**](/en/explanation/gas-pricing): Review the single-component fee model in detail. +- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior): Audit contracts for dual-role asset semantics, allowance safety, and `EXTCODEHASH` behavior. diff --git a/docs/pages/en/explanation/execution.mdx b/docs/pages/en/explanation/execution.mdx index 9afd5c0..bc64781 100755 --- a/docs/pages/en/explanation/execution.mdx +++ b/docs/pages/en/explanation/execution.mdx @@ -97,6 +97,6 @@ Stable is currently exploring alternative EVM implementations to boost execution ## Next recommended -- [**Storage (StableDB)**](/en/explanation/stable-db) — See how decoupled state commitment feeds execution without blocking on disk I/O. -- [**High performance RPC**](/en/explanation/high-performance-rpc) — Understand the split-path RPC that surfaces execution results to clients. -- [**Ethereum compatibility**](/en/explanation/ethereum-compatibility) — Port existing contracts using standard EVM tooling against Stable. +- [**Storage (StableDB)**](/en/explanation/stable-db): See how decoupled state commitment feeds execution without blocking on disk I/O. +- [**High performance RPC**](/en/explanation/high-performance-rpc): Understand the split-path RPC that surfaces execution results to clients. +- [**Ethereum compatibility**](/en/explanation/ethereum-compatibility): Port existing contracts using standard EVM tooling against Stable. diff --git a/docs/pages/en/explanation/flow-of-funds.mdx b/docs/pages/en/explanation/flow-of-funds.mdx index ff06fe4..2f5b1de 100755 --- a/docs/pages/en/explanation/flow-of-funds.mdx +++ b/docs/pages/en/explanation/flow-of-funds.mdx @@ -60,6 +60,6 @@ The conversion logic (e.g., BTC → USDT) may be handled by an exchange partner, ## Next recommended -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand how USDT0 serves as both native gas and ERC-20 balance on Stable. -- [**Bridging to Stable**](/en/explanation/usdt0-bridging) — See how USDT0 moves onto Stable from other chains via OFT Mesh or Legacy Mesh. -- [**Send your first USDT0**](/en/tutorial/send-usdt0) — Submit a USDT0 transfer on testnet using standard EVM tooling. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand how USDT0 serves as both native gas and ERC-20 balance on Stable. +- [**Bridging to Stable**](/en/explanation/usdt0-bridging): See how USDT0 moves onto Stable from other chains via OFT Mesh or Legacy Mesh. +- [**Send your first USDT0**](/en/tutorial/send-usdt0): Submit a USDT0 transfer on testnet using standard EVM tooling. diff --git a/docs/pages/en/explanation/gas-pricing.mdx b/docs/pages/en/explanation/gas-pricing.mdx index 2df5501..cee9553 100755 --- a/docs/pages/en/explanation/gas-pricing.mdx +++ b/docs/pages/en/explanation/gas-pricing.mdx @@ -35,6 +35,6 @@ Stable accepts EIP-1559 (Type 2) transactions, but `maxPriorityFeePerGas` is alw ## Next recommended -- [**Gas pricing reference**](/en/reference/gas-pricing-api) — Construct transactions, estimate gas, and configure tooling against Stable's fee model. -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — See how USDT0 serves as both native gas and ERC-20 balance. -- [**Ethereum comparison**](/en/explanation/ethereum-comparison) — Review every behavior difference you'll encounter porting from Ethereum. +- [**Gas pricing reference**](/en/reference/gas-pricing-api): Construct transactions, estimate gas, and configure tooling against Stable's fee model. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): See how USDT0 serves as both native gas and ERC-20 balance. +- [**Ethereum comparison**](/en/explanation/ethereum-comparison): Review every behavior difference you'll encounter porting from Ethereum. diff --git a/docs/pages/en/explanation/gas-waiver.mdx b/docs/pages/en/explanation/gas-waiver.mdx index 094d0be..7995b37 100755 --- a/docs/pages/en/explanation/gas-waiver.mdx +++ b/docs/pages/en/explanation/gas-waiver.mdx @@ -1,6 +1,6 @@ --- title: "Gas waiver" -description: "Gas Waiver lets applications cover gas on behalf of users. Governance-approved waivers submit wrapper transactions that execute the user's signed payload at zero gas price." +description: "Gas Waiver lets applications cover gas for users. Governance-approved waivers submit wrapper transactions that run a signed payload at zero gas price." diataxis: "explanation" --- @@ -54,6 +54,6 @@ For flows where the user does hold USDT0 but wants to bundle multiple calls into ## Next recommended -- [**Enable gas-free transactions**](/en/how-to/integrate-gas-waiver) — Integrate the hosted Waiver Server API with API-key submission and NDJSON responses. -- [**Gas waiver protocol**](/en/reference/gas-waiver-api) — Read the full protocol spec: marker routing, wrapper format, governance controls. -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand the gas token that the waiver covers. +- [**Enable gas-free transactions**](/en/how-to/integrate-gas-waiver): Integrate the hosted Waiver Server API with API-key submission and NDJSON responses. +- [**Gas waiver protocol**](/en/reference/gas-waiver-api): Read the full protocol spec: marker routing, wrapper format, governance controls. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand the gas token that the waiver covers. diff --git a/docs/pages/en/explanation/guaranteed-blockspace.mdx b/docs/pages/en/explanation/guaranteed-blockspace.mdx index f7ea9d5..e4251f3 100755 --- a/docs/pages/en/explanation/guaranteed-blockspace.mdx +++ b/docs/pages/en/explanation/guaranteed-blockspace.mdx @@ -42,6 +42,6 @@ The result, for an enrolled partner: ## Next recommended -- [**Guaranteed settlement**](/en/explanation/upcoming-use-cases) — See the payment pattern that depends on guaranteed blockspace: timed DvP settlement cycles with deterministic inclusion. -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand the asset that flows through guaranteed blockspace. -- [**Tokenomics**](/en/reference/tokenomics) — Review how STABLE staking underpins validator blockspace guarantees. +- [**Guaranteed settlement**](/en/explanation/upcoming-use-cases): See the payment pattern that depends on guaranteed blockspace: timed DvP settlement cycles with deterministic inclusion. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand the asset that flows through guaranteed blockspace. +- [**Tokenomics**](/en/reference/tokenomics): Review how STABLE staking underpins validator blockspace guarantees. diff --git a/docs/pages/en/explanation/high-performance-rpc.mdx b/docs/pages/en/explanation/high-performance-rpc.mdx index bc4a47a..e9b9e14 100755 --- a/docs/pages/en/explanation/high-performance-rpc.mdx +++ b/docs/pages/en/explanation/high-performance-rpc.mdx @@ -85,6 +85,6 @@ By integrating an indexer directly into the node, it becomes possible to serve t ## Next recommended -- [**JSON-RPC API**](/en/reference/json-rpc-api) — Use the `eth_*` methods Stable exposes for contract reads, transaction submission, and log filtering. -- [**Execution**](/en/explanation/execution) — See how execution feeds state to the RPC layer. -- [**Storage (StableDB)**](/en/explanation/stable-db) — Review the storage layer the RPC reads query. +- [**JSON-RPC API**](/en/reference/json-rpc-api): Use the `eth_*` methods Stable exposes for contract reads, transaction submission, and log filtering. +- [**Execution**](/en/explanation/execution): See how execution feeds state to the RPC layer. +- [**Storage (StableDB)**](/en/explanation/stable-db): Review the storage layer the RPC reads query. diff --git a/docs/pages/en/explanation/integrate-overview.mdx b/docs/pages/en/explanation/integrate-overview.mdx index d27d652..9dd60bd 100755 --- a/docs/pages/en/explanation/integrate-overview.mdx +++ b/docs/pages/en/explanation/integrate-overview.mdx @@ -10,22 +10,22 @@ Stable is an EVM-compatible Layer 1 where USDT0 is the native gas token. Most Et ## Connect and fund -- [**Connect**](/en/reference/connect) — Mainnet and testnet chain IDs, RPC endpoints, block explorers. -- [**Fund your testnet wallet**](/en/how-to/use-faucet) — Get testnet USDT0 via the faucet or bridge from Sepolia. -- [**Stable SDK**](/en/explanation/sdk-overview) — Use the typed TypeScript client for transfer, bridge, and swap. +- [**Connect**](/en/reference/connect): Mainnet and testnet chain IDs, RPC endpoints, block explorers. +- [**Fund your testnet wallet**](/en/how-to/use-faucet): Get testnet USDT0 via the faucet or bridge from Sepolia. +- [**Stable SDK**](/en/explanation/sdk-overview): Use the typed TypeScript client for transfer, bridge, and swap. ## Build with USDT0 -- [**Send your first USDT0**](/en/tutorial/send-usdt0) — Native and ERC-20 transfers with TypeScript examples. -- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior) — Dual-role balance reconciliation, contract design requirements, migration checklist. -- [**Differences from Ethereum**](/en/explanation/ethereum-comparison) — Single-slot finality, USDT0 gas, no priority tips. -- [**Zero-gas transactions**](/en/how-to/integrate-gas-waiver) — Gas Waiver integration via the Waiver Server API. +- [**Send your first USDT0**](/en/tutorial/send-usdt0): Native and ERC-20 transfers with TypeScript examples. +- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior): Dual-role balance reconciliation, contract design requirements, migration checklist. +- [**Differences from Ethereum**](/en/explanation/ethereum-comparison): Single-slot finality, USDT0 gas, no priority tips. +- [**Zero-gas transactions**](/en/how-to/integrate-gas-waiver): Gas Waiver integration via the Waiver Server API. ## Payments -- [**ERC-3009**](/en/explanation/erc-3009) — Transfer With Authorization: the on-chain settlement primitive. -- [**x402**](/en/explanation/x402) — HTTP-native payments with no accounts or API keys. -- [**P2P payments**](/en/reference/p2p-payments) — Native and ERC-3009 delegated transfers. +- [**ERC-3009**](/en/explanation/erc-3009): Transfer With Authorization: the on-chain settlement primitive. +- [**x402**](/en/explanation/x402): HTTP-native payments with no accounts or API keys. +- [**P2P payments**](/en/reference/p2p-payments): Native and ERC-3009 delegated transfers. ## Ecosystem diff --git a/docs/pages/en/explanation/key-features.mdx b/docs/pages/en/explanation/key-features.mdx index ec20a9f..743dbe7 100755 --- a/docs/pages/en/explanation/key-features.mdx +++ b/docs/pages/en/explanation/key-features.mdx @@ -19,16 +19,16 @@ Stable is a delegated Proof-of-Stake Layer 1 with single-slot finality, full EVM ## USDT-specific features -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — USDT0 serves as both the native gas token and an ERC-20 token on the same balance. -- [**Gas waiver**](/en/explanation/gas-waiver) — Governance-authorized waivers submit wrapper transactions that execute at zero gas price on the user's behalf. -- [**Guaranteed blockspace**](/en/explanation/guaranteed-blockspace) — Enterprise partners secure reserved capacity in every block for payment flows. -- [**USDT transfer aggregator**](/en/explanation/usdt-transfer-aggregator) — High-volume USDT0 transfers batch into parallelized, fault-tolerant settlement bundles. -- [**Confidential transfer**](/en/explanation/confidential-transfer) — Zero-knowledge cryptography shields transfer amounts while keeping parties auditable. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): USDT0 serves as both the native gas token and an ERC-20 token on the same balance. +- [**Gas waiver**](/en/explanation/gas-waiver): Governance-authorized waivers submit wrapper transactions that execute at zero gas price on the user's behalf. +- [**Guaranteed blockspace**](/en/explanation/guaranteed-blockspace): Enterprise partners secure reserved capacity in every block for payment flows. +- [**USDT transfer aggregator**](/en/explanation/usdt-transfer-aggregator): High-volume USDT0 transfers batch into parallelized, fault-tolerant settlement bundles. +- [**Confidential transfer**](/en/explanation/confidential-transfer): Zero-knowledge cryptography shields transfer amounts while keeping parties auditable. For which upgrades are live today and which are on the roadmap, see [Roadmap](/en/explanation/technical-roadmap). ## Next recommended -- [**Ethereum comparison**](/en/explanation/ethereum-comparison) — Identify what stays the same and what changes when you port from Ethereum to Stable. -- [**Flow of funds**](/en/explanation/flow-of-funds) — Trace USDT from on-ramp through on-chain transfer to off-ramp settlement. -- [**Architecture overview**](/en/explanation/core-optimization-overview) — Walk through the consensus, execution, database, and RPC layers that deliver these features. +- [**Ethereum comparison**](/en/explanation/ethereum-comparison): Identify what stays the same and what changes when you port from Ethereum to Stable. +- [**Flow of funds**](/en/explanation/flow-of-funds): Trace USDT from on-ramp through on-chain transfer to off-ramp settlement. +- [**Architecture overview**](/en/explanation/core-optimization-overview): Walk through the consensus, execution, database, and RPC layers that deliver these features. diff --git a/docs/pages/en/explanation/learn-overview.mdx b/docs/pages/en/explanation/learn-overview.mdx index 67ee178..a3bae70 100755 --- a/docs/pages/en/explanation/learn-overview.mdx +++ b/docs/pages/en/explanation/learn-overview.mdx @@ -8,29 +8,29 @@ diataxis: "explanation" ## Foundation -- [**Overview**](/en/explanation/overview) — What Stable is and how to read this documentation. -- [**Key features**](/en/explanation/key-features) — Headline specs: single-slot finality, USDT0 as gas, full EVM compatibility. -- [**Difference from Ethereum**](/en/explanation/ethereum-comparison) — What stays the same and what changes when you port from Ethereum. -- [**Core concepts**](/en/explanation/core-concepts) — USDT0 dual role, guaranteed blockspace, transfer aggregator, finality. +- [**Overview**](/en/explanation/overview): What Stable is and how to read this documentation. +- [**Key features**](/en/explanation/key-features): Headline specs: single-slot finality, USDT0 as gas, full EVM compatibility. +- [**Difference from Ethereum**](/en/explanation/ethereum-comparison): What stays the same and what changes when you port from Ethereum. +- [**Core concepts**](/en/explanation/core-concepts): USDT0 dual role, guaranteed blockspace, transfer aggregator, finality. ## USDT0 behavior -- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior) — Dual-role balance, reconciliation events, and contract design rules. -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Why Stable uses USDT0 to pay for gas and what that means for fees. -- [**Flow of funds**](/en/explanation/flow-of-funds) — How USDT moves end-to-end across Stable. -- [**USDT0 features**](/en/explanation/usdt-features-overview) — Every USDT0-specific feature with links to each. +- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior): Dual-role balance, reconciliation events, and contract design rules. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Why Stable uses USDT0 to pay for gas and what that means for fees. +- [**Flow of funds**](/en/explanation/flow-of-funds): How USDT moves end-to-end across Stable. +- [**USDT0 features**](/en/explanation/usdt-features-overview): Every USDT0-specific feature with links to each. ## Architecture -- [**Technical overview**](/en/explanation/tech-overview) — Consensus, execution, database, and RPC layers in one page. -- [**Core optimizations**](/en/explanation/core-optimization-overview) — The performance work behind sub-second finality. -- [**Finality**](/en/explanation/finality) — Single-slot finality, reorg behavior, and what "confirmed" means. -- [**Gas pricing**](/en/explanation/gas-pricing) — Base-fee-only model priced in USDT0. +- [**Technical overview**](/en/explanation/tech-overview): Consensus, execution, database, and RPC layers in one page. +- [**Core optimizations**](/en/explanation/core-optimization-overview): The performance work behind sub-second finality. +- [**Finality**](/en/explanation/finality): Single-slot finality, reorg behavior, and what "confirmed" means. +- [**Gas pricing**](/en/explanation/gas-pricing): Base-fee-only model priced in USDT0. ## Use case narratives -- [**Payments**](/en/explanation/use-case-payments) — Why Stable fits P2P, subscriptions, invoices, and pay-per-call. -- [**Payroll**](/en/explanation/use-case-payroll) — Batched and scheduled payroll runs on Stable. -- [**Sponsored transactions**](/en/explanation/use-case-sponsored) — Letting applications cover gas for their users. -- [**Private transfers**](/en/explanation/use-case-private) — Upcoming confidential payment flows. +- [**Payments**](/en/explanation/use-case-payments): Why Stable fits P2P, subscriptions, invoices, and pay-per-call. +- [**Payroll**](/en/explanation/use-case-payroll): Batched and scheduled payroll runs on Stable. +- [**Sponsored transactions**](/en/explanation/use-case-sponsored): Letting applications cover gas for their users. +- [**Private transfers**](/en/explanation/use-case-private): Upcoming confidential payment flows. diff --git a/docs/pages/en/explanation/mpp-sessions.mdx b/docs/pages/en/explanation/mpp-sessions.mdx index 872aae7..6f43e7c 100755 --- a/docs/pages/en/explanation/mpp-sessions.mdx +++ b/docs/pages/en/explanation/mpp-sessions.mdx @@ -42,6 +42,6 @@ Until both ship, MPP sessions are not usable on Stable. For high-frequency agent ## Next recommended -- [**MPP concept**](/en/explanation/mpp) — Read the broader standard, including charge and subscription intents. -- [**Agent settlement**](/en/explanation/agent-settlement) — See where MPP sessions would sit in the agent-payment rail on Stable. -- [**Build an MPP endpoint on Stable**](/en/how-to/build-mpp-endpoint) — Use the charge intent today while sessions are forthcoming. +- [**MPP concept**](/en/explanation/mpp): Read the broader standard, including charge and subscription intents. +- [**Agent settlement**](/en/explanation/agent-settlement): See where MPP sessions would sit in the agent-payment rail on Stable. +- [**Build an MPP endpoint on Stable**](/en/how-to/build-mpp-endpoint): Use the charge intent today while sessions are forthcoming. diff --git a/docs/pages/en/explanation/mpp.mdx b/docs/pages/en/explanation/mpp.mdx index 9aafb5f..02666af 100755 --- a/docs/pages/en/explanation/mpp.mdx +++ b/docs/pages/en/explanation/mpp.mdx @@ -56,6 +56,6 @@ The standard is permissionless, so you can author your own method. For USDT0 on ## Next recommended -- [**Build an MPP endpoint on Stable**](/en/how-to/build-mpp-endpoint) — Write the three MPP custom-method hooks for USDT0 and settle a real payment. -- [**MPP sessions**](/en/explanation/mpp-sessions) — Stream micropayments with off-chain vouchers and one net settlement. -- [**x402**](/en/explanation/x402) — Read the original HTTP-402 protocol that MPP generalizes. +- [**Build an MPP endpoint on Stable**](/en/how-to/build-mpp-endpoint): Write the three MPP custom-method hooks for USDT0 and settle a real payment. +- [**MPP sessions**](/en/explanation/mpp-sessions): Stream micropayments with off-chain vouchers and one net settlement. +- [**x402**](/en/explanation/x402): Read the original HTTP-402 protocol that MPP generalizes. diff --git a/docs/pages/en/explanation/payment-use-cases-overview.mdx b/docs/pages/en/explanation/payment-use-cases-overview.mdx index 4318f96..bf9607c 100755 --- a/docs/pages/en/explanation/payment-use-cases-overview.mdx +++ b/docs/pages/en/explanation/payment-use-cases-overview.mdx @@ -10,10 +10,10 @@ Stable supports multiple payment patterns, from simple wallet-to-wallet transfer ## Live use cases -- [**P2P payments**](/en/reference/p2p-payments) — Wallet-to-wallet USDT0 transfers. Sub-second settlement, zero gas via Gas Waiver. -- [**Subscription billing**](/en/reference/subscriptions) — Pull-based recurring billing via EIP-7702. Subscriber authorizes once, provider collects each cycle. -- [**Invoice settlement**](/en/reference/invoices) — B2B invoice payment with deterministic nonces. On-chain settlement links automatically to the invoice. -- [**Pay-per-call APIs**](/en/reference/pay-per-call) — Per-request HTTP payments via x402 middleware. No accounts, no API keys, no billing cycles. +- [**P2P payments**](/en/reference/p2p-payments): Wallet-to-wallet USDT0 transfers. Sub-second settlement, zero gas via Gas Waiver. +- [**Subscription billing**](/en/reference/subscriptions): Pull-based recurring billing via EIP-7702. Subscriber authorizes once, provider collects each cycle. +- [**Invoice settlement**](/en/reference/invoices): B2B invoice payment with deterministic nonces. On-chain settlement links automatically to the invoice. +- [**Pay-per-call APIs**](/en/reference/pay-per-call): Per-request HTTP payments via x402 middleware. No accounts, no API keys, no billing cycles. ## Shared foundations @@ -25,5 +25,5 @@ Most patterns build on the same two protocols: ## Next recommended -- [**ERC-3009**](/en/explanation/erc-3009) — Start with the core settlement standard. -- [**Upcoming use cases**](/en/explanation/upcoming-use-cases) — Preview agent-to-agent commerce, guaranteed settlement, and confidential payments. +- [**ERC-3009**](/en/explanation/erc-3009): Start with the core settlement standard. +- [**Upcoming use cases**](/en/explanation/upcoming-use-cases): Preview agent-to-agent commerce, guaranteed settlement, and confidential payments. diff --git a/docs/pages/en/explanation/payments-guides.mdx b/docs/pages/en/explanation/payments-guides.mdx index 11c29bc..0454891 100755 --- a/docs/pages/en/explanation/payments-guides.mdx +++ b/docs/pages/en/explanation/payments-guides.mdx @@ -10,24 +10,24 @@ Every guide, concept, and reference under the Payments tab, grouped by what you' ## Send and transfer -- [**Send your first USDT0**](/en/tutorial/send-usdt0) — Native and ERC-20 transfers on the same balance. -- [**Zero gas transactions**](/en/how-to/zero-gas-transactions) — Transfer USDT0 with the fee covered by a Gas Waiver. -- [**Work with USDT0 as gas**](/en/how-to/work-with-usdt-gas) — Construct transactions correctly: priority tip 0, `value` in USDT0. -- [**Bridge USDT0 to Stable**](/en/tutorial/bridge-usdt0) — Bridge from Ethereum Sepolia using LayerZero OFT. +- [**Send your first USDT0**](/en/tutorial/send-usdt0): Native and ERC-20 transfers on the same balance. +- [**Zero gas transactions**](/en/how-to/zero-gas-transactions): Transfer USDT0 with the fee covered by a Gas Waiver. +- [**Work with USDT0 as gas**](/en/how-to/work-with-usdt-gas): Construct transactions correctly: priority tip 0, `value` in USDT0. +- [**Bridge USDT0 to Stable**](/en/tutorial/bridge-usdt0): Bridge from Ethereum Sepolia using LayerZero OFT. ## Build a payment flow -- [**Learn P2P payments**](/en/how-to/build-p2p-payments) — Wallet + send + receive + history in one app. -- [**Subscribe and collect**](/en/how-to/subscribe-and-collect) — Pull-based recurring billing via EIP-7702. -- [**Paying with invoice**](/en/how-to/pay-with-invoice) — ERC-3009 with deterministic nonces for invoice settlement. -- [**Build a pay-per-call API**](/en/how-to/build-pay-per-call) — Monetise HTTP endpoints with x402 middleware. +- [**Learn P2P payments**](/en/how-to/build-p2p-payments): Wallet + send + receive + history in one app. +- [**Subscribe and collect**](/en/how-to/subscribe-and-collect): Pull-based recurring billing via EIP-7702. +- [**Paying with invoice**](/en/how-to/pay-with-invoice): ERC-3009 with deterministic nonces for invoice settlement. +- [**Build a pay-per-call API**](/en/how-to/build-pay-per-call): Monetise HTTP endpoints with x402 middleware. ## Protocols and references -- [**ERC-3009**](/en/explanation/erc-3009) — Transfer With Authorization: the signed-settlement primitive. -- [**x402 (HTTP-native payments)**](/en/explanation/x402) — Server responds 402, client signs, facilitator settles on-chain. -- [**P2P payments reference**](/en/reference/p2p-payments) — Model overview and comparison to traditional rails. -- [**Subscriptions reference**](/en/reference/subscriptions) — Pull-based billing model and trade-offs. -- [**Invoices reference**](/en/reference/invoices) — Deterministic-nonce settlement model. -- [**Pay-per-call reference**](/en/reference/pay-per-call) — x402 pricing and endpoint discovery model. -- [**Upcoming use cases**](/en/explanation/upcoming-use-cases) — Guaranteed settlement, confidential payments, agent-to-agent. +- [**ERC-3009**](/en/explanation/erc-3009): Transfer With Authorization: the signed-settlement primitive. +- [**x402 (HTTP-native payments)**](/en/explanation/x402): Server responds 402, client signs, facilitator settles on-chain. +- [**P2P payments reference**](/en/reference/p2p-payments): Model overview and comparison to traditional rails. +- [**Subscriptions reference**](/en/reference/subscriptions): Pull-based billing model and trade-offs. +- [**Invoices reference**](/en/reference/invoices): Deterministic-nonce settlement model. +- [**Pay-per-call reference**](/en/reference/pay-per-call): x402 pricing and endpoint discovery model. +- [**Upcoming use cases**](/en/explanation/upcoming-use-cases): Guaranteed settlement, confidential payments, agent-to-agent. diff --git a/docs/pages/en/explanation/payments-overview.mdx b/docs/pages/en/explanation/payments-overview.mdx index eafa850..ca8b4d0 100755 --- a/docs/pages/en/explanation/payments-overview.mdx +++ b/docs/pages/en/explanation/payments-overview.mdx @@ -6,16 +6,16 @@ diataxis: "explanation" # Payments on Stable -Stable is built around payments. USDT0 is the native asset and the gas token, so settlement and fees share one balance. Single-slot finality means a transfer clears in under a second. ERC-3009, EIP-7702, and x402 are native primitives, not workarounds — you can settle with a signature, pull from a delegated account, or charge per HTTP request without running a billing stack. +Stable is built around payments. USDT0 is the native asset and the gas token, so settlement and fees share one balance. Single-slot finality means a transfer clears in under a second. ERC-3009, EIP-7702, and x402 are native primitives, not workarounds. You can settle with a signature, pull from a delegated account, or charge per HTTP request without running a billing stack. ## What you can build -- **P2P transfers** — native USDT0 sends with 21k gas and sub-second finality. -- **Subscriptions** — pull-based recurring billing with EIP-7702 delegation. -- **Invoice settlement** — ERC-3009 `transferWithAuthorization` with deterministic nonces for exact reconciliation. -- **Pay-per-call APIs** — x402 middleware for per-request USDT0 payments; no API keys, no sign-ups. -- **Zero-gas UX** — application-sponsored transactions via the Gas Waiver service. -- **Cross-chain USDT0** — LayerZero OFT bridging from Ethereum and other networks. +- **P2P transfers**: native USDT0 sends with 21k gas and sub-second finality. +- **Subscriptions**: pull-based recurring billing with EIP-7702 delegation. +- **Invoice settlement**: ERC-3009 `transferWithAuthorization` with deterministic nonces for exact reconciliation. +- **Pay-per-call APIs**: x402 middleware for per-request USDT0 payments; no API keys, no sign-ups. +- **Zero-gas UX**: application-sponsored transactions via the Gas Waiver service. +- **Cross-chain USDT0**: LayerZero OFT bridging from Ethereum and other networks. ## How Stable differs @@ -26,19 +26,19 @@ Stable is built around payments. USDT0 is the native asset and the gas token, so ## Start here -- [**Send your first USDT0**](/en/tutorial/send-usdt0) — Native and ERC-20 transfers on the same balance. -- [**Zero gas transactions**](/en/how-to/zero-gas-transactions) — Transfer USDT0 with the fee covered by a Gas Waiver. -- [**Learn P2P payments**](/en/how-to/build-p2p-payments) — Build a wallet + send + receive + history app from scratch. -- [**Build a pay-per-call API**](/en/how-to/build-pay-per-call) — Price HTTP endpoints per request with x402. -- [**Stable SDK**](/en/explanation/sdk-overview) — Use the typed client for transfer, bridge, and swap in a few lines. +- [**Send your first USDT0**](/en/tutorial/send-usdt0): Native and ERC-20 transfers on the same balance. +- [**Zero gas transactions**](/en/how-to/zero-gas-transactions): Transfer USDT0 with the fee covered by a Gas Waiver. +- [**Learn P2P payments**](/en/how-to/build-p2p-payments): Build a wallet + send + receive + history app from scratch. +- [**Build a pay-per-call API**](/en/how-to/build-pay-per-call): Price HTTP endpoints per request with x402. +- [**Stable SDK**](/en/explanation/sdk-overview): Use the typed client for transfer, bridge, and swap in a few lines. ## Payment primitives -- [**ERC-3009**](/en/explanation/erc-3009) — Transfer With Authorization: the settlement standard behind invoices and x402. -- [**x402 (HTTP-native payments)**](/en/explanation/x402) — Server responds 402, client signs ERC-3009, facilitator settles on-chain. +- [**ERC-3009**](/en/explanation/erc-3009): Transfer With Authorization: the settlement standard behind invoices and x402. +- [**x402 (HTTP-native payments)**](/en/explanation/x402): Server responds 402, client signs ERC-3009, facilitator settles on-chain. ## Next recommended -- [**Payments guide index**](/en/explanation/payments-guides) — Every guide, concept, and reference under the Payments tab. -- [**Subscribe and collect**](/en/how-to/subscribe-and-collect) — Pull-based recurring billing via EIP-7702. -- [**Paying with invoice**](/en/how-to/pay-with-invoice) — ERC-3009 with deterministic nonces for exact reconciliation. +- [**Payments guide index**](/en/explanation/payments-guides): Every guide, concept, and reference under the Payments tab. +- [**Subscribe and collect**](/en/how-to/subscribe-and-collect): Pull-based recurring billing via EIP-7702. +- [**Paying with invoice**](/en/how-to/pay-with-invoice): ERC-3009 with deterministic nonces for exact reconciliation. diff --git a/docs/pages/en/explanation/sdk-overview.mdx b/docs/pages/en/explanation/sdk-overview.mdx index db4361d..efcb1b7 100755 --- a/docs/pages/en/explanation/sdk-overview.mdx +++ b/docs/pages/en/explanation/sdk-overview.mdx @@ -30,9 +30,9 @@ txHash: 0x8f3a...2d41 ## What the SDK does -- **`transfer`** — send native USDT0 or any ERC-20 on Stable. Gas is paid in USDT0 automatically. -- **`quoteBridge` / `bridge`** — cross-chain transfers. LayerZero for USDT0 → USDT0, LI.FI for everything else. Route is picked for you. -- **`quoteSwap` / `swap`** — same-chain token swaps via LI.FI, with ERC-20 approval handled internally. +- **`transfer`**: send native USDT0 or any ERC-20 on Stable. Gas is paid in USDT0 automatically. +- **`quoteBridge` / `bridge`**: cross-chain transfers. LayerZero for USDT0 → USDT0, LI.FI for everything else. Route is picked for you. +- **`quoteSwap` / `swap`**: same-chain token swaps via LI.FI, with ERC-20 approval handled internally. The SDK is published on npm as [`@stablechain/sdk`](https://www.npmjs.com/package/@stablechain/sdk) and requires `viem >= 2.0.0` as a peer dependency. @@ -46,13 +46,13 @@ The SDK signs with any viem-compatible signer: a private-key `Account`, a browse ## Start here -- [**Quickstart**](/en/tutorial/sdk-quickstart) — Install the SDK and run your first transfer, bridge, and swap on testnet. -- [**SDK reference**](/en/reference/sdk) — Every method, config option, enum, and error class. -- [**Use with viem**](/en/how-to/sdk-with-viem) — Server-side accounts, browser wallets, and bring-your-own `WalletClient`. -- [**Use with wagmi**](/en/how-to/sdk-with-wagmi) — Wire the SDK into a React app with `useWalletClient` and hooks. +- [**Quickstart**](/en/tutorial/sdk-quickstart): Install the SDK and run your first transfer, bridge, and swap on testnet. +- [**SDK reference**](/en/reference/sdk): Every method, config option, enum, and error class. +- [**Use with viem**](/en/how-to/sdk-with-viem): Server-side accounts, browser wallets, and bring-your-own `WalletClient`. +- [**Use with wagmi**](/en/how-to/sdk-with-wagmi): Wire the SDK into a React app with `useWalletClient` and hooks. ## Next recommended -- [**Install from npm**](https://www.npmjs.com/package/@stablechain/sdk) — View the package on npmjs.com and check the latest version. -- [**Connect to Stable**](/en/reference/connect) — Chain IDs, RPC endpoints, and explorers for mainnet and testnet. -- [**Fund a testnet wallet**](/en/how-to/use-faucet) — Get testnet USDT0 from the faucet before running the quickstart. +- [**Install from npm**](https://www.npmjs.com/package/@stablechain/sdk): View the package on npmjs.com and check the latest version. +- [**Connect to Stable**](/en/reference/connect): Chain IDs, RPC endpoints, and explorers for mainnet and testnet. +- [**Fund a testnet wallet**](/en/how-to/use-faucet): Get testnet USDT0 from the faucet before running the quickstart. diff --git a/docs/pages/en/explanation/stable-db.mdx b/docs/pages/en/explanation/stable-db.mdx index f8e6552..1b5136d 100755 --- a/docs/pages/en/explanation/stable-db.mdx +++ b/docs/pages/en/explanation/stable-db.mdx @@ -80,6 +80,6 @@ For more technical deep-dives and implementation details, refer to: ## Next recommended -- [**High performance RPC**](/en/explanation/high-performance-rpc) — See how the RPC layer exposes state reads without contending with writes. -- [**Execution**](/en/explanation/execution) — Understand how execution writes into the storage layer covered here. -- [**Consensus**](/en/explanation/consensus) — Review the consensus layer that orders blocks before they reach storage. +- [**High performance RPC**](/en/explanation/high-performance-rpc): See how the RPC layer exposes state reads without contending with writes. +- [**Execution**](/en/explanation/execution): Understand how execution writes into the storage layer covered here. +- [**Consensus**](/en/explanation/consensus): Review the consensus layer that orders blocks before they reach storage. diff --git a/docs/pages/en/explanation/staking-module.mdx b/docs/pages/en/explanation/staking-module.mdx index b2ec421..32af1af 100755 --- a/docs/pages/en/explanation/staking-module.mdx +++ b/docs/pages/en/explanation/staking-module.mdx @@ -41,6 +41,6 @@ Full method signatures, struct definitions, and emitted events are in the [Staki ## Next recommended -- [**Staking precompile reference**](/en/reference/staking-module-api) — Call `delegate`, `undelegate`, `redelegate`, and read validator state. -- [**System transactions**](/en/explanation/system-transactions) — Learn how unbonding completions reach the EVM as events. -- [**Distribution module**](/en/explanation/distribution-module) — Withdraw rewards earned from the delegations managed here. +- [**Staking precompile reference**](/en/reference/staking-module-api): Call `delegate`, `undelegate`, `redelegate`, and read validator state. +- [**System transactions**](/en/explanation/system-transactions): Learn how unbonding completions reach the EVM as events. +- [**Distribution module**](/en/explanation/distribution-module): Withdraw rewards earned from the delegations managed here. diff --git a/docs/pages/en/explanation/system-modules-overview.mdx b/docs/pages/en/explanation/system-modules-overview.mdx index 9fceb60..e9d156b 100755 --- a/docs/pages/en/explanation/system-modules-overview.mdx +++ b/docs/pages/en/explanation/system-modules-overview.mdx @@ -1,6 +1,6 @@ --- title: "System modules" -description: "Stable exposes Cosmos-SDK protocol modules to the EVM through precompiled contracts, so dApps can call staking, distribution, and bank operations without rewriting them." +description: "Call staking, distribution, and bank operations from the EVM. Stable exposes Cosmos-SDK protocol modules as precompiled contracts, with no rewriting." diataxis: "explanation" --- @@ -32,6 +32,6 @@ Some precompile methods (`mint`, `burn`, protocol-level staking operations) requ ## Next recommended -- [**Bank module**](/en/explanation/bank-module) — Understand token transfers, allowances, and the mint/burn authorization model. -- [**Staking module**](/en/explanation/staking-module) — See how delegation and validator management reach the EVM. -- [**System transactions**](/en/explanation/system-transactions) — Learn how protocol-level events like unbonding completions surface as EVM logs. +- [**Bank module**](/en/explanation/bank-module): Understand token transfers, allowances, and the mint/burn authorization model. +- [**Staking module**](/en/explanation/staking-module): See how delegation and validator management reach the EVM. +- [**System transactions**](/en/explanation/system-transactions): Learn how protocol-level events like unbonding completions surface as EVM logs. diff --git a/docs/pages/en/explanation/system-transactions.mdx b/docs/pages/en/explanation/system-transactions.mdx index 59aa5ae..0ca908e 100755 --- a/docs/pages/en/explanation/system-transactions.mdx +++ b/docs/pages/en/explanation/system-transactions.mdx @@ -1,6 +1,6 @@ --- title: "System transactions" -description: "System transactions bridge Cosmos-SDK events to EVM logs. Protocol-level operations like unbonding completions surface as standard Transfer-style events dApps can subscribe to." +description: "System transactions bridge Cosmos-SDK events to EVM logs, so operations like unbonding completions surface as standard events dApps can subscribe to." diataxis: "explanation" --- @@ -19,7 +19,7 @@ System transactions give dApps real-time event notifications through the same We ## How the flow works -``` +```text 1. Protocol event: An SDK-layer operation completes (e.g. staking unbonding). 2. Detection: The x/stable EndBlocker detects the event and queues it in state. 3. System TX: In the next block's PrepareProposal, the protocol generates a @@ -53,6 +53,6 @@ The `StableSystem` interface, event signatures, and sender-authorization rules a ## Next recommended -- [**System transactions reference**](/en/reference/system-transactions-api) — Review the `IStableSystem` interface, gas accounting, and authorization rules. -- [**Staking module**](/en/explanation/staking-module) — See the SDK operations that surface as system-transaction events. -- [**System modules overview**](/en/explanation/system-modules-overview) — Return to the precompile-exposed module list. +- [**System transactions reference**](/en/reference/system-transactions-api): Review the `IStableSystem` interface, gas accounting, and authorization rules. +- [**Staking module**](/en/explanation/staking-module): See the SDK operations that surface as system-transaction events. +- [**System modules overview**](/en/explanation/system-modules-overview): Return to the precompile-exposed module list. diff --git a/docs/pages/en/explanation/technical-roadmap.mdx b/docs/pages/en/explanation/technical-roadmap.mdx index 51096f5..669bf74 100755 --- a/docs/pages/en/explanation/technical-roadmap.mdx +++ b/docs/pages/en/explanation/technical-roadmap.mdx @@ -68,6 +68,6 @@ A full RPC stack covering node-level enhancements (real-time chain state process ## Next recommended -- [**Architecture overview**](/en/explanation/core-optimization-overview) — Walk through the current state of the stack the roadmap evolves. -- [**Tokenomics**](/en/reference/tokenomics) — Review the economic model that funds validator incentives across the roadmap. -- [**Tech overview**](/en/explanation/tech-overview) — Return to the architecture summary. +- [**Architecture overview**](/en/explanation/core-optimization-overview): Walk through the current state of the stack the roadmap evolves. +- [**Tokenomics**](/en/reference/tokenomics): Review the economic model that funds validator incentives across the roadmap. +- [**Tech overview**](/en/explanation/tech-overview): Return to the architecture summary. diff --git a/docs/pages/en/explanation/upcoming-use-cases.mdx b/docs/pages/en/explanation/upcoming-use-cases.mdx index 60bc4f5..bbbfc76 100755 --- a/docs/pages/en/explanation/upcoming-use-cases.mdx +++ b/docs/pages/en/explanation/upcoming-use-cases.mdx @@ -64,6 +64,6 @@ Agent-to-agent payment turns service procurement into a fully programmable loop. ## Next recommended -- [**Guaranteed blockspace**](/en/explanation/guaranteed-blockspace) — Review the protocol-level mechanism behind guaranteed settlement. -- [**Confidential transfer**](/en/explanation/confidential-transfer) — See the privacy model Stable is building. -- [**x402**](/en/explanation/x402) — Understand the settlement protocol behind agent-to-agent flows. +- [**Guaranteed blockspace**](/en/explanation/guaranteed-blockspace): Review the protocol-level mechanism behind guaranteed settlement. +- [**Confidential transfer**](/en/explanation/confidential-transfer): See the privacy model Stable is building. +- [**x402**](/en/explanation/x402): Understand the settlement protocol behind agent-to-agent flows. diff --git a/docs/pages/en/explanation/usdt-as-gas-token.mdx b/docs/pages/en/explanation/usdt-as-gas-token.mdx index b672e8c..8097bf3 100755 --- a/docs/pages/en/explanation/usdt-as-gas-token.mdx +++ b/docs/pages/en/explanation/usdt-as-gas-token.mdx @@ -79,7 +79,7 @@ Stable denominates all transaction fees in USDT0. Gas pricing follows an EIP-155 The transaction fee is defined as: -``` +```text fee = gasUsed × baseFee ``` Transactions may specify `maxFeePerGas` using standard EIP-1559 parameters. @@ -140,7 +140,7 @@ During `ApplyTransaction`: After execution: 1. The protocol computes the unused portion of the pre-charged fee: - ``` + ```text refund = (gasWanted − gasUsed) × baseFee ``` 2. The unused fee is refunded: @@ -294,6 +294,6 @@ Correct. After the upgrade, DEXs should use `0x779Ded0c9e1022225f8E0630b35a9b54b ## Next recommended -- [**Send your first USDT0**](/en/tutorial/send-usdt0) — Submit a USDT0 transfer on testnet using standard EVM tooling. -- [**Gas pricing**](/en/reference/gas-pricing-api) — Build transactions against Stable's single-component fee model. -- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior) — Audit contracts for dual-role asset semantics, balance reconciliation, and `EXTCODEHASH` behavior. +- [**Send your first USDT0**](/en/tutorial/send-usdt0): Submit a USDT0 transfer on testnet using standard EVM tooling. +- [**Gas pricing**](/en/reference/gas-pricing-api): Build transactions against Stable's single-component fee model. +- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior): Audit contracts for dual-role asset semantics, balance reconciliation, and `EXTCODEHASH` behavior. diff --git a/docs/pages/en/explanation/usdt-features-overview.mdx b/docs/pages/en/explanation/usdt-features-overview.mdx index e87a73a..67a8a81 100755 --- a/docs/pages/en/explanation/usdt-features-overview.mdx +++ b/docs/pages/en/explanation/usdt-features-overview.mdx @@ -36,6 +36,6 @@ For the full set of Stable's differences from a general-purpose EVM chain, see [ ## Next recommended -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand the asset that replaces ETH for gas and payment at once. -- [**Flow of funds**](/en/explanation/flow-of-funds) — Trace USDT from on-ramp through on-chain transfer to off-ramp settlement. -- [**Bridging to Stable**](/en/explanation/usdt0-bridging) — See how USDT0 moves onto Stable from other chains. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand the asset that replaces ETH for gas and payment at once. +- [**Flow of funds**](/en/explanation/flow-of-funds): Trace USDT from on-ramp through on-chain transfer to off-ramp settlement. +- [**Bridging to Stable**](/en/explanation/usdt0-bridging): See how USDT0 moves onto Stable from other chains. diff --git a/docs/pages/en/explanation/usdt-transfer-aggregator.mdx b/docs/pages/en/explanation/usdt-transfer-aggregator.mdx index 5bb6c55..2322941 100755 --- a/docs/pages/en/explanation/usdt-transfer-aggregator.mdx +++ b/docs/pages/en/explanation/usdt-transfer-aggregator.mdx @@ -77,6 +77,6 @@ Stable's USDT Transfer Aggregator is a targeted optimization that maximizes thro ## Next recommended -- [**Payments use cases**](/en/explanation/payment-use-cases-overview) — See the payment patterns that benefit most from aggregated throughput: P2P, subscriptions, pay-per-call. -- [**Execution**](/en/explanation/execution) — See the parallel execution engine the aggregator builds on. -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand the asset model the aggregator moves. +- [**Payments use cases**](/en/explanation/payment-use-cases-overview): See the payment patterns that benefit most from aggregated throughput: P2P, subscriptions, pay-per-call. +- [**Execution**](/en/explanation/execution): See the parallel execution engine the aggregator builds on. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand the asset model the aggregator moves. diff --git a/docs/pages/en/explanation/usdt0-behavior.mdx b/docs/pages/en/explanation/usdt0-behavior.mdx index f89e690..17a1c5d 100755 --- a/docs/pages/en/explanation/usdt0-behavior.mdx +++ b/docs/pages/en/explanation/usdt0-behavior.mdx @@ -20,7 +20,7 @@ For background on why USDT0 operates this way, see [USDT as gas](/en/explanation USDT0 uses 18 decimals as the native asset and 6 decimals as an ERC-20 token. Native transfers and ERC-20 transfers operate on the same underlying balance, but the 12-digit precision gap means the system must reconcile fractional amounts when a transfer involves sub-integer precision. -``` +```text before 0.000001 USDT0 (ERC-20) + 0.000000000000000000 USDT0 (internal) // address(account).balance = 0.000001000000000000 @@ -180,6 +180,6 @@ Off-chain services and indexers should: ## Next recommended -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand why USDT0 operates as both the native asset and an ERC-20 token. -- [**Send your first USDT0**](/en/tutorial/send-usdt0) — Submit a USDT0 transfer on testnet via native and ERC-20 paths. -- [**Ethereum comparison**](/en/explanation/ethereum-comparison) — Review every behavior difference when porting from Ethereum. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand why USDT0 operates as both the native asset and an ERC-20 token. +- [**Send your first USDT0**](/en/tutorial/send-usdt0): Submit a USDT0 transfer on testnet via native and ERC-20 paths. +- [**Ethereum comparison**](/en/explanation/ethereum-comparison): Review every behavior difference when porting from Ethereum. diff --git a/docs/pages/en/explanation/usdt0-bridging.mdx b/docs/pages/en/explanation/usdt0-bridging.mdx index a85e32a..5f1ebb6 100755 --- a/docs/pages/en/explanation/usdt0-bridging.mdx +++ b/docs/pages/en/explanation/usdt0-bridging.mdx @@ -144,6 +144,6 @@ The remaining steps follow the exact same path as [bridging USDT0 to Stable](#pa ## Next recommended -- [**Flow of funds**](/en/explanation/flow-of-funds) — See the end-to-end lifecycle of USDT from on-ramp through settlement. -- [**Bridge tutorial**](/en/tutorial/bridge-usdt0) — Bridge Test USDT from Sepolia to Stable testnet using the LayerZero OFT Adapter. -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand what the asset does once it lands on Stable. +- [**Flow of funds**](/en/explanation/flow-of-funds): See the end-to-end lifecycle of USDT from on-ramp through settlement. +- [**Bridge tutorial**](/en/tutorial/bridge-usdt0): Bridge Test USDT from Sepolia to Stable testnet using the LayerZero OFT Adapter. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand what the asset does once it lands on Stable. diff --git a/docs/pages/en/explanation/use-case-payments.mdx b/docs/pages/en/explanation/use-case-payments.mdx index be885bc..a5e26e7 100755 --- a/docs/pages/en/explanation/use-case-payments.mdx +++ b/docs/pages/en/explanation/use-case-payments.mdx @@ -20,6 +20,6 @@ On general-purpose chains, users must hold a separate gas token (ETH, SOL) just ## Next recommended -- [**USDT as gas**](/en/explanation/usdt-as-gas-token) — Understand the asset that replaces ETH for gas and payment at once. -- [**Gas waiver**](/en/explanation/gas-waiver) — See how applications cover user gas through governance-approved waiver addresses. -- [**Ethereum comparison**](/en/explanation/ethereum-comparison) — Review what changes (finality, gas token, priority tips) when moving from Ethereum. +- [**USDT as gas**](/en/explanation/usdt-as-gas-token): Understand the asset that replaces ETH for gas and payment at once. +- [**Gas waiver**](/en/explanation/gas-waiver): See how applications cover user gas through governance-approved waiver addresses. +- [**Ethereum comparison**](/en/explanation/ethereum-comparison): Review what changes (finality, gas token, priority tips) when moving from Ethereum. diff --git a/docs/pages/en/explanation/use-case-payroll.mdx b/docs/pages/en/explanation/use-case-payroll.mdx index ed009fb..354e35f 100755 --- a/docs/pages/en/explanation/use-case-payroll.mdx +++ b/docs/pages/en/explanation/use-case-payroll.mdx @@ -20,6 +20,6 @@ High-volume stablecoin disbursements hit per-transaction throughput limits on sh ## Next recommended -- [**USDT transfer aggregator**](/en/explanation/usdt-transfer-aggregator) — Understand how high-volume USDT0 transfers batch into parallelized settlement bundles. -- [**Guaranteed blockspace**](/en/explanation/guaranteed-blockspace) — See how enrolled partners secure reserved capacity in every block. -- [**Confidential transfer**](/en/explanation/confidential-transfer) — Review how ZK cryptography shields transfer amounts while keeping parties auditable. +- [**USDT transfer aggregator**](/en/explanation/usdt-transfer-aggregator): Understand how high-volume USDT0 transfers batch into parallelized settlement bundles. +- [**Guaranteed blockspace**](/en/explanation/guaranteed-blockspace): See how enrolled partners secure reserved capacity in every block. +- [**Confidential transfer**](/en/explanation/confidential-transfer): Review how ZK cryptography shields transfer amounts while keeping parties auditable. diff --git a/docs/pages/en/explanation/use-case-private.mdx b/docs/pages/en/explanation/use-case-private.mdx index 20cbf4e..8f0641a 100755 --- a/docs/pages/en/explanation/use-case-private.mdx +++ b/docs/pages/en/explanation/use-case-private.mdx @@ -19,5 +19,5 @@ All standard EVM transfers are publicly observable. A payroll run or supplier se ## Next recommended -- [**Confidential transfer**](/en/explanation/confidential-transfer) — Review how ZK cryptography shields transfer amounts while keeping parties auditable. -- [**Flow of funds**](/en/explanation/flow-of-funds) — Trace USDT from on-ramp through on-chain transfer to off-ramp settlement. +- [**Confidential transfer**](/en/explanation/confidential-transfer): Review how ZK cryptography shields transfer amounts while keeping parties auditable. +- [**Flow of funds**](/en/explanation/flow-of-funds): Trace USDT from on-ramp through on-chain transfer to off-ramp settlement. diff --git a/docs/pages/en/explanation/use-case-sponsored.mdx b/docs/pages/en/explanation/use-case-sponsored.mdx index 1b76f61..999da6d 100755 --- a/docs/pages/en/explanation/use-case-sponsored.mdx +++ b/docs/pages/en/explanation/use-case-sponsored.mdx @@ -19,5 +19,5 @@ Requiring users to acquire a gas token before using an app creates an onboarding ## Next recommended -- [**Gas waiver**](/en/explanation/gas-waiver) — See how governance-approved waivers submit wrapper transactions at zero gas price. -- [**EIP-7702**](/en/explanation/eip-7702) — Understand how EOAs can delegate scoped, time-limited permissions to a dApp. +- [**Gas waiver**](/en/explanation/gas-waiver): See how governance-approved waivers submit wrapper transactions at zero gas price. +- [**EIP-7702**](/en/explanation/eip-7702): Understand how EOAs can delegate scoped, time-limited permissions to a dApp. diff --git a/docs/pages/en/explanation/x402.mdx b/docs/pages/en/explanation/x402.mdx index ac98156..dd8747e 100755 --- a/docs/pages/en/explanation/x402.mdx +++ b/docs/pages/en/explanation/x402.mdx @@ -1,6 +1,6 @@ --- title: "Monetize HTTP endpoints" -description: "x402 is a payment protocol built on HTTP. A server asks for payment, a client signs it, and a facilitator settles it on-chain. No accounts, no API keys, no subscriptions." +description: "x402 is an HTTP payment protocol. A server asks for payment, a client signs it, a facilitator settles it on-chain. No accounts, API keys, or subscriptions." diataxis: "explanation" --- diff --git a/docs/pages/en/how-to/account-abstraction.mdx b/docs/pages/en/how-to/account-abstraction.mdx index 8eaa5c6..30e0b56 100755 --- a/docs/pages/en/how-to/account-abstraction.mdx +++ b/docs/pages/en/how-to/account-abstraction.mdx @@ -264,6 +264,6 @@ contract SessionKeyExecutor { ## Next recommended -- [**Subscribe and collect**](/en/how-to/subscribe-and-collect) — Apply EIP-7702 to recurring subscription payments with a SubscriptionManager. -- [**EIP-7702 concept**](/en/explanation/eip-7702) — Understand the delegation model before you ship it. -- [**EIP-7702 reference**](/en/reference/eip-7702-api) — Look up the `0x04` transaction format and authorization fields. +- [**Subscribe and collect**](/en/how-to/subscribe-and-collect): Apply EIP-7702 to recurring subscription payments with a SubscriptionManager. +- [**EIP-7702 concept**](/en/explanation/eip-7702): Understand the delegation model before you ship it. +- [**EIP-7702 reference**](/en/reference/eip-7702-api): Look up the `0x04` transaction format and authorization fields. diff --git a/docs/pages/en/how-to/build-mpp-endpoint.mdx b/docs/pages/en/how-to/build-mpp-endpoint.mdx index 6aff059..d7b857d 100755 --- a/docs/pages/en/how-to/build-mpp-endpoint.mdx +++ b/docs/pages/en/how-to/build-mpp-endpoint.mdx @@ -461,6 +461,6 @@ Open `https://stablescan.xyz/tx/0x8f3a1b2c...` and confirm the `transferWithAuth ## Next recommended -- [**MPP concept**](/en/explanation/mpp) — Read how MPP relates to x402 and what the other intents look like. -- [**MPP sessions**](/en/explanation/mpp-sessions) — Stream micropayments with off-chain vouchers when per-request settlement is too expensive. -- [**Facilitators**](/en/reference/agentic-facilitators) — Use Semantic Pay or Heurist as the settlement target instead of submitting directly. +- [**MPP concept**](/en/explanation/mpp): Read how MPP relates to x402 and what the other intents look like. +- [**MPP sessions**](/en/explanation/mpp-sessions): Stream micropayments with off-chain vouchers when per-request settlement is too expensive. +- [**Facilitators**](/en/reference/agentic-facilitators): Use Semantic Pay or Heurist as the settlement target instead of submitting directly. diff --git a/docs/pages/en/how-to/build-p2p-payments.mdx b/docs/pages/en/how-to/build-p2p-payments.mdx index cb21475..57dc356 100755 --- a/docs/pages/en/how-to/build-p2p-payments.mdx +++ b/docs/pages/en/how-to/build-p2p-payments.mdx @@ -14,11 +14,11 @@ No middleware, no intermediary. For the conceptual overview, see [P2P payments]( Five scripts forming a minimal payment app: -- `wallet.ts` — create or restore a wallet. -- `getBalance.ts` — query the current USDT0 balance. -- `send.ts` — send USDT0 to another address. -- `receive.ts` — watch for incoming payments in real time. -- `history.ts` — query past Transfer events for an address. +- `wallet.ts`: create or restore a wallet. +- `getBalance.ts`: query the current USDT0 balance. +- `send.ts`: send USDT0 to another address. +- `receive.ts`: watch for incoming payments in real time. +- `history.ts`: query past Transfer events for an address. ### Demo @@ -296,11 +296,11 @@ received 0.01 USDT0 0xFaucet... 0x22b1...3f09 ``` :::warning -Scanning wide block ranges (millions of blocks) can time out and exceed RPC rate limits. For production, use the [Stablescan Etherscan-compatible API](https://stablescan.xyz) for paginated history queries — every transaction is already indexed. +Scanning wide block ranges (millions of blocks) can time out and exceed RPC rate limits. For production, use the [Stablescan Etherscan-compatible API](https://stablescan.xyz) for paginated history queries. Every transaction is already indexed. ::: ## Next recommended -- [**Subscribe and collect**](/en/how-to/subscribe-and-collect) — Pull-based recurring subscriptions with EIP-7702 delegation. -- [**Paying with invoice**](/en/how-to/pay-with-invoice) — Settle invoices with ERC-3009 and deterministic nonces. -- [**Send your first USDT0**](/en/tutorial/send-usdt0) — Reference the basic native vs. ERC-20 transfer flow. +- [**Subscribe and collect**](/en/how-to/subscribe-and-collect): Pull-based recurring subscriptions with EIP-7702 delegation. +- [**Paying with invoice**](/en/how-to/pay-with-invoice): Settle invoices with ERC-3009 and deterministic nonces. +- [**Send your first USDT0**](/en/tutorial/send-usdt0): Reference the basic native vs. ERC-20 transfer flow. diff --git a/docs/pages/en/how-to/build-pay-per-call.mdx b/docs/pages/en/how-to/build-pay-per-call.mdx index c51728a..37e3f61 100755 --- a/docs/pages/en/how-to/build-pay-per-call.mdx +++ b/docs/pages/en/how-to/build-pay-per-call.mdx @@ -325,6 +325,6 @@ For the full hook reference and examples, see [x402 Lifecycle Hooks](https://x40 ## Next recommended -- [**x402 concept**](/en/explanation/x402) — Understand the protocol and where it fits. -- [**ERC-3009**](/en/explanation/erc-3009) — Review the settlement standard x402 uses. -- [**Paying with MCP server**](/en/how-to/pay-with-mcp) — Wrap this API as an MCP tool so AI clients can call it through prompts. +- [**x402 concept**](/en/explanation/x402): Understand the protocol and where it fits. +- [**ERC-3009**](/en/explanation/erc-3009): Review the settlement standard x402 uses. +- [**Paying with MCP server**](/en/how-to/pay-with-mcp): Wrap this API as an MCP tool so AI clients can call it through prompts. diff --git a/docs/pages/en/how-to/create-wallet.mdx b/docs/pages/en/how-to/create-wallet.mdx index 282b1f1..0735e9a 100755 --- a/docs/pages/en/how-to/create-wallet.mdx +++ b/docs/pages/en/how-to/create-wallet.mdx @@ -63,7 +63,7 @@ Seed phrase: liberty shoot ... (12 words) ``` :::warning -Never log or store the seed phrase in plain text in production. Encrypt it at rest, or use a secrets manager. `ethers.Wallet.createRandom` returns the phrase once per call — if you lose it, funds are unrecoverable. +Never log or store the seed phrase in plain text in production. Encrypt it at rest, or use a secrets manager. `ethers.Wallet.createRandom` returns the phrase once per call. If you lose it, funds are unrecoverable. ::: ## Option 2: Tether WDK @@ -148,6 +148,6 @@ Balance: 1.0 USDT0 ## Next recommended -- [**Delegate with EIP-7702**](/en/how-to/account-abstraction) — Add batch payments, spending limits, and session keys to this wallet. -- [**Send your first USDT0**](/en/tutorial/send-usdt0) — Native and ERC-20 transfers on the same balance. -- [**Fund a testnet wallet**](/en/how-to/use-faucet) — Faucet and Sepolia bridge options for larger test balances. +- [**Delegate with EIP-7702**](/en/how-to/account-abstraction): Add batch payments, spending limits, and session keys to this wallet. +- [**Send your first USDT0**](/en/tutorial/send-usdt0): Native and ERC-20 transfers on the same balance. +- [**Fund a testnet wallet**](/en/how-to/use-faucet): Faucet and Sepolia bridge options for larger test balances. diff --git a/docs/pages/en/how-to/develop-with-ai.mdx b/docs/pages/en/how-to/develop-with-ai.mdx index 621ff15..2dca54c 100755 --- a/docs/pages/en/how-to/develop-with-ai.mdx +++ b/docs/pages/en/how-to/develop-with-ai.mdx @@ -126,14 +126,14 @@ you adjust three gas fields (see Behavioral differences below). ## Common mistakes to avoid -- Copying Ethereum priority-fee constants (2 gwei tips, etc.) — has no effect - on Stable and can be rejected by wallets. +- Copying Ethereum priority-fee constants (2 gwei tips, etc.). This has no + effect on Stable and can be rejected by wallets. - Using `ethers.parseUnits(x, 18)` for ERC-20 USDT0 amounts. ERC-20 uses 6 decimals; native transfers use 18. -- Mirroring native balance in a `uint256 deposited` variable — USDT0 +- Mirroring native balance in a `uint256 deposited` variable. USDT0 allowance-based operations (transferFrom, permit) can reduce a contract's native balance without invoking its code. -- Sending native or ERC-20 USDT0 to `address(0)` — both revert on Stable. +- Sending native or ERC-20 USDT0 to `address(0)`. Both revert on Stable. - Assuming `EXTCODEHASH == 0` means an address is unused. On Stable, permit-based approvals can change state without incrementing nonce. - Writing `value: ethers.parseEther(amount, "ether")` and expecting ETH @@ -207,6 +207,6 @@ env. Print the configured routes on startup. ## Next recommended -- [**Paying with MCP server**](/en/how-to/pay-with-mcp) — Wrap a paid API as an MCP tool so AI clients can call and pay for it. -- [**Quick start**](/en/tutorial/quick-start) — Pair the AI context with a first-transaction run in five minutes. -- [**Difference from Ethereum**](/en/explanation/ethereum-comparison) — Deep-dive on the gas and USDT0 semantics in the context block. +- [**Paying with MCP server**](/en/how-to/pay-with-mcp): Wrap a paid API as an MCP tool so AI clients can call and pay for it. +- [**Quick start**](/en/tutorial/quick-start): Pair the AI context with a first-transaction run in five minutes. +- [**Difference from Ethereum**](/en/explanation/ethereum-comparison): Deep-dive on the gas and USDT0 semantics in the context block. diff --git a/docs/pages/en/how-to/index-contract.mdx b/docs/pages/en/how-to/index-contract.mdx index 5293e99..b32b9a6 100755 --- a/docs/pages/en/how-to/index-contract.mdx +++ b/docs/pages/en/how-to/index-contract.mdx @@ -187,6 +187,6 @@ setupWatcher(); ## Next recommended -- [**Track unbonding completions**](/en/how-to/track-unbonding) — Index system transaction events (unbonding completions) emitted by the protocol. -- [**Build a P2P payment app**](/en/how-to/build-p2p-payments) — Apply indexing to USDT0 Transfer events and build a payment history view. -- [**JSON-RPC reference**](/en/reference/json-rpc-api) — See which `eth_getLogs` and related methods Stable supports. +- [**Track unbonding completions**](/en/how-to/track-unbonding): Index system transaction events (unbonding completions) emitted by the protocol. +- [**Build a P2P payment app**](/en/how-to/build-p2p-payments): Apply indexing to USDT0 Transfer events and build a payment history view. +- [**JSON-RPC reference**](/en/reference/json-rpc-api): See which `eth_getLogs` and related methods Stable supports. diff --git a/docs/pages/en/how-to/index-validator-data.mdx b/docs/pages/en/how-to/index-validator-data.mdx index c61d058..87a9f18 100755 --- a/docs/pages/en/how-to/index-validator-data.mdx +++ b/docs/pages/en/how-to/index-validator-data.mdx @@ -174,7 +174,7 @@ The gov precompile follows the Cosmos EVM `x/gov` interface. Its address is list ## Next recommended -- [**Staking precompile reference**](/en/reference/staking-module-api) — Look up the full validators(), delegation methods, and event signatures. -- [**Create a validator**](/en/how-to/run-validator) — Register a synced node as a validator so it appears in the data above. -- [**Indexers and analytics**](/en/reference/indexers) — Browse indexing providers that already serve normalized Stable data. -- [**Mainnet information**](/en/reference/mainnet-information) — Get Chain ID, RPC endpoints, and rate limits before you start indexing. +- [**Staking precompile reference**](/en/reference/staking-module-api): Look up the full validators(), delegation methods, and event signatures. +- [**Create a validator**](/en/how-to/run-validator): Register a synced node as a validator so it appears in the data above. +- [**Indexers and analytics**](/en/reference/indexers): Browse indexing providers that already serve normalized Stable data. +- [**Mainnet information**](/en/reference/mainnet-information): Get Chain ID, RPC endpoints, and rate limits before you start indexing. diff --git a/docs/pages/en/how-to/integrate-gas-waiver.mdx b/docs/pages/en/how-to/integrate-gas-waiver.mdx index 95a46a3..eaaf45d 100755 --- a/docs/pages/en/how-to/integrate-gas-waiver.mdx +++ b/docs/pages/en/how-to/integrate-gas-waiver.mdx @@ -201,7 +201,7 @@ WebSocket interface for streaming submissions. Authentication: required (Bearer) ## Next recommended -- [**Zero gas transactions**](/en/how-to/zero-gas-transactions) — See the demo-focused flow and how to verify zero gas on a receipt. -- [**Self-hosted Gas Waiver**](/en/how-to/self-hosted-gas-waiver) — Run your own waiver without the hosted API. -- [**Gas waiver protocol**](/en/reference/gas-waiver-api) — Full wrapper transaction spec and governance model. -- [**Stable SDK**](/en/explanation/sdk-overview) — Use the typed client to sign user transactions you then submit to the Waiver Server. +- [**Zero gas transactions**](/en/how-to/zero-gas-transactions): See the demo-focused flow and how to verify zero gas on a receipt. +- [**Self-hosted Gas Waiver**](/en/how-to/self-hosted-gas-waiver): Run your own waiver without the hosted API. +- [**Gas waiver protocol**](/en/reference/gas-waiver-api): Full wrapper transaction spec and governance model. +- [**Stable SDK**](/en/explanation/sdk-overview): Use the typed client to sign user transactions you then submit to the Waiver Server. diff --git a/docs/pages/en/how-to/pay-with-invoice.mdx b/docs/pages/en/how-to/pay-with-invoice.mdx index 7c09e80..b7c9e4a 100755 --- a/docs/pages/en/how-to/pay-with-invoice.mdx +++ b/docs/pages/en/how-to/pay-with-invoice.mdx @@ -42,7 +42,7 @@ step 4. Reconciliation **Buyer:** -``` +```text ─── Buyer ─────────────────────────────────────────── nonce = getInvoiceNonce(invoice) authorization = { from: buyer, to: vendor, value: amount, nonce, ... } @@ -57,7 +57,7 @@ usdt0.transferWithAuthorization(authorization, signature) **Vendor:** -``` +```text ─── Vendor ────────────────────────────────────────── // If Option B: submit transferWithAuthorization using the buyer's signature @@ -409,6 +409,6 @@ Never retry a failed submission without classifying the error. Blind retries on ## Next recommended -- [**Invoice settlement concept**](/en/reference/invoices) — Understand the deterministic-nonce reconciliation model. -- [**ERC-3009**](/en/explanation/erc-3009) — Review the signed-authorization standard behind this flow. -- [**Enable gas-free transactions**](/en/how-to/integrate-gas-waiver) — Combine with Gas Waiver to eliminate gas from the settlement path. +- [**Invoice settlement concept**](/en/reference/invoices): Understand the deterministic-nonce reconciliation model. +- [**ERC-3009**](/en/explanation/erc-3009): Review the signed-authorization standard behind this flow. +- [**Enable gas-free transactions**](/en/how-to/integrate-gas-waiver): Combine with Gas Waiver to eliminate gas from the settlement path. diff --git a/docs/pages/en/how-to/pay-with-mcp.mdx b/docs/pages/en/how-to/pay-with-mcp.mdx index 355c978..bdf4581 100755 --- a/docs/pages/en/how-to/pay-with-mcp.mdx +++ b/docs/pages/en/how-to/pay-with-mcp.mdx @@ -65,7 +65,7 @@ tools = { **User (via AI client):** -``` +```text ─── AI Client ─────────────────────────────────────── User: "Pull financials for ACME Corp and assess their credit risk." @@ -243,6 +243,6 @@ These limits run server-side. The AI client cannot modify or bypass them. ## Next recommended -- [**Build a pay-per-call API**](/en/how-to/build-pay-per-call) — Set up the x402 server this MCP server bridges. -- [**x402 concept**](/en/explanation/x402) — Review the settlement protocol behind these payments. -- [**Develop with AI**](/en/how-to/develop-with-ai) — Wire Stable's Docs and Runtime MCP servers into the same AI client. +- [**Build a pay-per-call API**](/en/how-to/build-pay-per-call): Set up the x402 server this MCP server bridges. +- [**x402 concept**](/en/explanation/x402): Review the settlement protocol behind these payments. +- [**Develop with AI**](/en/how-to/develop-with-ai): Wire Stable's Docs and Runtime MCP servers into the same AI client. diff --git a/docs/pages/en/how-to/production-readiness.mdx b/docs/pages/en/how-to/production-readiness.mdx index 4789a19..99ec406 100755 --- a/docs/pages/en/how-to/production-readiness.mdx +++ b/docs/pages/en/how-to/production-readiness.mdx @@ -72,7 +72,7 @@ payable(recipient).call{value: amount}(""); ## Next recommended -- [**USDT0 behavior**](/en/explanation/usdt0-behavior) — Read the full migration checklist and contract design requirements. -- [**Mainnet information**](/en/reference/mainnet-information) — Check mainnet chain parameters and version history. -- [**RPC providers**](/en/reference/rpc-providers) — Pick third-party RPC providers for redundancy. -- [**Monitoring**](/en/how-to/monitor-node) — Wire metrics and alerts for block production and RPC health. +- [**USDT0 behavior**](/en/explanation/usdt0-behavior): Read the full migration checklist and contract design requirements. +- [**Mainnet information**](/en/reference/mainnet-information): Check mainnet chain parameters and version history. +- [**RPC providers**](/en/reference/rpc-providers): Pick third-party RPC providers for redundancy. +- [**Monitoring**](/en/how-to/monitor-node): Wire metrics and alerts for block production and RPC health. diff --git a/docs/pages/en/how-to/run-validator.mdx b/docs/pages/en/how-to/run-validator.mdx index 2ce47d3..d00aabf 100755 --- a/docs/pages/en/how-to/run-validator.mdx +++ b/docs/pages/en/how-to/run-validator.mdx @@ -146,7 +146,7 @@ Keep the validator healthy and ready for network upgrades: ## Next recommended -- [**Staking precompile reference**](/en/reference/staking-module-api) — Look up the full createValidator, delegate, and editValidator signatures and structs. -- [**Node configuration**](/en/reference/node-configuration) — Set double_sign_check_height and other validator-critical config before you register. -- [**Monitor a node**](/en/how-to/monitor-node) — Track signing, missed blocks, and resource usage so you catch problems before a slash. -- [**Index validator data**](/en/how-to/index-validator-data) — Read your validator's stake, uptime, and voting history on-chain once it is live. +- [**Staking precompile reference**](/en/reference/staking-module-api): Look up the full createValidator, delegate, and editValidator signatures and structs. +- [**Node configuration**](/en/reference/node-configuration): Set double_sign_check_height and other validator-critical config before you register. +- [**Monitor a node**](/en/how-to/monitor-node): Track signing, missed blocks, and resource usage so you catch problems before a slash. +- [**Index validator data**](/en/how-to/index-validator-data): Read your validator's stake, uptime, and voting history on-chain once it is live. diff --git a/docs/pages/en/how-to/sdk-with-viem.mdx b/docs/pages/en/how-to/sdk-with-viem.mdx index c80565f..48be50a 100755 --- a/docs/pages/en/how-to/sdk-with-viem.mdx +++ b/docs/pages/en/how-to/sdk-with-viem.mdx @@ -101,12 +101,12 @@ const { txHash } = await stable.transfer({ from, to: "0xRecipient", amount: 5 }) | **Mode** | **Use when** | | :--- | :--- | -| `account` | Backend services, scripts, agents — anywhere you hold the key. | +| `account` | Backend services, scripts, agents, anywhere you hold the key. | | `transport` | Browser apps where the user signs with MetaMask or a wagmi-less custom flow. | | `walletClient` | You already have a configured `WalletClient` (wagmi, RainbowKit, ConnectKit). | ## Next recommended -- [**Use with wagmi**](/en/how-to/sdk-with-wagmi) — Wire the SDK into a React app through wagmi hooks. -- [**SDK reference**](/en/reference/sdk) — Every config field, method, enum, and error class. -- [**SDK quickstart**](/en/tutorial/sdk-quickstart) — Run your first transfer, bridge, and swap on testnet. +- [**Use with wagmi**](/en/how-to/sdk-with-wagmi): Wire the SDK into a React app through wagmi hooks. +- [**SDK reference**](/en/reference/sdk): Every config field, method, enum, and error class. +- [**SDK quickstart**](/en/tutorial/sdk-quickstart): Run your first transfer, bridge, and swap on testnet. diff --git a/docs/pages/en/how-to/sdk-with-wagmi.mdx b/docs/pages/en/how-to/sdk-with-wagmi.mdx index d3266e1..396745c 100755 --- a/docs/pages/en/how-to/sdk-with-wagmi.mdx +++ b/docs/pages/en/how-to/sdk-with-wagmi.mdx @@ -126,6 +126,6 @@ Caching quotes with `useQuery` works well: pass `quoteSwap` / `quoteBridge` as t ## Next recommended -- [**SDK reference**](/en/reference/sdk) — Every method, config field, and error class. -- [**Use with viem**](/en/how-to/sdk-with-viem) — Compare the three signing modes side-by-side. -- [**SDK quickstart**](/en/tutorial/sdk-quickstart) — Run your first transfer, bridge, and swap on testnet. +- [**SDK reference**](/en/reference/sdk): Every method, config field, and error class. +- [**Use with viem**](/en/how-to/sdk-with-viem): Compare the three signing modes side-by-side. +- [**SDK quickstart**](/en/tutorial/sdk-quickstart): Run your first transfer, bridge, and swap on testnet. diff --git a/docs/pages/en/how-to/self-hosted-gas-waiver.mdx b/docs/pages/en/how-to/self-hosted-gas-waiver.mdx index 60e5bcc..c054baf 100755 --- a/docs/pages/en/how-to/self-hosted-gas-waiver.mdx +++ b/docs/pages/en/how-to/self-hosted-gas-waiver.mdx @@ -1,6 +1,6 @@ --- title: "Self-hosted gas waiver" -description: "Run your own gas waiver on Stable. Register a waiver address through governance, construct wrapper transactions, and broadcast them directly without the hosted Waiver Server API." +description: "Run your own gas waiver on Stable. Register a waiver address through governance, build wrapper transactions, and broadcast them without the hosted server." diataxis: "how-to" --- @@ -137,6 +137,6 @@ Confirmed: true ## Next recommended -- [**Gas waiver concept**](/en/explanation/gas-waiver) — Understand the mechanism before you run your own. -- [**Gas waiver protocol**](/en/reference/gas-waiver-api) — Reference the full protocol spec for marker routing, authorization, and execution semantics. -- [**Enable gas-free transactions**](/en/how-to/integrate-gas-waiver) — Use the hosted Waiver Server API instead of self-hosting. +- [**Gas waiver concept**](/en/explanation/gas-waiver): Understand the mechanism before you run your own. +- [**Gas waiver protocol**](/en/reference/gas-waiver-api): Reference the full protocol spec for marker routing, authorization, and execution semantics. +- [**Enable gas-free transactions**](/en/how-to/integrate-gas-waiver): Use the hosted Waiver Server API instead of self-hosting. diff --git a/docs/pages/en/how-to/subscribe-and-collect.mdx b/docs/pages/en/how-to/subscribe-and-collect.mdx index c1fe3d6..a381dc3 100755 --- a/docs/pages/en/how-to/subscribe-and-collect.mdx +++ b/docs/pages/en/how-to/subscribe-and-collect.mdx @@ -44,7 +44,7 @@ step 5. Subscriber cancels **Subscriber:** -``` +```text ─── Subscriber ─────────────────────────────────────── // One-time setup: delegate EOA to the subscription contract signAuthorization(delegateContract) @@ -59,7 +59,7 @@ sendTransaction({ to: self, data: cancelSubscription(subscriptionId) }) **Service provider:** -``` +```text ─── Service Provider ──────────────────────────────── // Each billing cycle: collect payment from subscriber's EOA // The delegate contract verifies caller, billing schedule, and amount @@ -384,6 +384,6 @@ The subscriber is authorizing the delegate contract to pull funds from their EOA ## Next recommended -- [**Subscription billing concept**](/en/reference/subscriptions) — Understand the pull-based billing model. -- [**Account abstraction**](/en/how-to/account-abstraction) — See how batch payments, spending limits, and session keys combine under one delegation. -- [**EIP-7702 concept**](/en/explanation/eip-7702) — Review the delegation model that makes this possible. +- [**Subscription billing concept**](/en/reference/subscriptions): Understand the pull-based billing model. +- [**Account abstraction**](/en/how-to/account-abstraction): See how batch payments, spending limits, and session keys combine under one delegation. +- [**EIP-7702 concept**](/en/explanation/eip-7702): Review the delegation model that makes this possible. diff --git a/docs/pages/en/how-to/track-unbonding.mdx b/docs/pages/en/how-to/track-unbonding.mdx index 33d66c8..5c4d430 100755 --- a/docs/pages/en/how-to/track-unbonding.mdx +++ b/docs/pages/en/how-to/track-unbonding.mdx @@ -181,6 +181,6 @@ setupEventListener(); ## Next recommended -- [**System transactions concept**](/en/explanation/system-transactions) — Understand how protocol-level events reach the EVM. -- [**Staking module concept**](/en/explanation/staking-module) — Review the delegation and unbonding flow. -- [**Staking precompile reference**](/en/reference/staking-module-api) — Look up the methods that trigger the events tracked here. +- [**System transactions concept**](/en/explanation/system-transactions): Understand how protocol-level events reach the EVM. +- [**Staking module concept**](/en/explanation/staking-module): Review the delegation and unbonding flow. +- [**Staking precompile reference**](/en/reference/staking-module-api): Look up the methods that trigger the events tracked here. diff --git a/docs/pages/en/how-to/troubleshoot-node.mdx b/docs/pages/en/how-to/troubleshoot-node.mdx index f4b7701..138c5c2 100755 --- a/docs/pages/en/how-to/troubleshoot-node.mdx +++ b/docs/pages/en/how-to/troubleshoot-node.mdx @@ -57,7 +57,7 @@ echo -e "\n=== Diagnostics Complete ===" #### Issue: binary not found **Error message:** -``` +```text stabled: command not found ``` @@ -76,7 +76,7 @@ sudo chmod +x /usr/bin/stabled #### Issue: permission denied **Error message:** -``` +```text Error: open /home/user/.stabled/config/config.toml: permission denied ``` @@ -94,7 +94,7 @@ chmod 644 ~/.stabled/config/*.toml #### Issue: address already in use **Error message:** -``` +```text Error: listen tcp 0.0.0.0:26657: bind: address already in use ``` @@ -137,7 +137,7 @@ sudo systemctl start ${SERVICE_NAME} #### Issue: "wrong Block.Header.AppHash" error **Error message:** -``` +```text panic: Wrong Block.Header.AppHash. Expected XXXX, got YYYY ``` @@ -202,7 +202,7 @@ sudo systemctl restart ${SERVICE_NAME} #### Issue: no peers connecting **Symptoms:** -``` +```text "n_peers": 0 ``` @@ -234,7 +234,7 @@ sudo systemctl restart ${SERVICE_NAME} #### Issue: "AppHash mismatch" after upgrade **Error message:** -``` +```text panic: AppHash mismatch ``` @@ -262,7 +262,7 @@ sudo systemctl start ${SERVICE_NAME} #### Issue: "database corruption" **Error message:** -``` +```text Error initializing database: resource temporarily unavailable ``` @@ -289,7 +289,7 @@ sudo systemctl start ${SERVICE_NAME} #### Issue: "too many open files" **Error message:** -``` +```text accept: too many open files ``` @@ -315,7 +315,7 @@ sudo systemctl restart ${SERVICE_NAME} #### Issue: out of memory (OOM) kills **Symptoms:** -``` +```text stabled.service: Main process exited, code=killed, status=9/KILL ``` @@ -351,7 +351,7 @@ sudo systemctl edit stabled #### Issue: no space left on device **Error message:** -``` +```text Error: write ~/.stabled/data/blockstore.db/001234.log: no space left on device ``` diff --git a/docs/pages/en/how-to/use-system-modules.mdx b/docs/pages/en/how-to/use-system-modules.mdx index 20a3d68..cfd6ec4 100755 --- a/docs/pages/en/how-to/use-system-modules.mdx +++ b/docs/pages/en/how-to/use-system-modules.mdx @@ -184,6 +184,6 @@ Each precompile's full method list, events, and authorization rules live in its ## Next recommended -- [**Track unbonding completions**](/en/how-to/track-unbonding) — Subscribe to the UnbondingCompleted event emitted via the StableSystem precompile. -- [**System modules reference**](/en/reference/system-modules-api-overview) — Jump to the per-module ABI, method signatures, and event schemas. -- [**System modules concept**](/en/explanation/system-modules-overview) — Understand why Stable exposes SDK modules through precompiles. +- [**Track unbonding completions**](/en/how-to/track-unbonding): Subscribe to the UnbondingCompleted event emitted via the StableSystem precompile. +- [**System modules reference**](/en/reference/system-modules-api-overview): Jump to the per-module ABI, method signatures, and event schemas. +- [**System modules concept**](/en/explanation/system-modules-overview): Understand why Stable exposes SDK modules through precompiles. diff --git a/docs/pages/en/how-to/verify-contract.mdx b/docs/pages/en/how-to/verify-contract.mdx index 830fdc1..6cc73e1 100755 --- a/docs/pages/en/how-to/verify-contract.mdx +++ b/docs/pages/en/how-to/verify-contract.mdx @@ -80,6 +80,6 @@ The **Contract** tab should now show source code, a green "Verified" badge, and ## Next recommended -- [**Index contract events**](/en/how-to/index-contract) — Subscribe to on-chain events with ethers.js and build a live event stream. -- [**Deploy a smart contract**](/en/tutorial/smart-contract) — Scaffold a fresh Foundry project and deploy to Stable testnet. -- [**JSON-RPC reference**](/en/reference/json-rpc-api) — See which `eth_*` methods Stable supports for on-chain interactions. +- [**Index contract events**](/en/how-to/index-contract): Subscribe to on-chain events with ethers.js and build a live event stream. +- [**Deploy a smart contract**](/en/tutorial/smart-contract): Scaffold a fresh Foundry project and deploy to Stable testnet. +- [**JSON-RPC reference**](/en/reference/json-rpc-api): See which `eth_*` methods Stable supports for on-chain interactions. diff --git a/docs/pages/en/how-to/work-with-usdt-gas.mdx b/docs/pages/en/how-to/work-with-usdt-gas.mdx index 8b0a60e..ec41da7 100755 --- a/docs/pages/en/how-to/work-with-usdt-gas.mdx +++ b/docs/pages/en/how-to/work-with-usdt-gas.mdx @@ -113,6 +113,6 @@ Estimated fee: 0.000021 USDT0 ## Next recommended -- [**Gas pricing reference**](/en/reference/gas-pricing-api) — Full base-fee model, EIP-1559 format, and `eth_*` method behavior. -- [**Zero gas transactions**](/en/how-to/zero-gas-transactions) — Let an application cover gas via the Gas Waiver. -- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior) — Balance reconciliation and contract design with USDT0's dual role. +- [**Gas pricing reference**](/en/reference/gas-pricing-api): Full base-fee model, EIP-1559 format, and `eth_*` method behavior. +- [**Zero gas transactions**](/en/how-to/zero-gas-transactions): Let an application cover gas via the Gas Waiver. +- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior): Balance reconciliation and contract design with USDT0's dual role. diff --git a/docs/pages/en/how-to/zero-gas-transactions.mdx b/docs/pages/en/how-to/zero-gas-transactions.mdx index 169da92..e339e4b 100755 --- a/docs/pages/en/how-to/zero-gas-transactions.mdx +++ b/docs/pages/en/how-to/zero-gas-transactions.mdx @@ -202,6 +202,6 @@ For the full policy model and per-waiver scope rules, see [Gas waiver protocol]( ## Next recommended -- [**Integrate the Waiver Server**](/en/how-to/integrate-gas-waiver) — Full API reference, batch submissions, error codes, and NDJSON streaming. -- [**Self-hosted Gas Waiver**](/en/how-to/self-hosted-gas-waiver) — Register your own waiver address and broadcast wrappers without the hosted API. -- [**Gas waiver protocol**](/en/reference/gas-waiver-api) — Read the full spec: marker routing, wrapper format, governance controls. +- [**Integrate the Waiver Server**](/en/how-to/integrate-gas-waiver): Full API reference, batch submissions, error codes, and NDJSON streaming. +- [**Self-hosted Gas Waiver**](/en/how-to/self-hosted-gas-waiver): Register your own waiver address and broadcast wrappers without the hosted API. +- [**Gas waiver protocol**](/en/reference/gas-waiver-api): Read the full spec: marker routing, wrapper format, governance controls. diff --git a/docs/pages/en/index.mdx b/docs/pages/en/index.mdx index 4f3855b..1245c68 100755 --- a/docs/pages/en/index.mdx +++ b/docs/pages/en/index.mdx @@ -12,18 +12,18 @@ Pick the capability you're building. Every path below leads to a runnable guide ## Pick your path -- [**Accounts**](/en/explanation/accounts-overview) — Wallets, EIP-7702 delegation, session keys, and spending limits. First-class support for user and agent accounts. -- [**Payments**](/en/explanation/payments-overview) — Send USDT0, build P2P wallets, recurring subscriptions, invoice settlement, and pay-per-call APIs. -- [**Contracts**](/en/explanation/contracts-overview) — Deploy, verify, and index contracts. Call Bank, Distribution, and Staking precompiles from Solidity. -- [**AI / Agents**](/en/explanation/agent-settlement) — Wire MCP servers and agent skills into AI editors. Price APIs per request for autonomous agents. -- [**Infrastructure**](/en/explanation/integrate-overview) — Gas waiver service, ecosystem providers (bridges, oracles, ramps), network info, and node operations. -- [**Learn**](/en/explanation/learn-overview) — Architecture, USDT0 behavior, use case narratives, and the Ethereum-to-Stable reference. +- [**Accounts**](/en/explanation/accounts-overview): Wallets, EIP-7702 delegation, session keys, and spending limits. First-class support for user and agent accounts. +- [**Payments**](/en/explanation/payments-overview): Send USDT0, build P2P wallets, recurring subscriptions, invoice settlement, and pay-per-call APIs. +- [**Contracts**](/en/explanation/contracts-overview): Deploy, verify, and index contracts. Call Bank, Distribution, and Staking precompiles from Solidity. +- [**AI / Agents**](/en/explanation/agent-settlement): Wire MCP servers and agent skills into AI editors. Price APIs per request for autonomous agents. +- [**Infrastructure**](/en/explanation/integrate-overview): Gas waiver service, ecosystem providers (bridges, oracles, ramps), network info, and node operations. +- [**Learn**](/en/explanation/learn-overview): Architecture, USDT0 behavior, use case narratives, and the Ethereum-to-Stable reference. ## Start in five minutes -- [**Quick start**](/en/tutorial/quick-start) — Connect, fund a wallet from the faucet, and send 0.001 USDT0 natively. -- [**Connect to Stable**](/en/reference/connect) — Chain IDs, RPC endpoints, faucet, and block explorers. -- [**Difference from Ethereum**](/en/explanation/ethereum-comparison) — What stays the same and what changes when porting from Ethereum. +- [**Quick start**](/en/tutorial/quick-start): Connect, fund a wallet from the faucet, and send 0.001 USDT0 natively. +- [**Connect to Stable**](/en/reference/connect): Chain IDs, RPC endpoints, faucet, and block explorers. +- [**Difference from Ethereum**](/en/explanation/ethereum-comparison): What stays the same and what changes when porting from Ethereum. ## Everything else diff --git a/docs/pages/en/reference/developer-assistance.mdx b/docs/pages/en/reference/developer-assistance.mdx index 740d84f..2e55049 100755 --- a/docs/pages/en/reference/developer-assistance.mdx +++ b/docs/pages/en/reference/developer-assistance.mdx @@ -42,6 +42,6 @@ Support contacts will be updated as community platforms become available. ## Next recommended -- [**Quick start**](/en/tutorial/quick-start) — Run your first testnet transaction in five minutes. -- [**Production readiness**](/en/how-to/production-readiness) — Validate an integration before shipping to mainnet. -- [**FAQ**](/en/reference/faq) — Common answers about chain IDs, endpoints, and onboarding. +- [**Quick start**](/en/tutorial/quick-start): Run your first testnet transaction in five minutes. +- [**Production readiness**](/en/how-to/production-readiness): Validate an integration before shipping to mainnet. +- [**FAQ**](/en/reference/faq): Common answers about chain IDs, endpoints, and onboarding. diff --git a/docs/pages/en/reference/eip-7702-api.mdx b/docs/pages/en/reference/eip-7702-api.mdx index ed9c7f3..e14a186 100755 --- a/docs/pages/en/reference/eip-7702-api.mdx +++ b/docs/pages/en/reference/eip-7702-api.mdx @@ -43,5 +43,5 @@ Wallets and libraries that support EIP-7702 handle the authorization format auto ## Next recommended -- [**EIP-7702 concept**](/en/explanation/eip-7702) — Understand the delegation model and when to use it. -- [**Account Abstraction (EIP-7702)**](/en/reference/eip-7702-api) — Implement batch payments, spending limits, and session keys step by step. +- [**EIP-7702 concept**](/en/explanation/eip-7702): Understand the delegation model and when to use it. +- [**Account Abstraction (EIP-7702)**](/en/reference/eip-7702-api): Implement batch payments, spending limits, and session keys step by step. diff --git a/docs/pages/en/reference/faq.mdx b/docs/pages/en/reference/faq.mdx index 8bc0e6b..348b72c 100755 --- a/docs/pages/en/reference/faq.mdx +++ b/docs/pages/en/reference/faq.mdx @@ -29,7 +29,7 @@ If you haven't connected to testnet yet, start with [Quick start](/en/tutorial/q **Is Stable EVM-compatible?** -Yes. Solidity, Vyper, Foundry, Hardhat, ethers, viem, and the `eth_*` JSON-RPC methods all work unchanged. Four behaviors differ from Ethereum — see [Differences from Ethereum](/en/explanation/ethereum-comparison). +Yes. Solidity, Vyper, Foundry, Hardhat, ethers, viem, and the `eth_*` JSON-RPC methods all work unchanged. Four behaviors differ from Ethereum. See [Differences from Ethereum](/en/explanation/ethereum-comparison). **Why is USDT0 the gas token?** @@ -67,7 +67,7 @@ Full checklist: [USDT0 behavior on Stable](/en/explanation/usdt0-behavior). ## Next recommended -- [**Quick start**](/en/tutorial/quick-start) — Send a first transaction on testnet. -- [**Core concepts**](/en/explanation/core-concepts) — Learn the four core concepts you need before you build. -- [**Learn overview**](/en/explanation/learn-overview) — Pick the docs path that fits what you're building. -- [**Production readiness**](/en/how-to/production-readiness) — Validate an integration before shipping to mainnet. +- [**Quick start**](/en/tutorial/quick-start): Send a first transaction on testnet. +- [**Core concepts**](/en/explanation/core-concepts): Learn the four core concepts you need before you build. +- [**Learn overview**](/en/explanation/learn-overview): Pick the docs path that fits what you're building. +- [**Production readiness**](/en/how-to/production-readiness): Validate an integration before shipping to mainnet. diff --git a/docs/pages/en/reference/gas-pricing-api.mdx b/docs/pages/en/reference/gas-pricing-api.mdx index 9355a78..54bf228 100755 --- a/docs/pages/en/reference/gas-pricing-api.mdx +++ b/docs/pages/en/reference/gas-pricing-api.mdx @@ -58,6 +58,6 @@ const estimatedFeeInUSDT0 = gasPrice * gasEstimate; ## Next recommended -- [**Gas pricing concept**](/en/explanation/gas-pricing) — Understand why Stable uses a single-component fee model. -- [**Ethereum comparison**](/en/explanation/ethereum-comparison) — Review every behavior difference you'll hit porting from Ethereum. -- [**JSON-RPC API**](/en/reference/json-rpc-api) — Reference the `eth_*` methods Stable exposes. +- [**Gas pricing concept**](/en/explanation/gas-pricing): Understand why Stable uses a single-component fee model. +- [**Ethereum comparison**](/en/explanation/ethereum-comparison): Review every behavior difference you'll hit porting from Ethereum. +- [**JSON-RPC API**](/en/reference/json-rpc-api): Reference the `eth_*` methods Stable exposes. diff --git a/docs/pages/en/reference/gas-waiver-api.mdx b/docs/pages/en/reference/gas-waiver-api.mdx index 92a2fff..73af0a8 100755 --- a/docs/pages/en/reference/gas-waiver-api.mdx +++ b/docs/pages/en/reference/gas-waiver-api.mdx @@ -160,7 +160,7 @@ Base URLs: All endpoints except health require bearer token authentication: -``` +```text Authorization: Bearer ``` @@ -271,7 +271,7 @@ async function createInnerTx(userWallet, contractAddress, callData, nonce) { ## Next recommended -- [**Zero gas transactions**](/en/how-to/zero-gas-transactions) — Demo-focused walkthrough with a receipt showing zero gas fee. -- [**Enable gas-free transactions**](/en/how-to/integrate-gas-waiver) — Full hosted-API integration guide with batch submissions and error handling. -- [**Self-hosted Gas Waiver**](/en/how-to/self-hosted-gas-waiver) — Run your own waiver infrastructure without the hosted API. +- [**Zero gas transactions**](/en/how-to/zero-gas-transactions): Demo-focused walkthrough with a receipt showing zero gas fee. +- [**Enable gas-free transactions**](/en/how-to/integrate-gas-waiver): Full hosted-API integration guide with batch submissions and error handling. +- [**Self-hosted Gas Waiver**](/en/how-to/self-hosted-gas-waiver): Run your own waiver infrastructure without the hosted API. diff --git a/docs/pages/en/reference/invoices.mdx b/docs/pages/en/reference/invoices.mdx index 7e3a42d..39c34da 100755 --- a/docs/pages/en/reference/invoices.mdx +++ b/docs/pages/en/reference/invoices.mdx @@ -14,7 +14,7 @@ Both the buyer and the vendor independently compute the same nonce from the same The nonce is derived deterministically: -``` +```text nonce = keccak256(invoiceNumber, vendor, buyer, amount, dueDate) ``` diff --git a/docs/pages/en/reference/json-rpc-api.mdx b/docs/pages/en/reference/json-rpc-api.mdx index 1b6ce25..838e9e9 100755 --- a/docs/pages/en/reference/json-rpc-api.mdx +++ b/docs/pages/en/reference/json-rpc-api.mdx @@ -123,6 +123,6 @@ diataxis: "reference" ## Next recommended -- [**Gas pricing reference**](/en/reference/gas-pricing-api) — Construct EIP-1559 transactions against Stable's base-fee-only model. -- [**EIP-7702 reference**](/en/reference/eip-7702-api) — Build type-4 transactions with the `authorizationList` field. -- [**System modules reference**](/en/reference/system-modules-api-overview) — Call Bank, Distribution, and Staking at their fixed precompile addresses. +- [**Gas pricing reference**](/en/reference/gas-pricing-api): Construct EIP-1559 transactions against Stable's base-fee-only model. +- [**EIP-7702 reference**](/en/reference/eip-7702-api): Build type-4 transactions with the `authorizationList` field. +- [**System modules reference**](/en/reference/system-modules-api-overview): Call Bank, Distribution, and Staking at their fixed precompile addresses. diff --git a/docs/pages/en/reference/sdk.mdx b/docs/pages/en/reference/sdk.mdx index 77de635..64d437c 100755 --- a/docs/pages/en/reference/sdk.mdx +++ b/docs/pages/en/reference/sdk.mdx @@ -76,7 +76,7 @@ Returns `OperationResult` (`{ txHash, toAmount? }`). ### `quoteBridge(params)` -Preview a bridge. Read-only — no signature, no gas. +Preview a bridge. Read-only. No signature, no gas. ```ts const quote = await stable.quoteBridge({ @@ -228,6 +228,6 @@ StableTransactionError: transfer: wallet rejected or failed to switch to chain 9 ## Next recommended -- [**SDK quickstart**](/en/tutorial/sdk-quickstart) — Install the SDK and run your first transfer on testnet. -- [**Use with viem**](/en/how-to/sdk-with-viem) — Switch between private-key, browser-wallet, and pre-built signers. -- [**Use with wagmi**](/en/how-to/sdk-with-wagmi) — Wire the SDK into a React app with hooks. +- [**SDK quickstart**](/en/tutorial/sdk-quickstart): Install the SDK and run your first transfer on testnet. +- [**Use with viem**](/en/how-to/sdk-with-viem): Switch between private-key, browser-wallet, and pre-built signers. +- [**Use with wagmi**](/en/how-to/sdk-with-wagmi): Wire the SDK into a React app with hooks. diff --git a/docs/pages/en/resources/brand-kit.mdx b/docs/pages/en/resources/brand-kit.mdx index df4ff06..6680237 100755 --- a/docs/pages/en/resources/brand-kit.mdx +++ b/docs/pages/en/resources/brand-kit.mdx @@ -1,6 +1,7 @@ --- title: "Brand Kit" description: "Stable's brand kit with logos and color palettes for consistent use in projects and communications." +diataxis: "reference" --- # Brand Kit diff --git a/docs/pages/en/tutorial/bridge-usdt0.mdx b/docs/pages/en/tutorial/bridge-usdt0.mdx index 401984b..975772b 100755 --- a/docs/pages/en/tutorial/bridge-usdt0.mdx +++ b/docs/pages/en/tutorial/bridge-usdt0.mdx @@ -296,7 +296,7 @@ npx tsx --env-file=.env bridge.ts **Checkpoint:** You should see output like this: -``` +```text Minting 1.0 USDT0 on Sepolia... Mint tx: 0x3a1f...c9d2 confirmed USDT0 balance: 1.0 @@ -331,6 +331,6 @@ You bridged USDT0 from Ethereum Sepolia to Stable Testnet. You now know how to: ## Next recommended -- [**Send your first USDT0**](/en/tutorial/send-usdt0) — Use the bridged USDT0 with native and ERC-20 transfers. -- [**Bridging to Stable**](/en/explanation/usdt0-bridging) — Deep dive on OFT Mesh vs Legacy Mesh mechanics. -- [**Testnet information**](/en/reference/testnet-information) — Full network parameters, RPC endpoints, and faucet details. +- [**Send your first USDT0**](/en/tutorial/send-usdt0): Use the bridged USDT0 with native and ERC-20 transfers. +- [**Bridging to Stable**](/en/explanation/usdt0-bridging): Deep dive on OFT Mesh vs Legacy Mesh mechanics. +- [**Testnet information**](/en/reference/testnet-information): Full network parameters, RPC endpoints, and faucet details. diff --git a/docs/pages/en/tutorial/quick-start.mdx b/docs/pages/en/tutorial/quick-start.mdx index ac60005..f3a60f0 100755 --- a/docs/pages/en/tutorial/quick-start.mdx +++ b/docs/pages/en/tutorial/quick-start.mdx @@ -115,6 +115,6 @@ Open the explorer link to confirm the transaction. Block time is roughly 0.7 sec ## Where to go next -- [**Deploy a smart contract**](/en/tutorial/smart-contract) — Scaffold a Foundry project and deploy to Stable testnet. -- [**Build a payment app**](/en/how-to/build-p2p-payments) — Create wallet, send, receive, and query payment history. -- [**Develop with AI**](/en/how-to/develop-with-ai) — Wire MCP servers and agent skills into your AI editor. +- [**Deploy a smart contract**](/en/tutorial/smart-contract): Scaffold a Foundry project and deploy to Stable testnet. +- [**Build a payment app**](/en/how-to/build-p2p-payments): Create wallet, send, receive, and query payment history. +- [**Develop with AI**](/en/how-to/develop-with-ai): Wire MCP servers and agent skills into your AI editor. diff --git a/docs/pages/en/tutorial/sdk-quickstart.mdx b/docs/pages/en/tutorial/sdk-quickstart.mdx index 7f6797e..24bdfc4 100755 --- a/docs/pages/en/tutorial/sdk-quickstart.mdx +++ b/docs/pages/en/tutorial/sdk-quickstart.mdx @@ -9,7 +9,7 @@ diataxis: "tutorial" You'll install `@stablechain/sdk`, create a client signed by a private key, send a USDT0 transfer on Stable Testnet, and fetch a bridge and swap quote. Total time: about five minutes. :::note -Stable uses USDT0 as the gas token. You only need testnet USDT0 to transact — there's no separate native asset to fund. +Stable uses USDT0 as the gas token. You only need testnet USDT0 to transact. There's no separate native asset to fund. ::: ## Prerequisites @@ -88,7 +88,7 @@ Open the hash on the [testnet explorer](https://testnet.stablescan.xyz) to confi ## 4. Quote a bridge -Bridge USDT0 from Ethereum Sepolia to Stable Testnet. `quoteBridge` is a read-only call — no signature, no gas: +Bridge USDT0 from Ethereum Sepolia to Stable Testnet. `quoteBridge` is a read-only call, with no signature and no gas: ```ts import { Chain } from "@stablechain/sdk"; @@ -133,6 +133,6 @@ Call `stable.swap({ ...params, quote: swapQuote })` to execute. Approval for ERC ## Next recommended -- [**SDK reference**](/en/reference/sdk) — Every parameter, return type, and error class. -- [**Use with viem**](/en/how-to/sdk-with-viem) — Switch between private-key, browser-wallet, and pre-built `WalletClient` signing. -- [**Use with wagmi**](/en/how-to/sdk-with-wagmi) — Wire the SDK into a React app using wagmi hooks. +- [**SDK reference**](/en/reference/sdk): Every parameter, return type, and error class. +- [**Use with viem**](/en/how-to/sdk-with-viem): Switch between private-key, browser-wallet, and pre-built `WalletClient` signing. +- [**Use with wagmi**](/en/how-to/sdk-with-wagmi): Wire the SDK into a React app using wagmi hooks. diff --git a/docs/pages/en/tutorial/send-usdt0.mdx b/docs/pages/en/tutorial/send-usdt0.mdx index 1fff06b..d631d3a 100755 --- a/docs/pages/en/tutorial/send-usdt0.mdx +++ b/docs/pages/en/tutorial/send-usdt0.mdx @@ -157,6 +157,6 @@ Both values represent the same balance. They may differ by up to 0.000001 USDT0 ## Next recommended -- [**Zero gas transactions**](/en/how-to/zero-gas-transactions) — Send USDT0 with gas fees paid by a waiver service. -- [**Build a P2P payment app**](/en/how-to/build-p2p-payments) — Create wallet, send, receive, and query payment history. -- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior) — Understand dual-role balance reconciliation and contract design. +- [**Zero gas transactions**](/en/how-to/zero-gas-transactions): Send USDT0 with gas fees paid by a waiver service. +- [**Build a P2P payment app**](/en/how-to/build-p2p-payments): Create wallet, send, receive, and query payment history. +- [**USDT0 behavior on Stable**](/en/explanation/usdt0-behavior): Understand dual-role balance reconciliation and contract design. diff --git a/docs/pages/en/tutorial/smart-contract.mdx b/docs/pages/en/tutorial/smart-contract.mdx index 55828da..c0e4ec8 100755 --- a/docs/pages/en/tutorial/smart-contract.mdx +++ b/docs/pages/en/tutorial/smart-contract.mdx @@ -108,7 +108,7 @@ cast chain-id --rpc-url https://rpc.testnet.stable.xyz Expected output: -``` +```text 2201 ``` @@ -133,7 +133,7 @@ Stable uses **USDT0** as its gas token. The same asset you use to pay for goods Visit the testnet faucet and request funds: -``` +```text https://faucet.stable.xyz ``` @@ -169,7 +169,7 @@ Foundry compiles the contract, broadcasts a deployment transaction, and waits fo **Checkpoint:** The output should look like this: -``` +```text [⠒] Compiling... No files changed, compilation skipped Deployer: 0xYourAddress @@ -204,17 +204,17 @@ cast call 0xSomeContractAddress "number()(uint256)" \ Expected output: -``` +```text 42 ``` -You just wrote to and read from the Stable Testnet. The round-trip — deploy, write, read — is the core loop of EVM development, and it works identically here to any other EVM chain. +You just wrote to and read from the Stable Testnet. The round-trip (deploy, write, read) is the core loop of EVM development, and it works identically here to any other EVM chain. ## 9. Inspect your deployment on Stablescan Open the Stable Testnet block explorer and paste your contract address: -``` +```text https://testnet.stablescan.xyz ``` @@ -224,7 +224,7 @@ You will see your deployment transaction and the `setNumber` call you made. Stab ## What you have built -You deployed a contract, sent a state-changing transaction, and read on-chain state — all on the Stable Testnet. You now know how to: +You deployed a contract, sent a state-changing transaction, and read on-chain state, all on the Stable Testnet. You now know how to: - Configure Foundry (or any EVM toolchain) to target Stable using a standard RPC endpoint - Fund a wallet using the USDT0 faucet @@ -233,6 +233,6 @@ You deployed a contract, sent a state-changing transaction, and read on-chain st ## Next recommended -- [**Verify the contract**](/en/how-to/verify-contract) — Upload your source to Stablescan so users can read and interact with it. -- [**Index contract events**](/en/how-to/index-contract) — Subscribe to events with ethers.js and backfill historical logs. -- [**Gas pricing reference**](/en/reference/gas-pricing-api) — Understand how USDT0-denominated fees are calculated. +- [**Verify the contract**](/en/how-to/verify-contract): Upload your source to Stablescan so users can read and interact with it. +- [**Index contract events**](/en/how-to/index-contract): Subscribe to events with ethers.js and backfill historical logs. +- [**Gas pricing reference**](/en/reference/gas-pricing-api): Understand how USDT0-denominated fees are calculated. diff --git a/docs/pages/ko/explanation/accounts-guides.mdx b/docs/pages/ko/explanation/accounts-guides.mdx index 78898f9..0bc9af7 100644 --- a/docs/pages/ko/explanation/accounts-guides.mdx +++ b/docs/pages/ko/explanation/accounts-guides.mdx @@ -1,26 +1,26 @@ --- source_path: explanation/accounts-guides.mdx -source_sha: cf8f431a04b9629b56f347af8835b979316da7ae +source_sha: a227a6651c1f8c559681e3e818155c67e39d3f7b title: "계정 가이드" -description: "모든 계정 가이드, 개념, 참조를 한 페이지에: 지갑 생성, EIP-7702 위임, 에이전트 지갑 및 관련 API 영역." +description: "지갑 생성, EIP-7702 위임, 에이전트 지갑 및 관련 API 표면 등 모든 계정 가이드, 개념 및 참조를 한 페이지에서 확인하세요." diataxis: "explanation" --- # 계정 가이드 -계정 탭 아래의 모든 가이드, 개념, 참조를 수행하려는 작업별로 분류했습니다. +계정 탭 아래의 모든 가이드, 개념 및 참조가 수행하려는 작업별로 그룹화되어 있습니다. ## 지갑 설정 -- [**지갑 생성하기**](/ko/how-to/create-wallet) — ethers.js 또는 Tether WDK를 사용하여 새 키 쌍을 생성하거나 시드 구문에서 복원합니다. -- [**에이전트 지갑**](/ko/reference/agentic-wallets) — AI 에이전트를 위한 자가 수탁형 지갑 — 사용자 지갑과의 차이점. +- [**지갑 생성**](/ko/how-to/create-wallet): ethers.js 또는 Tether WDK를 사용하여 새 키 쌍을 생성하거나 시드 구문에서 복원합니다. +- [**에이전트 지갑**](/ko/reference/agentic-wallets): AI 에이전트를 위한 자체 관리형 지갑 (사용자 지갑과의 차이점). ## 계정 위임 (EIP-7702) -- [**EIP-7702 개념**](/ko/explanation/eip-7702) — Stable에서 EIP-7702가 가능하게 하는 것과 보안 모델. -- [**계정 추상화 사용법**](/ko/how-to/account-abstraction) — EIP-7702를 일괄 결제, 지출 한도, 세션 키에 적용합니다. +- [**EIP-7702 개념**](/ko/explanation/eip-7702): Stable에서 EIP-7702가 가능하게 하는 기능 및 보안 모델. +- [**계정 추상화 방법**](/ko/how-to/account-abstraction): 일괄 결제, 지출 한도 및 세션 키에 EIP-7702를 적용합니다. ## 참조 -- [**EIP-7702 API**](/ko/reference/eip-7702-api) — Type-4 트랜잭션 형식과 권한 부여 목록. -- [**구독 및 수금**](/ko/how-to/subscribe-and-collect) — EIP-7702 위임을 구독 결제 흐름에 적용합니다 (교차 게시됨). +- [**EIP-7702 API**](/ko/reference/eip-7702-api): Type-4 트랜잭션 형식 및 승인 목록. +- [**구독 및 수집**](/ko/how-to/subscribe-and-collect): EIP-7702 대리인을 구독 결제 흐름에 적용 (교차 목록). diff --git a/docs/pages/ko/explanation/accounts-overview.mdx b/docs/pages/ko/explanation/accounts-overview.mdx index bfa8fb8..1da90ce 100644 --- a/docs/pages/ko/explanation/accounts-overview.mdx +++ b/docs/pages/ko/explanation/accounts-overview.mdx @@ -1,37 +1,37 @@ --- source_path: explanation/accounts-overview.mdx -source_sha: f1de0ee300d11d88fc2beb1574268becad865de4 +source_sha: a61b4059ba015ad3e32ff09134ed6df69381096e title: "Stable의 계정" -description: "Stable에서 사용자 및 에이전트 계정을 위한 지갑, EIP-7702 위임, 세션 키, 지출 한도." +description: "Stable의 사용자 및 에이전트 계정을 위한 지갑, EIP-7702 위임, 세션 키 및 지출 한도." diataxis: "explanation" --- # Stable의 계정 -Stable의 계정은 [EIP-7702 위임](/ko/explanation/eip-7702)을 통해 선택적으로 스마트 컨트랙트 로직을 실행할 수 있는 표준 이더리움 EOA입니다. 사용자는 지갑, 일괄 결제, 정기 구독, 세션 키 전반에 걸쳐 하나의 주소와 하나의 개인 키를 유지합니다. 에이전트는 어떠한 커스터디 미들웨어 없이 동일한 계정 모델을 실행합니다. +Stable의 계정은 [EIP-7702 위임](/ko/explanation/eip-7702)을 통해 선택적으로 스마트 계약 로직을 실행할 수 있는 표준 이더리움 EOA입니다. 사용자는 지갑, 일괄 결제, 정기 구독 및 세션 키에 걸쳐 단일 주소와 단일 개인 키를 유지합니다. 에이전트는 중개 미들웨어 없이 동일한 계정 모델을 실행합니다. -## 무엇을 구축할 수 있나요 +## 구축할 수 있는 것 -- 네이티브 USDT0 잔액 조회와 서명된 트랜잭션을 갖춘, 시드 문구로부터의 **지갑**. -- **일괄 결제**: 위임된 EOA를 통해 하나의 원자적 트랜잭션으로 여러 전송을 실행합니다. -- **지출 한도**: 위임 로직을 통해 EOA 자체에 트랜잭션당 또는 일일 상한을 적용합니다. -- **세션 키**: 범위가 제한되고 시간이 제한되며 예산이 제한된 키를 dApp에 부여하여 사용자가 모든 작업마다 다시 서명할 필요가 없도록 합니다. -- **에이전트 지갑**: 자체 보관 키로 AI 에이전트에 자금을 공급하고 x402 서비스 비용을 자율적으로 지불하게 합니다. 제공자 및 통합 패턴은 [에이전트 지갑](/ko/reference/agentic-wallets)을 참조하세요. +- 시드 구와 USDT0 잔액 쿼리 및 서명된 트랜잭션이 기본으로 제공되는 **지갑**. +- **일괄 결제**: 위임된 EOA를 통해 여러 전송을 하나의 아토믹 트랜잭션으로 실행합니다. +- **지출 한도**: 위임 로직을 통해 EOA 자체에 거래당 또는 일일 상한을 적용합니다. +- **세션 키**: dApp에 범위가 지정되고 시간 및 예산이 제한된 키를 부여하여 사용자가 모든 작업을 다시 서명할 필요가 없도록 합니다. +- **에이전트 지갑**: AI 에이전트에 자체 보관 키로 자금을 지원하고 x402 서비스를 자율적으로 결제하도록 합니다. 공급업체 및 통합 패턴은 [에이전트 지갑(Agentic wallets)](/ko/reference/agentic-wallets)을 참조하십시오. -## Stable이 다른 점 +## Stable의 차이점 -- **모든 것을 위한 하나의 주소.** 스마트 컨트랙트 기능을 사용하기 위한 계정 마이그레이션이 필요 없습니다. EIP-7702는 기존 EOA *위에* 코드를 위임합니다. -- **USDT0 전용 가스.** 사용자는 별도의 네이티브 토큰이 필요 없습니다. 새 계정은 USDT0로 자금을 공급하고 즉시 트랜잭션을 처리할 수 있습니다. -- **다기능 위임 패턴.** 단일 위임자가 일괄 처리, 지출 한도, 세션 키, 구독을 결합할 수 있어 하나의 위임으로 출시하는 모든 기능을 커버합니다. +- **모든 것을 위한 단일 주소.** 스마트 계약 기능을 잠금 해제하기 위한 계정 마이그레이션이 필요 없습니다. EIP-7702는 기존 EOA **에** 코드를 위임합니다. +- **USDT0 전용 가스.** 사용자는 별도의 기본 토큰이 필요 없습니다. 새 계정은 USDT0로 자금을 조달하며 즉시 거래할 수 있습니다. +- **다기능 위임 패턴.** 단일 위임은 일괄 처리, 지출 한도, 세션 키 및 구독을 결합하여 제공하는 모든 기능을 포괄할 수 있습니다. -## 여기서 시작하세요 +## 여기에서 시작 -- [**지갑 만들기**](/ko/how-to/create-wallet) — ethers.js 또는 Tether WDK로 지갑을 생성하거나 복원합니다. -- [**EIP-7702로 위임하기**](/ko/how-to/account-abstraction) — 기존 EOA에 일괄 결제, 지출 한도, 세션 키를 적용합니다. -- [**Stable SDK**](/ko/explanation/sdk-overview) — 타입이 지정된 클라이언트를 사용하여 모든 계정에서 트랜잭션을 서명하고 전송합니다. +- [**지갑 생성**](/ko/how-to/create-wallet): ethers.js 또는 Tether WDK를 사용하여 지갑을 생성하거나 복원합니다. +- [**EIP-7702로 위임**](/ko/how-to/account-abstraction): 기존 EOA에 일괄 결제, 지출 한도 및 세션 키를 적용합니다. +- [**Stable SDK**](/ko/explanation/sdk-overview): 유형이 지정된 클라이언트를 사용하여 모든 계정에서 트랜잭션을 서명하고 전송합니다. -## 다음 추천 +## 다음 권장 사항 -- [**계정 가이드 색인**](/ko/explanation/accounts-guides) — 계정 가이드 및 참조의 전체 목록으로 이동합니다. -- [**EIP-7702 개념**](/ko/explanation/eip-7702) — 계정 마이그레이션 없이 위임이 작동하는 이유. -- [**구독 및 수금**](/ko/how-to/subscribe-and-collect) — 계정 모델을 정기 결제 흐름에 적용합니다. +- [**계정 가이드 인덱스**](/ko/explanation/accounts-guides): 계정 가이드 및 참조의 전체 목록으로 이동합니다. +- [**EIP-7702 개념**](/ko/explanation/eip-7702): 계정 마이그레이션 없이 위임이 작동하는 이유. +- [**구독 및 수집**](/ko/how-to/subscribe-and-collect): 반복 결제 흐름에 계정 모델을 적용합니다. diff --git a/docs/pages/ko/explanation/agent-settlement.mdx b/docs/pages/ko/explanation/agent-settlement.mdx index b405e3b..b692e54 100644 --- a/docs/pages/ko/explanation/agent-settlement.mdx +++ b/docs/pages/ko/explanation/agent-settlement.mdx @@ -1,57 +1,57 @@ --- source_path: explanation/agent-settlement.mdx -source_sha: 161a49c64c60ae1d96e433bc9f7348f9f0220133 +source_sha: 1cf4364b9675c77a3542fbe1cbd4ac6aacaaaf53 title: "에이전트 정산" -description: "자율 에이전트가 별도의 가스 토큰 없이 1초 미만의 완결성으로 Stable에서 USDT를 보유하고, 지불하고, 정산하는 방법." +description: "자율 에이전트가 별도의 가스 토큰 없이, 그리고 1초 미만의 완결성으로 Stable에서 USDT를 보유하고, 지불하며, 정산하는 방법." diataxis: "explanation" --- # 에이전트 정산 -에이전트 정산은 머신 결제를 위한 Stable의 레일입니다. 에이전트는 USDT0 잔액을 보유하고, HTTP를 통해 리소스 비용을 지불하며, 결제는 동일한 요청 주기 안에서 온체인으로 정산됩니다. 에이전트는 결제와 네트워크 수수료 모두를 하나의 잔액에서 차감합니다. 별도의 가스 토큰도, 가입도, API 키 교체도 없습니다. +에이전트 정산은 Stable의 머신 결제 레일입니다. 에이전트는 USDT0 잔액을 보유하고, HTTP를 통해 리소스 비용을 지불하며, 결제는 동일한 요청 주기 내에 온체인으로 정산됩니다. 에이전트는 지불 및 네트워크 수수료 모두를 위해 단일 잔액에서 지출합니다. 별도의 가스 토큰, 가입 절차, API 키 로테이션은 없습니다. -## 이것이 에이전트에게 중요한 이유 +## 에이전트에게 중요한 이유 -에이전트는 사람과 다르게 거래합니다. 에이전트는 지속적으로 실행되고, 소액 결제를 여러 번 수행하며, 가입 절차를 완료하거나 API 키를 교체할 수 없습니다. Stable의 정산은 이러한 작업 부하에 부합합니다: +에이전트는 사람과 다르게 거래합니다. 에이전트는 지속적으로 실행되고, 많은 소액 결제를 하며, 가입 절차를 완료하거나 API 키를 로테이션할 수 없습니다. Stable의 정산은 이러한 작업 부하와 일치합니다. -- **USDT0는 가스 토큰이자 결제 토큰입니다.** 에이전트 지갑은 단일 자산을 보유하고 수수료와 결제 모두에 이를 차감합니다. -- **1센트 미만의 예측 가능한 수수료.** 수수료는 달러로 표시되므로, 에이전트는 변동성 있는 가스 자산을 환산하지 않고도 작업당 비용을 예산화할 수 있습니다. -- **1초 미만의 완결성.** 유료 HTTP 호출은 요청 수명 주기(블록 시간 약 700ms) 안에서 정산되며, 이는 고빈도 머신 트래픽을 실현 가능하게 만듭니다. -- **USDT 보급.** USDT는 가장 널리 보유된 스테이블코인이며, Stable은 이를 위해 특별히 구축된 플랫폼입니다. +- **USDT0이 가스 토큰이자 결제 토큰입니다.** 에이전트 지갑은 단일 자산을 보유하고 수수료 및 결제 모두를 위해 이를 지출합니다. +- **1센트 미만의 예측 가능한 수수료.** 수수료는 달러로 표시되므로 에이전트는 변동성이 큰 가스 자산으로 변환하지 않고도 작업당 비용을 예산할 수 있습니다. +- **1초 미만의 완결성.** 유료 HTTP 호출은 요청 라이프사이클(~700ms 블록 시간) 내에 정산되어 고주파 머신 트래픽을 가능하게 합니다. +- **USDT 분배.** USDT는 가장 널리 보유된 스테이블코인입니다. Stable은 이를 위해 특별히 구축된 장소입니다. -## 레이어가 어떻게 맞물리는가 +## 레이어가 작동하는 방식 -두 레이어는 서로 다른 작업을 수행하며 대안이 아니라 상호 보완적입니다: +두 레이어는 서로 다른 작업을 수행하며 상호 보완적이지, 대체제가 아닙니다. -- **x402**는 *결제 표준*입니다. 서버가 `402 Payment Required`로 응답하고, 클라이언트가 인가에 서명하며, 퍼실리테이터가 이를 제출하는 HTTP 네이티브 프로토콜입니다. -- **MPP (Machine Payments Protocol)**는 더 광범위한 인텐트와 멀티 레일 지원으로 x402를 대체하는 IETF 트랙 표준입니다. x402는 Stable이 오늘날 지원하는 하위 호환 부분 집합입니다. [MPP](/ko/explanation/mpp)를 참조하세요. -- **Stable**은 *정산 레이어*입니다. USDT0의 온체인 전송이 실제로 일어나는 곳입니다. +- **x402**는 *결제 표준*입니다. 서버가 `402 Payment Required`로 응답하고, 클라이언트가 승인에 서명하며, 촉진자가 이를 제출하는 HTTP 기본 프로토콜입니다. +- **MPP (Machine Payments Protocol)**는 x402를 더 넓은 의도와 다중 레일 지원으로 대체하는 IETF 트랙 표준입니다. x402는 Stable이 오늘날 지원하는 하위 호환성 하위 집합입니다. [MPP](/ko/explanation/mpp)를 참조하세요. +- **Stable**은 *정산 레이어*입니다. USDT0의 온체인 전송이 실제로 발생하는 곳입니다. -**퍼실리테이터**는 이 둘 사이에 위치합니다: 서명된 결제를 검증하고 온체인 호출을 제출하여 개발자가 정산 인프라를 운영하지 않아도 되도록 합니다. 오늘날 Stable을 지원하는 제공자는 [퍼실리테이터](/ko/reference/agentic-facilitators)를 참조하세요. +**촉진자**는 둘 사이에 위치합니다. 서명된 결제를 확인하고 온체인 호출을 제출하여 개발자가 정산 인프라를 운영할 필요가 없도록 합니다. 오늘날 Stable을 지원하는 제공업체는 [촉진자](/ko/reference/agentic-facilitators)를 참조하세요. ```text -agent (client) ──HTTP──▶ resource server ──signed payment──▶ facilitator ──tx──▶ Stable - (returns 402) (verify + submit) (USDT0 settles) +에이전트 (클라이언트) ──HTTP──▶ 리소스 서버 ──서명된 결제──▶ 촉진자 ──tx──▶ Stable + (402 반환) (확인 + 제출) (USDT0 정산) ``` -## 무엇을 만들 수 있는가 +## 구축할 수 있는 것 -- **호출당 지불 API** — x402 또는 MPP를 통해 정산되며 요청당 USDT0로 가격이 책정됩니다. -- **에이전트 간 상거래** — 한 에이전트가 HTTP를 통해 서비스 비용을 다른 에이전트에게 지불합니다. -- **유료 MCP 도구** — x402 엔드포인트를 래핑하여 AI 클라이언트가 프롬프트를 통해 이를 호출하고 비용을 지불합니다. -- **자율 조달** — 예산이 책정된 USDT0 잔액에 대해 수행됩니다. -- **사용량 기반 청구** — 인보이스당이 아니라 요청당 정산됩니다. -- **에이전트 지갑** — USDT0만으로 자금이 충전되며, 수탁 미들웨어가 없습니다. +- x402 또는 MPP를 통해 USDT0으로 요청당 가격이 책정되고 정산되는 **호출당 지불 API**. +- 한 에이전트가 HTTP를 통해 다른 에이전트에게 서비스 비용을 지불하는 **에이전트 간 상거래**. +- x402 엔드포인트를 래핑하여 AI 클라이언트가 프롬프트를 통해 호출하고 비용을 지불하는 **유료 MCP 도구**. +- 예산이 책정된 USDT0 잔액에 대한 **자율 조달**. +- 인보이스당 대신 요청당 정산되는 **사용량 기반 청구**. +- USDT0만으로 자금을 조달하며, 커스터디 미들웨어가 없는 **에이전트 지갑**. -## 여기서 시작하세요 +## 여기서 시작하기 -- [**호출당 지불 API 만들기**](/ko/how-to/build-pay-per-call) — x402로 게이팅된 엔드포인트를 구축하고 요청 내에서 실제 USDT0 결제를 정산합니다. -- [**Stable에서 MPP 엔드포인트 만들기**](/ko/how-to/build-mpp-endpoint) — USDT0를 위한 세 가지 MPP 커스텀 메서드 훅을 작성하고 Stable에서 정산합니다. -- [**AI로 개발하기**](/ko/how-to/develop-with-ai) — Docs MCP와 Runtime MCP를 AI 에디터에 연결하고 Stable 컨텍스트 블록을 붙여넣습니다. -- [**MCP 서버로 지불하기**](/ko/how-to/pay-with-mcp) — x402 유료 API를 에이전트가 자연어 프롬프트를 통해 호출할 수 있는 MCP 도구로 노출합니다. +- [**호출당 지불 API 구축**](/ko/how-to/build-pay-per-call): x402로 보호된 엔드포인트를 설정하고 요청에서 실제 USDT0 결제를 정산해봅니다. +- [**Stable에서 MPP 엔드포인트 구축**](/ko/how-to/build-mpp-endpoint): USDT0에 대한 세 가지 MPP 사용자 지정 메서드 훅을 작성하고 Stable에서 정산합니다. +- [**AI로 개발**](/ko/how-to/develop-with-ai): Docs MCP 및 Runtime MCP를 AI 편집기에 연결하고 Stable 컨텍스트 블록을 붙여넣습니다. +- [**MCP 서버로 결제**](/ko/how-to/pay-with-mcp): x402 유료 API를 에이전트가 자연어 프롬프트를 통해 호출할 수 있는 MCP 도구로 노출합니다. -## 다음 추천 +## 다음 권장 사항 -- [**x402 심층 분석**](/ko/explanation/x402) — HTTP 결제 프로토콜이 Stable에서 처음부터 끝까지 어떻게 작동하는지 읽어보세요. -- [**MPP**](/ko/explanation/mpp) — x402가 속한 더 광범위한 IETF 트랙 표준입니다. -- [**퍼실리테이터**](/ko/reference/agentic-facilitators) — 어떤 퍼실리테이터가 이미 Stable에서 USDT0 결제를 정산하는지 확인하세요. +- [**x402 심층 분석**](/ko/explanation/x402): HTTP 결제 프로토콜이 Stable에서 처음부터 끝까지 어떻게 작동하는지 읽어보세요. +- [**MPP**](/ko/explanation/mpp): x402가 속한 더 넓은 IETF 트랙 표준입니다. +- [**촉진자**](/ko/reference/agentic-facilitators): Stable에서 이미 USDT0 결제를 정산하는 촉진자를 확인해보세요. diff --git a/docs/pages/ko/explanation/ai-agents-guides.mdx b/docs/pages/ko/explanation/ai-agents-guides.mdx index 416c6fe..df6e3c2 100644 --- a/docs/pages/ko/explanation/ai-agents-guides.mdx +++ b/docs/pages/ko/explanation/ai-agents-guides.mdx @@ -1,32 +1,32 @@ --- source_path: explanation/ai-agents-guides.mdx -source_sha: feec6b3035c4245e42fd83f92982234e3394a59d +source_sha: 0e678109f589a9e41c9f1a8bcb36c139cd0e5275 title: "AI 및 에이전트 가이드" -description: "모든 에이전트 가이드, 개념 및 참조: MCP 설정, 유료 MCP 도구, 에이전트 지갑, 에이전트 퍼실리테이터." +description: "모든 에이전트 가이드, 개념 및 참조: MCP 설정, 유료 MCP 도구, 에이전트 지갑 및 에이전트 퍼실리테이터." diataxis: "explanation" --- # AI 및 에이전트 가이드 -AI/에이전트 탭 아래의 모든 가이드, 개념 및 참조를 하려는 작업별로 그룹화했습니다. +AI/에이전트 탭 아래의 모든 가이드, 개념 및 참조를 수행하려는 작업별로 그룹화했습니다. -## AI 에디터 준비하기 +## AI 편집기 장착 -- [**AI로 개발하기**](/ko/how-to/develop-with-ai) — Docs MCP, Runtime MCP, 에이전트 스킬을 설치하고 Stable 컨텍스트 블록을 붙여넣으세요. -- [**에이전트 지갑 만들기**](/ko/how-to/create-wallet) — WDK를 통한 자체 보관 키 — 에이전트 결제의 기반입니다. +- [**AI로 개발하기**](/ko/how-to/develop-with-ai): Docs MCP, Runtime MCP, 에이전트 스킬을 설치하고 Stable 컨텍스트 블록을 붙여넣습니다. +- [**에이전트 지갑 생성하기**](/ko/how-to/create-wallet): WDK를 통한 자체 관리 키, 에이전트 결제의 기반입니다. -## 서비스 수익화 및 소비하기 +## 서비스 수익화 및 이용 -- [**호출당 과금 API 만들기**](/ko/how-to/build-pay-per-call) — x402 미들웨어로 모든 HTTP 엔드포인트에 USDT0로 요청당 가격을 책정하세요. -- [**MCP 서버로 결제하기**](/ko/how-to/pay-with-mcp) — x402 유료 API를 MCP 도구로 래핑하여 AI 클라이언트가 호출하고 결제하도록 하세요. +- [**호출당 지불 API 구축하기**](/ko/how-to/build-pay-per-call): x402 미들웨어를 사용하여 USDT0로 요청당 모든 HTTP 엔드포인트 가격을 책정합니다. +- [**MCP 서버로 지불하기**](/ko/how-to/pay-with-mcp): x402 유료 API를 MCP 도구로 래핑하여 AI 클라이언트가 호출하고 비용을 지불하도록 합니다. ## 참조 -- [**에이전트 퍼실리테이터**](/ko/reference/agentic-facilitators) — Stable에서 에이전트 간 상거래를 위한 정산 서비스입니다. -- [**에이전트 지갑**](/ko/reference/agentic-wallets) — 자율 에이전트 사용을 위한 지갑 사양입니다. +- [**에이전트 퍼실리테이터**](/ko/reference/agentic-facilitators): Stable에서 에이전트 간 상거래를 위한 결제 서비스입니다. +- [**에이전트 지갑**](/ko/reference/agentic-wallets): 자율 에이전트 사용을 위한 지갑 사양입니다. ## 기본 개념 -- [**x402 (HTTP 네이티브 결제)**](/ko/explanation/x402) — 에이전트가 요청당 결제에 사용하는 HTTP 프로토콜입니다. -- [**MPP**](/ko/explanation/mpp) — x402가 속한 더 넓은 IETF 트랙 표준으로, 세션 및 멀티 레일 지원을 제공합니다. -- [**ERC-3009**](/ko/explanation/erc-3009) — x402가 정산하는 서명 승인 표준입니다. +- [**x402 (HTTP-네이티브 결제)**](/ko/explanation/x402): 에이전트가 요청당 지불하는 데 사용하는 HTTP 프로토콜입니다. +- [**MPP**](/ko/explanation/mpp): 세션 및 다중 레일 지원을 포함하여 x402가 속한 광범위한 IETF 트랙 표준입니다. +- [**ERC-3009**](/ko/explanation/erc-3009): x402가 결제되는 서명된 승인 표준입니다. diff --git a/docs/pages/ko/explanation/autobahn.mdx b/docs/pages/ko/explanation/autobahn.mdx index e164954..6541ba2 100755 --- a/docs/pages/ko/explanation/autobahn.mdx +++ b/docs/pages/ko/explanation/autobahn.mdx @@ -1,77 +1,83 @@ --- source_path: explanation/autobahn.mdx -source_sha: 166db38136cef9a5d17c1d38bc33bb434a5b1e51 -title: "Autobahn" -description: "저지연과 네트워크 장애 복원력을 균형 있게 제공하는 Autobahn DAG 기반 BFT 합의 프로토콜." +source_sha: ed268ab80c3a227b6989f1d9746eaf5f0410245c +title: "아우토반(Autobahn)" +description: "Autobahn DAG 기반 BFT 합의 프로토콜은 StableBFT를 위해 낮은 지연 시간과 결함 허용도 균형을 맞춥니다." +diataxis: "explanation" --- -# Autobahn +# 아우토반(Autobahn) -## BFT 내 트레이드오프: 레이턴시 vs. 견고성 +## BFT의 장단점: 지연 시간 대 견고성 -현대의 비잔틴 장애 허용(Byzantine Fault Tolerant, BFT) 합의 프로토콜은 일반적으로 부분 동기(partial synchrony) 모델에서 동작합니다. 이 모델은 어떤 시점 이후에는 네트워크가 안정되며 메시지 지연 시간이 유한하게 유지된다는 가정에 기반합니다. 이 모델은 프로토콜 설계에 있어 실용적으로 작용해 왔지만, 실제 운영 환경에서는 장기간 상태를 안정적으로 유지하기 어렵습니다. 대신 시스템은 지속적인 동기 구간과 간헐적인 장애(예: 레이턴시 증가, 노드 장애, 공격적 조건 등)를 반복적으로 겪습니다. 이러한 일시적 장애를 **"블립(blip)"** 이라고 합니다. +현대 비잔틴 장애 허용(BFT) 합의 프로토콜은 일반적으로 부분 동기 모델에서 작동합니다. 이 모델은 네트워크가 결국 안정화되고 메시지 지연이 제한된 상태를 유지한다고 가정합니다. 프로토콜 설계에는 실용적이지만 실제 배포에서는 오랜 기간 동안 중단 없는 안정성을 누리는 경우는 드뭅니다. 대신 시스템은 대기 시간 급증, 노드 중단 또는 악의적인 조건과 같은 짧은 중단에 이어 동기 기간을 자주 경험합니다. 이러한 일시적인 중단을 **"블립(blips)"**이라고 합니다. -이러한 조건 하에서, 기존 합의 프로토콜은 **안정적인 네트워크 환경에서의 저지연성과 장애 발생 시의 견고성 사이에서 선택**을 강요받습니다. +이러한 조건에서 기존 합의 프로토콜은 **안정적인 네트워크 조건에서 낮은 대기 시간과 오류 발생 시 견고성 간에 선택**해야 합니다. -- PBFT, HotStuff와 같은 전통적인 **view 기반 BFT 프로토콜**은 네트워크가 안정되어 있을 때 좋은 반응성을 갖추도록 최적화되어 있습니다. 그러나 블립이 발생하면 성능이 급격히 저하되며, 이 성능 저하의 여파로 네트워크가 회복된 후에도 백로그된 요청들이 누적되어 트랜잭션 처리가 지연될 수 있습니다. -- [Narwhal & Tusk](https://arxiv.org/pdf/2105.11827)/[Bullshark](https://arxiv.org/pdf/2201.05677)와 같은 **DAG 기반 BFT 프로토콜**은 데이터 전파(DAG)와 합의(BFT)를 분리하여, 트랜잭션을 비동기적으로 각 레플리카에 전파합니다. 이러한 설계는 높은 처리량을 가능하게 하며, 네트워크 장애 중에도 시스템이 계속 진행(progress)할 수 있도록 합니다. 하지만 비동기 정렬 메커니즘의 복잡성으로 인해, 안정된 상황에서도 높은 레이턴시를 보이는 경향이 있습니다. +- PBFT 및 HotStuff와 같은 **전통적인 뷰 기반 BFT 프로토콜**은 네트워크가 안정적일 때 좋은 간격 동안 응답성을 위해 최적화되어 있습니다. 그러나 블립이 발생하면 성능이 저하됩니다. 숙취(hangover)라고 알려진 이러한 저하는 네트워크가 복구된 후에도 지속될 수 있으며, 백로그된 요청이 누적되어 후속 트랜잭션을 지연시킵니다. +- [Narwhal & Tusk](https://arxiv.org/pdf/2105.11827)/[Bullshark](https://arxiv.org/pdf/2201.05677)와 같은 **DAG 기반 BFT 프로토콜**은 데이터 전파(DAG)를 합의(BFT)와 분리하고 복제본 간에 트랜잭션을 비동기적으로 전파합니다. 이 설계는 높은 처리량을 가능하게 하고 네트워크 중단 중에도 시스템이 계속 진행되도록 합니다. 그러나 이러한 프로토콜은 비동기 정렬 메커니즘의 복잡성으로 인해 좋은 간격 동안에도 높은 대기 시간을 초래하는 경향이 있습니다. -[**Autobahn**](https://arxiv.org/pdf/2401.10369)은 이러한 두 설계 철학을 연결하는 새로운 접근 방식을 제시합니다. Autobahn은 DAG 기반 프로토콜의 높은 처리량 및 블립 내성(blip tolerance)과, 전통적인 view 기반 합의의 낮은 레이턴시를 결합합니다. Autobahn의 핵심은 데이터 전파 계층이 합의의 진행 여부와 무관하게 지속적으로 제안을 네트워크 속도로 전파하는 고도로 병렬화된 구조입니다. 이를 기반으로 Autobahn은 낮은 레이턴시의 부분 동기 합의 프로토콜을 운영하며, 데이터 레이어 위에 올라가는 경량 스냅샷을 참조하여 프로포절을 커밋합니다. +[**Autobahn**](https://arxiv.org/pdf/2401.10369)은 이 두 가지 설계 철학을 연결하는 새로운 접근 방식을 소개합니다. DAG 기반 프로토콜의 높은 처리량과 블립 허용성을 전통적인 뷰 기반 합의의 낮은 대기 시간 성능과 결합합니다. Autobahn의 핵심은 합의 진행 상황에 관계없이 네트워크 속도로 제안을 지속적으로 전파하는 고도로 병렬적인 데이터 전파 계층입니다. 이 계층 위에 Autobahn은 데이터 계층의 경량 스냅샷을 참조하여 제안을 커밋하는 낮은 대기 시간, 부분 동기화 합의 프로토콜을 실행합니다. -Autobahn의 결정적인 특징은, 블립 이후에도 성능 저하 없이 복구가 될 수 있다는 점입니다. 이러한 속성은 “**seamlessness**“라 불리며, 네트워크가 안정화되면 누적된 트랜잭션 백로그를 재처리 없이 즉시 커밋할 수 있도록 보장합니다. 데이터의 가용성과 순서 정렬을 명확히 분리하고, 프로토콜에 의한 동기화 지연을 방지함으로써, Autobahn은 현실적 블록체인 환경에서 강력하면서도 반응성이 뛰어난 합의 기반을 제공합니다. +Autobahn의 특징적인 기능은 성능 저하 없이 블립에서 복구하는 능력입니다. **원활함(seamlessness)**이라고 불리는 이 속성은 네트워크가 안정화된 직후 시스템이 전체 처리량과 낮은 대기 시간으로 재개되도록 보장합니다. 백로그된 트랜잭션의 비용이 많이 드는 재처리가 필요하지 않습니다. 데이터 가용성을 정렬과 명확하게 분리하고 프로토콜 유도 동기화 지연을 피함으로써 Autobahn은 실제 조건에서 블록체인 합의를 위한 견고하면서도 반응적인 기반을 제공합니다. ## Autobahn 아키텍처 개요 -Autobahn은 두 핵심 계층 - **데이터 전파 계층**과 **합의 계층**의 책임을 명확히 분리한 구조 위에 설계되어 있습니다. 이러한 분리는 Narwhal과 같은 DAG 시스템에서 영감을 받았으며, Autobahn은 여기에 seamlessness와 낮은 레이턴시를 지원하기 위한 확장을 더했습니다. +Autobahn은 핵심 두 계층인 **데이터 전파 계층**과 **합의 계층** 간의 책임 분리 중심으로 설계되었습니다. 이러한 분리는 Narwhal과 같은 DAG 기반 시스템의 설계에서 영감을 받았지만, Autobahn은 원활함과 낮은 대기 시간을 지원하기 위해 이 구조를 강화합니다. -데이터 전파 계층은 클라이언트 트랜잭션을 확장 가능하고 비동기적인 방식으로 브로드캐스트하는 역할을 합니다. 각 레플리카는 각자 트랜잭션 묶음을 전파하는 별도의 ‘차선(lane)’을 가지고 있으며, 이는 합의 상태와 무관하게 독립적으로 전파 및 인증될 수 있습니다. 각 차선은 합의가 지연되더라도 지속적으로 유지되므로, 시스템은 항상 클라이언트에게 반응성을 유지합니다. +데이터 전파 계층은 확장 가능하고 비동기적인 방식으로 클라이언트 트랜잭션을 브로드캐스트하는 역할을 합니다. 각 복제본이 자체 트랜잭션 배치 레인(lane)을 유지하도록 허용하며, 이는 합의 상태와 독립적으로 전파 및 인증될 수 있습니다. 이러한 레인은 합의 프로세스가 중단될 때도 지속적으로 성장하여 시스템이 항상 클라이언트에 응답할 수 있도록 합니다. -이 위에서 Autobahn은 PBFT 스타일의 부분 동기 합의 계층을 운영합니다. 여기서 Autobahn은 각 트랜잭션 묶음이 아닌, 모든 데이터 차선의 ‘최신 상태 요약(tip cuts)’에 대해 합의를 수행합니다. 이러한 설계는 임의의 큰 데이터셋도 단일한 과정으로 커밋할 수 있게 하며, 블립의 영향을 최소화합니다. +이 위에 Autobahn은 PBFT 스타일 프로토콜을 기반으로 하는 부분 동기화 합의 계층을 실행합니다. 그러나 개별 트랜잭션 배치에 대한 합의에 도달하는 대신, 모든 데이터 레인의 최신 상태를 간결하게 요약한 "팁 컷(tip cuts)"에 대해 합의에 도달합니다. 이 설계는 Autobahn이 단일 단계에서 임의로 많은 양의 데이터를 커밋할 수 있도록 하여 블립의 영향을 최소화합니다. -데이터와 합의를 강하게 결합하여 리더가 실패하면 멈추는 Hotstuff나, DAG 순회 및 데이터 동기화로 인해 높은 커밋 레이턴시를 겪는 Bullshark와 비교했을때, Autobahn은 더 유연하고 빠른 합의 경험을 제공합니다. 즉, Autobahn은 DAG의 병렬화 속성을 가져가면서 레이턴시 단점은 개선한 구조입니다. +HotStuff는 데이터와 합의를 단단히 연결하여 리더가 실패할 때 중단을 야기합니다. Bullshark는 DAG 순회 및 데이터 동기화로 인해 높은 커밋 지연 시간을 발생시킵니다. Autobahn은 DAG의 병렬성을 상속하면서 대기 시간 문제를 방지하여 더 원활하고 빠른 합의 경험을 제공합니다. -## 데이터 전파 계층: 차선과 Car +## 데이터 전파 계층: 레인(lanes) 및 카(cars) ![Autobahn: Seamless high speed BFT](/images/autobahn-high-speed1.png) -*Autobahn: Seamless high speed BFT* +*Autobahn: 원활한 고속 BFT* -Autobahn에서는 각 레플리카가 자신만의 **차선(Lane)** 에 트랜잭션을 제안합니다. 각 데이터 프로포절은 다른 레플리카 노드들의 승인(Acknowledgment)과 함께 묶여 하나의 **‘Car’**(Certification of Available Request)를 형성합니다. 이 Car들은 최소 하나의 레플리카 노드가 해당 데이터를 들고 있다는 데이터 가용성 증명(Proof of Availability, PoA) 역할을 수행합니다. +Autobahn에서 각 복제본은 **레인**이라고 불리는 독립적으로 진행되는 자체 체인에서 트랜잭션을 제안합니다. 레인의 각 데이터 제안은 다른 복제본의 승인 세트와 함께 묶여 저자들이 "**카(car)**"(인증된 요청 인증의 약자)라고 부르는 것을 형성합니다. 이 카는 가용성 증명(PoA) 역할을 하여 적어도 하나의 올바른 복제본이 데이터를 보유하고 필요할 경우 재전송할 수 있도록 보장합니다. -각 Car는 이전 Car를 참조하여 체인처럼 연결되므로, 차선의 최신 블록을 검증하는 것만으로도 차선 전체의 데이터 가용성을 간접적으로 증명할 수 있습니다. 이러한 형태의 연쇄적인 가용성 증명은 즉각적인 참조를 가능하게 합니다. 여기서 즉각적인 참조란, 합의 계층이 DAG 순회 없이도 최신 상태 요약(tip cut, 현재 차선 헤드의 벡터)을 참조할 수 있으며, 모든 이전 데이터에 접근할 수 있음을 알 수 있다는 의미입니다. +카는 각 새 제안에 이전 카에 대한 참조를 포함하여 함께 연결됩니다. 이 구조는 레인의 팁을 검증하는 것이 전체 레인 기록의 가용성을 의미한다는 것을 보장합니다. 이 추이적인 가용성 증명은 Autobahn의 즉각적인 참조에 핵심입니다. 합의 계층은 팁 컷(현재 레인 헤드의 벡터)을 참조할 수 있으며 DAG 순회 또는 추가 동기화 없이 모든 이전 데이터를 검색할 수 있다는 것을 알 수 있습니다. -일반적인 DAG 프로토콜과 달리, Autobahn은 글로벌 가용성과 비중복성을 보장하기 위한 비용이 많이 드는 신뢰 가능한 브로드캐스트 단계를 피합니다. 대신, 최소한의 조율만을 사용하고, PoA(Proof of Availability)마다 하나 이상의 정직한 복제본이 데이터를 보유하고 있다고 신뢰합니다. 이를 통해 가변적인 부하나 부분적인 장애 상황에서도 높은 처리량과 낮은 지연 시간을 유지할 수 있습니다. 데이터 계층은 합의와 독립적으로 계속 진행되며, 일시적인 장애(blip) 상황에서도 시스템의 반응성을 보장합니다. +일반적인 DAG 프로토콜과 달리 Autobahn은 전역 가용성 및 비동등성을 강제하는 비용이 많이 드는 안정적인 브로드캐스트 단계를 피합니다. 대신, 최소한의 조정을 사용하고 각 PoA에 대해 최소한 하나의 정직한 복제본이 데이터를 보유하고 있다고 신뢰합니다. 이는 다양한 부하 또는 부분적 실패 하에서도 높은 처리량과 낮은 꼬리 지연 시간을 가능하게 합니다. 데이터 계층은 합의와 독립적으로 계속 진행되어 블립 동안 응답성을 보장합니다. -## **합의 레이어: 저지연 동의** +## 합의 계층: 낮은 지연 시간 합의 ![Autobahn: Seamless high speed BFT](/images/autobahn-high-speed2.png) -*Autobahn: Seamless high speed BFT* +*Autobahn: 원활한 고속 BFT* -Autobahn의 합의 계층은 기존 PBFT 원칙을 기반으로 하지만, 레이턴시 감소 및 원활한 복구를 위한 핵심 최적화 메커니즘을 도입합니다. 각 합의 슬롯은 모든 레플리카의 차선에서 가장 최신의 인증된 제안들을 요약한 "**tip cut**"을 커밋 대상으로 삼습니다. 합의 리더는 이 tip cut을 2단계 커밋 프로세스(Prepare → Confirm)를 통해 제안합니다. +Autobahn의 합의 계층은 고전적인 PBFT 원칙을 기반으로 하지만, 지연 시간을 줄이고 원활한 복구를 지원하기 위한 주요 최적화를 도입합니다. 각 합의 슬롯은 모든 복제본의 레인에서 최신 인증된 제안을 캡처하는 "**팁 컷**"을 커밋하는 것을 목표로 합니다. 합의 리더는 준비(Prepare) 및 확인(Confirm)이라는 두 단계 커밋 프로세스를 사용하여 이 컷을 제안합니다. -Prepare 단계에서는, 레플리카들이 제안된 tip cut에 투표합니다. 리더가 빠르게 정족수(quorum)만큼의 투표를 받으면, Fast Path로 진입하여 세 단계의 메시지 레이턴시 안에 커밋할 수 있습니다. 만약 투표를 빠르게 모으지 못했다면, Confirm 단계로 넘어갑니다. 여기서는 다시 레플리카들의 승인을 모아 여섯 단계의 메세지 레이턴시 내에 커밋을 완료합니다. +준비 단계 동안 복제본은 제안된 팁 컷에 대해 투표합니다. 리더가 빠르게 충분한 투표(완벽한 쿼럼)를 받으면 빠른 경로(Fast Path)에 진입하여 단 3번의 메시지 지연으로 즉시 커밋할 수 있습니다. 그렇지 않으면 6번의 메시지 지연으로 커밋을 완료하기 전에 또 다른 쿼럼의 승인을 수집하는 확인 단계를 진행합니다. -Autobahn의 핵심 혁신은, 데이터 동기화와 합의 투표의 분리입니다. 레플리카들은 전체 프로포절 데이터를 받지 못하였더라도, 인증된 tip에 대해서만 투표할 수 있습니다. PoA가 데이터 가용성을 보장해주기 때문에, tip에 대해서만 투표하더라도 안전하다고 볼 수 있는 것입니다. 동기화는 병렬로 진행되어 실행 단계 전에 완료되고, 이를 통해 프로토콜이 멈추는 것을 방지할 수 있습니다. 리더 실패 혹은 타임아웃의 경우, 타임아웃 인증서(timeout certificate)를 이용해 뷰 변경(view change)을 트리거하는 방식으로 새 리더가 작업을 이어갈 수 있습니다. +주요 혁신은 데이터 동기화를 합의 투표에서 분리하는 것입니다. 복제본은 전체 제안 데이터를 아직 받지 못했더라도 인증된 팁만을 기반으로 투표할 수 있습니다. PoA가 검색 가능성을 보장하기 때문에 이는 안전합니다. 동기화는 병렬로 발생하며 실행 단계 전에 완료되어 프로토콜 중단을 방지합니다. 리더 실패 또는 시간 초과 시에는 시간 초과 인증서를 사용하여 뷰 변경이 트리거되고, 새 리더는 효율적으로 진행을 재개할 수 있습니다. ## Autobahn의 핵심 속성 -Autobahn은 BFT 프로토콜이 제공해야 하는 표준적인 **안전성(safety)** 과 **생존성(liveness)** 보장을 충족합니다. 안전성은 두 개의 올바른 레플리카가 같은 슬롯에 대해 서로 다른 블록을 커밋하는 일이 없음을 보장하며, 생존성은 글로벌 동기화 시간(Global Stabilization Time, GST) 이후, 올바른 리더가 선정되면 합의가 진행됨을 보장합니다. +Autobahn은 BFT 프로토콜에서 기대되는 표준 **안전성** 및 **활성성** 보장을 충족합니다. 안전성은 두 개의 올바른 복제본이 동일한 슬롯에 대해 다른 블록을 커밋하지 않도록 보장합니다. 활성성은 올바른 리더가 결국 선택되는 한 전역 안정화 시간(GST) 이후에 진행을 보장합니다. -Autobahn의 가장 중요한 속성은 **seamlessness**입니다. 이 특성 덕분에 합의 레이어는 임의의 크기를 가진 백로그도 상수 시간 안에 커밋할 수 있고, 프로토콜 성능 저하를 막습니다. 블립이 발생하더라도 이후 네트워크가 안정화되면, 성공적으로 전파된 모든 제안은 즉시 커밋됩니다. 이를 통해 Autobahn은 간헐적 장애 환경에서도 부드럽게 동작하며, 회복 속도와 반응성 측면에서 전통적인 BFT 프로토콜을 능가합니다. +더 중요한 것은 Autobahn이 **원활함**을 달성한다는 것입니다. 합의 계층이 일정한 시간 내에 임의로 많은 데이터 백로그를 커밋하도록 하여 프로토콜 유도 숙취(hangover)를 피합니다. 블립 이후에도 동기화가 돌아오는 즉시 성공적으로 전파된 모든 데이터 제안이 즉시 커밋될 수 있습니다. 이를 통해 Autobahn은 간헐적인 오류가 있는 환경에서도 원활하게 작동할 수 있으며, 복구 시간과 시스템 응답성 모두에서 전통적인 BFT 프로토콜을 능가합니다. -또한, 프로토콜은 **수평 확장성**을 가집니다. 각 레플리카는 자신의 차선을 통해 전체 처리량에 기여하며, 합의 스냅샷(consensus cut) 역시 참여자 수에 따라 자연스럽게 확장됩니다. 이는 높은 성능과 견고함을 모두 요구하는 대규모 블록체인 배포에 적합합니다. +또한, 이 프로토콜은 **수평적으로 확장**됩니다. 각 복제본은 자체 레인을 통해 시스템의 처리량에 기여하며, 합의 컷은 참여자 수에 따라 자연스럽게 증가합니다. 이는 Autobahn을 고성능과 견고성 모두를 요구하는 대규모 배포에 적합하게 만듭니다. -## 낮은 레이턴시와 높은 복원력의 조화 +## 낮은 대기 시간과 높은 복원력의 만남 -Autobahn은 주요 BFT 프로토콜인 Bullshark 및 HotStuff와 비교 테스트되었습니다. 테스트 환경은 이상적인 조건과 장애 삽입 조건 모두를 포함합니다. 결과적으로 Autobahn은 모든 테스트에서 가장 좋은 결과를 달성했습니다: Autobahn은 Bullshark 수준의 처리량(초당 230,000건 이상)을 유지하면서, 레이턴시는 50% 이상 감소시켰습니다. +Autobahn은 이상적인 조건과 오류 주입 조건 모두에서 선도적인 BFT 프로토콜, 특히 Bullshark 및 HotStuff와 비교 평가되었습니다. 그 결과 Autobahn이 두 가지 장점을 모두 달성했음을 보여줍니다. Bullshark의 처리량과 일치하여 초당 230,000개 이상의 트랜잭션을 처리하는 동시에 대기 시간을 50% 이상 줄였습니다. -좋은 네트워크 환경에서, Autobahn은 3~6개의 메시지 레이턴시만으로 트랜잭션을 커밋하며, 이는 Bullshark의 12개 메시지 레이턴시보다 훨씬 낮습니다. 실제로 Autobahn은 약 280ms, Bullshark는 590ms 이상의 커밋 지연이 측정되었습니다. 또한 HotStuff는 블립 이후 백로그 처리로 인해 장시간 성능 저하가 발생하지만, Autobahn은 네트워크 안정화 즉시 전체 백로그를 단일 스텝으로 커밋합니다. +좋은 네트워크 조건에서 Autobahn은 Bullshark의 12 메시지 지연과 비교하여 단 3~6 메시지 지연으로 트랜잭션을 커밋합니다. 이는 실제 커밋 지연 시간이 Bullshark의 590ms 이상에 비해 280ms로 낮다는 것을 의미합니다. 백로그 처리 지연으로 인해 블립 후 긴 숙취를 겪는 HotStuff와 달리, Autobahn은 네트워크가 안정화되는 즉시 전체 백로그를 단일 단계로 커밋합니다. -리더 실패나 부분적인 네트워크 분할 시에도 Autobahn은 데이터를 계속 전파하며, 합의 재개 후 누적된 프로포절들을 빠르게 커밋합니다. 이러한 성능 상의 이점은 낮은 레이턴시와 높은 처리량 및 장애 허용성을 결합하려는 블록체인 플랫폼에 Autobahn이 매우 좋은 선택지임을 보여줍니다. +리더 장애 또는 부분적 네트워크 분할이 발생하는 시나리오에서 Autobahn은 원활한 복구를 보여줍니다. 장애 중에도 데이터를 계속 전파하고 합의가 재개되는 즉시 축적된 제안을 빠르게 커밋합니다. 이러한 성능상의 이점은 낮은 대기 시간 응답성과 높은 처리량 및 내결함성을 결합하려는 블록체인 플랫폼에게 Autobahn을 매력적인 선택으로 만듭니다. ## 추가 자료 -더 많은 기술적 상세 내용은 다음 문서를 참고하세요: +더 자세한 기술 정보는 다음을 참조하십시오: -- [Autobahn: Seamless high speed BFT](https://arxiv.org/pdf/2401.10369) \ No newline at end of file +- [Autobahn: Seamless high speed BFT](https://arxiv.org/pdf/2401.10369) + +## 다음으로 추천하는 자료 + +- [**합의(Consensus)**](/ko/explanation/consensus): Autobahn이 발전한 합의 구현인 StableBFT로 돌아갑니다. +- [**완결성(Finality)**](/ko/explanation/finality): RPC를 기반으로 빌드할 때 Stable의 단일 슬롯 완결성을 사용합니다. diff --git a/docs/pages/ko/explanation/bank-module.mdx b/docs/pages/ko/explanation/bank-module.mdx index de038cb..8e60f98 100755 --- a/docs/pages/ko/explanation/bank-module.mdx +++ b/docs/pages/ko/explanation/bank-module.mdx @@ -1,301 +1,44 @@ --- source_path: explanation/bank-module.mdx -source_sha: 95cf49e645e5694b709ae0b2db08735a0b0fde3a -title: Bank -description: "Stable에서 ERC-20 호환 토큰 전송, 위임, 승인 기능을 제공하는 Bank 프리컴파일." +source_sha: c19264aa3a4aa590a16f97192b30d5ffe1d88b08 +title: "뱅크 모듈" +description: "뱅크 사전 컴파일은 SDK x/bank 모듈을 기반으로 하는 ERC-20 호환 토큰 전송과 발행, 소각, 승인 메서드를 노출합니다." +diataxis: "explanation" --- -# Bank +# 뱅크 모듈 -## 개요 +Stable의 SDK에 있는 `x/bank` 모듈은 토큰 잔액, 전송, 공급을 처리합니다. EVM 표면( **뱅크 사전 컴파일**)은 이 모듈을 래핑하고 ERC-20 시맨틱과 특권 발행/소각 작업에 대한 승인 계층을 추가합니다. Stable에서 토큰을 이동해야 하는 컨트랙트는 자체 토큰 구현을 배포하지 않고 사전 컴파일을 직접 호출합니다. -Stable SDK의 `x/bank` 모듈은 기본적인 토큰 관리 기능만 제공합니다. -모든 토큰은 제한 없이 다른 계정으로 전송될 수 있으며, 사용자는 다른 계정에 토큰 전송 권한을 위임할 수 없습니다. -이러한 이유로, `bank` precompile 컨트랙트는 Stable SDK의 기존 `x/bank` 모듈 위에 추가적인 권한 부여 및 위임 기능을 제공합니다. +## 노출되는 기능 -## 목차 +뱅크 사전 컴파일은 표준 ERC-20 메서드를 제공합니다. -1. **[개념](#concepts)** -2. **[설정](#configuration)** -3. **[메서드](#methods)** -4. **[이벤트](#events)** +- `transfer`, `balanceOf`, `totalSupply` +- `approve`, `transferFrom`, `allowance`, `revoke` -## 개념 +이들은 어떤 호출자에게든 작동합니다. 등록이 필요하지 않습니다. -이 precompile 컨트랙트는 ERC20 표준 메서드를 제공합니다 - 전송을 위한 `transfer`와 `balanceOf`, 위임을 위한 `transferFrom`, `approve`, `allowance` 등이 있습니다. 이러한 메서드는 컨트랙트 주소 등록 없이 직접 호출할 수 있습니다. +또한 특권 메서드를 제공합니다. -그러나 `mint`와 `burn` 메서드는 `x/precompile` 모듈에 의해 등록된 컨트랙트 주소가 화이트리스트에 포함되어야 합니다. +- `mint`: 새 토큰을 발행하고 계정으로 전송합니다. +- `burn`: 계정이 보유한 토큰을 소각합니다. +- `multiTransfer`: 한 번의 호출로 토큰을 한 발신자에서 여러 수신자에게 이동합니다. -```go -func (p *Precompile) mint( - ctx sdk.Context, - contract *vm.Contract, - denom string, - method *abi.Method, - stateDB vm.StateDB, - args []interface{}, -) ([]byte, error) { - // ... +발행 및 소각은 호출자 컨트랙트가 거버넌스 제안을 통해 `x/precompile` 허용 목록에 등록되어야 합니다. 거버넌스 토큰 발행은 전면적으로 차단됩니다. 이는 공급 증가를 승인된 컨트랙트에만 국한시킵니다. - // mint method is only allowed for the registered caller contract - if _, err := precompilecommon.CheckPermissions(ctx, p.precompileKeeper, contract.CallerAddress, CallerPermissions); err != nil { - return nil, err - } -``` +## 사용 시점 -추가적인 검증 프로세스는 이 precompile 컨트랙트를 호출하는 토큰 컨트랙트가 승인되었음을 보장할 수 있습니다. +- DeFi 컨트랙트가 사용자 대신 STABLE 또는 USDT0을 이동해야 하는 경우: 사전 컴파일에서 `transfer` 또는 `transferFrom`을 직접 호출합니다. +- 프로토콜 컨트랙트가 비즈니스 로직에 따라 토큰을 발행하거나 소각하는 경우: 먼저 거버넌스를 통해 등록한 다음 `mint`/`burn`을 호출합니다. +- 결제 컨트랙트가 일대다 지불이 필요한 경우: 루프 전송 대신 단일 트랜잭션으로 `multiTransfer`를 호출합니다. -토큰 컨트랙트 주소와 해당 denom을 `x/precompile` 모듈의 화이트리스트에 등록하려면 거버넌스 제안이 필요합니다. +## ABI를 찾는 방법 -## 설정 +전체 메서드 서명, 이벤트 페이로드 및 승인 흐름은 [뱅크 사전 컴파일 참조](/ko/reference/bank-module-api)에서 확인할 수 있습니다. -컨트랙트 주소와 가스 비용은 사전 정의되어 있습니다. +## 다음 권장 사항 -### 컨트랙트 주소 - -- `0x0000000000000000000000000000000000001003` - STABLE (거버넌스 토큰) - -## 메서드 - -### `mint` - -요청된 수량의 새로운 토큰을 발행하고 계정으로 전송합니다. -발행할 토큰의 수량은 0보다 커야 합니다. - -토큰이 성공적으로 발행되고 계정으로 전송되면 `PrecompiledBankMint`가 발생합니다. - -주의사항: - -- 거버넌스 토큰 발행은 금지되어 있습니다. -- mint 메서드를 호출하는 컨트랙트는 x/precompile 모듈에 등록되어 있어야 합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|to|address|발행된 토큰을 받을 주소| -|amount|uint256|발행할 토큰의 수량| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|success|bool|토큰이 성공적으로 발행되고 계정으로 전송되면 true| - -### `burn` - -계정에서 요청된 수량의 토큰을 소각합니다. -소각할 토큰의 수량은 0보다 커야 합니다. - -토큰이 성공적으로 소각되면 `PrecompiledBankBurn`이 발생합니다. - -주의사항: - -- 거버넌스 토큰 소각은 금지되어 있습니다. -- mint 메서드를 호출하는 컨트랙트는 x/precompile 모듈에 등록되어 있어야 합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|from|address|토큰을 소각할 주소| -|amount|uint256|소각할 토큰의 수량| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|success|bool|토큰이 성공적으로 소각되면 true| - -### `transfer` - -발신자로부터 수신자에게 요청된 수량의 토큰을 전송합니다. -토큰은 전송 가능하도록 설정되어 있어야 합니다. 전송할 토큰의 수량은 0보다 커야 합니다. - -토큰이 성공적으로 전송되면 `PrecompiledBankTransfer`가 발생합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|to|address|토큰을 받을 주소| -|amount|uint256|전송할 토큰의 수량| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|success|bool|토큰이 성공적으로 전송되면 true| - -### `transferFrom` - -승인된 spender가 allowance 한도 내에서 소유자로부터 수신자에게 요청된 수량의 토큰을 전송합니다. -토큰은 전송 가능하도록 설정되어 있어야 합니다. -전송할 토큰의 수량은 0보다 크고 현재 allowance보다 작거나 같아야 합니다. - -토큰이 성공적으로 전송되면 `PrecompiledBankTransfer`가 발생합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|from|address|토큰을 전송할 주소| -|to|address|토큰을 받을 주소| -|amount|uint256|전송할 토큰의 수량| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|success|bool|토큰이 성공적으로 전송되면 true| - -### `multiTransfer` - -단일 계정에서 여러 계정으로 토큰을 전송합니다. -토큰은 전송 가능하도록 설정되어 있어야 합니다. -각 수신자에게 전송할 토큰의 수량은 0보다 커야 합니다. - -토큰이 성공적으로 전송되면 각 수신자마다 `PrecompiledBankTransfer`가 발생합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|to|address[]|전송된 토큰을 받을 주소들| -|amount|uint256[]|각 수신자에게 전송할 토큰의 수량| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|success|bool|모든 수신자에게 토큰이 성공적으로 전송되면 true| - -### `approve` - -spender가 소유자의 계정에서 토큰을 전송할 수 있도록 승인합니다. -승인할 토큰의 수량은 0보다 커야 합니다. - -승인이 성공적으로 설정되면 `PrecompiledBankApproval`이 발생합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|spender|address|승인할 주소| -|value|uint256|승인할 토큰의 수량| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|success|bool|승인이 성공적으로 설정되면 true| - -### `revoke` - -소유자로부터 토큰을 전송할 수 있는 spender의 승인을 취소합니다. - -승인이 성공적으로 취소되면 `PrecompiledBankRevoke`가 발생합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|spender|address|취소할 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|success|bool|승인이 성공적으로 취소되면 true| - -### `balanceOf` - -계정의 토큰 잔액을 반환합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|account|address|토큰 잔액을 조회할 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|balance|uint256|계정의 토큰 수량| - -### `totalSupply` - -토큰의 총 공급량을 반환합니다. - -#### 입력 - -없음 - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|totalSupply|uint256|토큰의 총 수량| - -### `allowance` - -spender가 owner로부터 여전히 인출할 수 있는 수량을 반환합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|owner|address|소유자의 주소| -|spender|address|spender의 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|amount|uint256|승인된 토큰의 수량| - -## 이벤트 - -이 precompile 컨트랙트에서 발생하는 모든 이벤트는 `PrecompiledBank` 접두사가 붙습니다. -모호함을 피하기 위해, 이 precompile 컨트랙트를 호출하는 토큰 컨트랙트는 동일한 접두사를 가진 이벤트 이름 사용을 피해야 합니다. - -### PrecompiledBankMint - -|이름|타입|인덱싱|설명| -|---|---|---|---| -|from|address|Y|토큰을 발행한 주소| -|to|address|Y|발행된 토큰을 받을 주소| -|amount|uint256|N|발행된 토큰의 수량| - -### PrecompiledBankBurn - -|이름|타입|인덱싱|설명| -|---|---|---|---| -|from|address|Y|토큰을 소각한 주소| -|to|address|Y|이 메서드에서는 사용되지 않음| -|amount|uint256|N|소각된 토큰의 수량| - -### PrecompiledBankTransfer - -|이름|타입|인덱싱|설명| -|---|---|---|---| -|from|address|Y|토큰을 전송한 주소| -|to|address|Y|전송된 토큰을 받을 주소| -|amount|uint256|N|전송된 토큰의 수량| - -### PrecompiledBankApproval - -|이름|타입|인덱싱|설명| -|---|---|---|---| -|owner|address|Y|토큰을 승인한 주소| -|spender|address|Y|승인할 주소| -|value|uint256|N|승인된 토큰의 수량| - -### PrecompiledBankRevoke - -|이름|타입|인덱싱|설명| -|---|---|---|---| -|owner|address|Y|토큰을 취소한 주소| -|spender|address|Y|취소할 주소| -|value|uint256|N|승인된 토큰의 수량| +- [**뱅크 사전 컴파일 참조**](/ko/reference/bank-module-api): `transfer`, `approve`, `mint`, `burn`을 호출하고 이벤트를 읽습니다. +- [**시스템 모듈 개요**](/ko/explanation/system-modules-overview): 사전 컴파일이 노출하는 모듈의 전체 목록으로 돌아갑니다. +- [**가스 토큰으로서의 USDT**](/ko/explanation/usdt-as-gas-token): 뱅크 모듈이 관리하는 이중 역할 자산 모델을 이해합니다. diff --git a/docs/pages/ko/explanation/bridge-security.mdx b/docs/pages/ko/explanation/bridge-security.mdx index 73b69e1..5d96ef0 100644 --- a/docs/pages/ko/explanation/bridge-security.mdx +++ b/docs/pages/ko/explanation/bridge-security.mdx @@ -1,50 +1,50 @@ --- source_path: explanation/bridge-security.mdx -source_sha: f1e67d648ec59eb4f8972eedeef0e8cda8c943af -title: "브리지 보안과 DVN" -description: "Stable이 LayerZero DVN을 구성하여 크로스체인 메시지를 검증하는 방법과 단일 키 손상이 치명적이지 않은 이유를 이해합니다." +source_sha: 1566bfa5dadef64d40a9d10ef7ece18b4384ca62 +title: "브리지 보안 및 DVN" +description: "Stable이 LayerZero DVN을 구성하여 교차 체인 메시지를 확인하는 방법과 단일 키 손상이 치명적이지 않은 이유를 이해하십시오." diataxis: "explanation" --- -# 브리지 보안과 DVN +# 브리지 보안 및 DVN -LayerZero 브리지의 보안은 한 체인에서 보낸 메시지가 다른 체인에서 발생했음을 확인하는 검증 계층만큼만 안전합니다. 그 계층이 바로 탈중앙화 검증자 네트워크(Decentralized Verifier Network, DVN)입니다. 이 페이지에서는 DVN이 무엇을 하는지, Stable이 자사 브리지에서 DVN을 어떻게 구성하는지, 그리고 단일 DVN의 손상이 왜 Stable을 위험에 빠뜨리지 않는지를 설명합니다. +LayerZero 브리지는 한 체인에서 보낸 메시지가 다른 체인에서 발생했음을 확인하는 검증 계층만큼 안전합니다. 이 계층은 분산형 검증자 네트워크(DVN)입니다. 이 페이지에서는 DVN이 하는 일, Stable이 브리지에서 DVN을 구성하는 방법, 단일 DVN 손상이 Stable을 위험에 빠뜨리지 않는 이유를 설명합니다. -## DVN의 작동 방식 +## DVN 작동 방식 -LayerZero 메시지가 체인 A에서 체인 B로 이동할 때, 구성된 DVN 집합이 독립적으로 그 메시지가 진짜임을 입증하기 전까지 목적지 컨트랙트는 메시지를 실행하지 않습니다. 각 애플리케이션은 자체 구성을 선택합니다: +LayerZero 메시지가 체인 A에서 체인 B로 이동할 때, 대상 계약은 구성된 DVN 세트가 메시지가 실제임을 독립적으로 증명할 때까지 메시지를 실행하지 않습니다. 각 애플리케이션은 자체 구성을 선택합니다. -- **필수 DVN.** 메시지가 수락되기 전에 모든 필수 DVN이 서명해야 합니다. -- **N-of-M 임계값을 갖는 선택적 DVN.** 필수 집합 위에 선택적 풀을 추가할 수 있으며, 필수 서명에 더해 2-of-5와 같은 임계값을 충족해야 합니다. -- **블록 확인 깊이.** DVN이 서명하기 전에 기다리는 소스 체인 확인 수입니다. +- **필수 DVN.** 메시지가 승인되기 전에 모든 필수 DVN이 서명해야 합니다. +- **N-of-M 임계값을 가진 선택적 DVN.** 필수 세트 외에 선택적 풀을 추가할 수 있으며, 필수 서명 외에 2-of-5와 같은 임계값이 충족되어야 합니다. +- **블록 확인 깊이.** DVN이 서명하기 전에 대기하는 소스 체인 확인 횟수입니다. -브리지의 안전성은 전적으로 이 구성에 달려 있습니다. 단일 DVN을 유일한 검증자로 두는 1/1 설정은 그 하나의 DVN 서명 키가 손상되면 공격자가 크로스체인 메시지를 위조할 수 있음을 의미합니다. 세 개의 독립적인 운영자에 걸친 3/3 구성은 세 운영자가 모두 동시에 손상되어야 합니다. 이 차이는 단일 도난 키로 브리지를 잃는 것과 한 운영자에 대한 표적 공격에서 살아남는 것의 차이입니다. +브리지의 안전은 전적으로 이 구성에 달려 있습니다. 단일 DVN이 유일한 검증자인 1/1 설정은 해당 DVN의 서명 키가 손상되면 공격자가 교차 체인 메시지를 위조할 수 있음을 의미합니다. 세 명의 독립적인 운영자에 걸쳐 3/3은 세 명 모두 동시에 손상되어야 합니다. 그 차이는 단일 도난 키로 브리지를 잃는 것과 한 운영자에 대한 표적 공격에서 살아남는 것의 차이입니다. ## Stable의 구성 -Stable의 브리지는 세 개의 독립적인 운영자인 **LayerZero Labs**, **Canary**, **Horizen**과 함께 **3/3 필수 DVN** 구성을 실행합니다. 목적지 컨트랙트가 메시지를 실행하기 전에 세 운영자 모두가 모든 크로스체인 메시지에 서명해야 합니다. 임계값을 갖는 선택적 풀은 없으며, 필수 집합이 전체 검증 표면입니다. +Stable의 브리지는 **LayerZero Labs**, **Canary**, **Horizen**의 세 명의 독립적인 운영자와 함께 **3/3 필수 DVN** 구성을 실행합니다. 세 명 모두 모든 교차 체인 메시지에 서명해야 대상 계약이 메시지를 실행합니다. 임계값을 가진 선택적 풀은 없습니다. 필수 세트가 전체 검증 표면입니다. -LayerZero 자체 키를 포함한 단일 서명 키의 손상은 이 태세에 아무런 영향을 미치지 못합니다. 메시지를 위조하려면 세 개의 독립적인 운영자 모두가 동시에 손상되어야 합니다. +LayerZero 자체를 포함하여 단일 서명 키가 손상되어도 이 자세에 아무런 영향을 미치지 않습니다. 메시지를 위조하려면 세 명의 독립적인 운영자 모두가 동시에 손상되어야 합니다. -DVN 컨트랙트 주소는 [브리지: Stable의 DVN 운영자](/ko/reference/bridges#stable-s-dvn-operators)를 참조하세요. +DVN 계약 주소는 [브리지: Stable의 DVN 운영자](/ko/reference/bridges#stable-s-dvn-operators)를 참조하십시오. ## STABLE OFT 아키텍처 -STABLE 토큰은 LayerZero의 Omnichain Fungible Token(OFT) 표준을 사용하여 다른 체인으로 브리지됩니다. 두 가지 컨트랙트 유형이 배포됩니다: +STABLE 토큰은 LayerZero의 Omnichain Fungible Token(OFT) 표준을 사용하여 다른 체인으로 브리징됩니다. 두 가지 계약 유형이 배포됩니다. -- Stable의 **`StableOFTAdapter`**. 어댑터는 홈 체인에서 STABLE을 잠그고 STABLE이 크로스체인으로 전송될 때 LayerZero 메시지를 발생시킵니다. -- 각 원격 체인의 **`StableOFTUpgradeable`**. 이 컨트랙트는 구성된 DVN이 메시지를 검증할 때 목적지에서 STABLE을 발행하고, 반환 경로에서 이를 소각하여 홈 체인 공급량이 정규(canonical) 상태로 유지되도록 합니다. +- Stable의 **`StableOFTAdapter`**. 어댑터는 홈 체인에서 STABLE을 잠그고 STABLE이 교차 체인으로 전송될 때 LayerZero 메시지를 내보냅니다. +- 각 원격 체인의 **`StableOFTUpgradeable`**. 이 계약은 구성된 DVN이 메시지를 확인하면 대상에서 STABLE을 발행하고, 홈 체인 공급이 정식 상태를 유지하도록 반환 경로에서 소각합니다. -각 체인에 배포된 주소는 [브리지: STABLE OFT 컨트랙트](/ko/reference/bridges#stable-oft-contracts)를 참조하세요. +각 체인에 배포된 주소는 [브리지: STABLE OFT 계약](/ko/reference/bridges#stable-oft-contracts)을 참조하십시오. -## 운영상의 의존성 +## 운영 종속성 -Stable 자체의 브리지 보안은 상위 프로토콜과 독립적이지만, 파트너 프로토콜이 자체 브리지를 일시 중지할 때 Stable을 통한 크로스체인 흐름은 여전히 일시 중지될 수 있습니다. 예를 들어 USDT0가 크로스체인 발행과 소각을 일시 중지하면, USDT0가 재개될 때까지 USDT0는 Stable로 또는 Stable에서 이동할 수 없습니다. Stable 내의 자금은 계속 자유롭게 이동하며, 특정 크로스체인 작업만 사용할 수 없습니다. +Stable 자체의 브리지 보안은 상위 프로토콜과 독립적이지만, 파트너 프로토콜이 자체 브리지를 일시 중지하면 Stable을 통한 교차 체인 흐름이 일시 중지될 수 있습니다. 예를 들어, USDT0이 교차 체인 발행 및 소각을 일시 중지하면 USDT0이 재개될 때까지 USDT0은 Stable으로 이동하거나 Stable에서 나올 수 없습니다. Stable 내의 자금은 자유롭게 이동하며, 특정 교차 체인 작업만 사용할 수 없습니다. -파트너 브리지를 통해 라우팅되는 애플리케이션 표면은 사용자가 그 구분을 이해할 수 있도록 이를 명확하게 전달해야 합니다. 사용자의 자금은 위험에 처한 것이 아니라, 특정 크로스체인 경로만 일시적으로 사용할 수 없는 것입니다. +파트너 브리지를 통해 라우팅하는 애플리케이션 표면은 사용자가 차이점을 이해할 수 있도록 이를 명확하게 전달해야 합니다. 즉, 자금이 위험에 처한 것이 아니라 특정 교차 체인 경로를 일시적으로 사용할 수 없는 것입니다. ## 다음 권장 사항 -- [**USDT0를 Stable로 브리징하기**](/ko/explanation/usdt0-bridging) — USDT0가 OFT Mesh와 Legacy Mesh를 통해 Stable에 도달하는 방법을 확인하세요. -- [**브리지 제공자와 주소**](/ko/reference/bridges) — 컨트랙트 주소, DVN 운영자, 지원되는 브리지 제공자를 참조하세요. -- [**LayerZero DVN 문서**](https://docs.layerzero.network/v2/concepts/protocol/security-stack-dvns) — 필수 및 선택적 DVN 검증에 대한 LayerZero의 사양을 읽어보세요. +- [**USDT0을 Stable로 브리징**](/ko/explanation/usdt0-bridging): USDT0이 OFT 메시 및 레거시 메시를 통해 Stable에 도달하는 방법을 확인하십시오. +- [**브리지 제공자 및 주소**](/ko/reference/bridges): 계약 주소, DVN 운영자 및 지원되는 브리지 제공자를 참조하십시오. +- [**LayerZero DVN 문서**](https://docs.layerzero.network/v2/concepts/protocol/security-stack-dvns): LayerZero의 필수 및 선택적 DVN 확인 사양을 읽어보십시오. diff --git a/docs/pages/ko/explanation/build-overview.mdx b/docs/pages/ko/explanation/build-overview.mdx index ae6733d..e8a19d1 100644 --- a/docs/pages/ko/explanation/build-overview.mdx +++ b/docs/pages/ko/explanation/build-overview.mdx @@ -1,25 +1,25 @@ --- source_path: explanation/build-overview.mdx -source_sha: 3a41b9e06dc843c2aa33c4b44ca5f37301b9e57f +source_sha: 4b19d1f913597181cd62426d9b82ef8e91c4fae3 title: "개요" -description: "Stable에서 출시하기: 지갑과 계정, 결제, 스마트 컨트랙트, AI 에이전트. 빠른 시작으로 시작하거나 필요한 기능으로 바로 이동하세요." +description: "Stable에서 출시: 지갑 및 계정, 결제, 스마트 계약 및 AI 에이전트. 빠른 시작으로 시작하거나 필요한 기능으로 바로 이동하세요." diataxis: "explanation" --- # 개요 -Stable이 처음이신가요? 먼저 [빠른 시작](/ko/tutorial/quick-start)을 실행하세요. 5분이면 테스트넷 트랜잭션을 전송하므로, 이 탭의 나머지 내용을 연결할 무언가가 생깁니다. +Stable이 처음이신가요? 먼저 [빠른 시작](/ko/tutorial/quick-start)을 실행하세요. 5분이면 테스트넷 트랜잭션을 보낼 수 있어서 나머지 탭에 연결할 수 있습니다. -## 살펴보기 +## 탐색 -- [**계정**](/ko/explanation/accounts-overview) — 지갑을 생성하고, EIP-7702로 EOA를 위임하며, 사용자와 에이전트를 위한 세션 키 범위를 지정하세요. -- [**결제**](/ko/explanation/payments-overview) — USDT0를 전송하고, P2P 및 구독 흐름을 구축하며, ERC-3009로 인보이스를 정산하고, x402로 API 가격을 책정하세요. -- [**컨트랙트**](/ko/explanation/contracts-overview) — Solidity 컨트랙트를 배포, 검증, 인덱싱하고, Bank / Distribution / Staking 프리컴파일을 호출하세요. -- [**AI와 에이전트**](/ko/explanation/agent-settlement) — MCP 서버를 AI 클라이언트에 연결하고, 에이전트가 프롬프트를 통해 호출할 수 있는 x402 유료 도구를 노출하세요. +- [**계정**](/ko/explanation/accounts-overview): 지갑을 만들고, EIP-7702로 EOA를 위임하고, 사용자 및 에이전트의 세션 키를 범위 지정합니다. +- [**결제**](/ko/explanation/payments-overview): USDT0를 보내고, P2P 및 구독 흐름을 구축하고, ERC-3009로 인보이스를 정산하고, x402로 API 가격을 책정합니다. +- [**계약**](/ko/explanation/contracts-overview): Solidity 계약을 배포하고, 확인하고, 인덱싱하고, Bank/Distribution/Staking 사전 컴파일을 호출합니다. +- [**AI 및 에이전트**](/ko/explanation/agent-settlement): MCP 서버를 AI 클라이언트에 연결하고 프롬프트를 통해 에이전트가 호출할 수 있는 x402 유료 도구를 노출합니다. -## 여기서 시작하기 +## 여기부터 시작하세요 -- [**빠른 시작**](/ko/tutorial/quick-start) — 테스트넷에 연결하고, 지갑에 자금을 충전하며, 첫 USDT0 트랜잭션을 전송하세요. -- [**첫 USDT0 전송하기**](/ko/tutorial/send-usdt0) — 동일한 잔액에서 네이티브 및 ERC-20 전송을 TypeScript 예제와 함께 수행하세요. -- [**스마트 컨트랙트 배포하기**](/ko/tutorial/smart-contract) — Foundry를 스캐폴딩하고, Stable을 구성하며, Counter 컨트랙트를 배포하세요. -- [**Stable SDK**](/ko/explanation/sdk-overview) — Stable에서 transfer, bridge, swap을 위한 타입이 지정된 TypeScript 클라이언트를 사용하세요. +- [**빠른 시작**](/ko/tutorial/quick-start): 테스트넷에 연결하고, 지갑에 자금을 지원하고, 첫 USDT0 트랜잭션을 보냅니다. +- [**첫 USDT0 보내기**](/ko/tutorial/send-usdt0): TypeScript 예제와 함께 동일한 잔액에 대한 기본 및 ERC-20 전송. +- [**스마트 계약 배포**](/ko/tutorial/smart-contract): Foundry를 스캐폴딩하고, Stable을 구성하고, Counter 계약을 배포합니다. +- [**Stable SDK**](/ko/explanation/sdk-overview): Stable에서 전송, 브리지 및 스왑을 위한 타입스크립트 클라이언트를 사용합니다. diff --git a/docs/pages/ko/explanation/confidential-transfer.mdx b/docs/pages/ko/explanation/confidential-transfer.mdx index b998491..21a2cb9 100755 --- a/docs/pages/ko/explanation/confidential-transfer.mdx +++ b/docs/pages/ko/explanation/confidential-transfer.mdx @@ -1,14 +1,60 @@ --- source_path: explanation/confidential-transfer.mdx -source_sha: 162fe40acbfbf24c5d2c60a861caa4b54175cd47 +source_sha: 44b9b0047f5252a2aa10b8e93a64f42854c9182d title: "기밀 전송" -description: "규정 준수를 유지하면서 USDT 거래 프라이버시를 보장하는 기밀 전송 메커니즘." +description: "Stable에서 규제 준수를 통한 프라이버시 보호 USDT 트랜잭션을 위한 기밀 전송 메커니즘." +diataxis: "explanation" --- # 기밀 전송 -기업들 사이에서 블록체인 채택이 특히 스테이블코인 분야에서 가속화됨에 따라, 트랜잭션 프라이버시에 대한 수요도 점점 증가하고 있습니다. 기업들은 종종 결제 금액과 같은 민감한 데이터를 보호하기 위해 금융 운영에서 기밀성을 요구합니다. 이러한 요구를 해결하기 위해 Stable은 프라이버시 요구와 규제 준수라는 두 가지 필수 요소의 균형을 맞춘 기밀 전송 메커니즘을 개발 중입니다. +**기밀 전송(Confidential Transfer)**은 발신자 및 수신자 주소를 공개적으로 볼 수 있도록 유지하면서 USDT0 전송의 **금액**을 보호하는 Stable의 프라이버시 계층입니다. 보호된 금액은 트랜잭션 당사자와 승인된 규제 감사관만 읽을 수 있으며, 영지식(ZK) 암호화를 사용하여 값을 공개하지 않고 유효성을 증명합니다. 이 기능은 개발 중이며, 이 페이지에서는 대상 모델에 대해 설명합니다. -Stable은 영지식(ZK) 암호 기술을 활용하여 트랜잭션 금액을 온체인에 공개하지 않고도 토큰을 전송할 수 있도록 하는 기밀 전송 레이어를 구축하고 있습니다. 전송 금액은 비공개로 유지되는 반면, 송신자와 수신자의 주소는 공개된 상태로 유지되어 금융 규제 및 감사 가능성을 확보합니다. +## 해결하는 문제 -보호된 트랜잭션 금액은 해당 거래 당사자 및 인가된 규제 감사인만 접근할 수 있어, 프라이버시 확보가 법적 투명성을 희생하지 않도록 보장합니다. \ No newline at end of file +표준 온체인 전송은 완벽하게 투명합니다. 누구든지 발신자, 수신자 및 금액을 읽을 수 있습니다. 비즈니스 결제의 경우 이러한 투명성은 데이터 유출 문제입니다. + +- 온체인에서 공급업체에 비용을 지불하는 소매업체는 모든 관찰자에게 주문량 및 도매 가격을 노출합니다. +- 계정 간에 자금을 이동하는 재무부는 포지션 규모를 광고합니다. +- 급여 실행은 전체 네트워크에 급여 데이터를 게시합니다. + +완벽한 불투명성(모네로 스타일)은 이 문제를 해결하지만 규정 준수를 위반합니다. 규제 기관과 감사관은 트랜잭션을 확인할 수 없습니다. 선택적 기밀성(금액은 숨겨지고 당사자는 감사 가능)이 Stable이 목표로 하는 모델입니다. + +## 보이는 것과 보이지 않는 것 + +| 필드 | 온체인에서 보이는 요소 | 보호되는 요소 | +| :--- | :--- | :--- | +| 발신자 주소 | ✓ | | +| 수신자 주소 | ✓ | | +| 전송 금액 | | ✓ | +| 보조 메타데이터 | | ✓ | + +보호된 금액은 암호화됩니다. 유효한 증명은 값 자체를 공개하지 않고 전송이 잔액 일관성(인플레이션 없음, 마이너스 금액 없음)을 가진다는 것을 증명합니다. 발신자, 수신자 및 승인된 규제 감사관만 보호된 값을 해독할 수 있습니다. + +## 규정 준수 모델에 적합한 방식 + +두 가지 속성은 디자인을 감사 가능하게 만듭니다. + +- **결정론적인 감사관 액세스.** 규제 감사관은 관할 구역 내 트랜잭션에 대한 보호된 금액을 해독하는 키를 보유합니다. 임의의 관찰자에 대해 비즈니스 프라이버시는 유지되지만, 규정 준수 조사는 예외입니다. +- **표준 주소 투명성.** 주소 수준 흐름(제재 확인, 자금 출처 분석)에서 작동하는 AML/KYC 도구는 모든 투명한 체인과 동일한 공개 주소 그래프에 대해 작동합니다. + +## 언제 사용하는가 + +기밀 전송은 금액이 상업적으로 민감하지만 상대방이 적절하게 공개되는 모든 흐름에 적합합니다. + +- 주문 규모가 가격을 나타내는 공급업체 및 송장 결제. +- 포지션 규모가 전략을 나타내는 재무 운영. +- 개별 급여가 경쟁업체에 의해 색인화되어서는 안 되는 급여 지급. +- 오더북 테이프에 대한 가격 발견이 위험인 대규모 OTC 정산. + +주소 수준 프라이버시도 필요한 흐름(예: 내부 고발자 기부금)의 경우 기밀 전송만으로는 충분하지 않습니다. 이러한 사용 사례에는 Stable이 제공하지 않는 추가 주소 난독화 프리미티브가 필요합니다. + +## 상태 + +기밀 전송은 개발 중입니다. 타이밍은 [로드맵](/ko/explanation/technical-roadmap)을 참조하십시오. 이 메커니즘은 표준 USDT0 전송과 함께 전용 전송 경로로 출시될 예정입니다. 옵트인하지 않는 기존 애플리케이션은 영향을 받지 않습니다. + +## 다음 권장 사항 + +- [**USDT를 가스로 활용**](/ko/explanation/usdt-as-gas-token): 기밀 전송이 보호하는 자산 모델을 이해합니다. +- [**자금 흐름**](/ko/explanation/flow-of-funds): 엔드투엔드 결제 라이프사이클에서 기밀성이 어디에 해당하는지 확인합니다. +- [**로드맵**](/ko/explanation/technical-roadmap): 기밀 전송이 언제 출시되는지 추적합니다. diff --git a/docs/pages/ko/explanation/consensus.mdx b/docs/pages/ko/explanation/consensus.mdx index 3ee3fd2..4749787 100755 --- a/docs/pages/ko/explanation/consensus.mdx +++ b/docs/pages/ko/explanation/consensus.mdx @@ -1,42 +1,42 @@ --- source_path: explanation/consensus.mdx -source_sha: e1ddd035470323b6b114d15deb175eb5f478febb +source_sha: c3243c12a02eb788cf914984ffa1f57726929778 title: "합의" -description: "StableBFT 합의 프로토콜 설계, DAG 기반 업그레이드 로드맵, 그리고 200,000 TPS 처리량 벤치마크." +description: "StableBFT 합의 프로토콜 설계, DAG 기반 업그레이드 로드맵, 200,000 TPS 처리량 벤치마크" diataxis: "explanation" --- # 합의 -## StableBFT를 활용한 PoS 합의 +## StableBFT를 이용한 PoS 합의 -Stable Blockchain은 CometBFT를 기반으로 구축된 맞춤형 PoS 합의 프로토콜인 **StableBFT**를 활용하여 높은 처리량, 낮은 지연 시간, 그리고 강력한 신뢰성을 제공합니다. StableBFT는 결정론적 완결성(블록은 포함되는 즉시 최종 확정되며 포크가 없음)과 검증자의 1/3까지 장애가 발생하거나 악의적으로 행동하더라도 견딜 수 있는 비잔틴 장애 허용성을 제공합니다. +Stable Blockchain은 높은 처리량, 낮은 지연 시간 및 강력한 안정성을 제공하기 위해 CometBFT를 기반으로 구축된 맞춤형 PoS 합의 프로토콜인 **StableBFT**를 활용합니다. StableBFT는 확정적 완결성(블록이 포함될 때 확정되며 포크가 없음)과 유효성 검사자의 1/3까지 실패하거나 악의적으로 행동하는 경우에도 비잔틴 장애 허용을 제공합니다. -합의 성능을 한층 더 최적화하기 위해 Stable은 가까운 미래에 다음과 같은 개선 사항을 구현할 계획입니다: +합의 성능을 더욱 최적화하기 위해 Stable은 가까운 시일 내에 다음 개선 사항을 구현할 계획입니다. -- **트랜잭션과 합의 가십의 분리(Decoupled Transaction and Consensus Gossiping)**: 트랜잭션 가십 계층을 합의 가십 계층과 분리함으로써, 트랜잭션 측의 네트워크 혼잡이 합의 통신을 방해하는 것을 방지합니다. -- **블록 제안자에게 트랜잭션 직접 브로드캐스트(Direct Transaction Broadcasting to the Block Proposer)**: 현재 모델에서는 트랜잭션이 노드 간 피어 투 피어 가십을 통해 전파되어 네트워크 전반에 높은 가십 트래픽을 발생시킵니다. Stable은 트랜잭션이 블록 제안자에게 직접 브로드캐스트되도록 함으로써 효율성을 개선하고자 합니다. +- **분리된 트랜잭션 및 합의 가십**: 트랜잭션 가십 계층을 합의 가십 계층과 분리하여 트랜잭션 측의 네트워크 혼잡이 합의 통신을 방해하는 것을 방지합니다. +- **블록 제안자에게 직접 트랜잭션 브로드캐스트**: 현재 모델에서는 트랜잭션이 노드 간 피어 투 피어 가십을 통해 전파되어 네트워크 전체에 높은 가십 트래픽을 발생시킵니다. Stable은 트랜잭션이 블록 제안자에게 직접 브로드캐스트되도록 하여 효율성을 개선하는 것을 목표로 합니다. -## 향후 로드맵: DAG 기반 합의 +## 미래 로드맵: DAG 기반 합의 -합의를 크게 가속화하기 위해, Stable은 최대 5배의 속도 향상을 제공할 수 있는 DAG 기반 설계로 프로토콜을 업그레이드할 계획입니다. +합의 속도를 크게 높이기 위해 Stable은 프로토콜을 최대 5배의 속도 향상을 제공할 수 있는 DAG 기반 아키텍처로 업그레이드할 계획입니다. -PBFT나 HotStuff 같은 전통적인 뷰 기반 BFT 프로토콜은 안정적인 네트워크 조건에서 낮은 지연 시간에 최적화되어 있습니다. 그러나 이러한 프로토콜은 장애 상황에서 성능이 크게 저하되며, 일시적인 결함 이후 종종 긴 복구 지연을 겪습니다. +PBFT 및 HotStuff와 같은 전통적인 뷰 기반 BFT 프로토콜은 안정적인 네트워크 조건에서 낮은 지연 시간을 위해 최적화되어 있습니다. 그러나 중단 시에는 성능이 크게 저하되며, 일시적인 오류 후 길게 복구 지연이 발생하는 경우가 많습니다. -Narwhal과 Tusk 같은 1세대 DAG 기반 엔진은 데이터 전파를 합의 순서화로부터 분리함으로써 단일 제안자 병목 현상을 제거하고 네트워크 불안정 상황에서의 견고성도 향상시킬 수 있음을 보여줍니다. 그러나 이들의 아키텍처는 기존의 높이 기반 블록 시맨틱과 멤풀 설계에서 벗어나기 때문에 CometBFT와 같은 시스템과 직접적으로 호환되지는 않습니다. +Narwhal 및 Tusk와 같은 1세대 DAG 기반 엔진은 데이터 전파를 합의 순서와 분리하면 단일 제안자 병목 현상을 제거하고 네트워크 불안정성 속에서도 견고성을 향상시킬 수 있음을 보여줍니다. 그러나 이러한 아키텍처는 기존 높이 기반 블록 의미 체계 및 멤풀 설계와 다르므로 CometBFT와 같은 시스템과 직접 호환되지 않습니다. -[Autobahn](/ko/explanation/autobahn)은 Stable의 합의 계층과 더 자연스럽게 통합되는 PBFT-on-DAG 아키텍처를 제공하며, 정상적인 조건에서 낮은 지연 시간을 제공하는 동시에 네트워크 결함 발생 시 빠른 복구를 제공합니다. Stable 팀은 Autobahn 논문 저자들과 긴밀한 관계를 유지하고 있으며, Autobahn의 아키텍처를 활용하여 StableBFT의 성능을 극대화할 것입니다. +[오토반(Autobahn)](/ko/explanation/autobahn)은 Stable의 합의 계층에 더 자연스럽게 통합되는 PBFT-on-DAG 아키텍처를 제공하며, 정상적인 조건에서 낮은 지연 시간을 제공하고 네트워크 오류 발생 시 빠른 복구를 제공합니다. Stable 팀은 오토반 논문의 저자들과 긴밀한 관계를 유지하며 StableBFT의 성능을 극대화하기 위해 오토반의 아키텍처를 활용할 것입니다. -Autobahn 위에 구축된 StableBFT는 다음을 가능하게 합니다: +오토반 위에 구축된 StableBFT는 다음을 가능하게 합니다. - 단일 리더 제한을 제거하여 병렬 제안 처리. -- 데이터 전파를 최종 순서화로부터 분리하여 더 빠른 완결성. -- 견고한 BFT 메커니즘을 통한 네트워크 장애에 대한 향상된 복원력. +- 데이터 전파를 최종 순서와 분리하여 더 빠른 완결성. +- 강력한 BFT 메커니즘을 통해 네트워크 역경에 대한 향상된 탄력성. -이 고급 합의 설계는 내부 개념 증명(proof-of-concept)을 기반으로 훨씬 더 높은 처리량을 지원하며, 통제된 환경에서 200,000 TPS 이상(합의 전용)을 입증했습니다. +이 고급 합의 설계는 제어된 환경에서 200,000 TPS(합의 전용) 이상을 시연한 내부 개념 증명에 기반하여 훨씬 더 높은 처리량을 지원합니다. ## 다음 권장 사항 -- [**Autobahn**](/ko/explanation/autobahn) — StableBFT의 DAG 기반 업그레이드 경로를 뒷받침하는 프로토콜 논문을 읽어보세요. -- [**실행**](/ko/explanation/execution) — 블록이 합의에서 병렬 실행으로 어떻게 이동하는지 확인하세요. -- [**완결성**](/ko/explanation/finality) — RPC를 기반으로 구축할 때 Stable의 단일 슬롯 완결성을 적용하세요. +- [**오토반(Autobahn)**](/ko/explanation/autobahn): StableBFT의 DAG 기반 업그레이드 경로의 기반이 되는 프로토콜 논문을 읽어보세요. +- [**실행(Execution)**](/ko/explanation/execution): 블록이 합의에서 병렬 실행으로 어떻게 이동하는지 알아보세요. +- [**완결성(Finality)**](/ko/explanation/finality): RPC를 구축할 때 Stable의 단일 슬롯 완결성을 적용하세요. diff --git a/docs/pages/ko/explanation/contracts-guides.mdx b/docs/pages/ko/explanation/contracts-guides.mdx index 63220bd..54ee606 100644 --- a/docs/pages/ko/explanation/contracts-guides.mdx +++ b/docs/pages/ko/explanation/contracts-guides.mdx @@ -1,32 +1,32 @@ --- source_path: explanation/contracts-guides.mdx -source_sha: d11a9b3683251378d49f56b7994d0f90de10bd7b +source_sha: 9399f7ec9f6cb709da5f547e311c8bbaa678d941 title: "컨트랙트 가이드" -description: "모든 컨트랙트 가이드, 개념, 레퍼런스: 배포 흐름, 시스템 모듈, JSON-RPC 호환성, 이더리움과의 차이점." +description: "모든 컨트랙트 가이드, 개념 및 레퍼런스: 배포 흐름, 시스템 모듈, JSON-RPC 호환성 및 이더리움과의 차이점." diataxis: "explanation" --- # 컨트랙트 가이드 -컨트랙트 탭 아래의 모든 가이드, 개념, 레퍼런스를 작업 목적별로 분류했습니다. +수행하려는 작업에 따라 그룹화된 컨트랙트 탭 아래의 모든 가이드, 개념 및 레퍼런스. ## 컨트랙트 빌드 및 배포 -- [**배포**](/ko/tutorial/smart-contract) — Foundry 프로젝트를 스캐폴딩하고 Counter를 Stable 테스트넷에 배포합니다. -- [**검증**](/ko/how-to/verify-contract) — Stablescan에 소스를 업로드하여 사용자가 컨트랙트를 읽고 호출할 수 있도록 합니다. -- [**이벤트 인덱싱**](/ko/how-to/index-contract) — ethers.js로 실시간 이벤트 스트림을 구축하고 과거 데이터를 백필합니다. +- [**배포**](/ko/tutorial/smart-contract): Foundry 프로젝트 스캐폴드 및 Counter를 Stable 테스트넷에 배포합니다. +- [**확인**](/ko/how-to/verify-contract): 사용자가 컨트랙트를 읽고 호출할 수 있도록 Stablescan에 소스를 업로드합니다. +- [**이벤트 인덱싱**](/ko/how-to/index-contract): ethers.js로 라이브 이벤트 스트림 및 과거 데이터 채우기를 구축합니다. ## 시스템 모듈 호출 -- [**시스템 모듈 사용**](/ko/how-to/use-system-modules) — Solidity 또는 ethers.js에서 Bank, Distribution, Staking 프리컴파일을 호출합니다. -- [**언본딩 완료 추적**](/ko/how-to/track-unbonding) — StableSystem 프리컴파일을 통해 발생하는 UnbondingCompleted 이벤트를 구독합니다. +- [**시스템 모듈 사용**](/ko/how-to/use-system-modules): Solidity 또는 ethers.js에서 Bank, Distribution 및 Staking 사전 컴파일을 호출합니다. +- [**언본딩 완료 추적**](/ko/how-to/track-unbonding): StableSystem 사전 컴파일을 통해 방출되는 UnbondingCompleted 이벤트 구독. ## 레퍼런스 -- [**시스템 모듈 레퍼런스**](/ko/reference/system-modules-api-overview) — 프리컴파일 주소 및 모듈별 ABI 포인터. -- [**JSON-RPC API**](/ko/reference/json-rpc-api) — 지원되는 `eth_*`, `net_*`, `web3_*`, `debug_*` 메서드. +- [**시스템 모듈 레퍼런스**](/ko/reference/system-modules-api-overview): 사전 컴파일 주소 및 모듈별 ABI 포인터. +- [**JSON-RPC API**](/ko/reference/json-rpc-api): 지원되는 `eth_*`, `net_*`, `web3_*` 및 `debug_*` 메서드. -## 기초 개념 +## 핵심 개념 -- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior) — 이중 역할 잔액, 조정 이벤트, 컨트랙트 설계 규칙. -- [**이더리움과의 차이점**](/ko/explanation/ethereum-comparison) — 가스 토큰, 최종성, 우선순위 팁, EVM 호환성. +- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior): 이중 역할 잔액, 조정 이벤트 및 컨트랙트 디자인 규칙. +- [**이더리움과의 차이점**](/ko/explanation/ethereum-comparison): 가스 토큰, 최종성, 우선 순위 팁 및 EVM 호환성. diff --git a/docs/pages/ko/explanation/contracts-overview.mdx b/docs/pages/ko/explanation/contracts-overview.mdx index ad620b4..fbbb782 100644 --- a/docs/pages/ko/explanation/contracts-overview.mdx +++ b/docs/pages/ko/explanation/contracts-overview.mdx @@ -1,36 +1,36 @@ --- source_path: explanation/contracts-overview.mdx -source_sha: 4b2c800a696bced5ac5ec2269d7ddfaf82506a18 +source_sha: d004e6f88f0f2db9748b4114627eabb27e41c94c title: "Stable의 컨트랙트" -description: "Stable에서 스마트 컨트랙트를 배포, 검증, 인덱싱하세요. 완전한 EVM 호환성과 함께 Bank, Distribution, Staking 모듈을 위한 프리컴파일을 제공합니다." +description: "Stable에서 스마트 컨트랙트를 배포, 검증 및 인덱싱합니다. Bank, Distribution 및 Staking 모듈을 위한 완전한 EVM 호환성 및 프리컴파일 기능이 제공됩니다." diataxis: "explanation" --- # Stable의 컨트랙트 -Stable은 완전히 EVM 호환됩니다. Solidity, Vyper, Hardhat, Foundry, ethers.js, viem이 변경 없이 작동합니다. 도구를 Stable의 RPC로 가리키기만 하면 기존 컨트랙트가 그대로 배포됩니다. 표준 EVM 위에, Stable은 프로토콜 수준 모듈(Bank, Distribution, Staking)을 고정 주소의 프리컴파일된 컨트랙트로 노출하므로, Solidity에서 스테이킹과 보상 분배를 다시 구현하지 않고도 호출할 수 있습니다. +Stable은 EVM과 완벽하게 호환됩니다. Solidity, Vyper, Hardhat, Foundry, ethers.js 및 viem은 변경 없이 작동합니다. 툴링을 Stable의 RPC로 지정하면 기존 컨트랙트가 그대로 배포됩니다. 표준 EVM 외에도 Stable은 프로토콜 수준 모듈(Bank, Distribution, Staking)을 고정 주소의 프리컴파일된 컨트랙트로 노출하므로 Solidity가 스테이킹 및 보상 분배를 다시 구현할 필요 없이 호출할 수 있습니다. -## 무엇을 만들 수 있는가 +## 만들 수 있는 것 -- 어떤 EVM 도구체인으로든 **표준 애플리케이션 컨트랙트**(ERC-20, ERC-721, 에스크로, AMM)를 만들 수 있습니다. -- ethers.js를 통한 실시간 이벤트 스트림과 함께 Stablescan에서 **검증되고 인덱싱된 컨트랙트**. -- Solidity에서 Bank / Distribution / Staking 프리컴파일을 호출하는 **프로토콜 통합 컨트랙트**. -- 표준 `eth_getLogs`를 통해 프로토콜이 발생시킨 이벤트(예: 언본딩 완료)를 감시하는 **시스템 트랜잭션 리스너**. +- 모든 EVM 툴체인을 사용한 **표준 애플리케이션 컨트랙트**(ERC-20, ERC-721, 에스크로, AMM). +- ethers.js를 통해 라이브 이벤트 스트림으로 Stablescan에서 **검증되고 인덱싱된 컨트랙트**. +- Solidity에서 Bank/Distribution/Staking 프리컴파일을 호출하는 **프로토콜 통합 컨트랙트**. +- 표준 `eth_getLogs`를 통해 프로토콜에서 방출된 이벤트(예: 언본딩 완료)를 감시하는 **시스템 트랜잭션 리스너**. -## Stable이 다른 점 +## Stable의 차이점 -- **USDT0가 가스 토큰입니다.** `maxPriorityFeePerGas`는 `0`이어야 합니다. 네이티브 전송의 `value` 필드는 ETH가 아닌 USDT0를 전달합니다. [USDT0를 가스로 사용하기](/ko/how-to/work-with-usdt-gas)를 참고하세요. -- **USDT0는 이중 역할을 합니다.** 네이티브 USDT0를 보유한 컨트랙트는 ERC-20 `transferFrom`이나 `permit`에 의해 잔액이 변경될 수 있으므로 — 절대 네이티브 잔액을 `uint256`에 미러링하지 마세요. [Stable에서의 USDT0 동작](/ko/explanation/usdt0-behavior)을 참고하세요. -- **프리컴파일 주소는 테스트넷과 메인넷에서 동일하게 고정되어 있습니다.** 컨트랙트에 상수로 박아 넣으세요. +- **USDT0은 가스 토큰입니다.** `maxPriorityFeePerGas`는 `0`이어야 합니다. 기본 전송의 `value` 필드는 ETH가 아닌 USDT0을 전달합니다. [가스로 USDT0 작업](/ko/how-to/work-with-usdt-gas)을 참조하세요. +- **USDT0은 이중 역할을 합니다.** 기본 USDT0을 보유하는 컨트랙트는 ERC-20 `transferFrom` 또는 `permit`에 의해 잔액이 변경될 수 있습니다. `uint256`에 기본 잔액을 미러링하지 마십시오. [Stable의 USDT0 동작](/ko/explanation/usdt0-behavior)을 참조하십시오. +- **프리컴파일 주소는 테스트넷 및 메인넷에서 고정됩니다.** 이를 상수로서 컨트랙트에 고정하십시오. -## 여기서 시작하세요 +## 시작하기 -- [**배포**](/ko/tutorial/smart-contract) — Foundry를 스캐폴딩하고, Stable을 구성하고, Counter를 배포합니다. -- [**검증**](/ko/how-to/verify-contract) — forge verify-contract로 Stablescan에 소스를 업로드합니다. -- [**인덱싱**](/ko/how-to/index-contract) — ethers.js로 이벤트를 구독하고 과거 로그를 백필합니다. +- [**배포**](/ko/tutorial/smart-contract): Foundry를 스캐폴드하고 Stable을 구성한 다음 Counter를 배포합니다. +- [**확인**](/ko/how-to/verify-contract): `forge verify-contract`를 사용하여 Stablescan에 소스를 업로드합니다. +- [**인덱스**](/ko/how-to/index-contract): ethers.js로 이벤트에 구독하고 기록 로그를 백필합니다. ## 다음 권장 사항 -- [**컨트랙트 가이드 색인**](/ko/explanation/contracts-guides) — 컨트랙트 가이드, 프리컴파일 참조, 시스템 모듈 ABI의 전체 목록. -- [**시스템 모듈 사용하기**](/ko/how-to/use-system-modules) — Solidity와 ethers.js에서 Bank / Distribution / Staking을 호출합니다. -- [**JSON-RPC 참조**](/ko/reference/json-rpc-api) — Stable이 지원하는 `eth_*` 및 `debug_*` 메서드. +- [**컨트랙트 가이드 인덱스**](/ko/explanation/contracts-guides): 컨트랙트 가이드, 프리컴파일 참조 및 시스템 모듈 ABI의 전체 목록입니다. +- [**시스템 모듈 사용**](/ko/how-to/use-system-modules): Solidity 및 ethers.js에서 Bank/Distribution/Staking을 호출합니다. +- [**JSON-RPC 참조**](/ko/reference/json-rpc-api): Stable이 지원하는 `eth_*` 및 `debug_*` 메서드입니다. diff --git a/docs/pages/ko/explanation/core-concepts.mdx b/docs/pages/ko/explanation/core-concepts.mdx index 790816f..a59e5a4 100755 --- a/docs/pages/ko/explanation/core-concepts.mdx +++ b/docs/pages/ko/explanation/core-concepts.mdx @@ -1,56 +1,56 @@ --- source_path: explanation/core-concepts.mdx -source_sha: 7400248a80aa3b8112e72c47e08229fbae84e654 +source_sha: 97f2155b7916504732f1b78674bbf3ec1909e8e2 title: "핵심 개념" -description: "빌드하기 전에 Stable의 네 가지 핵심 개념을 이해하세요: 가스로서의 USDT0, 보장된 블록 공간, 전송 집계, EVM 호환성." +description: "Stable을 구축하기 전에 USDT0를 가스로 사용, 보장된 블록 공간, 전송 집계 및 EVM 호환성이라는 Stable의 네 가지 핵심 개념을 이해하세요." diataxis: "explanation" --- # 핵심 개념 -빌드를 시작하는 데는 네 가지 개념이면 충분합니다. 각 섹션은 개념을 정의하고, 보여주며, 전체 참조 자료로 연결됩니다. +네 가지 개념만 알면 구축을 시작할 수 있습니다. 각 섹션에서는 개념을 정의하고, 이를 보여주며, 전체 참조로 연결합니다. -## 가스로서의 USDT0 +## USDT0을 가스로 사용 -여러분은 이미 보유하고 거래하고 있는 동일한 자산인 USDT0로 트랜잭션 수수료를 지불합니다. 자금을 충당하거나 관리해야 할 두 번째 토큰이 없습니다. +현재 보유하고 거래하는 자산과 동일한 USDT0로 거래 수수료를 지불합니다. 자금을 조달하거나 관리해야 할 두 번째 토큰은 없습니다. -USDT0는 네이티브 가스 자산(18자리 소수점, `address(x).balance`로 읽음)이자 ERC-20 토큰(6자리 소수점, `USDT0.balanceOf(x)`로 읽음)입니다. 두 인터페이스 모두 동일한 기본 잔액에서 작동하며, 프로토콜은 12자리 정밀도 차이를 자동으로 조정합니다. +USDT0는 기본 가스 자산(18진수, `address(x).balance`를 통해 읽음)이자 ERC-20 토큰(6진수, `USDT0.balanceOf(x)`를 통해 읽음)입니다. 두 인터페이스 모두 동일한 기본 잔액에서 작동하며, 프로토콜은 12자리 정밀도 차이를 자동으로 조정합니다. ```solidity -// Both read the same balance: +// 둘 다 동일한 잔액을 읽습니다: uint256 native = address(user).balance; // 18 decimals uint256 erc20 = IERC20(USDT0).balanceOf(user); // 6 decimals ``` :::warning -잔액 조정은 예비 주소 `0x5113954bbC0eD721F1C68671EBa3d91e9e9bF7b5`에서 추가 `Transfer` 이벤트를 발생시킵니다. `Transfer` 이벤트를 재생하는 인덱서는 이 주소로 들어오고 나가는 전송을 필터링해야 하며, 그렇지 않으면 자동으로 잔액을 이중으로 계산하게 됩니다. +잔액 조정은 예비 주소 `0x5113954bbC0eD721F1C68671EBa3d91e9e9bF7b5`에서 추가 `Transfer` 이벤트를 발생시킵니다. `Transfer` 이벤트를 재생하는 인덱서는 이 주소로의 전송을 필터링해야 합니다. 그렇지 않으면 잔액이 조용히 두 번 계산됩니다. ::: -자세히 보기: [가스로서의 USDT0](/ko/explanation/usdt-as-gas-token) · [Stable에서의 USDT0 동작](/ko/explanation/usdt0-behavior). +자세히 보기: [가스로 USDT0](/ko/explanation/usdt-as-gas-token) · [Stable에서 USDT0 동작](/ko/explanation/usdt0-behavior). ## 보장된 블록 공간 -Stable은 사전 할당된 엔터프라이즈 워크로드를 위해 각 블록 용량의 일부를 예약합니다. 예약된 트래픽은 일반 트래픽이 혼잡할 때에도 예측 가능한 지연 시간과 비용으로 정산되며, 수수료 시장에서 경쟁하지 않습니다. +Stable은 사전 할당된 기업 워크로드를 위해 각 블록 용량의 일부를 예약합니다. 예약된 트래픽은 일반 트래픽이 혼잡한 경우에도 예측 가능한 지연 시간과 비용으로 정산됩니다. 이는 수수료 시장에서 경쟁하지 않습니다. -이 동작은 호출자 수준에서 투명합니다. 여러분은 일반적인 방식으로 트랜잭션을 제출하고, 할당은 등록된 계정에 대해 프로토콜 수준에서 적용됩니다. +이 동작은 호출자 수준에서 투명합니다. 거래는 일반적인 방식으로 제출되며, 등록된 계정에 대해서는 프로토콜 수준에서 할당이 적용됩니다. 자세히 보기: [보장된 블록 공간](/ko/explanation/guaranteed-blockspace). ## USDT 전송 집계기 -대량 USDT0 전송은 MapReduce에서 영감을 받은 파이프라인을 사용하여 병렬로 일괄 처리되고 검증됩니다. 계정별 실패는 격리되므로, 하나의 잘못된 전송이 배치를 중단시키지 않습니다. +대용량 USDT0 전송은 MapReduce에서 영감을 받은 파이프라인을 사용하여 병렬로 일괄 처리되고 확인됩니다. 계정별 오류는 격리되므로 하나의 잘못된 전송이 일괄 처리를 중단시키지 않습니다. -호출자 측 전송 API는 변경되지 않습니다. 여러분은 일반적인 방식으로 전송을 제출하고 코드 변경 없이 처리량을 얻습니다. +호출자 측 전송 API는 변경되지 않습니다. 코드를 변경하지 않고도 일반적인 방식으로 전송을 제출하고 처리량을 확보할 수 있습니다. 자세히 보기: [USDT 전송 집계기](/ko/explanation/usdt-transfer-aggregator). ## EVM 호환성 -표준 EVM 도구가 변경 없이 작동합니다. EVM 수준에서 세 가지 동작이 이더리움과 다릅니다(위에서 다룬 가스로서의 USDT0가 네 번째입니다). +표준 EVM 툴링은 변경 없이 작동합니다. EVM 수준에서 세 가지 동작이 이더리움과 다릅니다(위에서 다룬 가스로서의 USDT0가 네 번째). -**단일 슬롯 완결성.** 트랜잭션은 블록에 포함되는 즉시 완결됩니다. 블록은 대략 0.7초마다 생성됩니다. +**단일 슬롯 완결성.** 거래는 블록에 포함되면 최종적입니다. 블록은 대략 0.7초마다 생성됩니다. -**우선순위 팁 없음.** `maxPriorityFeePerGas`는 항상 무시됩니다. 유효 가스 가격은 프로토콜이 설정한 기본 수수료입니다. +**우선순위 팁 없음.** `maxPriorityFeePerGas`는 항상 무시됩니다. 실제 가스 가격은 프로토콜에 의해 설정된 기본 수수료입니다. ```typescript import { ethers } from "ethers"; @@ -73,23 +73,23 @@ console.log("Included at gas price:", tx.gasPrice?.toString()); Included at gas price: 1000000000 ``` -**이중 역할 USDT0, 포팅 위험.** 이더리움에서 포팅된 컨트랙트는 네이티브 잔액을 미러링해서는 안 되며, `address(0)` 전송을 거부해야 하고, 주소 재사용 감지를 위해 `EXTCODEHASH`에 의존해서는 안 됩니다. +**이중 역할 USDT0, 포팅 위험.** 이더리움에서 포팅된 계약은 기본 잔액을 미러링해서는 안 되며, `address(0)` 전송을 거부해야 하며, 주소 재사용 감지를 위해 `EXTCODEHASH`에 의존해서는 안 됩니다. :::warning -네이티브 잔액을 내부 변수에 미러링하는 컨트랙트를 포팅하는 것은 Stable에서 안전하지 않습니다. 외부 `USDT0.transferFrom` 호출은 어떤 컨트랙트 코드도 실행하지 않고 컨트랙트의 네이티브 잔액을 고갈시킬 수 있습니다. 항상 전송 시점에 `address(this).balance`로 지급 능력을 확인하세요. +내부 변수에 기본 잔액을 미러링하는 Contract를 Stable로 포팅하는 것은 안전하지 않습니다. 외부 `USDT0.transferFrom` 호출은 Contract 코드를 호출하지 않고 Contract의 기본 잔액을 소진할 수 있습니다. 전송 시 항상 `address(this).balance`로 지급 능력을 확인하십시오. ::: -자세히 보기: [이더리움과의 차이점](/ko/explanation/ethereum-comparison) · [Stable의 컨트랙트](/ko/explanation/contracts-overview) · [USDT0 마이그레이션 체크리스트](/ko/explanation/usdt0-behavior). +더 읽어보기: [이더리움과의 차이점](/ko/explanation/ethereum-comparison) · [Stable의 계약](/ko/explanation/contracts-overview) · [USDT0 마이그레이션 체크리스트](/ko/explanation/usdt0-behavior). -## 기밀 전송 (예정) +## 기밀 전송 (계획됨) -Stable에는 금액을 숨기면서 승인된 당사자에게는 감사 가능한 상태를 유지하는 영지식 전송 기능이 예정되어 있습니다. 아직 출시되지 않았습니다. +Stable은 승인된 당사자가 감사할 수 있는 상태를 유지하면서 금액을 숨기는 영지식 전송을 위한 기능을 계획하고 있습니다. 아직 출시되지 않았습니다. -자세히 보기: [기밀 전송](/ko/explanation/confidential-transfer). +더 읽어보기: [기밀 전송](/ko/explanation/confidential-transfer). ## 다음 권장 사항 -- [**빠른 시작**](/ko/tutorial/quick-start) — 테스트넷에 연결하고 첫 트랜잭션을 전송합니다. -- [**USDT0 동작**](/ko/explanation/usdt0-behavior) — 이중 역할 함정에 빠지지 않고 컨트랙트를 Stable로 포팅합니다. -- [**가스 가격 책정**](/ko/reference/gas-pricing-api) — Stable의 수수료 모델에서 트랜잭션을 올바르게 구성합니다. -- [**프로덕션 준비**](/ko/how-to/production-readiness) — 메인넷에 배포하기 전에 통합을 검증합니다. +- [**빠른 시작**](/ko/tutorial/quick-start): 테스트넷에 연결하고 첫 번째 트랜잭션을 보냅니다. +- [**USDT0 동작**](/ko/explanation/usdt0-behavior): 이중 역할 문제 없이 계약을 Stable로 포팅합니다. +- [**가스 가격 책정**](/ko/reference/gas-pricing-api): Stable의 수수료 모델에서 트랜잭션을 올바르게 구성합니다. +- [**운영 준비 완료**](/ko/how-to/production-readiness): 메인넷에 출시하기 전에 통합을 검증합니다. diff --git a/docs/pages/ko/explanation/core-optimization-overview.mdx b/docs/pages/ko/explanation/core-optimization-overview.mdx index fe9e36d..2d66517 100755 --- a/docs/pages/ko/explanation/core-optimization-overview.mdx +++ b/docs/pages/ko/explanation/core-optimization-overview.mdx @@ -1,22 +1,30 @@ --- source_path: explanation/core-optimization-overview.mdx -source_sha: 64589b294e0b6057b4feb1811f4e81864d52dab7 +source_sha: 29de6d48ee5097a621ab02f579847af6d068dc9d title: "개요" -description: "합의, 실행, 데이터베이스, RPC 계층을 아우르는 Stable의 전 스택 최적화 접근법 소개." +description: "합의, 실행, 데이터베이스 및 RPC 레이어를 다루는 Stable의 전체 스택 최적화 소개." +diataxis: "explanation" --- # 개요 -## 풀스택 코어 최적화 +## 전체 스택 핵심 최적화 Blockchain Transaction Lifecycle -제출부터 결과 완결까지 블록체인 트랜잭션의 라이프사이클은, 강하게 연결된 여러 단계로 구성되어 있습니다. 트랜잭션은 **RPC** 인터페이스를 통해 제출되어, **멤풀**에 추가되고, 블록에 포함되며, **합의**를 통해 검증되고, **상태 머신**에 의해 실행되며, **데이터베이스**에 최종 저장됩니다. 전체 파이프라인을 모두 완료한 이후에야 사용자는 확정된 결과를 받을 수 있습니다. +블록체인 트랜잭션의 라이프사이클은 제출부터 최종 결과까지 여러 밀접하게 연결된 단계를 거칩니다. 트랜잭션은 먼저 **RPC** 인터페이스를 통해 제출되고, **mempool**에 추가되며, 블록으로 패키징되고, **합의**를 통해 검증되고, **상태 머신**에 의해 실행되며, 마지막으로 **데이터베이스**의 영구 저장소에 기록됩니다. 이 전체 파이프라인을 완료한 후에야 사용자는 확인된 결과를 받습니다. -단 하나의 단계만 개선하는 것으로는 충분하지 않습니다. 파이프라인 내 비효율적인 부분이 하나라도 존재한다면, 이는 전체 시스템의 성능에 악영향을 줄 수 있습니다. Stable이 블록체인 스택 전체를 최적화하는 데에 집중하는 이유입니다. +한 단계만 개선하는 것으로는 충분하지 않습니다. 파이프라인의 비효율성은 시스템 전체 성능에 영향을 미칠 수 있습니다. 이것이 바로 Stable이 블록체인 스택을 처음부터 끝까지 최적화하는 데 중점을 두는 이유입니다. -전체 네트워크에 걸쳐 Stable이 합의, 실행, 데이터베이스, RPC를 포함한 전체 스택 내 각 레이어를 어떻게 최적화하여 신뢰성 있고 고성능의 트랜잭션 처리를 가능하게 하는지 알고 싶으시다면, 다음 페이지들을 읽어보세요. \ No newline at end of file +다음 페이지에서는 Stable이 안정적이고 고성능의 트랜잭션 처리를 보장하기 위해 아키텍처의 각 레이어(합의, 실행, 데이터베이스 및 RPC)를 어떻게 업그레이드하는지 설명합니다. + +## 다음 권장 + +- [**합의**](/ko/explanation/consensus): StableBFT가 높은 처리량과 낮은 지연 시간을 위해 CometBFT를 어떻게 확장하는지 알아보세요. +- [**실행**](/ko/explanation/execution): Stable EVM이 Block-STM 및 낙관적 블록 처리를 통해 트랜잭션을 병렬로 실행하는 방법을 살펴보세요. +- [**저장소 (StableDB)**](/ko/explanation/stable-db): 분리된 상태 커밋과 메모리 매핑된 저장소가 디스크 I/O 병목 현상을 어떻게 제거하는지 이해하세요. +- [**고성능 RPC**](/ko/explanation/high-performance-rpc): 읽기 및 쓰기를 분리하는 분할 경로 RPC 아키텍처를 이해하세요. diff --git a/docs/pages/ko/explanation/distribution-module.mdx b/docs/pages/ko/explanation/distribution-module.mdx index 4c5bf51..a4e3eda 100755 --- a/docs/pages/ko/explanation/distribution-module.mdx +++ b/docs/pages/ko/explanation/distribution-module.mdx @@ -1,311 +1,38 @@ --- source_path: explanation/distribution-module.mdx -source_sha: 704e0b6d878ca629ffa66f024070c339d066eca1 -title: Distribution -description: "EVM 환경에서 수수료 수집 및 보상 인출을 위한 x/distribution 연결 Distribution 프리컴파일." +source_sha: b4b638cbe7c29d11dc0a29398fd8c1280d898d93 +title: "분배 모듈" +description: "분배 사전 컴파일은 스테이킹 보상(인출 주소, 보상 쿼리 및 수수료 관리)을 EVM 계약에 제공합니다." +diataxis: "explanation" --- -# Distribution +# 분배 모듈 -## 개요 +`x/distribution` 모듈은 위임자와 검증자를 위한 스테이킹 보상 누적 및 인출을 처리합니다. 사전 컴파일은 이 동작을 EVM으로 연결하여 Solidity 계약이 Cosmos SDK와 직접 상호 작용하지 않고도 보상을 청구하고, 인출 주소를 설정하고, 미지급 보상을 쿼리할 수 있도록 합니다. -`distribution` precompile 컨트랙트는 Stable SDK의 `x/distribution` 모듈 기능을 EVM 환경에서 사용할 수 있도록 브리지 역할을 합니다. +## 노출되는 기능 -## 목차 +- **인출 주소 설정**: 위임자는 보상을 받을 주소를 지정합니다. 기본적으로 보상은 위임자 자신의 주소로 전달됩니다. 인출 주소를 설정하면 다른 곳으로 라우팅됩니다(계약 관리 스테이킹에 유용). +- **위임자 보상 인출**: 단일 호출로 단일 검증자로부터 모든 미지급 보상을 청구합니다. +- **검증자 수수료 인출**: 검증자는 위임자의 보상에서 누적된 수수료를 청구합니다. +- **쿼리 메서드**: 거래 없이 보상 잔액, 수수료율 및 커뮤니티 풀 상태를 읽습니다. -1. **[개념](#개념)** -2. **[구성](#구성)** -3. **[메서드](#메서드)** -4. **[이벤트](#이벤트)** +## 권한 의미론 -## 개념 +사전 컴파일은 호출자가 상태가 수정되는 위임자(또는 검증자)인지 확인합니다. 다른 사람의 보상을 청구하거나 인출 주소를 변경할 수 없습니다. -`distribution` precompile 컨트랙트에서는 위임자 또는 예치자가 호출자인지 확인하는 추가 검사가 수행됩니다. +## 언제 사용해야 하는가 -## 구성 +- 금고 또는 스테이킹 애그리게이터가 일정에 따라 보상을 청구합니다: `withdrawDelegatorRewards`를 직접 호출합니다. +- DAO가 스테이킹 보상을 재무 주소로 라우팅합니다: 인출 주소를 한 번 설정하면 보상이 자동으로 흐릅니다. +- 프런트엔드가 현재 보상 잔액을 표시합니다: 쿼리 메서드를 사용합니다(거래 필요 없음). -컨트랙트 주소와 가스 비용은 사전 정의되어 있습니다. +## ABI를 찾는 방법 -### 컨트랙트 주소 +전체 메서드 시그니처, 입력/출력 유형 및 방출된 이벤트는 [분배 사전 컴파일 참조](/ko/reference/distribution-module-api)에 있습니다. -- `0x0000000000000000000000000000000000000801` +## 다음 권장 사항 -## 메서드 - -### `setWithdrawAddress` - -위임자가 검증자에게 위임한 토큰에 대한 rewards를 받을 주소를 설정합니다. -때로는 위임자가 자기 위임(self-delegated)일 때 검증자 주소가 위임자로 사용됩니다. - -`SetWithdrawAddress`는 출금 주소가 성공적으로 설정되었을 때 발생합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|delegatorAddress|address|위임자의 주소| -|withdrawerAddress|address|위임에 대한 rewards를 받을 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|success|bool|출금 주소가 성공적으로 설정되면 true| - -### `withdrawDelegatorRewards` - -검증자로부터 위임자가 받을 rewards를 출금합니다. -검증자가 위임자에게 지급하는 모든 유형의 토큰이 단일 트랜잭션으로 출금됩니다. - -`WithdrawDelegatorRewards`는 rewards가 성공적으로 출금되었을 때 발생합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|delegatorAddress|address|위임자의 주소| -|validatorAddress|address|검증자의 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|amount|Coin[]|위임자가 받을 다양한 토큰의 rewards| - -`Coin`은 다음 필드를 가진 구조체입니다: - -|이름|타입|설명| -|---|---|---| -|denom|string|reward의 denom| -|amount|uint256|reward의 수량| - -### `withdrawValidatorCommission` - -검증자의 수수료를 출금합니다. -검증자가 수수료로 받는 모든 유형의 토큰이 단일 트랜잭션으로 출금됩니다. - -`WithdrawValidatorCommission`은 수수료가 성공적으로 출금되었을 때 발생합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|validatorAddress|address|검증자의 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|amount|Coin[]|검증자가 받을 다양한 토큰의 수수료| - -### `validatorDistributionInfo` - -검증자가 받을 reward를 나타내는 분배 정보를 반환합니다. 검증자는 자신의 주소로 토큰을 위임하여 자기 결합(self-bonded)이라고 하는 위임자 역할을 할 수 있습니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|validatorAddress|address|검증자의 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|distributionInfo|ValidatorDistributionInfo|검증자의 분배 정보| - -`ValidatorDistributionInfo`는 다음 필드를 가진 구조체입니다: - -|이름|타입|설명| -|---|---|---| -|operatorAddress|address|검증자의 운영자 주소| -|selfBondRewards|DecCoin[]|검증자의 자기 결합 수량| -|commission|DecCoin[]|검증자의 수수료| - -`DecCoin`은 다음 필드를 가진 구조체입니다: - -|이름|타입|설명| -|---|---|---| -|denom|string|reward의 denom| -|amount|uint256|reward의 수량| -|precision|uint8|reward의 정밀도| - -### `validatorOutstandingRewards` - -검증자의 미지급 rewards를 반환합니다. 미지급 rewards는 검증자의 수수료와 자기 결합 rewards, 그리고 위임자들의 총 rewards로 구성된 총 reward 금액을 나타냅니다. 검증자 A가 있고 위임자 B, C, D가 A에게 위임하는 경우, 검증자의 미지급 rewards는 A의 수수료와 자기 결합 rewards + B, C, D의 rewards의 합계입니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|validatorAddress|address|검증자의 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|rewards|DecCoin[]|검증자의 미지급 rewards| - -### `validatorCommission` - -검증자의 수수료를 반환합니다. 이 메서드는 `withdrawValidatorCommission` 메서드를 호출하기 전에 검증자의 수수료를 조회하는 데 사용됩니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|validatorAddress|address|검증자의 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|commission|DecCoin[]|검증자의 수수료| - -### `validatorSlashes` - -시작 높이와 종료 높이 사이에 검증자의 슬래시 이력을 반환합니다. 슬래싱은 검증자가 악의적으로 행동하거나 이중 서명, 잘못된 행동, 체인 규칙을 따르지 않는 등의 네트워크 규칙을 위반했을 때 부과되는 벌금입니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|validatorAddress|address|검증자의 주소| -|startingHeight|uint64|시작 높이 -|endingHeight|uint64|종료 높이 -|pageRequest|PageReq|페이지네이션 요청| - -`PageReq`는 다음 필드를 가진 구조체입니다: - -|이름|타입|설명| -|---|---|---| -|key|bytes|페이지네이션의 키| -|offset|uint64|페이지네이션의 오프셋| -|limit|uint64|페이지네이션의 제한| -|countTotal|bool|총 페이지 수를 계산할지 여부| -|reverse|bool|페이지네이션을 역순으로 할지 여부| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|slashes|ValidatorSlashEvent[]|검증자의 슬래시| -|pagination|PageResp|페이지네이션 응답 - -`ValidatorSlashEvent`는 다음 필드를 가진 구조체입니다: - -|이름|타입|설명| -|---|---|---| -|validatorPeriod|uint64|검증자의 기간| -|fraction|Dec|슬래시의 비율| - -`Dec`은 다음 필드를 가진 구조체입니다: - -|이름|타입|설명| -|---|---|---| -|value|uint64|Dec의 값| -|precision|uint8|Dec의 정밀도| - -`PageResp`는 다음 필드를 가진 구조체입니다: - -|이름|타입|설명| -|---|---|---| -|nextKey|bytes|페이지네이션의 다음 키| -|total|uint64|총 페이지 수| - -### `delegationRewards` - -위임자가 검증자로부터 받는 rewards를 반환합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|delegatorAddress|address|위임자의 hex 주소| -|validatorAddress|address|검증자의 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|rewards|DecCoin[]|위임자가 검증자로부터 받는 rewards| - -### `delegationTotalRewards` - -위임자가 모든 검증자로부터 받는 총 rewards를 반환합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|delegatorAddress|address|위임자의 hex 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|rewards|DelegationDelegatorReward[]|위임자가 모든 검증자로부터 받는 총 rewards| -|total|DecCoin[]|rewards의 총 수량| - -`DelegationDelegatorReward`는 다음 필드를 가진 구조체입니다: - -|이름|타입|설명| -|---|---|---| -|validatorAddress|address|검증자의 주소| -|reward|DecCoin[]|위임자가 검증자로부터 받는 rewards| - -### `delegatorValidators` - -위임자가 결합된 검증자들을 반환합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|delegatorAddress|address|위임자의 hex 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|validators|string[]|위임자가 결합된 검증자들| - -### `delegatorWithdrawAddress` - -`setWithdrawAddress` 메서드로 설정한 위임 rewards를 받을 주소를 반환합니다. - -#### 입력 - -|이름|타입|설명| -|---|---|---| -|delegatorAddress|address|위임자의 hex 주소| - -#### 출력 - -|이름|타입|설명| -|---|---|---| -|withdrawAddress|address|위임 rewards를 받을 주소| - -## 이벤트 - -### SetWithdrawAddress - -|이름|타입|인덱스|설명| -|---|---|---|---| -|caller|address|Y|호출자(위임자)의 주소| -|withdrawAddress|address|N|위임 rewards를 받을 주소| - -### WithdrawDelegatorRewards - -|이름|타입|인덱스|설명| -|---|---|---|---| -|delegatorAddress|address|Y|위임자의 주소| -|validatorAddress|address|Y|검증자의 주소| -|amount|uint256|N|reward의 수량| - -### WithdrawValidatorCommission - -|이름|타입|인덱스|설명| -|---|---|---|---| -|validatorAddress|address|Y|검증자의 주소| -|commission|uint256|N|수수료의 총 수량| +- [**분배 사전 컴파일 참조**](/ko/reference/distribution-module-api): `withdrawDelegatorRewards`를 호출하고, 인출 주소를 설정하고, 보상 잔액을 읽습니다. +- [**스테이킹 모듈**](/ko/explanation/staking-module): 위임(이러한 보상의 원천)이 어떻게 작동하는지 확인합니다. +- [**시스템 트랜잭션**](/ko/explanation/system-transactions): 언본딩 완료가 이벤트로 EVM에 도달하는 방법을 알아봅니다. diff --git a/docs/pages/ko/explanation/eip-7702.mdx b/docs/pages/ko/explanation/eip-7702.mdx index 1695090..a1ca0b5 100755 --- a/docs/pages/ko/explanation/eip-7702.mdx +++ b/docs/pages/ko/explanation/eip-7702.mdx @@ -1,21 +1,53 @@ --- source_path: explanation/eip-7702.mdx -source_sha: 0abc92a6ce7f1df42ce8f247d3a7cccab8819f6d -title: EIP-7702 -description: "EOA가 스마트 계정처럼 임시 작동할 수 있게 하는 EIP-7702 지원과 개발자 영향." +source_sha: 599d3ed0fdc99452166ebb51a8d74932622954f6 +title: "EIP-7702" +description: "새로운 계정 또는 지갑 마이그레이션이 필요 없는 EOA를 위한 일괄 결제, 지출 한도 및 세션 키." +diataxis: "explanation" --- # EIP-7702 -Stable은 **EIP-7702**를 지원하여 EOA(외부 소유 계정)가 임시로 스마트 계정처럼 작동할 수 있는 통합 계정 모델을 도입합니다. +Stable은 **EIP-7702**를 지원하며, 이를 통해 EOA는 **자신의 계정 코드를 기존 스마트 계약으로 설정**할 수 있습니다. EOA는 원래 주소와 개인 키를 유지하면서 해당 계약의 로직을 실행합니다. 위임은 EOA가 명시적으로 변경하거나 지울 때까지 지속됩니다. -**주요 동작:** +전체 사양은 [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)를 참조하세요. -- 사용자는 기존 키로 트랜잭션에 서명합니다 -- 영구적인 계정 업그레이드 없이 컨트랙트와 같은 로직을 실행에 통합할 수 있습니다 -- 결제 및 수탁을 위한 안전한 승인 흐름을 가능하게 합니다 -- USDT를 사용하는 지갑과 가맹점의 UX를 개선합니다 +## EIP-7702가 Stable에서 가능하게 하는 것 -개발자에게 미치는 영향: +EIP-7702를 통해 기존 EOA는 계정 마이그레이션 없이 스마트 계약 로직을 실행할 수 있습니다. Stable의 USDT 중심 결제 환경에서 이는 다음과 같은 패턴을 지원합니다. -- 사용자는 새로운 컨트랙트를 배포하지 않고도 컨트랙트급 기능을 획득하여 온보딩 마찰을 줄이고 수탁을 단순화합니다. +- **일괄 결제**: 여러 호출(예: 급여 지급 시 여러 수신자에게 지급)이 단일 원자 트랜잭션으로 실행됩니다. +- **지출 한도**: 위임 계약은 EOA에 대한 일일 한도 또는 트랜잭션당 한도를 강제합니다. +- **세션 키**: EOA는 소유자의 개인 키를 노출하지 않고 dApp에 범위가 지정되고 시간 제한된 트랜잭션 권한을 부여합니다. + +:::note +**구현 준비가 되셨나요?** 계약 템플릿, 권한 부여 서명 및 트랜잭션 제출에 대한 [계정 추상화(EIP-7702) 구현 가이드](/ko/reference/eip-7702-api)를 참조하세요. +::: + +## 작동 방식 + +EIP-7702는 `authorizationList`를 포함하는 새로운 트랜잭션 유형(`0x04`)을 도입합니다. 각 권한 부여는 EOA가 해당 트랜잭션에 대해 실행할 코드인 스마트 계약을 지정합니다. 흐름은 다음과 같습니다. + +1. **위임 계약 선택 또는 배포**: EOA가 실행하려는 로직을 구현하는 표준 솔리디티 계약입니다. 기존의 배포된 계약을 사용하거나 직접 배포할 수 있습니다. 가능하면 감사된 계약을 사용하세요. +2. **권한 부여 서명**: EOA 소유자가 위임 계약을 지정하는 메시지에 서명합니다. +3. **EIP-7702 트랜잭션 제출**: 트랜잭션에는 권한 부여가 포함되며, EOA는 실행 중에 위임자의 코드를 실행합니다. + +제출 후 EOA의 계정 코드는 위임자로 설정됩니다. 소유자가 위임을 지우거나 교체할 때까지 EOA에 대한 후속 트랜잭션은 위임자의 로직을 실행합니다. + +## 변경되지 않는 사항 + +- **새로운 계정 필요 없음**: 사용자는 기존 EOA 주소와 개인 키를 유지합니다. 마이그레이션 단계는 없습니다. +- **기존 키는 여전히 서명**: EOA의 개인 키는 권한 부여 및 모든 후속 트랜잭션에 서명합니다. EIP-7702는 새로운 서명 체계를 도입하지 않습니다. +- **표준 EVM 실행**: 위임자는 일반 계약 코드처럼 실행됩니다. 계약 실행을 디버그하거나 추적하는 도구는 변경 없이 작동합니다. + +## 보안 고려 사항 + +- **위임자 접근은 전면적입니다.** 위임 계약은 위임 기간 동안 EOA에 대한 완전한 실행 권한을 가집니다. 위임자 선택을 신뢰 결정으로 다루세요. 악의적인 위임자는 자산을 고갈시킬 수 있습니다. +- **위임은 지속됩니다.** 단일 트랜잭션으로 만료되지 않습니다. 소유자는 더 이상 원하지 않을 때 위임을 명시적으로 지우거나 교체해야 합니다. +- **가스 비용은 약간 높습니다.** 권한 부여 처리로 인해 약간 높지만, 위임자가 여러 호출을 일괄 처리할 때 상쇄됩니다. 기본 수수료가 1 gwei이고 가스가 USDT0으로 표시되는 Stable에서는 추가 권한 부여 오버헤드가 1센트 미만으로 유지되며, 비용 면에서 표준 ERC-20 전송과 비슷합니다. + +## 다음 권장 사항 + +- [**계정 추상화(EIP-7702)**](/ko/reference/eip-7702-api): 위임 계약에 대해 일괄 결제, 지출 한도 및 세션 키를 구현하세요. +- [**가스 토큰으로서의 USDT**](/ko/explanation/usdt-as-gas-token): EIP-7702 트랜잭션이 실행되는 가스 모델을 이해하세요. +- [**가스 면제**](/ko/explanation/gas-waiver): 위임을 애플리케이션이 사용자 가스를 대신 지불하는 가스 면제 흐름과 비교하세요. diff --git a/docs/pages/ko/explanation/erc-3009.mdx b/docs/pages/ko/explanation/erc-3009.mdx index 0ce8cfe..0d935b6 100644 --- a/docs/pages/ko/explanation/erc-3009.mdx +++ b/docs/pages/ko/explanation/erc-3009.mdx @@ -1,98 +1,98 @@ --- source_path: explanation/erc-3009.mdx -source_sha: a3574e36ec8a922102e44d799c5aedbe2d3cb53c -title: "서명된 인가로 정산하기" -description: "ERC-3009는 토큰 보유자가 컨트랙트를 직접 호출하지 않고 메시지에 서명하여 전송을 인가할 수 있게 합니다. Stable에서 x402 결제를 뒷받침하는 정산 메커니즘입니다." +source_sha: 355aa51b2e83bc01b1345eb0ec5d437956854d01 +title: "서명된 승인으로 정산" +description: "직접적인 계약 호출 없이 메시지 서명을 통해 토큰 이체를 승인합니다. ERC-3009는 Stable의 x402 결제 뒤에 있는 정산 메커니즘입니다." diataxis: "explanation" --- -# 서명된 인가로 정산하기 +# 서명된 승인으로 정산 -ERC-3009는 토큰 보유자가 메시지에 서명하여 전송을 인가할 수 있게 합니다. 그러면 누구든지 그 서명된 인가를 제출하여 온체인에서 전송을 실행할 수 있습니다. 송신자는 컨트랙트를 직접 호출할 필요가 전혀 없습니다. +ERC-3009는 토큰 보유자가 메시지에 서명하여 이체를 승인할 수 있도록 합니다. 그러면 누구나 서명된 승인을 제출하여 온체인으로 이체를 실행할 수 있습니다. 발신자는 계약을 직접 호출할 필요가 없습니다. -이것은 Stable에서 [x402](/ko/explanation/x402) 결제를 뒷받침하는 정산 메커니즘입니다. +이는 Stable의 [x4402](/ko/explanation/x402) 결제 뒤에 있는 정산 메커니즘입니다. ## 어떤 문제를 해결하나요? -### 허용량(allowance) 문제 +### 허용 문제 -제3자 전송을 위한 전통적인 ERC-20 패턴은 `approve` + `transferFrom`입니다. 송신자는 먼저 `approve`를 호출하여 지출 허용량을 부여한 다음, 제3자가 `transferFrom`을 호출하여 자금을 옮깁니다. 여기에는 잘 알려진 문제들이 있습니다: +서드파티 이체를 위한 기존 ERC-20 패턴은 `approve` + `transferFrom`입니다. 발신자는 먼저 `approve`를 호출하여 사용 허가를 부여한 다음, 서드파티가 `transferFrom`을 호출하여 자금을 이동합니다. 여기에는 잘 알려진 문제가 있습니다. -- **두 개의 트랜잭션 필요**: 송신자는 어떤 전송이 일어나기 전에 먼저 온체인 `approve` 트랜잭션을 보내야 합니다. 이는 가스 비용이 들고 지연이 추가됩니다. -- **무한 허용량 위험**: 반복적인 승인 트랜잭션을 피하기 위해 많은 애플리케이션이 무제한 지출 권한을 요청하며, 이는 심각한 보안 위험을 만듭니다. +- **두 번의 트랜잭션 필요**: 이체가 발생하기 전에 발신자는 온체인 `approve` 트랜잭션을 보내야 합니다. 이는 가스를 소모하고 지연 시간을 추가합니다. +- **무한 허용 위험**: 반복적인 승인 트랜잭션을 피하기 위해 많은 애플리케이션은 무제한 사용 권한을 요청하여 상당한 보안 위험을 발생시킵니다. -ERC-3009는 다른 접근 방식을 취합니다. 허용량을 부여하는 대신, 송신자는 특정 전송에 대한 일회성 인가에 서명합니다. 별도의 승인 단계도, 남아있는 지출 권한도 없습니다. +ERC-3009는 다른 접근 방식을 취합니다. 허용을 부여하는 대신 발신자는 특정 이체에 대한 일회성 승인에 서명합니다. 별도의 승인 단계도 없고, 남아있는 사용 권한도 없습니다. -### 순차 nonce 문제 +### 순차 논스 문제 -ERC-2612(`permit`) 역시 서명된 인가를 가능하게 하지만, 순차 nonce를 사용합니다. 여러 permit는 순서 의존성을 가집니다: nonce 5가 소비되지 않으면, nonce 6은 절대 실행될 수 없습니다. +ERC-2612(`permit`)도 서명된 승인을 가능하게 하지만, 순차 논스를 사용합니다. 여러 허가(permit)는 순서 종속성을 가집니다. 논스 5가 소비되지 않으면 논스 6은 절대 실행될 수 없습니다. -ERC-3009는 이를 **고유 nonce**로 해결합니다. 각 인가는 순차 카운터 대신 32바이트 값을 사용합니다. 여러 인가가 서로 의존하지 않고, 어떤 순서로든 독립적으로 생성되고 제출될 수 있습니다. +ERC-3009는 **고유 논스**로 이 문제를 해결합니다. 각 승인은 순차 카운터 대신 32바이트 값을 사용합니다. 여러 승인을 서로 독립적으로, 어떤 순서로든 생성하고 제출할 수 있습니다. ### 비교 | **속성** | **ERC-20** (`approve`) | **ERC-2612** (`permit`) | **ERC-3009** | | :--- | :--- | :--- | :--- | | 온체인 단계 | 2 (`approve` + `transferFrom`) | 1 (`transferFrom`) | 1 (`transferWithAuthorization`) | -| 허용량 모델 사용 | 필요 (온체인 tx) | 예 (`permit`을 통해 허용량 설정) | 불필요 (서명) | -| Nonce 모델 | 순차 | 순차 | 고유 | -| 동시 인가 | 아니오 | 아니오 | 예 | +| 허용 모델 사용 | 필요 (온체인 트랜잭션) | 예 (`permit`을 통해 허용 설정) | 필요 없음 (서명) | +| 논스 모델 | 순차 | 순차 | 고유 | +| 동시 승인 | 아니요 | 아니요 | 예 | ## 작동 방식 ### transferWithAuthorization -송신자는 전송 세부 정보를 담은 EIP-712 타입 데이터 메시지에 서명합니다. 그러면 누구든지 그 서명된 메시지로 토큰 컨트랙트의 `transferWithAuthorization`를 호출할 수 있습니다. 컨트랙트는 서명을 검증하고, 유효 기간을 확인하고, 전송을 실행하고, nonce를 사용됨으로 표시합니다. +발신자는 이체 세부 정보를 포함하는 EIP-712 형식의 데이터 메시지에 서명합니다. 그러면 누구나 해당 서명된 메시지로 토큰 컨트랙트에서 `transferWithAuthorization`을 호출할 수 있습니다. 컨트랙트는 서명을 확인하고, 유효 기간을 확인하며, 이체를 실행하고, 논스를 사용된 것으로 표시합니다. -서명된 인가에는 다음이 포함됩니다: +서명된 승인에는 다음이 포함됩니다. -- `from`: 송신자(서명자)의 주소 +- `from`: 발신자(서명자)의 주소 - `to`: 수신자의 주소 -- `value`: 전송 금액 -- `validAfter`: 이 인가가 실행될 수 있는 가장 이른 시점 (Unix 타임스탬프) -- `validBefore`: 이 인가가 실행될 수 있는 가장 늦은 시점 (Unix 타임스탬프) +- `value`: 이체 금액 +- `validAfter`: 이 승인을 실행할 수 있는 가장 이른 시간 (Unix 타임스탬프) +- `validBefore`: 이 승인을 실행할 수 있는 가장 늦은 시간 (Unix 타임스탬프) - `nonce`: 고유성을 보장하는 32바이트 값 -시간 기간(`validAfter`/`validBefore`)은 송신자에게 전송이 언제 일어날 수 있는지에 대한 정밀한 제어권을 줍니다. 인가는 미래로 예약하거나, 마감 기한을 정하거나, 둘 다 할 수 있습니다. 제출 전에 기간이 만료되면 인가는 무효가 되고 자금은 송신자에게 남습니다. +시간 창(`validAfter`/`validBefore`)을 통해 발신자는 이체가 발생할 수 있는 시점을 정확하게 제어할 수 있습니다. 승인을 미래로 예약하거나, 마감일을 정하거나, 이 둘 다를 수행할 수 있습니다. 제출 전에 창이 만료되면 승인은 유효하지 않게 되며 자금은 발신자에게 남아 있습니다. ### receiveWithAuthorization -이 함수는 `transferWithAuthorization`와 동일하게 작동하지만, 한 가지 추가 검사가 있습니다: **호출자는 반드시 수신자여야 합니다**. 이는 제3자가 대기 중인 인가를 관찰하고 먼저 제출하여 트랜잭션 순서를 조작하는 프런트러닝 공격을 방지합니다. +이 함수는 `transferWithAuthorization`과 동일하게 작동하지만, 한 가지 추가 확인이 있습니다. **호출자는 수신자여야 합니다**. 이는 서드파티가 보류 중인 승인을 관찰하고 먼저 제출하여 트랜잭션 순서를 조작하는 선행 공격을 방지합니다. -이는 수신자(가맹점 또는 서비스 제공자)가 정산을 개시하는 주체여야 하는 결제 시나리오에서 유용합니다. +이것은 수신자(판매자 또는 서비스 제공업체)가 정산을 시작해야 하는 결제 시나리오에서 유용합니다. ### cancelAuthorization -송신자는 사용되지 않은 인가가 실행되기 전에 이를 취소할 수 있습니다. 송신자가 EIP-712 취소 메시지에 서명하면, 컨트랙트는 전송을 실행하지 않고 nonce를 사용됨으로 표시합니다. 원래의 인가는 더 이상 제출될 수 없습니다. +발신자는 실행되기 전에 사용되지 않은 승인을 철회할 수 있습니다. 발신자는 EIP-712 취소 메시지에 서명하고, 컨트랙트는 이체를 실행하지 않고 논스를 사용된 것으로 표시합니다. 원래 승인은 더 이상 제출될 수 없습니다. ## 내장된 안전 속성 -- **일회성 사용**: 각 고유 nonce는 한 번만 사용할 수 있습니다. 동일한 서명된 인가를 다시 제출하면 되돌려집니다(revert). -- **시간 제한**: `validAfter`/`validBefore` 기간은 인가가 무기한 유효하게 남지 않도록 보장합니다. -- **자기 완결성**: 하나의 서명은 하나의 특정 수신자에게 하나의 특정 금액에 대한 하나의 특정 전송을 인가합니다. 남아있는 권한이 없습니다. -- **비수탁(Non-custodial)**: 제출자는 송신자의 자금을 절대 보유하지 않습니다. 전송은 컨트랙트 내에서 송신자로부터 수신자에게 직접 이동합니다. +- **일회성 사용**: 각 고유 논스는 한 번만 사용할 수 있습니다. 동일한 서명된 승인을 다시 제출하면 되돌려집니다. +- **시간 제한**: `validAfter`/`validBefore` 창은 승인이 무기한 유효하지 않도록 보장합니다. +- **자율성**: 하나의 서명은 하나의 특정 수신자에게 특정 금액의 하나의 특정 이체를 승인합니다. 남아있는 권한이 없습니다. +- **비수탁**: 제출자는 발신자의 자금을 절대 보유하지 않습니다. 이체는 컨트랙트 내에서 발신자에서 수신자로 직접 이동합니다. -## Stable에서의 ERC-3009 +## Stable의 ERC-3009 -Stable의 USDT0는 ERC-3009를 기본적으로 구현합니다. 어떤 애플리케이션이든 추가 컨트랙트나 릴레이 인프라를 배포하지 않고도 `transferWithAuthorization`를 사용할 수 있습니다. +Stable의 USDT0은 ERC-3009를 기본적으로 구현합니다. 어떤 애플리케이션이든 추가 컨트랙트나 릴레이 인프라를 배포할 필요 없이 `transferWithAuthorization`을 사용할 수 있습니다. ### 단일 자산 정산 -이더리움에서는 ERC-3009를 사용하더라도 제출자가 `transferWithAuthorization`를 호출하는 가스를 지불하기 위해 ETH가 필요합니다. 전송 자체는 USDT이지만, 실행은 별도의 네이티브 자산에 의존합니다. +이더리움에서는 ERC-3009를 사용하더라도 제출자는 `transferWithAuthorization`을 호출하기 위해 가스를 지불할 ETH가 필요합니다. 이체 자체는 USDT로 이루어지지만, 실행은 별도의 기본 자산에 의존합니다. -Stable에서는 USDT0가 결제 토큰이자 가스 토큰 역할을 동시에 합니다. 인가부터 온체인 정산까지 전체 결제 라이프사이클이 단일 스테이블코인 위에서 실행됩니다. 어떤 단계에서도 별도의 네이티브 자산이 필요하지 않습니다. +Stable에서는 USDT0이 결제 토큰과 가스 토큰 역할을 모두 합니다. 승인부터 온체인 정산까지 전체 결제 수명 주기가 단일 스테이블코인으로 실행됩니다. 어떤 단계에서도 별도의 기본 자산이 필요하지 않습니다. -이 속성이 바로 Stable에서의 ERC-3009를 상위 수준 결제 프로토콜을 위한 강력한 기반으로 만드는 요소입니다. [x402](/ko/explanation/x402)는 이를 직접 활용하여, 표준 HTTP 통신 내에서 ERC-3009를 온체인 정산 메커니즘으로 사용합니다. +이러한 특성 덕분에 Stable의 ERC-3009는 고수준 결제 프로토콜의 강력한 기반이 됩니다. [x402](/ko/explanation/x402)는 이를 직접 활용하여, 표준 HTTP 통신 내에서 ERC-3009를 온체인 정산 메커니즘으로 사용합니다. -## 핵심 요약 +## 핵심 요점 -- ERC-3009는 토큰 보유자가 메시지에 서명하여 전송을 인가할 수 있게 합니다. 누구든지 그 서명된 인가를 제출하여 전송을 실행할 수 있습니다. -- 이는 ERC-20 허용량 모델을 일회성 사용, 자기 완결적 인가로 대체합니다. `approve` 단계도, 남아있는 권한도, 이중 지출 위험도 없습니다. -- 고유 nonce는 여러 인가가 어떤 순서로든 동시에 생성되고 제출될 수 있게 합니다. -- Stable의 USDT0는 ERC-3009를 기본적으로 지원하며, USDT0만으로 정산을 완료할 수 있기 때문에 x402를 위한 실용적인 기반을 제공합니다. +- ERC-3009는 토큰 보유자가 메시지에 서명하여 이체를 승인할 수 있도록 합니다. 누구나 서명된 승인을 제출하여 이체를 실행할 수 있습니다. +- 이는 ERC-20 허용 모델을 일회성, 자율적 승인으로 대체합니다. `approve` 단계도, 남아있는 권한도, 이중 지불 위험도 없습니다. +- 고유 논스는 여러 승인을 어떤 순서로든 동시에 생성하고 제출할 수 있도록 합니다. +- Stable의 USDT0은 ERC-3009를 기본적으로 지원하며, USDT0만으로 정산을 완료할 수 있으므로 x402의 실용적인 기반을 제공합니다. -**함께 보기:** +**참고:** -- [가스로서의 USDT](/ko/explanation/usdt-as-gas-token) -- [Stable에서의 USDT0 동작](/ko/explanation/usdt0-behavior) -- [x402 (HTTP 네이티브 결제)](/ko/explanation/x402) +- [가스 토큰으로서의 USDT](/ko/explanation/usdt-as-gas-token) +- [Stable에서의 USDT0 동작 방식](/ko/explanation/usdt0-behavior) +- [x402 (HTTP-원시 결제)](/ko/explanation/x402) diff --git a/docs/pages/ko/explanation/ethereum-comparison.mdx b/docs/pages/ko/explanation/ethereum-comparison.mdx index ff364f8..3a826fc 100644 --- a/docs/pages/ko/explanation/ethereum-comparison.mdx +++ b/docs/pages/ko/explanation/ethereum-comparison.mdx @@ -1,81 +1,81 @@ --- source_path: explanation/ethereum-comparison.mdx -source_sha: 725ca9815a4f258f89945ec7c668c9729a1652c8 -title: "Ethereum 비교" -description: "Stable은 완전히 EVM과 호환됩니다. Ethereum에서 포팅할 때 동일하게 유지되는 것, 변경되는 것, 그리고 주의해야 할 점을 설명합니다." +source_sha: 899ef035bfd583ce5d1f14916e2dbd9df613a7bb +title: "이더리움 비교" +description: "Stable은 완전한 EVM 호환성을 제공합니다. 이더리움에서 포팅할 때 변경되지 않는 사항, 변경되는 사항, 주의해야 할 사항을 설명합니다." diataxis: "explanation" --- -# Ethereum 비교 +# 이더리움 비교 -Stable은 완전히 EVM과 호환되므로 대부분의 Ethereum 도구, 라이브러리, 컨트랙트 패턴이 수정 없이 작동합니다. 아래 섹션에서는 Ethereum에서 Stable로 옮길 때 동일하게 유지되는 것과 변경되는 것을 살펴봅니다. +Stable은 완전한 EVM 호환성을 제공하므로 대부분의 이더리움 도구, 라이브러리 및 계약 패턴은 수정 없이 작동합니다. 다음 섹션에서는 이더리움에서 Stable로 전환할 때 변경되지 않는 사항과 변경되는 사항을 설명합니다. -## 동일하게 유지되는 것 +## 변경되지 않는 사항 -Stable은 Ethereum 개발 생태계와 완전한 호환성을 유지합니다: +Stable은 이더리움 개발 생태계와 완벽한 호환성을 유지합니다. | **영역** | **호환성** | | :--- | :--- | | 언어 | Solidity, Vyper | -| 도구 | Hardhat, Foundry | +| 툴링 | Hardhat, Foundry | | 라이브러리 | ethers.js, web3.js | -| 컨트랙트 패턴 | 모든 표준 EVM 규약 (ERC-20, ERC-721, ERC-1155, 프록시 등) | -| RPC 인터페이스 | 대부분의 `eth_*` 메서드 지원 (`eth_call`, `eth_sendRawTransaction`, `eth_getBalance`, `eth_getLogs`, `eth_estimateGas` 등). 전체 목록은 [JSON-RPC API](/ko/reference/json-rpc-api)를 참조하세요 | +| 계약 패턴 | 모든 표준 EVM 컨벤션 (ERC-20, ERC-721, ERC-1155, 프록시 등) | +| RPC 인터페이스 | 대부분의 `eth_*` 메서드 지원 (`eth_call`, `eth_sendRawTransaction`, `eth_getBalance`, `eth_getLogs`, `eth_estimateGas` 등). 전체 목록은 [JSON-RPC API](/ko/reference/json-rpc-api) 참조 | -기존 스마트 컨트랙트, 배포 스크립트, 프론트엔드 통합은 RPC 엔드포인트와 체인 ID를 변경하여 Stable을 대상으로 설정할 수 있습니다. +기존 스마트 계약, 배포 스크립트 및 프론트엔드 통합은 RPC 엔드포인트와 체인 ID를 변경하여 Stable을 대상으로 합니다. ## 다른 점 -네 가지 동작이 Ethereum과 다릅니다. +이더리움과 네 가지 동작이 다릅니다. -### 1. 단일 슬롯 완결성(Single-slot finality) +### 1. 단일 슬롯 완결성 -Ethereum은 트랜잭션이 최종으로 간주되기 전에 여러 블록 확인을 요구합니다. Stable은 단일 슬롯 완결성을 제공합니다: 트랜잭션은 블록에 포함되는 즉시 최종 확정됩니다. +이더리움은 트랜잭션이 최종으로 간주되기 전에 여러 블록 확인이 필요합니다. Stable은 단일 슬롯 완결성을 제공합니다. 즉, 트랜잭션은 블록에 포함되는 즉시 최종이 됩니다. -개발자에게 이는 다음을 의미합니다: +개발자를 위한 의미는 다음과 같습니다. -- 트랜잭션이 확정된 블록에 나타나면, 그 상태 변경은 최종적이며 되돌릴 수 없습니다. -- 애플리케이션은 블록 포함을 정산 확인으로 안전하게 신뢰할 수 있습니다. +- 트랜잭션이 확인된 블록에 나타나면 해당 상태 변경은 최종적이며 되돌릴 수 없습니다. +- 애플리케이션은 결제 확인 수단으로 블록 포함에 안전하게 의존할 수 있습니다. -결정론적 완결성에도 불구하고, 금융적으로 민감한 흐름을 처리하는 애플리케이션은 다음을 수행해야 합니다: +확정적 완결성을 갖추고 있음에도 불구하고, 재정적으로 민감한 흐름을 처리하는 애플리케이션은 다음을 수행해야 합니다. -- 종속 작업(예: 잠금 해제, 상환)을 진행하기 전에 RPC 또는 발생한 이벤트를 통해 트랜잭션 성공을 확인하세요. -- 일시적인 제출 또는 RPC 오류를 처리하기 위해 자동화 및 배치 작업에 재시도 및 조정 로직을 구현하세요. +- 종속 작업(예: 잠금 해제, 상환)을 진행하기 전에 RPC 또는 발생한 이벤트를 통해 트랜잭션 성공을 확인합니다. +- 자동화 및 배치 작업을 위해 재시도 및 조정 로직을 구현하여 일시적인 제출 또는 RPC 오류를 처리합니다. ### 2. 가스 토큰: USDT0 -Stable에서는 트랜잭션 수수료가 변동성이 큰 네이티브 토큰이 아닌 USDT0로 지불됩니다. 이는 USDT로 표시되는 예측 가능한 낮은 가스 비용을 제공합니다. +Stable에서는 이더리움 블록체인에서 ETH로 가스를 결제하는 방식과 유사하게, USDT0로 거래 수수료를 지불합니다. 이는 USDT 단위로 예측 가능한 낮은 가스 비용을 제공합니다. -- 사용자는 트랜잭션을 제출하기 위해 지갑에 USDT0가 필요합니다. -- 트랜잭션의 `value` 필드는 Ethereum에서 ETH를 보내는 것과 유사하게 USDT0를 보내는 데 여전히 작동합니다. -- 자세한 내용은 [가스로서의 USDT](/ko/explanation/usdt-as-gas-token)를 참조하세요. +- 사용자는 거래를 제출하려면 지갑에 USDT0를 보유해야 합니다. +- 거래의 `value` 필드는 이더리움에서 ETH를 보내는 방식과 유사하게 USDT0를 보내는 데 계속 작동합니다. +- 자세한 내용은 [가스 지불 수단으로서의 USDT](/ko/explanation/usdt-as-gas-token)를 참조하십시오. ### 3. 우선순위 팁 없음 -Stable은 단일 구성 요소 가스 모델을 사용합니다. 팁 기반 트랜잭션 순서 지정이 없습니다. +Stable은 단일 구성 요소 가스 모델을 사용합니다. 팁 기반 트랜잭션 순서 지정은 없습니다. - `maxPriorityFeePerGas`는 무시됩니다(항상 0). - 트랜잭션 순서는 수수료 입찰의 영향을 받지 않습니다. - 지갑은 우선순위 팁 입력 필드를 숨기거나 비활성화해야 합니다. -- 자세한 내용은 [가스 가격 책정](/ko/explanation/gas-pricing)을 참조하세요. +- 자세한 내용은 [가스 가격 책정](/ko/explanation/gas-pricing)을 참조하십시오. ### 4. USDT0 이중 역할 동작 -USDT0는 네이티브 가스 토큰과 ERC-20 토큰 두 가지 모두로 기능합니다. 이로 인해 잔액 의미론, 허용량 안전성, 특정 opcode 가정과 관련된 동작 차이가 발생합니다. 자세한 내용은 [Stable에서의 USDT0 동작](/ko/explanation/usdt0-behavior)을 참조하세요. +USDT0는 네이티브 가스 토큰이자 ERC-20 토큰으로 기능합니다. 이로 인해 잔액 의미론, 허용 안전성 및 특정 opcode 가정에 대한 행동 차이가 발생합니다. 자세한 내용은 [Stable에서의 USDT0 동작](/ko/explanation/usdt0-behavior)을 참조하십시오. ## 빠른 비교 -| **매개변수** | **Stable** | **Ethereum** | +| **매개변수** | **Stable** | **이더리움** | | :--- | :--- | :--- | | 가스 토큰 | USDT0 | ETH | | 완결성 | 단일 슬롯 | 다중 블록 확인 | -| 블록 시간 | ~0.7초 | ~12초 | -| 우선순위 팁 (`maxPriorityFeePerGas`) | 무시됨(항상 0) | 순서 지정에 사용 | +| 블록 타임 | ~0.7 초 | ~12 초 | +| 우선순위 팁 (`maxPriorityFeePerGas`) | 무시됨 (항상 0) | 순서 지정을 위해 사용됨 | | EIP-1559 트랜잭션 형식 | 지원됨 | 지원됨 | -| EVM 호환성 | 완전 | 해당 없음 | +| EVM 호환성 | 완전 | N/A | ## 다음 권장 사항 -- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token) — 가스를 위해 ETH를 대체하는 자산 모델을 이해하세요. -- [**가스 가격 책정**](/ko/explanation/gas-pricing) — 단일 구성 요소 수수료 모델을 자세히 검토하세요. -- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior) — 이중 역할 자산 의미론, 허용량 안전성, `EXTCODEHASH` 동작에 대해 컨트랙트를 감사하세요. +- [**가스 지불 수단으로서의 USDT**](/ko/explanation/usdt-as-gas-token): 이더리움을 대체하는 자산 모델을 이해하세요. +- [**가스 가격 책정**](/ko/explanation/gas-pricing): 단일 구성 요소 수수료 모델을 자세히 검토하세요. +- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior): 이중 역할 자산 의미론, 허용 안전성 및 `EXTCODEHASH` 동작에 대해 계약을 감사하세요. diff --git a/docs/pages/ko/explanation/execution.mdx b/docs/pages/ko/explanation/execution.mdx index c3bd812..db98399 100755 --- a/docs/pages/ko/explanation/execution.mdx +++ b/docs/pages/ko/explanation/execution.mdx @@ -1,8 +1,9 @@ --- source_path: explanation/execution.mdx -source_sha: 9afd5c0b659254ef8509480e9de4da6d351fc6d9 +source_sha: bc64781e476fda556f242c5ec924b0e026a13f33 title: "실행" -description: "Block-STM 병렬 실행, Optimistic Block Processing, 미래의 StableVM++ 성능 개선 사항." +description: "Block-STM, 낙관적 블록 처리, 향후 StableVM++ 개선 사항을 이용한 Stable EVM 병렬 실행입니다." +diataxis: "explanation" --- # 실행 @@ -15,83 +16,89 @@ description: "Block-STM 병렬 실행, Optimistic Block Processing, 미래의 St alt="Stable EVM" /> -**Stable EVM**은 Stable의 Ethereum 호환 실행 계층으로, MetaMask와 같은 기존 Ethereum 도구 및 지갑을 사용하여 체인과 원활하게 상호작용할 수 있도록 합니다. Stable EVM은 EVM의 개발자 경험과 StableSDK의 모듈러한 고성능 인프라를 결합합니다. +**Stable EVM**은 Stable의 이더리움 호환 실행 계층입니다. MetaMask와 같은 기존 이더리움 툴 및 지갑은 변경 없이 Stable과 상호 작용합니다. Stable EVM은 EVM의 개발자 경험과 Stable SDK의 모듈식 인프라를 결합합니다. -Stable EVM과 StableSDK 간의 간극을 메우기 위해, Stable EVM은 일련의 **프리컴파일**을 도입합니다. 이 프리컴파일들은 EVM 스마트 컨트랙트가 StableSDK의 네이티브 모듈 기능에 접근할 수 있도록 하며, 핵심 체인 로직을 안전하고 아토믹하게 호출할 수 있게 합니다. 이러한 설계는 스마트 컨트랙트가 토큰 전송, 스테이킹, 거버넌스 참여와 같은 특별한 작업을 수행할 수 있도록 합니다. +Stable EVM과 Stable SDK 간의 격차를 해소하기 위해 Stable EVM은 **프리컴파일** 세트를 도입합니다. 이러한 프리컴파일은 네이티브 Stable SDK 모듈 기능을 EVM 스마트 컨트랙트에 노출하여 코어 체인 로직을 안전하고 원자적으로 호출할 수 있도록 합니다. 스마트 컨트랙트는 토큰 전송, 스테이킹 또는 거버넌스 참여와 같은 특권 작업을 수행할 수 있습니다. -## 향후 로드맵 1: 낙관적 병렬 실행 +## 미래 로드맵 1: 낙관적 병렬 실행 -역사적으로, 블록체인 시스템은 각 트랜잭션이 순차적으로 하나씩 처리되는 ‘순차 실행’에 의존해 왔으며, 이는 모든 노드에서 결정론적인 상태를 보장하기 위함이었습니다. 이러한 설계는 일관성을 보장하지만, 동시에 처리량과 확장성에 심각한 제약을 만듭니다. 특히 현대 블록체인이 수만 건의 TPS를 지원하고자 할 때 더욱 그러합니다. +역사적으로 블록체인 시스템은 순차적 실행에 의존해 왔습니다. 각 트랜잭션은 모든 노드에서 결정론적 상태를 보장하기 위해 하나씩 처리되었습니다. 이러한 설계는 일관성을 보장하지만, 특히 현대 블록체인이 초당 수만 건의 트랜잭션을 지원하는 것을 목표로 함에 따라 처리량과 확장성을 심각하게 제한합니다. -이 제약을 극복하기 위해, Stable은 **낙관적 병렬 실행(Optimistic Parallel Execution, OPE)** 을 가능하게 하는 검증된 병렬 실행 엔진인 **Block-STM**을 채택하고 있습니다. 이를 통해 트랜잭션은 결정론성을 유지하면서 병렬로 실행될 수 있으며, 성능이 크게 향상됩니다. +이러한 제약을 극복하기 위해 Stable은 **Block-STM**을 채택하고 있습니다. 이는 **낙관적 병렬 실행(OPE)**을 가능하게 하는 입증된 병렬 실행 엔진입니다. 이를 통해 트랜잭션을 병렬로 실행하면서 결정론을 보존하여 성능을 크게 향상시킬 수 있습니다. ### Block-STM 작동 방식 -Block-STM은 낙관적 동시성 제어 메커니즘을 활용합니다. 트랜잭션은 충돌이 없다는 가정 하에 병렬로 먼저 실행되며, 이후 검증 단계에서 충돌이 감지되면 재실행을 통해 처리됩니다. 이 과정은 다음 다섯 가지 핵심 기술에 기반합니다: +Block-STM은 낙관적 동시성 제어 메커니즘을 사용합니다. 트랜잭션은 충돌하지 않을 것이라는 가정하에 먼저 병렬로 실행됩니다. 그런 다음, 유효성 검사 단계에서 충돌이 감지되고 재실행을 통해 처리됩니다. 이 프로세스는 다음 다섯 가지 주요 기술에 의존합니다. -**1. 다중 버전 메모리 구조 (Multi-Version Memory Structure)** +**1. 다중 버전 메모리 구조** -Block-STM은 각 메모리 키에 대해 여러 버전을 저장합니다: +Block-STM은 각 메모리 키의 여러 버전을 저장합니다. -- 각 트랜잭션은 이전 트랜잭션이 커밋한 최신 버전을 읽습니다. -- 실행 중의 읽기와 쓰기 모두 버전이 지정됩니다. -- 이후 검증 시 이러한 버전들에 대한 일관성 검사를 통해 충돌 여부를 판단합니다. +- 각 트랜잭션은 이전 트랜잭션에서 커밋된 최신 버전을 읽습니다. +- 실행 중에는 읽기 및 쓰기가 모두 버전 관리됩니다. +- 나중에 유효성 검사 중에 이러한 버전의 일관성이 확인되어 충돌을 감지합니다. -**2. Read-Set / Write-Set 기반 검증** +**2. Read-Set / Write-Set 기반 유효성 검사** -- 각 트랜잭션은 실행 중 읽은 키와 버전을 Read-Set에 기록합니다. -- 실행이 끝나면 Write-Set이 다중 버전 메모리에 기록됩니다. -- 검증 과정에서 다른 트랜잭션이 해당 Read-Set의 키를 수정한 경우, 이는 충돌로 간주되어 트랜잭션은 중단되고, 반복 시도 번호(incarnation number)를 증가시켜 재실행됩니다. +- 실행 중에 각 트랜잭션은 Read-Set에 읽는 키와 버전을 기록합니다. +- 실행이 끝나면 Write-Set을 다중 버전 메모리에 기록합니다. +- 유효성 검사 중에 다른 트랜잭션이 Read-Set의 키를 수정한 경우, 해당 트랜잭션은 충돌로 표시됩니다. 그런 다음 중단되고 증가된 버전 번호로 다시 실행됩니다. **3. ESTIMATE 마커를 이용한 빠른 충돌 감지** -- 트랜잭션이 실패하면 해당 Write-Set은 ESTIMATE 플래그로 마크됩니다. -- 다른 트랜잭션이 ESTIMATE로 표시된 값을 읽으면 (**`READ_ERROR`** 가 발생하면) 즉시 중단하고 재실행을 대기합니다. -- 이를 통해 전체 트랜잭션을 다시 실행하지 않고도 의존 관계를 빠르게 식별할 수 있습니다. +- 트랜잭션이 실패하면 Write-Set에 ESTIMATE 플래그가 표시됩니다. +- 다른 트랜잭션이 ESTIMATE 표시된 값을 읽으면 즉시 중지하고 재실행을 기다립니다(`READ_ERROR`에 의해 트리거됨). +- 이는 전체 트랜잭션 세트를 재실행하지 않고 의존성을 빠르게 식별하여 오버헤드를 줄이는 데 도움이 됩니다. -**4. 사전 정의된 트랜잭션 순서** +**4. 사전 설정 트랜잭션 순서** -- 블록 내 모든 트랜잭션은 사전 정의된 결정론적 순서에 따라 실행됩니다. -- 검증 및 커밋 단계 또한 동일한 순서를 따릅니다. -- 이를 통해 병렬 실행 환경에서도 모든 노드가 동일한 최종 상태에 도달하도록 보장합니다. +- 블록 내의 모든 트랜잭션은 사전 설정된 결정론적 순서에 따라 실행됩니다. +- 유효성 검사 및 커밋 단계도 동일한 순서를 따릅니다. +- 이를 통해 병렬 실행에서도 모든 노드가 동일한 최종 상태에 도달할 수 있습니다. **5. 협업 스케줄러** -- 협업 스케줄러는 실행 및 검증 워커 간에 작업을 스레드-세이프 방식으로 분배합니다. -- 인덱스가 낮은 트랜잭션을 우선 처리하여, 조기 커밋을 가속화하고 재실행을 최소화합니다. -- 스케줄러는 트랜잭션의 반복 시도 번호를 관리하며, 성공적으로 커밋될 때까지 반복 실행합니다. +- 협업 스케줄러는 스레드 안전 방식으로 실행 및 유효성 검사 작업자 간에 작업을 분배합니다. +- 조기 커밋을 가속화하고 재실행을 최소화하기 위해 낮은 인덱스 트랜잭션의 우선순위를 지정합니다. +- 스케줄러는 트랜잭션이 성공적으로 커밋될 때까지 반복 시도에 대한 트랜잭션 버전을 관리합니다. ### Block-STM의 주요 이점 -- **락 없이 병렬성 실현**: MVCC(Multi-Version Concurrency Control)를 활용하여, Block-STM은 뮤텍스 락 없이 여러 트랜잭션의 동시 읽기/쓰기를 가능하게 합니다. 충돌 검사는 실행 이후에만 수행되므로, 초기 처리 단계에서 최대 처리량을 확보할 수 있습니다. -- **ESTIMATE 마커를 통한 최소한의 오버헤드**: 실패한 트랜잭션은 자신의 Write-Set에 ESTIMATE 마커를 설정하여, 여기에 의존하는 트랜잭션을 조기에 중단하고 불필요한 실행을 피할 수 있도록 합니다. 이로 인해 유효한 실행 경로에 더 빠르게 도달할 수 있습니다. -- **효율적인 스케줄링 및 우선 커밋**: 협업 스케줄러를 통해 인덱스가 낮은 트랜잭션을 우선 커밋함으로써, 재시도를 최소화합니다. 이는 전체 처리량을 개선하고 실행 주기를 단축시킵니다. -- **결정론성과 합의 호환성**: 모든 트랜잭션은 고정된 순서를 따르므로, 재실행된 트랜잭션도 결국 동일한 순서로 커밋됩니다. 이를 통해 모든 노드 간 안전하고 결정론적인 상태 합의가 가능하며, 병렬화된 환경에서도 합의 무결성이 유지됩니다. +- **잠금 없는 병렬 처리**: MVCC(다중 버전 동시성 제어)를 활용하여 Block-STM은 뮤텍스 잠금 없이 여러 트랜잭션이 동시에 읽고 쓸 수 있도록 합니다. 충돌은 실행 후에만 확인되므로 초기 처리 단계에서 최대 처리량을 허용합니다. +- **ESTIMATE 마커를 통한 최소 오버헤드**: 실패한 트랜잭션은 Write-Set에 ESTIMATE 마커를 표시하여 종속 트랜잭션이 일찍 일시 중지되도록 신호를 보내 불필요한 실행을 방지합니다. 이는 유효한 실행 경로를 더 빠르게 수렴하는 결과를 가져옵니다. +- **효율적인 스케줄링 및 우선순위 커밋**: 협업 스케줄러를 사용하여 시스템은 낮은 인덱스 트랜잭션을 먼저 커밋하여 재시도를 최소화합니다. 이는 전체 처리량을 개선하고 실행 주기를 단축합니다. +- **결정론 및 합의 호환성**: 모든 트랜잭션이 고정된 순서를 따르기 때문에 재실행된 트랜잭션도 궁극적으로 동일한 순서로 커밋됩니다. 이는 병렬화된 환경에서도 합의 무결성을 유지하면서 모든 노드에서 안전하고 결정론적인 상태 합의를 보장합니다. ### Stable의 OPE Optimistic Parallel Execution on Stable -Stablechain은 **낙관적 병렬 실행(OPE)** 을 실행 계층의 핵심 기능으로 통합할 예정이며, 이는 **낙관적 블록 처리(Optimistic Block Processing, OBP)** 와 함께 사용됩니다. OPE와 OBP는 서로 보완적이지만 본질적으로 다른 전략이라는 점에 유의해야 합니다. +Stable은 **낙관적 블록 처리(OBP)**와 함께 **낙관적 병렬 실행(OPE)**을 자체 실행 계층의 핵심 기능으로 통합할 예정입니다. OPE와 OBP는 상호 보완적이지만 근본적으로 다른 전략이라는 점에 유의하십시오. -### OBP란 +### OBP 정보 -- OBP는 병렬 전략이 아니라, 실행 타이밍과 관련이 있습니다. -- `ProcessProposal` 단계에서, Stable은 다른 노드에 블록이 전파되는 동안 해당 블록을 미리 실행합니다. -- 결과 상태는 메모리에 캐시되며, 이는 `FinalizeBlock` 단계에서 재사용되어 불필요한 시간 낭비와 중복된 연산을 줄입니다. +- OBP는 병렬 처리에 관한 것이 아니라 실행 타이밍에 관한 것입니다. +- `ProcessProposal` 단계 동안 Stable은 블록이 다른 노드에 가십되는 동안 블록을 사전 실행합니다. +- 결과 상태는 메모리에 캐시되고 `FinalizeBlock` 중에 재사용되어 시간을 절약하고 중복 계산을 줄입니다. -OPE와 OBP를 결합함으로써, Stable은 실행 지연과 리소스 충돌을 모두 최소화하고, 높은 트랜잭션 부하 환경에서도 우수한 성능을 제공합니다. +OPE와 OBP를 결합함으로써 Stable은 실행 대기 시간과 리소스 경합을 모두 최소화하여 높은 트랜잭션 부하에서 우수한 성능을 제공할 수 있습니다. ### 예상 성능 향상 -내부 벤치마크에 따르면, **Block-STM 기반 OPE**와 **StableDB** 통합을 통해 Stable은 전체 트랜잭션 처리량에서 **최소 2배 이상의 향상**을 달성할 수 있습니다. +내부 벤치마크에 따르면 **Block-STM 기반 OPE** 및 **StableDB** 통합을 통해 Stable은 종단 간 트랜잭션 처리에서 **최소 2배의 처리량 향상**을 달성할 수 있습니다. -## 향후 로드맵 2: StableVM++ +## 미래 로드맵 2: StableVM++ -OPE 및 OBP와 같은 노력은 *다수의 트랜잭션을 동시에 실행하는 방식을 최적화* 하는 데 초점을 맞추지만, 또 하나의 핵심 성능 요소는 **각 개별 트랜잭션을 얼마나 효율적으로 처리할 수 있는가**입니다. +낙관적 병렬 실행(OPE) 및 낙관적 블록 처리(OBP)와 같은 노력은 *여러 트랜잭션이 동시에 실행되는 방식*을 최적화하는 데 중점을 두지만, 또 다른 중요한 성능 레버가 있습니다. 바로 *각 개별 트랜잭션이 얼마나 효율적으로 처리되는지*입니다. -Stable은 현재 실행 속도를 높이기 위해 대체 EVM 구현체들을 탐색하는 중입니다. 그중에서도 C++로 작성된 고성능 EVM인 **EVMONE**이 기존의 Go 기반 EVM을 대체할 유력한 후보로 떠오르고 있습니다. EVMONE으로의 전환은 이론적인 벤치마크 기준으로 **최대 6배의 EVM 실행 성능 향상**을 가져올 것으로 기대됩니다. \ No newline at end of file +Stable은 현재 실행 속도를 높이기 위해 대체 EVM 구현을 모색하고 있습니다. 후보 중에서 C++로 작성된 고성능 EVM인 **EVMONE**은 기존 Go 기반 EVM을 대체할 강력한 후보로 돋보입니다. 이론적 벤치마크에 따르면 이 전환은 EVM 실행 성능에서 최대 **6배 증가**를 가져올 것으로 예상됩니다. + +## 다음 권장 사항 + +- [**스토리지(StableDB)**](/ko/explanation/stable-db): 디스크 I/O에 의존하지 않고 분리된 상태 커밋이 실행에 어떻게 공급되는지 확인하세요. +- [**고성능 RPC**](/ko/explanation/high-performance-rpc): 클라이언트에 실행 결과를 제공하는 분할 경로 RPC를 이해하세요. +- [**이더리움 호환성**](/ko/explanation/ethereum-compatibility): 표준 EVM 툴링을 사용하여 Stable에 대해 기존 컨트랙트를 포팅하세요. diff --git a/docs/pages/ko/explanation/flow-of-funds.mdx b/docs/pages/ko/explanation/flow-of-funds.mdx index 5cc8f54..cc318d2 100644 --- a/docs/pages/ko/explanation/flow-of-funds.mdx +++ b/docs/pages/ko/explanation/flow-of-funds.mdx @@ -1,67 +1,67 @@ --- source_path: explanation/flow-of-funds.mdx -source_sha: ff06fe4313b45eaf2ea4b93e3e3e507b5dba22e3 -title: "자금의 흐름" -description: "온램프부터 온체인 전송, 오프램프 정산에 이르는 Stable에서의 USDT 엔드투엔드 생명주기." +source_sha: 2f5b1dee38396eae48f9ded863b7b2c508bf6b4d +title: "자금 흐름" +description: "온램프부터 온체인 전송, 오프램프 결제까지 Stable에서 USDT의 일대일 라이프사이클." diataxis: "explanation" --- -# 자금의 흐름 +# 자금 흐름 -Stable은 스테이블코인 결제를 위해 특별히 설계된 최초의 블록체인입니다. 이 네트워크는 고처리량, 저지연 스테이블코인 거래에 최적화되어 있으며, USDT로 즉시 정산되는 P2P 결제와 가맹점 결제 수용을 제공합니다. 애플리케이션 계층의 가스 후원 및 면제를 통해 제공업체는 최종 사용자에게 수수료 없는 경험을 제공할 수 있으며, 블록체인 시스템의 복잡성을 추상화하면서 주류 결제 네트워크와 같은 느낌을 줍니다. +Stable은 스테이블코인 결제를 위해 특별히 구축된 최초의 블록체인입니다. 이 네트워크는 높은 처리량, 낮은 지연 시간의 스테이블코인 거래에 최적화되어 즉각적인 USDT 결제로 P2P 결제 및 가맹점 결제를 제공합니다. 애플리케이션 계층 가스 후원 및 면제를 통해 제공업체는 최종 사용자에게 수수료가 없는 경험을 제공하여 블록체인 시스템의 복잡성을 추상화하는 동시에 주류 결제 네트워크 느낌을 제공할 수 있습니다. -이 페이지는 Stable에서 자금의 완전한 생명주기를 설명합니다. USDT가 어떻게 네트워크에 진입하고, 참여자 간에 이동하며, 다시 법정화폐 레일로 빠져나가는지를 다룹니다. +이 페이지에서는 Stable에서 자금의 전체 라이프사이클을 설명합니다. 즉, USDT가 네트워크에 유입되는 방법, 참가자 간에 이동하는 방법, 법정화폐 레일로 다시 유출되는 방법입니다. -## 1. 고객 입금 (온램프) +## 1. 고객 예치 (온램프) -사용자는 세 가지 주요 채널 중 하나를 통해 네트워크로 자금을 들여옵니다: +사용자는 세 가지 주요 채널 중 하나를 통해 네트워크에 돈을 가져옵니다. -- **암호화폐 전송**: 주요 암호화폐는 Stable에서 USDT0로 브리징되거나 변환됩니다. USDT0는 USDT를 위한 옴니체인 표준이자 네트워크의 주요 형식입니다. -- **법정화폐 온램프**: 카드, ACH 또는 현지 결제 수단이 법정화폐를 USDT0로 변환하여 사용자의 지갑으로 직접 전달합니다. -- **CEX 출금**: 사용자가 지원되는 중앙화 거래소에서 USDT를 출금하면서 Stable을 목적지 네트워크로 선택합니다. 거래소는 사용자의 지갑으로 직접 정산합니다. +- **암호화폐 전송**: 주요 암호화폐는 Stable에서 USDT0으로 브리징되거나 변환됩니다. USDT0은 USDT의 옴니체인 표준이며 네트워크의 주요 형태 요소입니다. +- **법정화폐 온램프**: 카드, ACH 또는 지역 결제 방법을 통해 법정화폐를 USDT0으로 변환하여 사용자의 지갑으로 직접 전달합니다. +- **CEX 출금**: 사용자는 지원되는 중앙화된 거래소에서 USDT를 출금하고 Stable을 목적지 네트워크로 선택합니다. 거래소는 사용자의 지갑으로 직접 결제합니다. -모든 경우에 최종 상태는 동일합니다: 사용자의 지갑이 Stable에서 직접 USDT(USDT0 형태)를 보유합니다. +모든 경우에 최종 상태는 동일합니다. 사용자의 지갑은 Stable에서 직접 USDT(USDT0으로)를 보유합니다. -## 2. P2P / 가맹점 전송 (온체인 페이인) +## 2. P2P / 판매자 전송 (온체인 결제) -자금이 Stable에 들어오면, 고객은 다른 사용자나 가맹점에게 USDT를 직접 전송합니다. 온체인 전송의 주요 특성: +자금이 Stable에 입금되면 고객은 USDT를 다른 사용자나 판매자에게 직접 보냅니다. 온체인 전송의 주요 속성은 다음과 같습니다. -- **즉시 정산**: 전송이 온체인에서 즉시 정산됩니다. -- **비수탁형**: 비수탁형 지갑의 경우, 출발지와 목적지 사이에서 어떠한 PSP나 중개자도 사용자 잔액을 건드리지 않습니다. -- **단일 자산**: USDT가 가스이자 정산 자산이기 때문에, 흐름에 추가 토큰이 없고 숨겨진 스프레드도 없습니다. -- **제로 가스 옵션**: 가스 면제를 통해 최종 사용자가 블록체인 수수료를 관리할 필요 없이 자금을 이동할 수 있습니다. 자세한 내용은 [가스 면제](/ko/reference/gas-waiver-api)를 참조하세요. +- **즉시 결제**: 전송은 온체인에서 즉시 결제됩니다. +- **비수탁형**: 비수탁형 지갑의 경우, PSP 또는 중개자는 소스와 목적지 사이에서 사용자 잔액을 전혀 건드리지 않습니다. +- **단일 자산**: USDT가 가스 및 결제 자산이기 때문에 흐름에 추가 토큰이 없으며 숨겨진 스프레드가 없습니다. +- **무가스 옵션**: 가스 면제를 통해 최종 사용자는 블록체인 수수료를 관리할 필요 없이 자금을 이동할 수 있습니다. 자세한 내용은 [가스 면제](/ko/reference/gas-waiver-api)를 참조하십시오. -## 3. 사용자 / 가맹점 잔액 +## 3. 사용자 / 판매자 잔액 -가맹점은 자신의 직접적인 통제 하에 있는 Stable 지갑으로 USDT를 받습니다. 자금은 사용자 또는 가맹점의 수탁 하에 온체인에 보관됩니다. 이러한 지갑은 사용자를 대신하여 결제 제공업체가 생성하고 관리할 수 있습니다. +판매자는 자신의 직접 통제 하에 있는 Stable 지갑으로 USDT를 받습니다. 자금은 사용자 또는 판매자의 수탁 하에 온체인에 보관됩니다. 이러한 지갑은 결제 제공업체가 사용자를 대신하여 생성하고 관리할 수 있습니다. -## 4. 가맹점 출금 (오프램프 / 페이아웃) +## 4. 판매자 출금 (오프램프 / 지급) -가맹점 또는 사용자가 오프체인 법정화폐 정산을 요청할 때: +판매자 또는 사용자가 오프체인 법정화폐 결제를 요청할 때: -1. 제공업체가 뱅킹 또는 페이아웃 레일을 통해 변환(USDT → 법정화폐)을 시작합니다. -2. 자금이 가맹점이 선택한 계좌로 입금됩니다. +1. 제공업체는 뱅킹 또는 지급 레일을 통해 전환(USDT → 법정화폐)을 시작합니다. +2. 자금은 판매자가 선택한 계좌로 입금됩니다. -제공업체는 생태계 내부 전송 중이 아니라 가맹점의 현금화 시에만 흐름에 다시 진입합니다. 일상적인 P2P 흐름에는 중개가 필요하지 않으며, 제공업체는 입금(가맹점 계좌로의 USDT 전송) 또는 출금(USDT → 법정화폐) 시에만 참여합니다. +제공업체는 판매자를 현금화할 때만 흐름에 다시 들어오고, 생태계 내 전송 중에는 들어오지 않습니다. 일상적인 P2P 흐름에는 중개가 필요하지 않습니다. 제공업체는 입금(판매자 계좌로 USDT 전송) 또는 출금(USDT → 법정화폐) 시에만 참여합니다. ## 교차 자산 거래 -Stable은 결제자가 USDT가 아닌 암호화폐를 보유한 시나리오도 지원합니다. +Stable은 지불인이 비USDT 암호화폐를 보유하는 시나리오도 지원합니다. ### 사용자가 다른 암호화폐로 거래 -사용자는 통합 거래소, 브로커 또는 온체인 DEX를 통해 다른 암호화폐(예: BTC 또는 ETH)를 보유하거나 거래할 수 있습니다. 결제 시점에 시스템은 선택된 암호화폐를 자동으로 USDT로 변환하며, 이는 가맹점의 Stable 지갑으로 전송됩니다. 사용자가 선호하는 자산과 관계없이 모든 온체인 정산은 계속 USDT로 이루어집니다. +사용자는 통합 거래소, 브로커 또는 온체인 DEX를 통해 다른 암호화폐(예: BTC 또는 ETH)를 보유하거나 거래할 수 있습니다. 결제 시 시스템은 자동으로 선택된 암호화폐를 USDT로 변환한 다음 판매자의 Stable 지갑으로 전송합니다. 온체인 결제는 사용자가 선호하는 자산과 관계없이 USDT로 계속 이루어집니다. -### 가맹점의 암호화폐 결제 수용 +### 판매자의 암호화폐 결제 수락 -가맹점은 여러 암호화폐를 직접 수용하거나 관리할 필요가 없습니다. 그들은 항상 자신의 Stable 지갑으로 USDT를 받으며, 네트워크 전반에 걸쳐 단일 정산 통화를 유지합니다. 이 설계는 가맹점의 환율 노출을 최소화하고 대사 및 보고를 단순화합니다. +판매자는 여러 암호화폐를 직접 수락하거나 관리할 필요가 없습니다. 그들은 항상 Stable 지갑에 USDT로 입금되어 네트워크 전체에서 단일 결제 통화를 유지합니다. 이 설계는 판매자의 환율 노출을 최소화하고 조정 및 보고를 단순화합니다. -### 변환에서의 제공업체 역할 +### 변환에서 제공업체의 역할 -변환 로직(예: BTC → USDT)은 거래소 파트너, 유동성 공급자 또는 결제 제공업체 자체의 자금 관리부에서 처리할 수 있습니다. 가맹점은 변동성이나 유동성 위험으로부터 차단되며, 오직 USDT만 받습니다. +변환 로직(예: BTC → USDT)은 교환 파트너, 유동성 제공업체 또는 결제 제공업체의 자체 자금으로 처리될 수 있습니다. 판매자는 변동성 또는 유동성 위험으로부터 보호됩니다. 그들은 오직 USDT만 받습니다. ## 다음 권장 사항 -- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token) — USDT0가 Stable에서 네이티브 가스와 ERC-20 잔액 모두로 어떻게 작동하는지 이해합니다. -- [**Stable로 브리징**](/ko/explanation/usdt0-bridging) — USDT0가 OFT Mesh 또는 Legacy Mesh를 통해 다른 체인에서 Stable로 어떻게 이동하는지 살펴봅니다. -- [**첫 USDT0 전송하기**](/ko/tutorial/send-usdt0) — 표준 EVM 도구를 사용하여 테스트넷에서 USDT0 전송을 제출합니다. +- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token): USDT0이 Stable에서 기본 가스 및 ERC-20 잔액으로 사용되는 방법을 이해합니다. +- [**Stable로 브리징**](/ko/explanation/usdt0-bridging): OFT Mesh 또는 Legacy Mesh를 통해 USDT0이 다른 체인에서 Stable로 이동하는 방법을 확인합니다. +- [**첫 USDT0 보내기**](/ko/tutorial/send-usdt0): 표준 EVM 도구를 사용하여 테스트넷에서 USDT0 전송을 제출합니다. diff --git a/docs/pages/ko/explanation/gas-pricing.mdx b/docs/pages/ko/explanation/gas-pricing.mdx index 4a23f1e..6f28761 100755 --- a/docs/pages/ko/explanation/gas-pricing.mdx +++ b/docs/pages/ko/explanation/gas-pricing.mdx @@ -1,25 +1,42 @@ --- source_path: explanation/gas-pricing.mdx -source_sha: 2df550135708d69fa3d4b68bf1579652c4fff68d -title: Gas 가격 책정 -description: "우선순위 팁 없이 USDT0로 지불하는 Stable의 단일 구성 요소 가스 요금 모델." +source_sha: cee955370fcdfb739edadd48366ac6c984cbc9d9 +title: "가스 가격 책정" +description: "Stable은 우선순위 팁이 없는 단일 구성 요소 가스 요금 모델을 사용하여 USDT0으로 표시되는 예측 가능한 비용을 제공합니다." +diataxis: "explanation" --- -# Gas 가격 책정 +# 가스 가격 책정 -Stable은 단일 구성 요소 gas 수수료 모델을 사용합니다: +Stable은 요금 변동성을 제거하고 예측 가능하며 낮은 트랜잭션 비용을 제공하도록 설계된 단순화된 단일 구성 요소 가스 요금 모델을 사용합니다. 트랜잭션 순서는 팁 입찰에 의해 영향을 받지 않습니다. 유효한 가스 가격은 프로토콜의 기본 요금에 의해서만 결정됩니다. -- **우선순위 팁 없음 (maxPriorityFeePerGas는 무시됨)** -- 수수료는 순수하게 기본 실행 비용에 기반합니다 -- 수수료는 **USDT0**로 지불됩니다 +## 이 모델을 사용하는 이유 -근거: +단일 구성 요소 설계에서 세 가지 속성이 파생됩니다. -- Stable은 예측 가능한 결제를 위해 수수료 변동성을 제거합니다 -- "팁"과 채굴자 인센티브에 대한 사용자 혼란을 제거합니다 +- **예측 가능한 비용**: 수수료는 순전히 기본 실행 비용을 기반으로 합니다. 팁 경매는 분산을 도입하지 않습니다. +- **USDT 표시 가격 책정**: 가스는 USDT0으로 가격이 책정되므로 달러 기준으로 비용을 추론하는 개발자 또는 사용자는 기본 토큰 가격 변동을 고려할 필요가 없습니다. +- **극히 낮은 수수료**: 1 gwei의 기본 수수료로 기본 USDT0 전송(21,000 가스)은 약 **0.0000021 USDT0**이 듭니다. 복잡한 계약 상호 작용도 1센트 미만입니다. -개발자에 미치는 영향: +## 이더리움과 비교 -- 개발자는 트랜잭션 가속화를 위해 **우선순위 수수료**에 의존해서는 안 됩니다 -- 지갑은 팁 입력 필드를 숨기거나 비활성화해야 합니다 -- Gas 추정 도구는 Stable RPC 가격 책정 로직을 참조해야 합니다 +| **매개변수** | **Stable** | **이더리움** | +| :--- | :--- | :--- | +| 가스 토큰 | USDT0 | ETH | +| 기본 수수료 | 예 | 예 | +| 우선순위 팁 (`maxPriorityFeePerGas`) | 무시됨 (항상 0) | 주문에 사용됨 | +| EIP-1559 트랜잭션 형식 | 지원됨 | 지원됨 | + +Stable은 EIP-1559 (유형 2) 트랜잭션을 허용하지만, `maxPriorityFeePerGas`는 항상 무시됩니다. 트랜잭션 순서는 팁 입찰에 의해 영향을 받지 않습니다. + +## 의미 + +- **지갑**은 우선순위 팁 입력 필드를 숨기거나 비활성화해야 합니다. 값을 표시해도 효과가 없으므로 사용자를 혼란스럽게 할 수 있습니다. +- **분석 대시보드**는 우선순위 수수료를 추적해서는 안 됩니다. 항상 0입니다. +- **트랜잭션 구성 도구**는 `maxPriorityFeePerGas`를 명시적으로 `0`으로 설정한 다음, 최신 블록의 기본 수수료에서 안전 마진을 사용하여 `maxFeePerGas`를 계산해야 합니다. + +## 다음 권장 사항 + +- [**가스 가격 책정 참조**](/ko/reference/gas-pricing-api): Stable의 요금 모델에 맞춰 트랜잭션을 구성하고, 가스를 추정하며, 도구를 구성합니다. +- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token): USDT0이 기본 가스와 ERC-20 잔액으로 어떻게 사용되는지 확인합니다. +- [**이더리움 비교**](/ko/explanation/ethereum-comparison): 이더리움에서 포팅할 때 발생할 수 있는 모든 동작 차이를 검토합니다. diff --git a/docs/pages/ko/explanation/gas-waiver.mdx b/docs/pages/ko/explanation/gas-waiver.mdx index 878fa72..d2790c1 100755 --- a/docs/pages/ko/explanation/gas-waiver.mdx +++ b/docs/pages/ko/explanation/gas-waiver.mdx @@ -1,267 +1,61 @@ --- source_path: explanation/gas-waiver.mdx -source_sha: 094d0be55d626fd84d16fee6f1f842dd11be54d8 -title: Gas Waiver -description: "거버넌스 승인 주소가 가스리스 트랜잭션을 처리하는 Gas Waiver 프로토콜과 Waiver Server API." +source_sha: 7995b37c002721e3b84297b0e4c3ba54281c0d14 +title: "가스 면제" +description: "가스 면제(Gas Waiver)를 통해 애플리케이션은 사용자를 위한 가스를 부담할 수 있습니다. 거버넌스 승인을 받은 면제는 서명된 페이로드를 가스 가격 0으로 실행하는 래퍼 트랜잭션을 제출합니다." +diataxis: "explanation" --- -# Gas Waiver +# 가스 면제 -## 요약 +거버넌스 승인을 받은 주소(이하 **면제자**)는 사용자의 서명된 페이로드를 담고 있는 래퍼 트랜잭션을 제출하며, 이를 `gasPrice = 0`으로 실행합니다. 사용자는 USDT0을 가지고 있지 않아도 되며 가스 비용을 지불하지 않습니다. Stable은 호스팅 서비스로 하나의 면제자를 운영하며, 파트너는 검증자 거버넌스를 통해 자체 면제자 주소를 등록할 수도 있습니다. -Gas Waiver는 소수의 거버넌스 승인 주소("면제자")가 `gasPrice = 0`인 트랜잭션을 제출할 수 있도록 허용하여 Stable에서 가스리스 최종 사용자 트랜잭션을 가능하게 합니다. Stable은 현재 파트너가 프로토콜별 래퍼 로직을 구현하지 않고도 가스리스 UX를 제공하기 위해 통합할 수 있는 면제자 서비스("면제자 서버")를 운영하고 있습니다. +## 동작 방식 -본 문서는 Gas Waiver 메커니즘, 트랜잭션 형식, 거버넌스 제어 및 파트너를 위한 면제자 서버 API를 명시합니다. +가스 면제는 래퍼 트랜잭션 패턴을 사용합니다: -## 범위 +1. **사용자는 `gasPrice = 0`으로 `InnerTx`에 서명합니다.** 사용자의 서명은 처음부터 끝까지 보존됩니다. 면제자는 유효성을 손상시키지 않고 페이로드를 수정할 수 없습니다. +2. **면제자는 `InnerTx`를 (`value = 0`, `gasPrice = 0`, 서명된 `InnerTx`를 데이터 페이로드로 하는) 프로토콜 마커 주소 (`0x000000000000000000000000000000000000f333`)로 전송되는 `WrapperTx`로 래핑합니다.** +3. **검증자는 마커를 감지하여** 면제자의 권한 및 정책 제약을 확인하고, 사용자 신원(`from`, `nonce`, 호출 의미론)으로 내부 트랜잭션을 실행합니다. -본 명세는 다음을 다룹니다: +가스 회계는 면제 메커니즘 내에서 처리됩니다. 사용자는 아무것도 지불하지 않고, 래퍼도 아무것도 지불하지 않으며, 검증자는 면제자별 정책에 따라 비용을 흡수합니다. -- 가스 면제 트랜잭션에 대한 프로토콜 수준 규칙 -- 래퍼 트랜잭션 메커니즘 및 마커 주소 -- 거버넌스 제어 권한 부여 및 허용된 대상 -- 서명된 사용자 트랜잭션 제출을 위한 면제자 서버 인터페이스 +## 권한 부여 및 정책 -## 정의 +면제자는 애플리케이션 로직이 아닌 검증자 거버넌스에 의해 제어됩니다. 거버넌스는 다음을 제공합니다: -- **Waiver(면제자)**: 검증자 거버넌스를 통해 온체인에 등록된 이더리움 주소로, 가스 면제 트랜잭션을 제출할 권한이 있습니다. -- **InnerTx(내부 트랜잭션)**: `gasPrice = 0`인 최종 사용자의 서명된 트랜잭션입니다. -- **WrapperTx(래퍼 트랜잭션)**: 면제자가 서명한 트랜잭션으로, 사용자의 `InnerTx`를 체인으로 전송하고 실행을 승인합니다. -- **Marker address(마커 주소)**: 면제자 래퍼 트랜잭션을 식별하는 데 사용되는 센티널 주소: `0x000000000000000000000000000000000000f333`. -- **AllowedTarget(허용된 대상)**: 면제자를 특정 컨트랙트 주소 및 메서드 선택자로 제한하는 정책입니다. +- **검토 가능한 등록**: 모든 면제자 주소는 온체인에 등록되며 상태에서 확인할 수 있습니다. +- **철회**: 검증자는 오작동하는 면제자를 언제든지 제거할 수 있습니다. +- **`AllowedTarget`을 통한 범위 지정 액세스**: 각 면제자는 특정 대상 계약 및 메서드 선택자 집합에 바인딩됩니다. 프로토콜은 내부 `to` 주소와 메서드 선택자가 해당 범위 밖에 있는 모든 래퍼를 거부합니다. -## 개요 +유효한 래퍼 트랜잭션은 다음 모든 조건을 충족해야 합니다: -Gas Waiver는 래퍼 트랜잭션 패턴을 사용합니다: +- `WrapperTx.to == 0x000000000000000000000000000000000000f333` (마커 주소). +- `WrapperTx.from`은 거버넌스를 통해 온체인에 등록된 면제자입니다. +- `WrapperTx.gasPrice == 0` 및 `InnerTx.gasPrice == 0`. +- `WrapperTx.value == 0`. +- `InnerTx.to`와 추출된 메서드 선택자는 면제자의 `AllowedTarget` 정책에 의해 허용됩니다. -1. 사용자가 `gasPrice = 0`인 `InnerTx`에 서명합니다. -2. 면제자가 `InnerTx`를 `WrapperTx`로 래핑하여 브로드캐스트합니다. -3. 검증자는 마커 트랜잭션을 감지하고, 면제자 권한 및 정책 제약 조건을 확인한 후 임베디드된 `InnerTx`를 실행합니다. - -Stable은 온체인에 승인된 면제자로 등록된 면제자 서비스(면제자 서버)를 운영합니다. 파트너는 면제자 서버 API와 통합하여 서명된 `InnerTx` 페이로드를 제출합니다. - -## 프로토콜 명세 - -### 마커 주소 라우팅 - -다음 조건을 만족하는 경우에만 트랜잭션이 면제자 래퍼 트랜잭션으로 처리됩니다: - -- `to == 0x000000000000000000000000000000000000f333`. - -프로토콜은 트랜잭션 `data` 필드를 인코딩된 내부 트랜잭션 페이로드로 해석하고 아래의 면제자 검증 규칙을 사용하여 처리합니다. - -### 권한 부여 및 정책 검사 - -각 후보 래퍼 트랜잭션에 대해 검증자는 다음을 시행해야 합니다: - -1. **면제자 권한 부여** - - `WrapperTx.from`은 거버넌스를 통해 온체인에 등록된 면제자 주소여야 합니다. -2. **가스 면제** - - `WrapperTx.gasPrice`는 `0`이어야 합니다. - - `InnerTx.gasPrice`는 `0`이어야 합니다. -3. **대상 허용 목록** - - `InnerTx.to` 및 `InnerTx.data`에서 추출된 메서드 선택자는 면제자의 `AllowedTarget` 정책에 의해 허용되어야 합니다. -4. **Value 제한** - - `WrapperTx.value`는 `0`이어야 합니다. - -검사가 실패하면 래퍼 트랜잭션은 거부되어야 하며 내부 트랜잭션은 실행되지 않아야 합니다. - -### 실행 의미론 - -모든 검사가 통과되면: - -1. 프로토콜은 사용자의 `from`, `nonce` 및 호출 의미론을 보존하면서 사용자로서 `InnerTx`를 실행합니다. -2. 가스 회계는 면제자 메커니즘에 의해 처리됩니다: 사용자는 가스를 지불하지 않으며, 면제자 트랜잭션은 기능의 정의에 따라 `gasPrice = 0`을 사용합니다. -3. 래퍼 트랜잭션은 `InnerTx`의 실행을 커버할 충분한 `gasLimit`를 제공해야 합니다(언래핑 및 검증 오버헤드 포함). - -## 트랜잭션 형식 - -### WrapperTx - -래퍼 트랜잭션은 면제자가 서명하고 마커 주소로 전송됩니다. - -```javascript -WrapperTx { - from: waiver_address, - to: 0x000000000000000000000000000000000000f333, - value: 0, // 0이어야 함 - data: RLP(InnerTx), // RLP 인코딩된 내부 트랜잭션 - gasPrice: 0, // 0이어야 함 - gasLimit: sufficient_for_inner, // 내부 실행 + 오버헤드를 커버해야 함 - nonce: waiver_nonce -} -``` - -### InnerTx - -내부 트랜잭션은 최종 사용자가 서명합니다. - -```javascript -InnerTx { - from: user_address, - to: target_contract, - value: value, - data: call_data, - gasPrice: 0, // 0이어야 함 - gasLimit: execution_gas, - nonce: user_nonce -} -``` - -## 거버넌스 제어 액세스 - -면제자 권한 부여는 검증자 거버넌스에 의해 온체인에서 관리됩니다. - -거버넌스 제어는 다음을 제공합니다: - -- 면제자 주소의 검토 가능한 권한 부여 -- 면제자 등록 및 업데이트의 온체인 투명성 -- 철회 기능 -- `AllowedTarget`을 통한 면제자별 범위 지정 +어떤 조건이라도 실패하면, 검증자는 내부 트랜잭션을 실행하지 않고 래퍼를 거부합니다. ## 보안 모델 -### 최종 사용자 서명 무결성 - -사용자는 `InnerTx`에 서명합니다. 면제자는 서명을 무효화하지 않고는 내부 트랜잭션 페이로드를 수정할 수 없습니다. 파트너는 여전히 사용자가 의도된 트랜잭션 페이로드에만 서명하도록 보장해야 합니다. - -### 신뢰 경계 - -파트너가 면제자 서버를 통해 제출을 라우팅하는 경우 Gas Waiver는 서비스 종속성을 도입합니다: - -- 서비스의 가용성은 가스리스 트랜잭션을 제출할 수 있는 능력에 영향을 미칩니다. -- 권한 부여는 온체인에 유지됩니다. 등록된 면제자 주소만 유효한 래퍼 제출을 생성할 수 있습니다. - -## 파트너 통합 - -파트너는 다음과 같이 통합합니다: - -1. 사용자로부터 서명된 `InnerTx`를 수집합니다(`gasPrice = 0`). -2. 서명된 내부 트랜잭션을 면제자 서버 API에 제출합니다. -3. 스트리밍된 결과를 처리하고 최종 사용자에게 트랜잭션 해시를 표시합니다. - -## 면제자 서버 - -### 개요 - -면제자 서버는 서명된 사용자 `InnerTx` 페이로드를 면제자 승인 래퍼 트랜잭션으로 래핑하고 브로드캐스트합니다. 파트너는 래퍼 트랜잭션을 구성하거나 면제자 주소를 운영할 필요가 없습니다. - -### 엔드포인트 및 기본 URL - -기본 URL: - -- 메인넷: 미정 -- 테스트넷: `https://waiver.testnet.stable.xyz` - -### 인증 - -상태 확인을 제외한 모든 엔드포인트는 Bearer 토큰 인증이 필요합니다: - -``` -Authorization: Bearer -``` - -### API - -#### GET `/v1/health` - -상태 확인 엔드포인트입니다. - -인증: 없음. - -#### POST `/v1/submit` - -서명된 내부 트랜잭션 배치를 제출합니다. - -인증: 필수(`Bearer`). - -요청 본문: - -```json -{ - "transactions": ["0x", "0x"] -} -``` - -응답은 NDJSON(줄 바꿈 구분 JSON)으로 스트리밍됩니다. 각 줄은 제출된 트랜잭션 인덱스에 해당합니다. - -예시: - -```json -{"index":0,"id":"abc123","success":true,"txHash":"0x..."} -{"index":1,"id":"def456","success":false,"error":{"code":"VALIDATION_FAILED","message":"invalid signature"}} -``` - -#### GET `/v1/submit` - -스트리밍 제출을 위한 WebSocket 인터페이스입니다. - -인증: 필수(`Bearer`). - -### 통합 예시 - -```javascript -const WAIVER_SERVER = "https://waiver.testnet.stable.xyz"; - -async function submitGaslessTransaction(signedInnerTxHex, apiKey) { - const response = await fetch(`${WAIVER_SERVER}/v1/submit`, { - method: "POST", - headers: { - "Content-Type": "application/json", - "Authorization": `Bearer ${apiKey}`, - }, - body: JSON.stringify({ - transactions: [signedInnerTxHex], - }), - }); - - const reader = response.body.getReader(); - const decoder = new TextDecoder(); - - while (true) { - const { done, value } = await reader.read(); - if (done) break; - - const lines = decoder.decode(value).trim().split("\n"); - for (const line of lines) { - const result = JSON.parse(line); - console.log(result); - } - } -} -``` - -### 사용자 InnerTx 생성 - -파트너는 `gasPrice = 0`인 `InnerTx`를 구성한 후 사용자 서명을 수집할 책임이 있습니다. +- **사용자 서명 무결성**: 사용자가 `InnerTx`에 서명합니다. 면제자는 서명의 유효성을 손상시키지 않고 페이로드를 변경할 수 없습니다. 파트너는 사용자가 의도한 페이로드에만 서명하도록 보장할 책임이 여전히 있습니다. +- **온체인 권한 부여**: 권한 부여는 온체인에 있습니다. 요청이 어디에서 시작되었는지에 관계없이 거버넌스에 등록된 면제자 주소만 유효한 래퍼 제출을 생성할 수 있습니다. +- **서비스 가용성 경계**: 파트너가 Stable의 호스팅된 면제 서버를 통해 라우팅할 때 제출 가용성은 서비스에 따라 달라집니다. 프로토콜 수준의 권한 부여 보장은 영향을 받지 않습니다. -예시: +## 가스 면제를 사용해야 하는 경우 -```javascript -import { ethers } from "ethers"; +가스 면제는 최종 사용자가 가스를 위해 USDT0을 보유할 필요가 없는 모든 흐름에 적합합니다: -async function createInnerTx(userWallet, contractAddress, callData, nonce) { - const innerTx = { - to: contractAddress, - data: callData, - value: value, - gasPrice: 0, // 면제를 위해 0이어야 함 - gasLimit: 100000, - nonce: nonce, - chainId: 2201, // 메인넷: 988, 테스트넷: 2201 - }; +- 아직 스테이블코인 잔액이 없는 사용자를 온보딩하는 소비자 앱. +- 에이전트의 지갑이 가스를 지원하는 에이전트 주도 흐름. +- 운영자가 네트워크 비용을 흡수하는 기업 결제 시스템. - return await userWallet.signTransaction(innerTx); -} -``` +사용자가 USDT0을 보유하고 있지만 여러 호출을 하나의 서명된 트랜잭션으로 묶고 싶어하는 흐름의 경우, 대신 [EIP-7702 위임](/ko/reference/eip-7702-api)을 참조하십시오. -### 오류 코드 +## 다음 권장 사항 -- `PARSE_ERROR`: 트랜잭션 파싱 실패 -- `INVALID_REQUEST`: 요청 본문 형식 오류 -- `BATCH_SIZE_EXCEEDED`: 배치 크기가 허용된 최대값 초과 -- `VALIDATION_FAILED`: 트랜잭션 검증 실패 -- `BROADCAST_FAILED`: 체인으로 브로드캐스트 실패 -- `RATE_LIMITED`: 속도 제한 초과 -- `QUEUE_FULL`: 서버 대기열이 용량에 도달 -- `TIMEOUT`: 요청 시간 초과 +- [**가스 없는 트랜잭션 활성화**](/ko/how-to/integrate-gas-waiver): API 키 제출 및 NDJSON 응답으로 호스팅된 면제 서버 API를 통합합니다. +- [**가스 면제 프로토콜**](/ko/reference/gas-waiver-api): 마커 라우팅, 래퍼 형식, 거버넌스 제어 등 전체 프로토콜 사양을 읽어보세요. +- [**가스 토큰으로서의 USDT**](/ko/explanation/usdt-as-gas-token): 면제가 적용되는 가스 토큰을 이해합니다. diff --git a/docs/pages/ko/explanation/guaranteed-blockspace.mdx b/docs/pages/ko/explanation/guaranteed-blockspace.mdx index e893466..32aa9ea 100755 --- a/docs/pages/ko/explanation/guaranteed-blockspace.mdx +++ b/docs/pages/ko/explanation/guaranteed-blockspace.mdx @@ -1,42 +1,49 @@ --- source_path: explanation/guaranteed-blockspace.mdx -source_sha: f7ea9d588c7686dd55bd3c0f2323ad749b03d1c9 -title: "보장된 블록스페이스" -description: "엔터프라이즈 파트너에게 예약된 트랜잭션 처리량을 보장하는 블록 공간 할당 메커니즘." +source_sha: e4251f3214551742d492fdfe9dfc33077cb77d76 +title: "보장된 블록 공간" +description: "기업 파트너에게 Stable 네트워크에서 예약된 처리량 용량을 제공하는 보장된 블록 공간 할당입니다." +diataxis: "explanation" --- -# 보장된 블록스페이스 +# 보장된 블록 공간 -## 비즈니스를 위한 스테이블코인 결제 필요성 +**보장된 블록 공간**은 네트워크 조건에 관계없이 모든 블록 용량의 고정된 부분을 등록된 기업 파트너에게 할당하도록 예약된 전용 블록 공간 할당 모델입니다. 보장된 경로를 통해 라우팅된 트랜잭션은 예측 가능한 대기 시간과 비용으로 실행됩니다. 급여, 결제 및 공급업체 지급은 공개 멤풀 트래픽과 경쟁하지 않습니다. -스테이블코인이 지속적으로 진화함에 따라, 점점 더 많은 기업들이 이를 결제, 재무 흐름, 국경 간 정산 등 금융 운영에 통합하고 있습니다. 이러한 변화는 특히 안정적인 명목 화폐 접근이 제한된 지역에서 두드러집니다. 아프리카 및 라틴 아메리카와 같은 시장에서는 인플레이션과 환율 통제가 일반적이기 때문에, 스테이블코인은 운영 안정성을 위한 핵심 도구가 되고 있습니다. +:::note +**계획 중입니다.** 보장된 블록 공간은 미래 지향적인 로드맵 항목입니다. 시점에 대한 자세한 내용은 [로드맵](/ko/explanation/technical-roadmap)을 참조하세요. +::: -오늘날 스테이블코인 트랜잭션은 주로 Ethereum, Solana, Tron과 같은 범용 블록체인에서 발생합니다. 이러한 네트워크는 넓은 composability와 스마트 컨트랙트 지원을 제공하지만, 수수료 예측 가능성이나 실행 보장을 염두에 두고 설계되지 않았습니다. +## 왜 중요한가 -- **Ethereum**: 2022년 5월 1일, Yuga Labs의 “Otherside” NFT 민팅은 Ethereum에서 2억 달러 이상의 가스 수수료가 소각되도록 만들었습니다. 최고 가스는 8,000 gwei를 초과했고, 네트워크 전반에 걸쳐 불안정하고 비결정적인 트랜잭션 비용이 발생했습니다. -- **기타 네트워크**: Solana, Base와 같은 저수수료 네트워크에서는 MEV와 차익 거래 기회가 존재함에 따라 대량의 트랜잭션 스팸이 유입됩니다. 이러한 네트워크는 온체인 가치를 포착하려는 봇들로 인해 과부하 상태를 자주 경험하고, 합법적인 사용자에게 네트워크 혼잡 및 성능 저하를 초래합니다. +범용 체인은 부하 시 비용 예측 가능성을 위해 설계되지 않았습니다. -![Source: MEV and the Limits of Scaling by Flashbots and Rober Miller](/images/share-of-gas.png) +- **이더리움**: 2022년 5월 1일, Yuga Labs의 "Otherside" NFT 발행은 최고 가스를 8,000 gwei 이상으로 밀어 올리고 2억 달러 이상의 수수료를 소각하여 확정적 비용이 필요한 모든 워크로드를 파괴했습니다. +- **솔라나 및 베이스와 같은 저비용 네트워크**는 MEV와 아비트라지 스팸을 유인하여 합법적인 트랜잭션이 포함을 위해 봇 트래픽과 경쟁합니다. -*Source: MEV and the Limits of Scaling by Flashbots and Rober Miller* +![출처: Flashbots와 Robert Miller의 MEV와 스케일링의 한계](/images/share-of-gas.png) -기업이 대규모로 스테이블코인 결제를 채택하려면, 그 기반 인프라는 결제 신뢰성을 위해 최적화되어야 합니다. 이를 위해서는 모든 조건에서 예측 가능한 트랜잭션 지연 시간과 수수료 안정성이 필요합니다. 이러한 보장이 없다면, 범용 체인에서의 스테이블코인 결제는 여전히 신뢰할 수 없는 상태로 남게 됩니다. +*출처: Flashbots와 Robert Miller의 MEV와 스케일링의 한계* -## 보장된 블록스페이스 +기업 결제 흐름은 이러한 변동을 허용할 수 없습니다. 보장된 블록 공간은 이를 직접 해결합니다. -기업의 안정적이고 신뢰 가능한 결제 운영을 보장하기 위해, Stable은 보장된 블록스페이스에 대한 지원을 도입할 예정입니다. +## 보증 작동 방식 -보장된 블록스페이스는 기업에 고정된 블록 용량을 보장하는 전용 블록 공간 할당 모델로, 네트워크 전반의 상태와 무관하게 적용됩니다. 이를 통해 급여 지급, 정산, 공급업체 결제 등 미션 크리티컬한 트랜잭션이 예측 가능한 지연 시간과 비용으로 실행될 수 있습니다. +보증은 세 가지 계층에서 적용됩니다. -이 보장은 다음과 같은 인프라를 통해 강제됩니다: +- **보장된 멤풀**: 검증인(validator)은 공개 트래픽과 격리된 전용 멤풀에서 보장된 트랜잭션을 가져옵니다. +- **검증인 수준 예약**: 각 검증인은 보장된 레인을 위해 모든 블록의 가스 용량 중 미리 정의된 부분을 예약합니다. 확정적 포함은 이로부터 파생됩니다. +- **전용 RPC 노드**: 보장된 블록 공간 API는 격리된 RPC 엔드포인트를 통해 트랜잭션을 라우팅하므로, 공개 RPC 부하에 따라 제출 대기 시간이 급증하지 않습니다. -- **보장된 멤풀**: 밸리데이터는 퍼블릭 트래픽과 분리된 전용 멤풀을 운영하며, 여기서 가져온 보장된 트랜잭션들을 우선적으로 처리합니다. -- **밸리데이터 단의 커스터마이제이션**: 밸리데이터는 사전에 정의된 만큼의 블록 공간을 예약하여, 결정론적인 포함을 보장합니다. -- **전용 RPC 노드**: 보장된 블록스페이스 API는 격리된 RPC 엔드포인트를 통해 트랜잭션을 라우팅하여, 충돌을 줄이고 일관된 처리량을 제공합니다. +등록된 파트너의 결과: -보장된 블록스페이스는 사용자에게 다음과 같은 이점을 제공합니다: +- **독점 라우팅 경로**: 제출은 공개 멤풀 트래픽과 경쟁하지 않습니다. +- **포함 보장**: 네트워크 혼잡에 관계없이 모든 블록에 용량이 예약됩니다. +- **분산화 트레이드오프 없음**: 검증인 개방성과 네트워크 참여가 유지됩니다. 보증은 공개 레인과 함께 존재하며 그 위에 군림하지 않습니다. +- **비즈니스에 필수적인 운영을 위한 신뢰할 수 있는 온체인 성능**, 부하가 걸린 경우에도 마찬가지입니다. -- 전용 업로드 경로를 통한 독점적 트랜잭션 라우팅으로 블록 공간에 우선 접근 -- 네트워크 혼잡 여부와 관계없이 모든 블록에 예약된 용량을 확보하여 보장된 실행 -- 밸리데이터의 개방성이나 네트워크 참여에 대한 타협 없이 탈중앙화를 유지 -- 높은 네트워크 부하 상황에서도 비즈니스에서 중요한 작업들에 대한 안정적인 온체인 성능 \ No newline at end of file +## 다음 권장 사항 + +- [**보장된 결제**](/ko/explanation/upcoming-use-cases): 보장된 블록 공간에 의존하는 결제 패턴을 확인하세요. 즉, 확정적 포함이 있는 정해진 DvP 결제 주기입니다. +- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token): 보장된 블록 공간을 통해 흐르는 자산을 이해합니다. +- [**토큰 경제학**](/ko/reference/tokenomics): STABLE 스테이킹이 검증인의 블록 공간 보증을 어떻게 뒷받침하는지 검토합니다. diff --git a/docs/pages/ko/explanation/high-performance-rpc.mdx b/docs/pages/ko/explanation/high-performance-rpc.mdx index e32e6a1..b51787f 100755 --- a/docs/pages/ko/explanation/high-performance-rpc.mdx +++ b/docs/pages/ko/explanation/high-performance-rpc.mdx @@ -1,85 +1,92 @@ --- source_path: explanation/high-performance-rpc.mdx -source_sha: bc4a47aca13a4da0d335144b2d417952fc657edc +source_sha: e9b9e14a5ef34ddf17d96530fc4c39dcce765caf title: "고성능 RPC" -description: "읽기와 쓰기를 분리하여 고처리량과 저지연을 달성하는 Stable의 분리형 RPC 아키텍처." +description: "읽기와 쓰기를 분리하여 높은 처리량, 낮은 지연 시간 액세스를 제공하는 Stable의 분할 경로 RPC 아키텍처." +diataxis: "explanation" --- # 고성능 RPC -고성능 블록체인을 구현하기 위해서는 합의나 블록 생성만을 최적화해서는 충분하지 않습니다. RPC 계층은 블록체인과 사용자를 연결하는 인터페이스로, 사용자 경험에 있어 핵심적인 구성 요소입니다. Stable은 기존 RPC 설계의 한계를 극복하기 위해 새로운 RPC 전용 아키텍처를 제안합니다. +고성능 블록체인을 추구하는 데 있어서 합의 또는 블록 생성만 최적화하는 것으로는 충분하지 않습니다. RPC 계층은 블록체인과 사용자 간의 인터페이스이므로 종단 간 사용자 경험의 중요한 구성 요소입니다. Stable은 기존 RPC 설계의 한계를 극복하기 위해 새로운 RPC 전용 아키텍처를 제안합니다. -## 왜 고성능 RPC가 중요한가 +## 고성능 RPC가 중요한 이유 -### 사용자를 위한 블록체인 진입 관문 +### 블록체인으로 향하는 사용자의 관문 -**RPC(Remote Procedure Call)** 인터페이스는 사용자가 블록체인과 상호작용하는 주요 방법입니다: +**원격 프로시저 호출(RPC)** 인터페이스는 사용자가 블록체인과 상호 작용하는 주요 방법입니다. -- 지갑은 트랜잭션을 브로드캐스트하기 위해 RPC를 사용합니다. -- DApp은 UI 렌더링을 위한 온체인 데이터 조회뿐 아니라, 트랜잭션 준비 및 시뮬레이션, 로그 및 이벤트 수집 등을 위해 RPC를 사용합니다. -- 익스플로러, 인덱서, 봇 등도 모두 실시간 데이터를 위해 RPC에 의존합니다. +- 지갑은 RPC를 사용하여 트랜잭션을 브로드캐스트합니다. +- dApp은 RPC를 통해 상태를 쿼리하여 온체인 데이터로 UI를 렌더링하고, 트랜잭션을 준비 및 시뮬레이션하고, 로그 및 이벤트를 가져오는 등의 작업을 수행합니다. +- 익스플로러, 인덱서 및 봇은 모두 실시간 데이터를 위해 RPC에 의존합니다. -아무리 블록체인이 트랜잭션을 빠르게 처리하고 블록을 신속하게 생성할 수 있어도, 사용자가 RPC 단의 지연 때문에 느리다고 느낀다면 아무 소용이 없습니다. 실제로는 RPC가 전체 사용자 경험에서 병목 지점이 되는 경우가 많습니다. +블록체인이 번개 같은 속도로 트랜잭션을 처리하고 블록을 빠르게 생성할 수 있더라도, 느린 RPC로 인해 사용자가 지연 시간을 경험한다면 아무 소용이 없습니다. 실제로 RPC는 종종 전반적인 사용자 경험에서 병목 현상이 될 수 있습니다. -Stable은 고성능 체인을 위한 로드맵에서 **RPC 최적화**를 최우선 과제로 명시하고 있습니다. +Stable의 고성능 체인을 향한 로드맵에는 **RPC 최적화**가 최우선 과제로 명시적으로 포함되어 있습니다. ## 기존 RPC 아키텍처의 문제점 -### 모놀리식 설계와 리소스 충돌 +### 모놀리스 설계 및 리소스 경합 Traditional RPC Architecture -기존의 RPC 노드는 단순히 기존 풀노드를 재활용하여 RPC 엔드포인트를 추가로 노출시킨 형태입니다. 이는 다음과 같은 단점이 존재한다는 것을 의미합니다: +전통적으로 RPC 노드는 추가 RPC 엔드포인트가 노출된 용도 변경된 풀 노드에 불과합니다. 이는 다음을 의미합니다. -- 체인 동기화와 RPC 요청 처리가 동일한 인스턴스에서 수행됩니다. -- RPC를 확장하려면 풀노드를 새로 셋업해야 하며, 이로 인해 상태 동기화(state sync)나 합의 셋업과 같은 리소스 집약적인 작업이 필요합니다. -- 합의, 실행, RPC가 모두 동일한 CPU, 메모리, 디스크를 공유합니다. 예를 들어 트랜잭션 부하가 높을 때 한 컴포넌트가 자원을 독점하면, 나머지 컴포넌트가 충분한 리소스를 얻지 못해 RPC 성능이 저하됩니다. +- 체인 동기화 및 RPC 요청 서비스가 동일한 인스턴스에서 발생합니다. +- RPC를 확장하려면 팀은 전체 새 풀 노드를 가동해야 하며, 이는 상태 동기화 및 합의 설정과 같이 리소스가 많이 소모되는 작업을 트리거합니다. +- 합의, 실행 및 RPC는 모두 동일한 CPU, 메모리 및 디스크를 공유합니다. 높은 트랜잭션 부하 기간 동안 바쁜 구성 요소는 **다른 구성 요소를 굶겨** RPC 성능을 저하시킵니다. -또한 기존 아키텍처는 읽기 위주와 쓰기 위주의 연산을 구분하지 않고 동일한 방식으로 처리합니다. 예를 들어 `eth_getBalance`와 같은 읽기 쿼리는 쓰기 트랜잭션보다 훨씬 빈도 수가 많지만, 처리 방식에는 차이가 없습니다. 이러한 구조는 본질적으로 비효율적이며 확장성이 떨어집니다. +또한 기존 RPC 아키텍처는 읽기 위주 작업과 쓰기 위주 작업을 동일하게 처리합니다. 읽기 쿼리(예: `eth_getBalance`)가 쓰기 트랜잭션보다 훨씬 많음에도 불구하고 처리 방식에 차이가 없습니다. 이 설계는 본질적으로 비효율적이고 확장 불가능합니다. -## Stable의 RPC 아키텍처 +## Stable RPC 아키텍처 -Stable은 읽기와 쓰기를 분리하고 각 경로를 독립적으로 최적화하는 split-path RPC 아키텍처를 도입합니다. +Stable은 읽기와 쓰기를 분리하고 각각을 독립적으로 최적화하는 분할 경로 RPC 아키텍처를 도입합니다. Stable RPC Architecture ### 핵심 원칙 -- RPC를 기능에 따라 효율적이고 경량화된 RPC 노드로 분리 -- 경량 RPC를 엣지 노드(edge nodes)로 배포하여 확장성 강화 -- 각 기능별 RPC의 데이터 경로를 최적화하여 지연을 줄이고 더 직접적이고 효율적인 데이터 구조로 처리 +- 기능에 따라 RPC를 효율적인 경량 RPC 노드로 분리합니다. +- 확장성을 향상시키기 위해 경량 RPC를 에지 노드로 사용합니다. +- 기능별 RPC의 데이터 경로를 최적화하여 대기 시간을 줄이고, 보다 효율적인 데이터 구조를 통해 보다 직접적인 액세스 또는 관리를 제공합니다. ### 성능 향상 -새로운 읽기 전용 RPC 경로에 대한 내부 벤치마크 결과는 다음과 같습니다. +새로운 읽기 RPC 경로에 대한 내부 벤치마크는 다음을 보여줍니다. -- 동일한 환경에서 10,000 RPS 이상의 처리량, 100ms 미만의 엔드투엔드 레이턴시 -- 전체 상태 동기화나 합의 부담 없이 선형 확장 가능한 엣지 노드 +- 동일 환경에서 종단 간 대기 시간 100ms 미만으로 10,000 RPS 이상의 처리량을 지원합니다. +- 완전한 상태 동기화 또는 합의 오버헤드 없이 에지 노드의 선형적 확장성. -Stable의 새로운 RPC 아키텍처는 높은 트래픽에서도 훨씬 더 부드럽고 빠른 사용자 경험을 제공합니다. +Stable의 새로운 RPC 아키텍처는 트래픽이 많을 때에도 훨씬 더 원활하고 빠른 사용자 경험을 제공합니다. -## 향후 계획 +## 향후 작업 -### EVM View 호출 최적화 +### EVM 뷰 호출 최적화 -현재 진행 중인 리서치 중 하나는 EVM view 연산 (`eth_call`)에 대한 전용 지원입니다: +진행 중인 연구의 흥미로운 영역 중 하나는 EVM 뷰 작업(`eth_call`)에 대한 전용 지원입니다. -- 이 연산은 트랜잭션 커밋이나 상태 업데이트를 필요로 하지 않습니다. -- 현재의 상태에 대한 스냅샷만을 사용하는 경량화된 무상태(stateless) 환경에서 실행이 가능합니다. -- 이러한 작업을 위한 특화된 RPC 노드를 설계하면, 응답 시간을 더욱 단축시키고 주요 전체 노드의 부하를 줄일 수 있습니다. +- 이들은 트랜잭션 커밋 또는 상태 업데이트를 필요로 하지 않습니다. +- 실행은 현재 상태 스냅샷만 사용하는 경량 무상태 환경에서 발생할 수 있습니다. +- 이러한 작업을 위해 특별히 설계된 특수 RPC 노드를 통해 응답 시간을 더욱 단축하고 기본 풀 노드의 부하를 줄일 수 있습니다. -### 인덱서와 노드의 결합 +### 인덱서를 노드에 직접 통합 -인덱서를 노드에 직접 통합하면 dApp에 최대한 빠른 데이터 제공이 가능해집니다. +인덱서를 노드에 직접 통합하면 dApp에 가능한 가장 빠른 데이터를 제공할 수 있습니다. -- 기존 아키텍처: 노드 → RPC → 인덱서 (예: The Graph) → 스토리지 → dApp -- 제안된 아키텍처: 인덱서 + 노드 → DB → dApp -- 이 아키텍처는 인덱서가 노드에 네이티브로 통합되어 있기 때문에, 네트워크 통신 단계를 제거하고 데이터 전달 속도를 획기적으로 향상시킵니다. \ No newline at end of file +- 일반적인 아키텍처: Node → RPC → Indexer (예: The Graph) → Storage → dApp +- 제안하는 아키텍처: Node with Indexer → DB → dApp +- 이 아키텍처는 인덱서가 노드에 내장되어 네트워크 통신 단계를 제거하므로 훨씬 빠른 데이터 전송이 가능합니다. + +## 다음 권장 사항 + +- [**JSON-RPC API**](/ko/reference/json-rpc-api): Stable이 노출하는 `eth_*` 메서드를 사용하여 계약 읽기, 트랜잭션 제출 및 로그 필터링을 수행합니다. +- [**실행**](/ko/explanation/execution): 실행이 어떻게 상태를 RPC 계층에 공급하는지 확인합니다. +- [**스토리지(StableDB)**](/ko/explanation/stable-db): RPC 읽기 쿼리가 사용하는 스토리지 계층을 검토합니다. diff --git a/docs/pages/ko/explanation/integrate-overview.mdx b/docs/pages/ko/explanation/integrate-overview.mdx index dc855e1..016b7f6 100644 --- a/docs/pages/ko/explanation/integrate-overview.mdx +++ b/docs/pages/ko/explanation/integrate-overview.mdx @@ -1,34 +1,34 @@ --- source_path: explanation/integrate-overview.mdx -source_sha: d27d65208399664dc2a63d2133789c860d4bd32f +source_sha: 9dd60bd0150dd9582e3cfb0bba0a72469b34a1bc title: "개요" -description: "Stable에 연결하고, USDT0를 전송하고, USDT 네이티브 Layer 1에서 결제 흐름을 구축하는 데 필요한 모든 것." +description: "Stable에 연결하고, USDT0를 보내고, USDT 기반 레이어 1에서 결제 흐름을 구축하는 데 필요한 모든 것." diataxis: "explanation" --- # 개요 -Stable은 USDT0가 네이티브 가스 토큰인 EVM 호환 Layer 1입니다. 대부분의 이더리움 도구, 라이브러리, 컨트랙트 패턴은 수정 없이 작동합니다. RPC를 Stable로 지정하고 체인 ID를 전환하여 연결할 수 있습니다. +Stable은 USDT0가 기본 가스 토큰인 EVM 호환 레이어 1입니다. 대부분의 이더리움 툴, 라이브러리 및 컨트랙트 패턴은 수정 없이 작동합니다. RPC를 Stable로 연결하고 체인 ID를 전환하여 연결합니다. -## 연결 및 자금 충전 +## 연결 및 자금 조달 -- [**연결**](/ko/reference/connect) — 메인넷 및 테스트넷 체인 ID, RPC 엔드포인트, 블록 익스플로러. -- [**테스트넷 지갑에 자금 충전**](/ko/how-to/use-faucet) — 포셋을 통해 테스트넷 USDT0를 받거나 Sepolia에서 브리지하세요. -- [**Stable SDK**](/ko/explanation/sdk-overview) — 전송, 브리지, 스왑을 위한 타입이 지정된 TypeScript 클라이언트를 사용하세요. +- [**연결**](/ko/reference/connect): 메인넷 및 테스트넷 체인 ID, RPC 엔드포인트, 블록 탐색기. +- [**테스트넷 지갑에 자금 조달**](/ko/how-to/use-faucet): faucet 또는 Sepolia에서 브리지를 통해 테스트넷 USDT0를 받으세요. +- [**Stable SDK**](/ko/explanation/sdk-overview): 전송, 브리지 및 스왑을 위해 타입스크립트 클라이언트를 사용하세요. ## USDT0로 구축하기 -- [**첫 USDT0 전송하기**](/ko/tutorial/send-usdt0) — TypeScript 예제와 함께하는 네이티브 및 ERC-20 전송. -- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior) — 이중 역할 잔액 조정, 컨트랙트 설계 요구사항, 마이그레이션 체크리스트. -- [**이더리움과의 차이점**](/ko/explanation/ethereum-comparison) — 단일 슬롯 완결성, USDT0 가스, 우선순위 팁 없음. -- [**제로 가스 트랜잭션**](/ko/how-to/integrate-gas-waiver) — Waiver Server API를 통한 Gas Waiver 통합. +- [**첫 USDT0 전송하기**](/ko/tutorial/send-usdt0): 타입스크립트 예시를 통한 네이티브 및 ERC-20 전송. +- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior): 이중 역할 잔액 조정, 컨트랙트 설계 요구사항, 마이그레이션 체크리스트. +- [**이더리움과의 차이점**](/ko/explanation/ethereum-comparison): 단일 슬롯 완결성, USDT0 가스, 우선순위 팁 없음. +- [**가스 없는 트랜잭션**](/ko/how-to/integrate-gas-waiver): Waiver Server API를 통한 가스 면제 통합. ## 결제 -- [**ERC-3009**](/ko/explanation/erc-3009) — Transfer With Authorization: 온체인 정산 프리미티브. -- [**x402**](/ko/explanation/x402) — 계정이나 API 키가 필요 없는 HTTP 네이티브 결제. -- [**P2P 결제**](/ko/reference/p2p-payments) — 네이티브 및 ERC-3009 위임 전송. +- [**ERC-3009**](/ko/explanation/erc-3009): 승인 전송: 온체인 정산 기본 요소. +- [**x402**](/ko/explanation/x402): 계정이나 API 키 없이 HTTP 네이티브 결제. +- [**P2P 결제**](/ko/reference/p2p-payments): 네이티브 및 ERC-3009 위임 전송. -## 에코시스템 +## 생태계 -공급자와 인프라가 이미 Stable에서 운영되고 있습니다: 브리지, [표준 Uniswap v3 배포](/ko/reference/dexes), 오라클, RPC, 지갑, 커스터디 등. 전체 목록은 [에코시스템](/ko/reference/bridges) 섹션을 둘러보세요. +Stable에 이미 활성화된 공급자 및 인프라: 브리지, [정식 Uniswap v3 배포](/ko/reference/dexes), 오라클, RPC, 지갑, 커스터디 등. 전체 목록은 [생태계](/ko/reference/bridges) 섹션을 참조하세요. diff --git a/docs/pages/ko/explanation/key-features.mdx b/docs/pages/ko/explanation/key-features.mdx index 6b50a12..e51d58c 100755 --- a/docs/pages/ko/explanation/key-features.mdx +++ b/docs/pages/ko/explanation/key-features.mdx @@ -1,20 +1,36 @@ --- source_path: explanation/key-features.mdx -source_sha: ec20a9f726140707f7ebd0cb56b921b3fc4e26b2 -title: "주요 기능" -description: "EVM 호환성, dPoS 합의, 서브초 파이널리티, USDT 네이티브 설계 등 Stable의 핵심 기술 특성." +source_sha: 743dbe77cee418846f01652fecf871c2ab504539 +title: '주요 기능' +description: "Stable의 주요 사양(단일 슬롯 완결성, USDT0를 가스비로 사용, 완벽한 EVM 호환성)과 그 위에 구축된 USDT 특정 기능." +diataxis: "explanation" --- # 주요 기능 -Stable은 USDT 기반 활동을 원활하게 지원하기 위해 설계된 고성능 블록체인입니다. **위임 지분증명 (dPoS)** 메커니즘 위에 구축된 Stable은 **완전한 EVM 호환성**을 제공하며, **1초 미만의 블록 생성 시간**을 통해 빠르고 신뢰성 높은 트랜잭션 완결성을 달성합니다. **USDT에 특화**된 네트워크인 Stable은 사용자 경험을 최적화하는 다양한 USDT 전용 기능을 제공합니다. +Stable은 단일 슬롯 완결성, 완전한 EVM 호환성, USDT0를 기본 가스 토큰으로 사용하는 DPoS(Delegated Proof-of-Stake) 레이어 1입니다. 아래 기능들은 일상적인 통합을 형성하는 기능들입니다. 각 기능은 해당 기능을 심층적으로 다루는 페이지로 연결됩니다. -### 주요 기능 +## 프로토콜 수준 기능 -- **1초 미만의 블록 완결성**: 단일 슬롯 완결성와 함께 1초 미만의 블록 타임을 달성합니다. -- **100% EVM 호환성**: Ethereum의 스마트 컨트랙트 및 툴링을 완벽히 지원합니다. -- **USDT를 가스 토큰으로 사용**: USDT0를 네이티브 가스 토큰으로 사용합니다. USDT0는 가스 결제와 가치 전송을 위한 네이티브 자산으로 동시에 기능하며, `approve`, `transfer`, `transferFrom`, `permit`을 지원하는 ERC20 토큰으로도 동작합니다. -- **USDT0 크로스체인 브릿지**: Ethereum, Arbitrum, HyperEVM 같은 EVM 체인뿐 아니라 Tron 등 다른 체인에서도 USDT0를 Stable로 브릿지할 수 있습니다. -- **Stable Pay을 통한 Web2.5 수준의 사용자 경험**: Stable Pay을 통해 직관적이고 원활한 사용자 경험을 제공합니다. +| 기능 | 의미 | +| :--- | :--- | +| **단일 슬롯 완결성** | 트랜잭션은 블록에 포함되면 최종 확정됩니다. 여러 블록 확인을 기다릴 필요가 없습니다. | +| **완벽한 EVM 호환성** | Solidity, Vyper, Foundry, Hardhat, ethers, viem 및 `eth_*` RPC 메서드가 변경 없이 작동합니다. | +| **USDT0를 가스비로 사용** | 하나의 자산이 기본 잔액과 ERC-20 역할을 모두 수행합니다. 별도의 가스 토큰을 보유할 필요가 없습니다. | +| **크로스체인 브릿징** | USDT0는 LayerZero OFT를 통해 이더리움, Arbitrum, HyperEVM, Tron 및 기타 체인에서 Stable로 이동합니다. | -향후 Stable은 USDT의 활용성과 네트워크 효율을 더욱 높이기 위한 기능을 추가로 도입할 예정입니다. **USDT 전송 집계** 기능은 여러 개의 USDT 관련 트랜잭션을 하나의 번들로 묶어 처리량을 향상할 것이며, **보장된 블록스페이스**는 기관이 예측 가능하고 안정적인 환경에서 USDT를 사용할 수 있도록 지원할 것입니다. 이러한 업그레이드를 통해 Stable은 USDT의 중심지로 자리매김할 것입니다. \ No newline at end of file +## USDT 특정 기능 + +- [**USDT를 가스비로 사용**](/ko/explanation/usdt-as-gas-token): USDT0는 동일한 잔액에서 기본 가스 토큰과 ERC-20 토큰의 역할을 모두 수행합니다. +- [**가스비 면제**](/ko/explanation/gas-waiver): 거버넌스 승인 면제는 사용자 대신 0 가스 가격으로 실행되는 래퍼 트랜잭션을 제출합니다. +- [**보장된 블록 공간**](/ko/explanation/guaranteed-blockspace): 엔터프라이즈 파트너는 결제 흐름을 위해 모든 블록에 예약된 용량을 확보합니다. +- [**USDT 전송 애그리게이터**](/ko/explanation/usdt-transfer-aggregator): 대량의 USDT0 전송은 병렬화되고 내결함성이 있는 정산 번들로 일괄 처리됩니다. +- [**기밀 전송**](/ko/explanation/confidential-transfer): 영지식 암호화는 전송 금액을 보호하면서 당사자가 감사받을 수 있도록 합니다. + +어떤 업그레이드가 현재 적용되고 있고 어떤 업그레이드가 로드맵에 있는지 확인하려면 [로드맵](/ko/explanation/technical-roadmap)을 참조하세요. + +## 다음 권장 사항 + +- [**이더리움 비교**](/ko/explanation/ethereum-comparison): 이더리움에서 Stable로 포팅할 때 어떤 점이 동일하게 유지되고 어떤 점이 변경되는지 확인합니다. +- [**자금 흐름**](/ko/explanation/flow-of-funds): 온램프에서 온체인 전송을 거쳐 오프램프 정산까지 USDT의 경로를 추적합니다. +- [**아키텍처 개요**](/ko/explanation/core-optimization-overview): 이러한 기능을 제공하는 합의, 실행, 데이터베이스 및 RPC 계층을 살펴봅니다. diff --git a/docs/pages/ko/explanation/learn-overview.mdx b/docs/pages/ko/explanation/learn-overview.mdx index 9c9db80..fd10cee 100644 --- a/docs/pages/ko/explanation/learn-overview.mdx +++ b/docs/pages/ko/explanation/learn-overview.mdx @@ -1,37 +1,37 @@ --- source_path: explanation/learn-overview.mdx -source_sha: 67ee178c4a5e4a4fbf9902ff3c40a022a75818eb -title: "학습하기" -description: "Stable의 개념, 아키텍처, 사용 사례 내러티브. Stable이 무엇인지, 이더리움과 어떻게 다른지, 그리고 가스로서의 USDT0에 담긴 사고 모델을 다룹니다." +source_sha: a3bae707c2afb7477e50291b1b1311296a75a208 +title: "배우기" +description: "Stable에 대한 개념, 아키텍처, 사용 사례 내러티브. Stable이 무엇인지, 이더리움과 어떻게 다른지, 그리고 USDT0를 가스로 사용하는 배경에 대한 정신적 모델." diataxis: "explanation" --- -# 학습하기 +# 배우기 ## 기초 -- [**개요**](/ko/explanation/overview) — Stable이 무엇이며 이 문서를 어떻게 읽어야 하는지 설명합니다. -- [**주요 기능**](/ko/explanation/key-features) — 핵심 사양: 단일 슬롯 완결성, 가스로서의 USDT0, 완전한 EVM 호환성. -- [**이더리움과의 차이점**](/ko/explanation/ethereum-comparison) — 이더리움에서 포팅할 때 유지되는 것과 바뀌는 것. -- [**핵심 개념**](/ko/explanation/core-concepts) — USDT0의 이중 역할, 보장된 블록 공간, 전송 애그리게이터, 완결성. +- [**개요**](/ko/explanation/overview): Stable이 무엇이며 이 문서를 읽는 방법. +- [**주요 기능**](/ko/explanation/key-features): 주요 사양: 단일 슬롯 완결성, 가스로서의 USDT0, 완전한 EVM 호환성. +- [**이더리움과의 차이점**](/ko/explanation/ethereum-comparison): 이더리움에서 포팅할 때 유지되는 것과 변경되는 것. +- [**핵심 개념**](/ko/explanation/core-concepts): USDT0의 이중 역할, 보장된 블록 공간, 전송 통합자, 완결성. -## USDT0 동작 +

USDT0 동작

-- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior) — 이중 역할 잔액, 조정 이벤트, 컨트랙트 설계 규칙. -- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token) — Stable이 가스 지불에 USDT0를 사용하는 이유와 그것이 수수료에 미치는 의미. -- [**자금 흐름**](/ko/explanation/flow-of-funds) — USDT가 Stable 전반에서 처음부터 끝까지 어떻게 이동하는지. -- [**USDT0 기능**](/ko/explanation/usdt-features-overview) — 모든 USDT0 전용 기능과 각각으로 연결되는 링크. +- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior): 이중 역할 잔액, 조정 이벤트, 계약 설계 규칙. +- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token): Stable이 가스 비용 지불에 USDT0를 사용하는 이유와 이것이 수수료에 미치는 영향. +- [**자금 흐름**](/ko/explanation/flow-of-funds): Stable에서 USDT가 엔드투엔드로 이동하는 방법. +- [**USDT0 기능**](/ko/explanation/usdt-features-overview): 각 링크가 있는 모든 USDT0 특정 기능. ## 아키텍처 -- [**기술 개요**](/ko/explanation/tech-overview) — 합의, 실행, 데이터베이스, RPC 계층을 한 페이지에 담았습니다. -- [**핵심 최적화**](/ko/explanation/core-optimization-overview) — 1초 미만의 완결성을 뒷받침하는 성능 작업. -- [**완결성**](/ko/explanation/finality) — 단일 슬롯 완결성, 리오그 동작, 그리고 "확정됨"이 의미하는 것. -- [**가스 가격 책정**](/ko/explanation/gas-pricing) — USDT0로 가격이 책정되는 기본 수수료 전용 모델. +- [**기술 개요**](/ko/explanation/tech-overview): 합의, 실행, 데이터베이스 및 RPC 계층을 한 페이지에. +- [**핵심 최적화**](/ko/explanation/core-optimization-overview): 1초 미만 완결성 뒤에 숨겨진 성능 작업. +- [**완결성**](/ko/explanation/finality): 단일 슬롯 완결성, 재구성 동작, "확인됨"의 의미. +- [**가스 가격 책정**](/ko/explanation/gas-pricing): USDT0로 가격이 책정된 기본 수수료 전용 모델. ## 사용 사례 내러티브 -- [**결제**](/ko/explanation/use-case-payments) — Stable이 P2P, 구독, 청구서, 호출당 지불에 적합한 이유. -- [**급여 지급**](/ko/explanation/use-case-payroll) — Stable에서 일괄 처리 및 예약된 급여 지급 실행. -- [**스폰서드 트랜잭션**](/ko/explanation/use-case-sponsored) — 애플리케이션이 사용자를 위해 가스를 대신 부담하도록 하기. -- [**프라이빗 전송**](/ko/explanation/use-case-private) — 곧 출시될 기밀 결제 흐름. +- [**결제**](/ko/explanation/use-case-payments): Stable이 P2P, 구독, 송장, 종량제에 적합한 이유. +- [**급여**](/ko/explanation/use-case-payroll): Stable에서 일괄 및 예약된 급여 실행. +- [**스폰서 트랜잭션**](/ko/explanation/use-case-sponsored): 애플리케이션이 사용자 가스 비용을 부담하게 하는 기능. +- [**개인 전송**](/ko/explanation/use-case-private): 향후 기밀 결제 흐름. diff --git a/docs/pages/ko/explanation/mpp-sessions.mdx b/docs/pages/ko/explanation/mpp-sessions.mdx index 1156b9e..226581d 100644 --- a/docs/pages/ko/explanation/mpp-sessions.mdx +++ b/docs/pages/ko/explanation/mpp-sessions.mdx @@ -1,49 +1,49 @@ --- source_path: explanation/mpp-sessions.mdx -source_sha: 872aae7c355e2b4c4bcc1af096a3aafd94b6c629 +source_sha: 6f43e7cd526e4569c47f211fd30a611e3f3cbd50 title: "MPP 세션" -description: "요청마다 온체인 결제를 하나씩 처리하는 대신, 오프체인 바우처와 한 번의 순결제로 마이크로페이먼트를 스트리밍하세요." +description: "요청당 하나의 온체인 결제 대신 오프체인 바우처와 하나의 순정산을 통해 마이크로 결제를 스트리밍합니다." diataxis: "explanation" --- # MPP 세션 -세션은 여러 개의 작은 결제를 하나의 온체인 정산으로 묶는 MPP 결제 인텐트입니다. 클라이언트는 에스크로에 자금을 한 번 예치한 후, 각 요청에 대해 저렴한 오프체인 바우처에 서명합니다. 온체인에서는 순액만 정산되므로, 스트리밍 워크로드에서 요청당 1센트 미만의 경제성을 실현할 수 있습니다. +세션은 많은 소액 결제를 단일 온체인 정산으로 일괄 처리하는 MPP 결제 의도입니다. 클라이언트는 에스크로에 한 번 자금을 예치한 다음 각 요청에 대해 저렴한 오프체인 바우처에 서명합니다. 온체인에서는 순액만 정산되므로 스트리밍 워크로드에 대해 요청당 센트 미만의 경제성이 가능합니다. -## 세션의 작동 방식 +## 세션 작동 방식 -1. **예치.** 클라이언트는 정산 레이어의 세션 에스크로 컨트랙트에 예산을 전송합니다. 에스크로는 자금을 보관하고, 판매자에게 지급하고 나머지를 환불하는 정산 함수를 노출합니다. -2. **요청당 바우처.** 각 유료 요청에 대해 클라이언트는 `(sessionId, cumulativeAmount, nonce, expiry)`를 담은 오프체인 바우처에 서명합니다. 서버는 누적 금액이 단조 증가하며 예치된 잔액 이내인지 확인합니다. 이 단계에서는 온체인 작업이 필요하지 않습니다. -3. **정산.** 세션 종료 시 또는 설정된 주기에 따라, 퍼실리테이터가 최신 바우처를 에스크로에 제출합니다. 에스크로는 판매자에게 누적 금액을 지급하고 남은 잔액을 클라이언트에게 반환합니다. 오직 이 트랜잭션만 체인에 기록됩니다. +1. **예치.** 클라이언트는 정산 계층의 세션-에스크로 계약에 예산을 이체합니다. 에스크로는 자금을 보유하고 판매자에게 지급하고 잔액을 환불하는 정산 기능을 노출합니다. +2. **요청당 바우처.** 각 유료 요청에 대해 클라이언트는 `(sessionId, cumulativeAmount, nonce, expiry)`를 포함하는 오프체인 바우처에 서명합니다. 서버는 누적 금액이 단조 증가하고 예치된 잔액 내에 있는지 확인합니다. 이 단계에서는 온체인 작업이 필요하지 않습니다. +3. **정산.** 세션이 끝날 때 또는 구성된 주기에 따라 촉진자는 최신 바우처를 에스크로에 제출합니다. 에스크로는 판매자에게 누적 금액을 지불하고 남은 잔액을 클라이언트에게 반환합니다. 이 거래만 체인을 건드립니다. -세션은 최신 바우처가 정산되거나 바우처 만료 시점이 지나면 종료됩니다. +세션은 최신 바우처가 정산되거나 바우처 만료가 지나면 최종적으로 확정됩니다. -## 세션과 charge 중 어느 것을 사용할지 +## 세션과 청구 사용 시기 -| **워크로드** | **최적의 인텐트** | +| **워크로드** | **최고의 의도** | | :--- | :--- | -| 토큰당 과금 LLM 추론, 프레임당 과금 비디오, 실시간 데이터 스트림. 동일한 판매자에게 보내는 다수의 소액 결제. | Session | -| 일회성 유료 API 호출, 단일 구매 리소스, 각 트랜잭션이 독립적인 에이전트 간 커머스. | Charge | +| 토큰당 LLM 추론, 프레임당 비디오, 실시간 데이터 스트림. 동일한 판매자에게 많은 소액 결제. | 세션 | +| 일회성 유료 API 호출, 단일 구매 리소스, 각 거래가 독립적인 에이전트 간 상거래. | 청구 | -손익분기점은 요청 가격 대비 요청당 온체인 정산 비용이 얼마나 비싼지에 따라 달라집니다. 결제보다 가스에 더 많은 비용을 지불하게 되는 순간, 세션이 적합한 패턴입니다. +손익분기점은 요청 가격 대비 요청당 온체인 정산 비용에 따라 달라집니다. 결제보다 가스에 더 많은 비용을 지불하는 즉시 세션이 올바른 패턴입니다. -## 에이전트 활용 사례 +## 에이전트 사용 사례 -- **토큰 단위 과금 LLM 추론.** 클라이언트가 컴플리션을 스트리밍하고 토큰 배치마다 바우처에 서명하며, 추론 서버는 세션 종료 시 정산합니다. -- **프레임 단위 과금 비디오.** 생성된 비디오를 소비하는 에이전트가 N개 프레임마다 바우처에 서명하며, 렌더러는 스트림이 종료될 때 정산합니다. -- **실시간 데이터 피드.** 구독자가 오라클 또는 마켓 데이터 스트림의 틱마다 결제하고, 세션 윈도우당 한 번 정산합니다. +- **토큰 가격 LLM 추론.** 클라이언트는 완성을 스트리밍하고 토큰 배치당 바우처에 서명합니다. 추론 서버는 세션 종료 시 정산합니다. +- **프레임 가격 비디오.** 생성된 비디오를 소비하는 에이전트는 N 프레임당 바우처에 서명합니다. 렌더러는 스트림이 닫힐 때 정산합니다. +- **실시간 데이터 피드.** 구독자는 오라클 또는 시장 데이터 스트림의 틱당 지불하며, 세션 창당 한 번 정산합니다. -## Stable에서의 현황 +## Stable의 상태 -세션에는 Stable이 현재 제공하지 않는 두 가지 요소가 필요합니다: +세션에는 Stable에서 현재 제공하지 않는 두 가지 요소가 필요합니다. -1. 예치금을 보관하고 `settleVouchers`(또는 동등한) 함수를 노출하는, USDT0용 세션 인식 에스크로 컨트랙트. -2. 판매자 측에서 바우처를 발행하고 구매자 측에서 검증하며, 에스크로 제출을 배치 처리하는 퍼실리테이터. +1. 예치금을 보유하고 `settleVouchers`(또는 이와 동등한) 함수를 노출하는 USDT0용 세션 인식 에스크로 계약. +2. 판매자 측에서 바우처를 발행하고 구매자 측에서 확인하여 에스크로에 제출을 일괄 처리하는 촉진자. -이 두 가지가 모두 출시되기 전까지 MPP 세션은 Stable에서 사용할 수 없습니다. 오늘날 고빈도 에이전트 결제를 위한 가장 오버헤드가 낮은 패턴은 Stable의 [가스 면제](/ko/how-to/integrate-gas-waiver)를 통해 제출되는 **charge** 인텐트로, 판매자 측의 트랜잭션당 가스 비용을 제거하고 구매자의 USDT0 잔액을 유일하게 관리할 자산으로 유지합니다. 요청당 charge 패턴은 [Stable에서 MPP 엔드포인트 구축하기](/ko/how-to/build-mpp-endpoint)를 참고하세요. +두 가지 모두 출시될 때까지 MPP 세션은 Stable에서 사용할 수 없습니다. 오늘날 고주파 에이전트 결제의 경우, 가장 낮은 오버헤드 패턴은 Stable의 [가스 면제](/ko/how-to/integrate-gas-waiver)를 통해 제출된 **청구** 의도로, 판매자 측의 거래당 가스 비용을 제거하고 구매자의 USDT0 잔액을 관리해야 할 유일한 자산으로 유지합니다. 요청당 청구 패턴은 [Stable에서 MPP 엔드포인트 구축](/ko/how-to/build-mpp-endpoint)을 참조하십시오. -## 다음 추천 +## 다음 권장 사항 -- [**MPP 개념**](/ko/explanation/mpp) — charge 및 subscription 인텐트를 포함한 더 넓은 표준을 읽어보세요. -- [**에이전트 정산**](/ko/explanation/agent-settlement) — MPP 세션이 Stable의 에이전트 결제 레일에서 어디에 위치할지 확인하세요. -- [**Stable에서 MPP 엔드포인트 구축하기**](/ko/how-to/build-mpp-endpoint) — 세션이 출시되기 전까지 오늘날 charge 인텐트를 사용하세요. +- [**MPP 개념**](/ko/explanation/mpp): 청구 및 구독 의도를 포함한 광범위한 표준을 읽어보세요. +- [**에이전트 정산**](/ko/explanation/agent-settlement): Stable의 에이전트 결제 레일에 MPP 세션이 어디에 위치하는지 확인하세요. +- [**Stable에서 MPP 엔드포인트 구축**](/ko/how-to/build-mpp-endpoint): 세션이 출시될 때까지 오늘날 청구 의도를 사용하세요. diff --git a/docs/pages/ko/explanation/mpp.mdx b/docs/pages/ko/explanation/mpp.mdx index 1fcf551..b22e75f 100644 --- a/docs/pages/ko/explanation/mpp.mdx +++ b/docs/pages/ko/explanation/mpp.mdx @@ -1,63 +1,63 @@ --- source_path: explanation/mpp.mdx -source_sha: 9aafb5fd6791e2d6d14b6cb938ce94878b0e27a1 -title: "Machine Payments Protocol (MPP)" -description: "x402를 확장하는 IETF 트랙 결제 표준인 MPP와 Stable에서 USDT0 결제에 이를 사용하는 방법을 이해합니다." +source_sha: 02666af168909bb96414ce0c52d158b4af376522 +title: "머신 결제 프로토콜(MPP)" +description: "x402를 확장한 IETF 트랙 결제 표준 MPP와 Stable에서 USDT0 결제에 사용하는 방법을 이해해 보세요." diataxis: "explanation" --- -# Machine Payments Protocol (MPP) +# 머신 결제 프로토콜(MPP) -MPP(Machine Payments Protocol)는 HTTP 리소스를 요청하는 동일한 요청 내에서 결제할 수 있는 개방형 표준입니다. 이는 [x402](/ko/explanation/x402)를 새로운 결제 의도(charge, subscription, session), 멀티 레일 지원(스테이블코인, 카드, Lightning), 프로덕션 기능(멱등성, 본문 다이제스트 바인딩, 만료), 추가 전송 방식(MCP, WebSocket)으로 확장합니다. 이 프로토콜은 IETF 표준 트랙에 올라 있습니다. +MPP(Machine Payments Protocol)는 요청과 동시에 HTTP 리소스 비용을 지불하기 위한 개방형 표준입니다. 새로운 결제 의도(청구, 구독, 세션), 멀티 레일 지원(스테이블코인, 카드, 라이트닝), 생산 기능(멱등성, 본문 다이제스트 바인딩, 만료), 추가 전송(MCP, WebSocket)으로 [x402](/ko/explanation/x402)를 확장합니다. 이 프로토콜은 IETF 표준화 트랙에 있습니다. ## MPP와 x402 -MPP 클라이언트는 하위 호환성을 갖습니다. MPP 클라이언트는 변경 없이 기존 x402 서버를 호출할 수 있습니다. 두 프로토콜이 다른 부분은 다음과 같습니다: +MPP 클라이언트는 이전 버전과 호환됩니다. MPP 클라이언트는 기존 x402 서버를 변경 없이 호출할 수 있습니다. 두 프로토콜의 차이점: -| **항목** | **x402** | **MPP** | +| **측면** | **x402** | **MPP** | | :--- | :--- | :--- | -| 결제 의도 | 요청별 charge | Charge, subscription, session | -| 레일 | 블록체인만 | 스테이블코인, 카드, Lightning, 커스텀 | -| 프로덕션 기능 | 제한적 | 멱등성, 본문 다이제스트 바인딩, 만료 | -| 전송 방식 | HTTP | HTTP, MCP/JSON-RPC, WebSocket | -| 헤더 (클라이언트 ↔ 서버) | `PAYMENT-REQUIRED` / `PAYMENT-SIGNATURE` / `PAYMENT-RESPONSE` | `WWW-Authenticate` / `Authorization` / `Payment-Receipt` | -| 거버넌스 | 커뮤니티 프로토콜 | IETF 표준 트랙 | -| 메서드 작성 | 재단 통제 | 무허가형 | +| 결제 의도 | 요청당 청구 | 청구, 구독, 세션 | +| 레일 | 블록체인 전용 | 스테이블코인, 카드, 라이트닝, 사용자 지정 | +| 생산 기능 | 제한적 | 멱등성, 본문 다이제스트 바인딩, 만료 | +| 전송 | HTTP | HTTP, MCP/JSON-RPC, WebSocket | +| 헤더(클라이언트 ↔ 서버) | `PAYMENT-REQUIRED` / `PAYMENT-SIGNATURE` / `PAYMENT-RESPONSE` | `WWW-Authenticate` / `Authorization` / `Payment-Receipt` | +| 거버넌스 | 커뮤니티 프로토콜 | IETF 표준화 트랙 | +| 메서드 작성 | 재단 관리 | 허가 없는 | ## 챌린지, 자격 증명, 영수증 -MPP는 모든 유료 요청을 클라이언트와 리소스 서버 간의 3단계 교환으로 감쌉니다: +MPP는 모든 유료 요청을 클라이언트와 리소스 서버 간의 3단계 교환으로 래핑합니다. 1. **챌린지.** 서버는 `402 Payment Required`와 지원되는 메서드, 금액, 만료를 명시하는 `WWW-Authenticate` 헤더로 응답합니다. -2. **자격 증명.** 클라이언트는 메서드를 선택하고, 결제 증명에 서명한 뒤, 직렬화된 자격 증명을 담은 `Authorization` 헤더와 함께 요청을 다시 제출합니다. -3. **영수증.** 서버는 자격 증명을 검증하고, 결제를 정산한 뒤, 정산 참조를 담은 `Payment-Receipt` 헤더와 함께 응답을 반환합니다. +2. **자격 증명.** 클라이언트는 메서드를 선택하고, 결제 증명을 서명하고, 직렬화된 자격 증명을 전달하는 `Authorization` 헤더와 함께 요청을 다시 제출합니다. +3. **영수증.** 서버는 자격 증명을 확인하고, 결제를 정산하고, 정산 참조를 포함하는 `Payment-Receipt` 헤더와 함께 응답을 반환합니다. -챌린지는 본문 다이제스트를 통해 요청 본문에 암호학적으로 바인딩될 수 있으므로, 한 요청에 대해 서명된 자격 증명은 다른 요청에 재사용할 수 없습니다. +챌린지는 본문 다이제스트를 통해 요청 본문에 암호화 방식으로 바인딩될 수 있으므로, 한 요청에 서명된 자격 증명은 다른 요청에 재사용할 수 없습니다. ## 결제 의도 -**Charge.** 단일 리소스에 대한 일회성 결제입니다. 자격 증명은 정확한 금액의 한 번의 전송을 승인합니다. +**청구.** 단일 리소스에 대한 일회성 결제. 자격 증명은 정확한 금액의 한 번의 이체를 승인합니다. -**Subscription.** 단일 범위 자격 증명 하에서 반복되는 결제입니다. 자격 증명은 청구 기간에 걸쳐 반복 청구를 승인하며, 레일이 갱신 주기를 적용합니다. +**구독.** 단일 범위 자격 증명에 따른 반복 결제. 자격 증명은 과금 기간 동안 반복 청구를 승인하며, 레일이 갱신 주기를 적용합니다. -**Session.** 오프체인 바우처를 사용하는 종량제입니다. 클라이언트는 자금을 에스크로에 한 번 예치한 뒤, 각 요청에 대해 저렴한 오프체인 바우처에 서명합니다. 순 금액만 온체인에서 정산됩니다. 자세한 내용은 [MPP 세션](/ko/explanation/mpp-sessions)을 참고하세요. +**세션.** 오프체인 바우처를 사용한 종량제. 클라이언트는 에스크로에 한 번 자금을 예치한 다음, 각 요청에 대해 저렴한 오프체인 바우처를 서명합니다. 오직 순 금액만 온체인에서 정산됩니다. 자세한 내용은 [MPP 세션](/ko/explanation/mpp-sessions)을 참조하십시오. -## 전송 방식 +## 전송 -MPP는 여러 전송 방식에 걸쳐 동일한 챌린지 / 자격 증명 / 영수증 교환을 정의합니다: +MPP는 여러 전송을 통해 동일한 챌린지 / 자격 증명 / 영수증 교환을 정의합니다. -- **HTTP.** 기본값. 위에 나열된 헤더를 사용합니다. -- **MCP / JSON-RPC.** MCP 서버가 개별 툴 호출을 수익화할 수 있게 합니다. AI 클라이언트는 툴을 호출하기 전에 자격 증명에 서명합니다. -- **WebSocket.** 대역 내 바우처 충전이 가능한 지속 연결로, 스트리밍 세션을 위해 설계되었습니다. +- **HTTP.** 기본값. 위에 나열된 헤더. +- **MCP / JSON-RPC.** MCP 서버가 개별 도구 호출을 수익화할 수 있도록 합니다. AI 클라이언트는 도구를 호출하기 전에 자격 증명에 서명합니다. +- **WebSocket.** 스트리밍 세션용으로 설계된 인밴드 바우처 충전이 가능한 영속적인 연결. -## Stable에서의 MPP +## Stable의 MPP -MPP는 Stable 결제 메서드를 기본 제공하지 않습니다. `mppx` SDK([wevm/mppx](https://github.com/wevm/mppx))에는 Tempo와 Stripe 메서드가 포함되어 있으며, `mpp.dev`는 Tempo, Stripe, Lightning, Solana, Stellar, Monad, RedotPay를 나열합니다. 현재 Stable은 두 목록 어디에도 없습니다. +MPP는 Stable 결제 방법을 제공하지 않습니다. `mppx` SDK([wevm/mppx](https://github.com/wevm/mppx))에는 Tempo 및 Stripe 메서드가 포함되어 있으며, `mpp.dev`에는 Tempo, Stripe, Lightning, Solana, Stellar, Monad, RedotPay가 나열되어 있습니다. Stable은 오늘날 두 목록에 모두 없습니다. -이 표준은 무허가형이므로 직접 메서드를 작성할 수 있습니다. Stable의 USDT0의 경우, `verify()` 훅은 ERC-3009에 대한 서명 검증이며, 정산은 기존 정산 서비스에 위임됩니다. [Semantic Pay](https://docs.semanticpay.io)나 [Heurist](https://docs.heurist.ai/x402-products/facilitator) 같은 x402 퍼실리테이터, 또는 Stable 자체 [Gas Waiver](/ko/how-to/integrate-gas-waiver)가 그 예입니다. 전체 안내는 [Stable에서 MPP 엔드포인트 구축하기](/ko/how-to/build-mpp-endpoint)를 참고하세요. +표준은 허가되지 않으므로, 자신만의 메서드를 작성할 수 있습니다. Stable의 USDT0의 경우 `verify()` 훅은 ERC-3009에 대한 서명 유효성 검사이며, 정산은 기존 정산 서비스에 위임됩니다. [Semantic Pay](https://docs.semanticpay.io) 또는 [Heurist](https://docs.heurist.ai/x402-products/facilitator)와 같은 x402 촉진자 또는 Stable의 자체 [Gas Waiver](/ko/how-to/integrate-gas-waiver)입니다. 전체 설명은 [Stable에 MPP 엔드포인트 구축](/ko/how-to/build-mpp-endpoint)을 참조하십시오. -## 다음 추천 +## 다음 권장 사항 -- [**Stable에서 MPP 엔드포인트 구축하기**](/ko/how-to/build-mpp-endpoint) — USDT0를 위한 세 가지 MPP 커스텀 메서드 훅을 작성하고 실제 결제를 정산합니다. -- [**MPP 세션**](/ko/explanation/mpp-sessions) — 오프체인 바우처와 단일 순 정산으로 마이크로페이먼트를 스트리밍합니다. -- [**x402**](/ko/explanation/x402) — MPP가 일반화한 원래의 HTTP-402 프로토콜을 읽어봅니다. +- [**Stable에 MPP 엔드포인트 구축**](/ko/how-to/build-mpp-endpoint): USDT0에 대한 세 가지 MPP 사용자 지정 메서드 훅을 작성하고 실제 결제를 정산합니다. +- [**MPP 세션**](/ko/explanation/mpp-sessions): 오프체인 바우처와 하나의 순 정산을 통해 소액 결제를 스트리밍합니다. +- [**x402**](/ko/explanation/x402): MPP가 일반화하는 원래 HTTP-402 프로토콜을 읽습니다. diff --git a/docs/pages/ko/explanation/payment-use-cases-overview.mdx b/docs/pages/ko/explanation/payment-use-cases-overview.mdx index 90a6190..c1cffee 100644 --- a/docs/pages/ko/explanation/payment-use-cases-overview.mdx +++ b/docs/pages/ko/explanation/payment-use-cases-overview.mdx @@ -1,31 +1,31 @@ --- source_path: explanation/payment-use-cases-overview.mdx -source_sha: 4318f96f731d9b094368974969e39818ddee3488 -title: "활용 사례 개요" -description: "Stable의 결제 패턴: P2P 송금, 구독 청구, 인보이스 정산, 호출당 결제 API." +source_sha: bf9607c6c0449af0e3eb7cfc9a817d9c0e9cb9f2 +title: "사용 사례 개요" +description: "Stable의 결제 패턴: P2P 송금, 구독 결제, 청구서 결제, API 종량제." diataxis: "explanation" --- -# 활용 사례 개요 +# 사용 사례 개요 -Stable은 간단한 지갑 간 송금부터 에이전트 기반 서비스 결제까지 다양한 결제 패턴을 지원합니다. 아래 활용 사례는 오늘날 프로덕션에 바로 사용할 수 있는 패턴을 다룹니다. 곧 도입될 패턴(보장된 정산, 비공개 결제, 에이전트 간 상거래)에 대해서는 [예정된 활용 사례](/ko/explanation/upcoming-use-cases)를 참조하세요. +Stable은 단순한 지갑 간 송금부터 에이전트 기반 서비스 결제에 이르기까지 다양한 결제 패턴을 지원합니다. 아래 사용 사례는 현재 프로덕션에서 사용 가능한 패턴을 다룹니다. 향후 구현될 패턴(확약된 정산, 기밀 결제, 에이전트 간 상거래)에 대해서는 [향후 사용 사례](/ko/explanation/upcoming-use-cases)를 참조하십시오. -## 사용 가능한 활용 사례 +## 현재 사용 사례 -- [**P2P 결제**](/ko/reference/p2p-payments) — 지갑 간 USDT0 송금. 1초 미만의 정산, Gas Waiver를 통한 가스 비용 제로. -- [**구독 청구**](/ko/reference/subscriptions) — EIP-7702를 통한 풀 기반 정기 청구. 구독자가 한 번 승인하면 제공자가 주기마다 수금합니다. -- [**인보이스 정산**](/ko/reference/invoices) — 결정론적 논스를 사용하는 B2B 인보이스 결제. 온체인 정산이 인보이스에 자동으로 연결됩니다. -- [**호출당 결제 API**](/ko/reference/pay-per-call) — x402 미들웨어를 통한 요청별 HTTP 결제. 계정, API 키, 청구 주기가 필요 없습니다. +- [**P2P 결제**](/ko/reference/p2p-payments): 지갑 간 USDT0 송금. 1초 미만 정산, 가스 면제를 통한 가스 비용 없음. +- [**구독 결제**](/ko/reference/subscriptions): EIP-7702를 통한 풀 기반 반복 결제. 구독자는 한 번만 승인하고, 제공자는 매 주기마다 수금합니다. +- [**청구서 결제**](/ko/reference/invoices): 확정적인 논스를 사용한 B2B 청구서 결제. 온체인 정산은 자동으로 청구서에 연결됩니다. +- [**API 종량제**](/ko/reference/pay-per-call): x402 미들웨어를 통한 요청별 HTTP 결제. 계정, API 키, 청구 주기가 없습니다. -## 공통 기반 +## 공유 기반 -대부분의 패턴은 동일한 두 가지 프로토콜을 기반으로 구축됩니다: +대부분의 패턴은 동일한 두 가지 프로토콜을 기반으로 합니다. -- **[ERC-3009](/ko/explanation/erc-3009)**: 위임 정산을 위한 서명된 승인. 인보이스, 호출당 결제, P2P 애플리케이션 시작 송금에 사용됩니다. -- **[x402](/ko/explanation/x402)**: 표준 헤더를 통한 HTTP 네이티브 결제. 호출당 결제 API와 MCP 기반 결제 흐름에 사용됩니다. -- **[EIP-7702](/ko/explanation/eip-7702)**: 정기 승인을 위한 EOA 위임. 구독 청구에 사용됩니다. +- **[ERC-3009](/ko/explanation/erc-3009)**: 위임된 정산을 위한 서명된 승인. 청구서, 종량제 및 P2P 애플리케이션 시작 전송에 사용됩니다. +- **[x402](/ko/explanation/x402)**: 표준 헤더를 통한 HTTP 기본 결제. 종량제 API 및 MCP 기반 결제 흐름에 사용됩니다. +- **[EIP-7702](/ko/explanation/eip-7702)**: 반복 승인을 위한 EOA 위임. 구독 결제에 사용됩니다. -## 다음 추천 +## 다음 권장 사항 -- [**ERC-3009**](/ko/explanation/erc-3009) — 핵심 정산 표준부터 시작하세요. -- [**예정된 활용 사례**](/ko/explanation/upcoming-use-cases) — 에이전트 간 상거래, 보장된 정산, 비공개 결제를 미리 살펴보세요. +- [**ERC-3009**](/ko/explanation/erc-3009): 핵심 정산 표준부터 시작하십시오. +- [**향후 사용 사례**](/ko/explanation/upcoming-use-cases): 에이전트 간 상거래, 확약된 정산 및 기밀 결제를 미리 확인하십시오. diff --git a/docs/pages/ko/explanation/payments-guides.mdx b/docs/pages/ko/explanation/payments-guides.mdx index 4276f22..de6f00d 100644 --- a/docs/pages/ko/explanation/payments-guides.mdx +++ b/docs/pages/ko/explanation/payments-guides.mdx @@ -1,35 +1,35 @@ --- source_path: explanation/payments-guides.mdx -source_sha: 11c29bc514f62bd2d382c961ee76bd928b60daf7 +source_sha: 0454891901e0f1fe522a9dd1a91c5d73fd7519d7 title: "결제 가이드" -description: "모든 결제 가이드, 개념, 참조: USDT0 전송, P2P, 구독, 인보이스, 호출당 결제, 브리징, 제로 가스." +description: "모든 결제 가이드, 개념 및 참조 자료: USDT0 전송, P2P, 구독, 송장, 종량제, 브리징 및 제로 가스." diataxis: "explanation" --- # 결제 가이드 -결제 탭의 모든 가이드, 개념, 참조를 하려는 작업별로 그룹화했습니다. +결제 탭 아래의 모든 가이드, 개념 및 참조 자료를 시도하려는 작업별로 그룹화했습니다. -## 보내기 및 전송 +## 전송 및 이전 -- [**첫 USDT0 전송하기**](/ko/tutorial/send-usdt0) — 동일한 잔액에서의 네이티브 및 ERC-20 전송. -- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions) — Gas Waiver로 수수료가 충당되는 USDT0 전송. -- [**USDT0를 가스로 사용하기**](/ko/how-to/work-with-usdt-gas) — 트랜잭션을 올바르게 구성하기: priority tip 0, USDT0의 `value`. -- [**USDT0를 Stable로 브리징하기**](/ko/tutorial/bridge-usdt0) — LayerZero OFT를 사용하여 Ethereum Sepolia에서 브리징. +- [**첫 USDT0 전송하기**](/ko/tutorial/send-usdt0): 동일한 잔액에서 네이티브 및 ERC-20 전송. +- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions): 가스 면제(Gas Waiver)를 통해 수수료가 처리되는 USDT0 전송. +- [**USDT0를 가스로 사용하기**](/ko/how-to/work-with-usdt-gas): 트랜잭션 올바르게 구성하기: 우선순위 팁 0, USDT0로 `value`. +- [**USDT0를 Stable로 브릿징하기**](/ko/tutorial/bridge-usdt0): LayerZero OFT를 사용하여 이더리움 세폴리아에서 브릿징. ## 결제 흐름 구축 -- [**P2P 결제 알아보기**](/ko/how-to/build-p2p-payments) — 하나의 앱에서 지갑 + 보내기 + 받기 + 내역. -- [**구독 및 수금**](/ko/how-to/subscribe-and-collect) — EIP-7702를 통한 풀 기반 정기 청구. -- [**인보이스로 결제하기**](/ko/how-to/pay-with-invoice) — 인보이스 정산을 위한 결정적 nonce가 포함된 ERC-3009. -- [**호출당 결제 API 구축하기**](/ko/how-to/build-pay-per-call) — x402 미들웨어로 HTTP 엔드포인트 수익화. +- [**P2P 결제 알아보기**](/ko/how-to/build-p2p-payments): 하나의 앱에서 지갑 + 전송 + 수신 + 내역. +- [**구독 및 수금**](/ko/how-to/subscribe-and-collect): EIP-7702를 통한 풀 기반 반복 청구. +- [**송장으로 결제하기**](/ko/how-to/pay-with-invoice): 송장 결제를 위한 결정론적 논스(nonces)가 있는 ERC-3009. +- [**종량제(pay-per-call) API 구축하기**](/ko/how-to/build-pay-per-call): x402 미들웨어를 사용하여 HTTP 엔드포인트 수익화. -## 프로토콜 및 참조 +## 프로토콜 및 참조 자료 -- [**ERC-3009**](/ko/explanation/erc-3009) — Transfer With Authorization: 서명 기반 정산 프리미티브. -- [**x402 (HTTP 네이티브 결제)**](/ko/explanation/x402) — 서버가 402로 응답하고, 클라이언트가 서명하며, 퍼실리테이터가 온체인에서 정산. -- [**P2P 결제 참조**](/ko/reference/p2p-payments) — 모델 개요 및 전통적인 결제망과의 비교. -- [**구독 참조**](/ko/reference/subscriptions) — 풀 기반 청구 모델 및 트레이드오프. -- [**인보이스 참조**](/ko/reference/invoices) — 결정적 nonce 정산 모델. -- [**호출당 결제 참조**](/ko/reference/pay-per-call) — x402 가격 책정 및 엔드포인트 디스커버리 모델. -- [**예정된 사용 사례**](/ko/explanation/upcoming-use-cases) — 보장된 정산, 기밀 결제, 에이전트 간 결제. +- [**ERC-3009**](/ko/explanation/erc-3009): 승인된 전송: 서명된 결제 기본 요소. +- [**x402 (HTTP-네이티브 결제)**](/ko/explanation/x402): 서버가 402를 응답하고, 클라이언트가 서명하면, 조력자가 온체인에서 결제. +- [**P2P 결제 참조 자료**](/ko/reference/p2p-payments): 모델 개요 및 기존 방식과의 비교. +- [**구독 참조 자료**](/ko/reference/subscriptions): 풀 기반 청구 모델 및 장단점. +- [**송장 참조 자료**](/ko/reference/invoices): 결정론적 논스(deterministic-nonce) 결제 모델. +- [**종량제 참조 자료**](/ko/reference/pay-per-call): x402 가격 책정 및 엔드포인트 발견 모델. +- [**예정된 사용 사례**](/ko/explanation/upcoming-use-cases): 보장된 결제, 기밀 결제, 에이전트 간 결제. diff --git a/docs/pages/ko/explanation/payments-overview.mdx b/docs/pages/ko/explanation/payments-overview.mdx index 7b0af96..ea3f2a0 100644 --- a/docs/pages/ko/explanation/payments-overview.mdx +++ b/docs/pages/ko/explanation/payments-overview.mdx @@ -1,46 +1,46 @@ --- source_path: explanation/payments-overview.mdx -source_sha: eafa85081c0c5f116d9435f403cd9cb1e757a1a8 +source_sha: ca8b4d0fe13257b16803c7c519f2126a47977183 title: "Stable의 결제" -description: "Stable에서 결제 플로우 구축: P2P 송금, 구독, 인보이스, 호출당 과금 API, 제로 가스 플로우, 브리징." +description: "Stable에서 결제 흐름 구축: P2P 전송, 구독, 송장, 종량제 API, 제로 가스 흐름 및 브리징." diataxis: "explanation" --- # Stable의 결제 -Stable은 결제를 중심으로 설계되었습니다. USDT0는 네이티브 자산이자 가스 토큰이므로, 정산과 수수료가 하나의 잔액을 공유합니다. 단일 슬롯 완결성(single-slot finality)은 송금이 1초 이내에 처리됨을 의미합니다. ERC-3009, EIP-7702, x402는 우회책이 아니라 네이티브 프리미티브입니다 — 서명으로 정산하거나, 위임된 계정에서 자금을 끌어오거나, 빌링 스택을 운영하지 않고도 HTTP 요청당 과금할 수 있습니다. +Stable은 결제를 중심으로 구축됩니다. USDT0는 기본 자산이자 가스 토큰이므로, 결제와 수수료는 하나의 잔액을 공유합니다. 단일 슬롯 완결성 덕분에 전송은 1초 이내에 완료됩니다. ERC-3009, EIP-7702, x402는 고유한 기본 요소이며, 임시방편이 아닙니다. 서명으로 결제하고, 위임된 계좌에서 인출하거나, 결제 스택을 실행하지 않고 HTTP 요청당 요금을 청구할 수 있습니다. -## 무엇을 구축할 수 있나요 +## 구축할 수 있는 것 -- **P2P 송금** — 21k 가스와 1초 미만의 완결성을 갖춘 네이티브 USDT0 전송. -- **구독** — EIP-7702 위임을 이용한 풀(pull) 기반 반복 빌링. -- **인보이스 정산** — 정확한 대사를 위한 결정적 nonce를 갖춘 ERC-3009 `transferWithAuthorization`. -- **호출당 과금 API** — 요청당 USDT0 결제를 위한 x402 미들웨어; API 키나 가입이 필요 없습니다. -- **제로 가스 UX** — Gas Waiver 서비스를 통한 애플리케이션 후원 트랜잭션. -- **크로스체인 USDT0** — Ethereum 및 기타 네트워크로부터의 LayerZero OFT 브리징. +- **P2P 전송**: 21k gas와 1초 미만의 완결성을 가진 기본 USDT0 전송. +- **구독**: EIP-7702 위임을 통한 풀 기반 반복 결제. +- **송장 결제**: 정확한 조정(reconciliation)을 위한 결정적 논스(nonce)를 사용하는 ERC-3009 `transferWithAuthorization`. +- **종량제 API**: 요청당 USDT0 결제를 위한 x402 미들웨어; API 키나 가입 불필요. +- **제로 가스 UX**: Gas Waiver 서비스를 통한 애플리케이션 후원 트랜잭션. +- **크로스체인 USDT0**: 이더리움 및 기타 네트워크에서 LayerZero OFT 브리징. -## Stable의 차별점 +## Stable의 차이점 -- **모든 것을 위한 하나의 자산**: 송신자가 별도의 가스 토큰을 보유할 필요가 없습니다. -- **네이티브 ERC-3009**: USDT0가 `transferWithAuthorization`을 직접 구현하므로, 결제가 서명으로 정산되며 approve 단계가 필요 없습니다. -- **결정적 완결성**: 블록은 커밋되는 순간 최종 확정됩니다. 확인 대기가 없습니다. -- **네이티브 x402**: 퍼실리테이터가 Gas Waiver를 통해 가스를 지불하지 않으므로, 요청당 정산 비용이 1센트 미만으로 유지됩니다. +- **모든 것을 위한 하나의 자산**: 발신자는 별도의 가스 토큰을 보유하지 않습니다. +- **네이티브 ERC-3009**: USDT0는 `transferWithAuthorization`을 직접 구현하므로 결제는 서명으로 정산되며 승인 단계가 없습니다. +- **결정론적 완결성**: 블록은 커밋되는 순간 확정됩니다. 확인을 기다릴 필요가 없습니다. +- **네이티브 x402**: 촉진자는 Gas Waiver를 통해 가스를 지불하지 않으므로 요청당 결제 비용은 1센트 미만으로 유지됩니다. -## 여기서 시작하세요 +## 시작하기 -- [**첫 USDT0 보내기**](/ko/tutorial/send-usdt0) — 동일한 잔액에서의 네이티브 및 ERC-20 전송. -- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions) — Gas Waiver로 수수료가 충당된 USDT0 전송. -- [**P2P 결제 배우기**](/ko/how-to/build-p2p-payments) — 지갑 + 보내기 + 받기 + 내역 앱을 처음부터 구축. -- [**호출당 과금 API 구축**](/ko/how-to/build-pay-per-call) — x402로 HTTP 엔드포인트를 요청당 과금. -- [**Stable SDK**](/ko/explanation/sdk-overview) — 타입이 지정된 클라이언트로 몇 줄 만에 transfer, bridge, swap을 수행. +- [**첫 USDT0 전송**](/ko/tutorial/send-usdt0): 동일한 잔액에서 네이티브 및 ERC-20 전송. +- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions): Gas Waiver가 수수료를 부담하는 USDT0 전송. +- [**P2P 결제 학습**](/ko/how-to/build-p2p-payments): 지갑 + 전송 + 수신 + 기록 앱을 처음부터 구축. +- [**종량제 API 구축**](/ko/how-to/build-pay-per-call): x402로 요청당 HTTP 엔드포인트 가격 책정. +- [**Stable SDK**](/ko/explanation/sdk-overview): 몇 줄의 코드로 전송, 브리지 및 스왑을 위한 타입스크립트 클라이언트 사용. -## 결제 프리미티브 +## 결제 기본 요소 -- [**ERC-3009**](/ko/explanation/erc-3009) — Transfer With Authorization: 인보이스와 x402 뒤에 있는 정산 표준. -- [**x402 (HTTP 네이티브 결제)**](/ko/explanation/x402) — 서버가 402로 응답하고, 클라이언트가 ERC-3009에 서명하면, 퍼실리테이터가 온체인에서 정산합니다. +- [**ERC-3009**](/ko/explanation/erc-3009): Transfer With Authorization: 송장 및 x402의 결제 표준. +- [**x402 (HTTP-native payments)**](/ko/explanation/x402): 서버가 402를 응답하고, 클라이언트가 ERC-3009에 서명하며, 촉진자가 온체인에서 결제. -## 다음 추천 +## 다음 권장 사항 -- [**결제 가이드 색인**](/ko/explanation/payments-guides) — 결제(Payments) 탭 아래의 모든 가이드, 개념, 레퍼런스. -- [**구독 및 수금**](/ko/how-to/subscribe-and-collect) — EIP-7702를 통한 풀 기반 반복 빌링. -- [**인보이스로 결제하기**](/ko/how-to/pay-with-invoice) — 정확한 대사를 위한 결정적 nonce를 갖춘 ERC-3009. +- [**결제 가이드 색인**](/ko/explanation/payments-guides): 결제 탭 아래의 모든 가이드, 개념 및 참조. +- [**구독 및 수집**](/ko/how-to/subscribe-and-collect): EIP-7702를 통한 풀 기반 반복 결제. +- [**송장으로 결제**](/ko/how-to/pay-with-invoice): 정확한 조정(reconciliation)을 위한 결정적 논스(nonce)를 사용하는 ERC-3009. diff --git a/docs/pages/ko/explanation/sdk-overview.mdx b/docs/pages/ko/explanation/sdk-overview.mdx index a656708..78aaa4b 100644 --- a/docs/pages/ko/explanation/sdk-overview.mdx +++ b/docs/pages/ko/explanation/sdk-overview.mdx @@ -1,14 +1,14 @@ --- source_path: explanation/sdk-overview.mdx -source_sha: db4361dfdc3233c02ea6e871850e34e477964a67 +source_sha: efcb1b7d8aaf0782573a67c4964ac01904c220ae title: "Stable SDK" -description: "타입이 지정된 TypeScript SDK를 사용하여 USDT0를 전송하고, 체인 간 브리지하고, Stable에서 토큰을 스왑하는 작업을 단 몇 줄로 수행하세요." +description: "몇 줄의 코드로 Stable에서 USDT0 전송, 체인 간 브릿지, 토큰 스왑을 위해 타입이 지정된 TypeScript SDK를 사용하세요." diataxis: "explanation" --- # Stable SDK -`@stablechain/sdk`는 Stable을 위한 공식 TypeScript 클라이언트입니다. viem을 감싸서 가장 자주 사용하는 작업들을 위한 작고 타입이 지정된 API를 제공합니다: USDT0 전송, 체인 간 브리지, 그리고 Stable에서의 토큰 스왑. 라우팅, 승인, 소수점 처리, 체인 전환은 모두 자동으로 처리됩니다. +`@stablechain/sdk`는 Stable용 공식 TypeScript 클라이언트입니다. viem을 래핑하여 가장 많이 사용하는 작업(USDT0 전송, 체인 간 브릿지, Stable에서 토큰 스왑)을 위한 작고 타입이 지정된 API를 제공합니다. 라우팅, 승인, 소수점 처리 및 체인 전환은 자동으로 처리됩니다. ```ts import { createStable, Network } from "@stablechain/sdk"; @@ -32,29 +32,29 @@ txHash: 0x8f3a...2d41 ## SDK가 하는 일 -- **`transfer`** — 네이티브 USDT0 또는 Stable의 모든 ERC-20을 전송합니다. 가스는 자동으로 USDT0로 지불됩니다. -- **`quoteBridge` / `bridge`** — 체인 간 전송. USDT0 → USDT0에는 LayerZero를, 그 외 모든 것에는 LI.FI를 사용합니다. 경로는 자동으로 선택됩니다. -- **`quoteSwap` / `swap`** — LI.FI를 통한 동일 체인 토큰 스왑이며, ERC-20 승인은 내부적으로 처리됩니다. +- **`transfer`**: 기본 USDT0 또는 Stable의 모든 ERC-20을 전송합니다. 가스는 USDT0으로 자동 지불됩니다. +- **`quoteBridge` / `bridge`**: 크로스체인 전송. USDT0 → USDT0의 경우 LayerZero를, 다른 모든 것에는 LI.FI를 사용합니다. 경로는 자동으로 선택됩니다. +- **`quoteSwap` / `swap`**: LI.FI를 통한 동일 체인 토큰 스왑으로, ERC-20 승인은 내부적으로 처리됩니다. -SDK는 npm에 [`@stablechain/sdk`](https://www.npmjs.com/package/@stablechain/sdk)로 게시되어 있으며, 피어 의존성으로 `viem >= 2.0.0`이 필요합니다. +SDK는 [`@stablechain/sdk`](https://www.npmjs.com/package/@stablechain/sdk)로 npm에 게시되어 있으며 피어 종속성으로 `viem >= 2.0.0`이 필요합니다. -## 언제 사용해야 하나 (그리고 언제 사용하지 말아야 하나) +## 언제 사용해야 할까요 (그리고 언제 사용하지 말아야 할까요) -라우팅과 승인 보일러플레이트를 숨겨주는, 타입이 지정되고 의견이 반영된 클라이언트를 원할 때 SDK를 사용하세요. 트랜잭션 구성에 대한 직접적인 제어, 사용자 정의 가스 전략, 또는 transfer / bridge / swap 외부의 컨트랙트 호출이 필요할 때는 원시 viem이나 ethers로 내려가세요. +라우팅 및 승인 상용구를 숨기는 타입이 지정되고 의견이 명확한 클라이언트를 원할 때 SDK를 사용하세요. 트랜잭션 구성, 사용자 지정 가스 전략 또는 전송/브릿지/스왑 외의 컨트랙트 호출에 대한 직접적인 제어가 필요한 경우 원시 viem 또는 ethers로 전환하세요. :::note -SDK는 viem 호환 서명자라면 무엇으로든 서명합니다: 프라이빗 키 `Account`, `custom(window.ethereum)`과 같은 브라우저 `Transport`, 또는 미리 빌드된 `WalletClient`(예를 들어 wagmi의 `useWalletClient`가 반환하는 것). +SDK는 모든 viem 호환 서명자로 서명합니다: 개인 키 `Account`, `custom(window.ethereum)`과 같은 브라우저 `Transport`, 또는 미리 빌드된 `WalletClient` (예: wagmi의 `useWalletClient`가 반환하는 것). ::: -## 여기서 시작하세요 +## 시작하기 -- [**빠른 시작**](/ko/tutorial/sdk-quickstart) — SDK를 설치하고 테스트넷에서 첫 번째 전송, 브리지, 스왑을 실행해 보세요. -- [**SDK 레퍼런스**](/ko/reference/sdk) — 모든 메서드, 설정 옵션, 열거형, 그리고 오류 클래스. -- [**viem과 함께 사용하기**](/ko/how-to/sdk-with-viem) — 서버 측 계정, 브라우저 지갑, 그리고 직접 만든 `WalletClient` 사용. -- [**wagmi와 함께 사용하기**](/ko/how-to/sdk-with-wagmi) — `useWalletClient`와 훅으로 SDK를 React 앱에 연결하기. +- [**빠른 시작**](/ko/tutorial/sdk-quickstart): SDK를 설치하고 테스트넷에서 첫 번째 전송, 브릿지 및 스왑을 실행합니다. +- [**SDK 참조**](/ko/reference/sdk): 모든 메서드, 구성 옵션, 열거형 및 오류 클래스. +- [**viem과 함께 사용하기**](/ko/how-to/sdk-with-viem): 서버 측 계정, 브라우저 지갑 및 자체 `WalletClient` 가져오기. +- [**wagmi와 함께 사용하기**](/ko/how-to/sdk-with-wagmi): `useWalletClient` 및 훅을 사용하여 React 앱에 SDK를 연결합니다. ## 다음 권장 사항 -- [**npm에서 설치하기**](https://www.npmjs.com/package/@stablechain/sdk) — npmjs.com에서 패키지를 보고 최신 버전을 확인하세요. -- [**Stable에 연결하기**](/ko/reference/connect) — 메인넷과 테스트넷의 체인 ID, RPC 엔드포인트, 그리고 익스플로러. -- [**테스트넷 지갑에 자금 충전하기**](/ko/how-to/use-faucet) — 빠른 시작을 실행하기 전에 faucet에서 테스트넷 USDT0를 받으세요. +- [**npm에서 설치**](https://www.npmjs.com/package/@stablechain/sdk): npmjs.com에서 패키지를 보고 최신 버전을 확인합니다. +- [**Stable에 연결**](/ko/reference/connect): 메인넷 및 테스트넷의 체인 ID, RPC 엔드포인트 및 탐색기. +- [**테스트넷 지갑에 자금 조달**](/ko/how-to/use-faucet): 빠른 시작을 실행하기 전에 수도꼭지에서 테스트넷 USDT0을 받으세요. diff --git a/docs/pages/ko/explanation/stable-db.mdx b/docs/pages/ko/explanation/stable-db.mdx index 8e5b6f9..5d13307 100755 --- a/docs/pages/ko/explanation/stable-db.mdx +++ b/docs/pages/ko/explanation/stable-db.mdx @@ -1,80 +1,87 @@ --- source_path: explanation/stable-db.mdx -source_sha: f8e6552090f6f352bcdbfa82870803979ea82c1e -title: "StableDB" -description: "상태 커밋 분리, MemDB, mmap을 활용하여 디스크 I/O 병목을 제거하는 StableDB 아키텍처." +source_sha: 1b5136d111f56a7a32bf3730d44d97755770091f +title: "스토리지 (StableDB)" +description: "디스크 I/O 병목 현상을 제거하기 위한 분리된 상태 커밋, MemDB, mmap을 사용한 StableDB 아키텍처." +diataxis: "explanation" --- -# StableDB +# 스토리지 (StableDB) -블록체인 성능에서 주요 병목 중 하나는 **디스크 I/O**에 있습니다. 보다 구체적으로는, 블록 실행 후 상태 데이터를 커밋하고 저장하는 작업이 핵심 병목 지점입니다. Stable은 이 문제를 해결하기 위해 `MemDB`, `VersionDB`, 메모리 매핑 파일 I/O 메커니즘 (`mmap`)와 같은 아키텍처 혁신을 도입하여 처리량을 획기적으로 향상시킵니다. +종단 간 블록체인 성능의 주요 병목 현상 중 하나는 **디스크 I/O**입니다. 특히, 블록 실행 후 상태 데이터를 커밋하고 저장하는 것이 핵심 병목 현상을 야기합니다. Stable은 `MemDB`, `VersionDB`, 메모리 맵 스토리지(`mmap`)와 같은 아키텍처 혁신을 통해 이 문제를 해결하여 처리량을 획기적으로 개선합니다. -## 디스크 I/O가 병목이 되는 이유 +## 디스크 I/O가 병목 현상인 이유 -### 상태 전환과 저장 +### 상태 전환 및 영속성 -트랜잭션 블록이 실행될 때마다 블록체인은 하나의 상태에서 다음 상태로 전환됩니다. 이 과정은 다음과 같은 두 가지 기본 단계로 나뉩니다: +거래 블록이 실행될 때마다 블록체인은 한 상태에서 다음 상태로 전환됩니다. 이 프로세스는 두 가지 근본적인 단계를 거칩니다. -1. **상태 커밋**: 트랜잭션 실행 후, 새로운 애플리케이션 상태가 커밋됩니다 -2. **상태 저장**: 커밋된 상태가 디스크에 영구적으로 저장되어, 향후 접근성과 과거 기록에 검증을 가능하게 합니다. +1. **상태 커밋**: 거래 실행 후 새로운 애플리케이션 상태가 커밋됩니다. +2. **상태 저장**: 커밋된 상태는 장기적인 접근과 기록 검증을 위해 디스크에 영속화됩니다. Coupled State Commitment and Storage -기존 아키텍처에서는, 상태 저장이 상태 커밋과 **강하게 결합되어** 있습니다. 이는 다음을 의미합니다. +기존 아키텍처에서는 상태 저장이 상태 커밋과 **밀접하게 결합**되어 있습니다. 이는 다음을 의미합니다. -- 노드는 다음 블록을 실행하기 전에 새로운 상태가 디스크에 완전히 저장될 때까지 대기해야 합니다. -- 상태 데이터는 고정된 주소를 가지지 않은 임의의 디스크 위치에 기록됩니다. 이로 인해 이후 트랜잭션 실행 시 상태 데이터를 검색하는 데 높은 레이턴시가 발생합니다. +- 노드는 다음 블록 실행을 진행하기 전에 새 상태가 디스크에 완전히 저장될 때까지 기다려야 합니다. +- 상태 데이터는 고정된 주소에 매핑되지 않은 임의의 디스크 위치에 기록됩니다. 이로 인해 후속 거래 실행 중에 상태 데이터를 검색할 때 높은 지연 시간이 발생합니다. -합의 및 실행 계층이 아무리 최적화되어 있어도, 이처럼 느린 디스크 작업에 대한 의존성 때문에 시스템 전체 성능에는 상한선이 생깁니다. +합의 및 실행 계층이 아무리 최적화되더라도 느린 디스크 작업에 대한 이 직렬화된 종속성은 전체 시스템의 달성 가능한 성능을 제한합니다. -## 더 높은 처리량을 위한 DB 연산 최적화 +## 더 높은 처리량을 위한 DB 작업 최적화 -이러한 제약을 극복하기 위해 Stable은 **상태 연산의 분리** 및 **메모리 매핑 DB 최적화** 라는 두 가지 아키텍처 개선을 제안합니다. +이러한 한계를 극복하기 위해 Stable은 **상태 작업 분리**와 **메모리 맵 DB 최적화 도입**에 중점을 둔 두 가지 아키텍처 개선을 제안합니다. -### 1. 상태 커밋과 저장의 분리 +### 1. 상태 커밋 및 스토리지 분리 Decoupled State Commitment and Storage -첫 번째 단계는 상태 커밋과 저장을 분리하는 것입니다: +첫 번째 단계는 상태 커밋을 스토리지에서 분리하는 것입니다. -- 새로운 상태가 커밋되면, 노드는 즉시 다음 블록을 실행합니다. -- 상태를 디스크에 저장하는 작업은 비동기적으로 백그라운드에서 처리됩니다. +- 새 상태를 커밋한 후 노드는 즉시 다음 블록 실행을 진행합니다. +- 실제 상태의 디스크 영속화는 백그라운드에서 비동기적으로 발생합니다. -이러한 분리를 통해 실행은 디스크 쓰기의 레이턴시에 영향받지 않고 즉시 진행될 수 있으며, 의존성에 의해 작업이 멈추는 현상을 제거하여 결국 전체적인 성능이 향상될 수 있습니다. +이러한 분리는 실행이 즉시 발생하고 느린 디스크 쓰기의 지연 시간을 뛰어넘을 수 있도록 하여, 차단 종속성을 제거하고 궁극적으로 종단 간 성능을 향상시킵니다. -### 2. `mmap` 을 통한`MemDB` 및 `VersionDB` 도입 +### 2. `mmap`을 통한 `MemDB` 및 `VersionDB` 도입 -Stable은 메모리 매핑 파일 I/O 메커니즘 (`mmap`)을 기반으로 한 이중 데이터베이스 모델을 도입하여 이를 보강합니다: +Stable은 `mmap`(메모리 맵 파일 접근)으로 구동되는 듀얼 데이터베이스 모델로 이를 강화합니다. -- **MemDB (메모리 DB)**: - - 자주 접근되는 최근/활성 데이터를 저장 - - mmap을 통한 고정 주소 매핑을 사용하여 빠르고 결정론적인 조회가 가능 - - 최근 수정된 상태에 접근하는 대부분의 트랜잭션에 대해 이상적인 구조 -- **VersionDB (히스토리컬 DB)**: - - 오래된 과거 상태를 디스크에 저장 - - 자주 접근되지 않는, 오래되거나 넓은 범위의 데이터에 대한 쿼리에 최적화됨 +- **MemDB (메모리 DB)**: + - 자주 액세스되는 최근의 활성 상태를 저장합니다. + - `mmap`을 통해 고정 주소 매핑을 사용하여 빠르고 결정론적인 조회를 가능하게 합니다. + - 최근에 수정된 상태를 대상으로 하는 대부분의 거래 워크로드에 이상적입니다. +- **VersionDB (히스토리 DB)**: + - 오래된 히스토리 상태를 디스크에 저장합니다. + - 아카이브 및 장거리 쿼리에 최적화되어 있으며, 고주파수 액세스에는 적합하지 않습니다. -이 설계를 통해 **핫 데이터는 빠른 메모리 기반 구조에서 제공**되고, 콜드 데이터는 느리지만 영구적인 스토리지로 오프로드됩니다. 효율을 고려하여 상태를 분류하고 `mmap` 접근을 활용함으로써, Stable은 블록 실행 중 DB의 읽기/쓰기 지연을 크게 줄일 수 있습니다. +이 설계는 **활성 데이터가 빠르고 메모리 상주 구조에서 제공**되도록 보장하며, 비활성 데이터는 더 느리고 영구적인 스토리지로 오프로드됩니다. `mmap` 액세스와 스마트 상태 계층화를 결합함으로써 Stable은 블록 실행 중 DB 읽기/쓰기 지연 시간을 크게 줄일 수 있습니다. -## 예상되는 성능 개선 및 선례 +## 예상되는 성과 및 선례 -이 아키텍처 최적화는 이론적인 아이디어에 그치지 않습니다. Sei 및 Cronos와 같은 고성능 블록체인들이 유사한 구조를 이미 구현하고 있으며, 메모리 매핑 DB 및 상태 커밋/저장의 분리를 통해 **전체 TPS가 최대 2배 향상**되었음을 보고했습니다. +이러한 아키텍처 최적화는 이론적인 것만이 아닙니다. Sei 및 Cronos와 같은 고성능 블록체인에서 이미 구현되고 있습니다. 둘 다 메모리 맵 DB를 사용하는 유사한 분리 아키텍처를 채택했으며 **전반적인 TPS가 최대 2배 증가**하는 것을 관찰했습니다. -Stable 또한 이와 유사한 성능 향상을 기대하고 있으며, 새로운 아키텍처에서는 스토리지 레이어가 더 이상 병목이 되지 않기 때문에, 합의 및 실행 성능이 디스크 연산에 의해 제한되지 않고 자유롭게 확장될 수 있게 됩니다. +Stable 역시 아키텍처가 더 이상 스토리지 계층에 병목 현상을 일으키지 않으므로 비슷한 성과를 예상합니다. 대신, 합의 및 실행 성능은 디스크 작업에 의해 조절되지 않고 확장될 수 있습니다. ## 추가 자료 -더 자세한 기술 분석과 구현 내용을 보려면 다음 문서를 참고하세요: +더 자세한 기술 심층 분석 및 구현 세부 정보는 다음을 참조하십시오. -- [ADR-065: Cosmos Store V2 Architecture](https://docs.cosmos.network/main/build/architecture/adr-065-store-v2) -- [MemIAVL: A Practical Guide](https://hackmd.io/@yihuang/rkeCvy5xh) -- [Cronos MemIAVL Node Configuration](https://docs.cronos.org/for-node-hosts/running-nodes/memiavl) -- [Sei’s DB Design Approach](https://4pillars.io/ko/articles/sei-db) \ No newline at end of file +- [ADR-065: Cosmos Store V2 Architecture](https://docs.cosmos.network/main/build/architecture/adr-065-store-v2) +- [MemIAVL: A Practical Guide](https://hackmd.io/@yihuang/rkeCvy5xh) +- [Cronos MemIAVL Node Configuration](https://docs.cronos.org/for-node-hosts/running-nodes/memiavl) +- [Sei’s DB Design Approach](https://4pillars.io/ko/articles/sei-db) + +## 다음으로 추천하는 자료 + +- [**고성능 RPC**](/ko/explanation/high-performance-rpc): RPC 계층이 쓰기와 충돌하지 않고 상태 읽기를 어떻게 노출하는지 확인하세요. +- [**실행**](/ko/explanation/execution): 실행이 여기서 다루는 스토리지 계층에 어떻게 쓰여지는지 이해하세요. +- [**합의**](/ko/explanation/consensus): 블록이 스토리지에 도달하기 전에 블록을 정렬하는 합의 계층을 검토하세요. diff --git a/docs/pages/ko/explanation/staking-module.mdx b/docs/pages/ko/explanation/staking-module.mdx index f4964c4..03714ba 100755 --- a/docs/pages/ko/explanation/staking-module.mdx +++ b/docs/pages/ko/explanation/staking-module.mdx @@ -1,414 +1,48 @@ --- source_path: explanation/staking-module.mdx -source_sha: b2ec42174c8f286072288127461ab39c538fd932 -title: Staking -description: "EVM 스마트 계약에서 검증자 참여 및 위임을 위한 x/staking 노출 Staking 프리컴파일." +source_sha: 32af1af02985137c678f7ed6d46376607121b6bf +title: "스테이킹 모듈" +description: "스테이킹 사전 컴파일은 위임, 위임 해제 및 유효성 검사기 관리를 EVM 계약에 노출하며, 발신자 신원을 적용하는 권한 부여 확인을 제공합니다." +diataxis: "explanation" --- -# Staking +# 스테이킹 모듈 -## 개요 +`x/staking` 모듈은 Stable에서 유효성 검사기 참여 및 위임을 제어합니다. 이 사전 컴파일은 이러한 작업을 Solidity에서 호출할 수 있도록 하여, 계약이 STABLE을 위임하고, 언본딩 기간 후에 위임을 해제하며, 유효성 검사기 간에 재위임하거나, EVM을 벗어나지 않고 유효성 검사기 상태를 쿼리할 수 있도록 합니다. -`staking` precompile 컨트랙트는 Stable SDK의 `x/staking` 모듈 기능을 EVM 환경에서 사용할 수 있도록 브리지 역할을 합니다. +## 제공하는 기능 -## 목차 +- **유효성 검사기 생성**: 설명, 수수료율 및 초기 자체 위임을 사용하여 새 유효성 검사기를 등록합니다. +- **유효성 검사기 편집**: 유효성 검사기 메타데이터 및 수수료 매개변수를 업데이트합니다. +- **위임**: 유효성 검사기에게 STABLE을 스테이킹합니다. +- **위임 해제**: 유효성 검사기에서 언본딩을 시작합니다 (토큰은 언본딩 기간 후에 사용 가능해집니다). +- **재위임**: 언본딩 없이 유효성 검사기 간에 스테이크를 이동합니다. +- **언본딩 위임 취소**: 기간이 완료되기 전에 진행 중인 언본딩을 되돌립니다. +- **쿼리 메서드**: 유효성 검사기 세트, 위임 기록, 언본딩 기록 및 매개변수를 읽습니다. -1. **[개념](#concepts)** -2. **[구성](#configuration)** -3. **[메서드](#methods)** -4. **[이벤트](#events)** +## 권한 부여 의미론 -## 개념 +사전 컴파일은 두 가지 검사를 수행합니다. -Stable SDK의 `x/staking` 모듈에서는 스테이킹을 위해 체인 초기화 시 bond denom이 등록되어야 합니다. -Validator와 delegator는 bond denom 스테이킹 토큰만 사용할 수 있습니다. -`staking` precompile 컨트랙트에서는 validator 또는 delegator가 호출자인지 확인하는 추가 검증이 수행됩니다. +1. 본드 데놈 (스테이킹 토큰)은 체인 초기화 시 등록되어야 합니다. Stable에서는 STABLE 토큰입니다. +2. 발신자는 수정되는 유효성 검사기 또는 위임자와 일치해야 합니다. 사전 컴파일을 직접 호출하여 다른 사람을 대신하여 위임할 수 없습니다. -## 구성 +## 언본딩 완료 -컨트랙트 주소와 가스 비용은 사전에 정의되어 있습니다. +언본딩 기간이 끝나면 토큰은 유동성이 되지만, SDK는 이를 조용히 처리하며 EVM은 직접적인 이벤트를 볼 수 없습니다. Stable의 [시스템 트랜잭션](/ko/explanation/system-transactions) 메커니즘은 이 간극을 메웁니다. 프로토콜은 언본딩이 해제되면 `StableSystem` 사전 컴파일을 통해 `UnbondingCompleted` 이벤트를 발생시키므로 dApp은 표준 EVM 로그를 통해 구독할 수 있습니다. -### 컨트랙트 주소 +## 언제 사용해야 하는가 -- `0x0000000000000000000000000000000000000800` +- 스테이킹 프로토콜이 볼트 계약에서 위임을 관리하는 경우: 사용자가 예치하고 인출할 때 `delegate` 및 `undelegate`를 호출합니다. +- 거버넌스 대시보드에 실시간 유효성 검사기 세트가 필요한 경우: 쿼리 메서드를 사용합니다. +- 리스테이킹 또는 유동성 스테이킹 제품이 언본딩 완료를 추적하는 경우: `UnbondingCompleted` 이벤트를 구독합니다 (가이드가 출시되면 [언본딩 추적](/ko/how-to/track-unbonding)을 참조하세요). -## 메서드 +## ABI를 찾는 곳 -### `createValidator` +전체 메서드 시그니처, 구조체 정의 및 발생된 이벤트는 [스테이킹 사전 컴파일 참조](/ko/reference/staking-module-api)에 있습니다. -Validator가 생성됩니다. -Validator는 운영자의 초기 delegation과 함께 생성되어야 합니다. -잠재적인 delegator를 위해 validator는 자신의 정보와 수수료율 계획을 제공해야 합니다. -Delegator는 시장 메커니즘의 자연스러운 규제를 통해 공개된 정보를 바탕으로 자신의 토큰을 위임할 validator를 선택할 수 있습니다. +## 다음 권장 사항 -Validator가 성공적으로 등록되면 `CreateValidator` 이벤트가 발생합니다. - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|description|Description|validator의 정보| -|commissionRates|CommissionRates|validator가 보상받는 스테이킹 토큰의 수수료율| -|minSelfDelegation|uint256|validator의 최소 자체 위임 금액| -|validatorAddress|address|validator의 주소| -|pubkey|string|validator의 공개 키| -|value|uint256|validator에게 초기 자체 위임되는 스테이킹 토큰의 양| - -`Description`은 다음 필드를 가진 구조체입니다: - -|Name|Type|Description| -|---|---|---| -|moniker|string|validator의 이름| -|identity|string|validator의 신원| -|website|string|validator 웹사이트의 URL| -|securityContact|string|보안 연락처 정보| -|details|string|validator의 추가 설명| - -`CommissionRates`는 다음 필드를 가진 구조체입니다: - -|Name|Type|Description| -|---|---|---| -|rate|uint256|validator가 받는 현재 수수료율| -|maxRate|uint256|최대 수수료율 (이보다 높게 설정할 수 없음)| -|maxChangeRate|uint256|validator가 하루에 변경할 수 있는 최대 수수료율| - -`rate`는 시장에서 수용 가능한 적절한 값으로 설정해야 합니다. - -- Validator의 수수료율이 높으면 delegator의 수익이 낮아집니다. -- Validator의 수수료율이 낮으면 validator의 수익이 낮아지고 운영이 어려워집니다. - -높은 `maxRate`는 validator의 예상치 못한 높은 수수료율에 대한 delegator의 우려를 야기할 수 있으므로 `maxRate`는 신중하게 설정해야 합니다. `maxChangeRate`는 초기화 후 변경할 수 없습니다. - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|success|bool|validator가 성공적으로 등록되면 true| - -### `editValidator` - -Validator가 정보를 업데이트합니다. -Validator는 `CommissionRates` 구조체의 `maxRate` 및 `maxChangeRate`와 같이 변경 불가능한 필드를 제외한 정보만 업데이트할 수 있습니다. - -Validator가 성공적으로 업데이트되면 `EditValidator` 이벤트가 발생합니다. - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|description|Description|validator의 정보| -|validatorAddress|address|validator의 주소| -|commissionRate|int256|validator가 보상받는 스테이킹 토큰의 수수료율| -|minSelfDelegation|int256|validator의 최소 자체 위임 금액| - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|success|bool|validator가 성공적으로 업데이트되면 true| - -### `delegate` - -Delegator가 validator에게 위임할 토큰의 양을 설정합니다. - -Delegation이 성공적으로 완료되면 `Delegate` 이벤트가 발생합니다. - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|delegatorAddress|address|delegator의 주소| -|validatorAddress|address|validator의 주소| -|amount|uint256|validator에게 위임되는 스테이킹 토큰의 양| - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|success|bool|delegation이 성공적으로 완료되면 true| - -#### Events - -`newShares`는 delegator의 소유 비율을 나타냅니다. -동일한 양의 토큰이 위임되더라도 시간에 따라 계산되는 shares는 달라질 수 있습니다. - -### `undelegate` - -Delegator가 validator에게 위임한 토큰의 양을 인출합니다. - -언델리게이션이 성공적으로 완료되면 `Unbond` 이벤트가 발생합니다. - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|delegatorAddress|address|delegator의 주소| -|validatorAddress|address|validator의 주소| -|amount|uint256|validator로부터 언델리게이트하려는 스테이킹 토큰의 양| - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|success|bool|언델리게이션이 성공적으로 완료되면 true| - -### `redelegate` - -Delegator가 validator에게 위임한 토큰의 양을 다른 validator에게 재위임합니다. - -재위임이 성공적으로 완료되면 `Redelegate` 이벤트가 발생합니다. - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|delegatorAddress|address|delegator의 주소| -|validatorSrc|string|출발지 validator의 주소| -|validatorDst|string|목적지 validator의 주소| -|amount|uint256|재위임할 스테이킹 토큰의 양| - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|success|bool|재위임이 성공적으로 완료되면 true| - -### `delegation` - -Delegator와 validator 간의 delegation 정보를 반환합니다. -Delegation을 찾을 수 없으면 `shares`와 `balance`는 `0`이 됩니다. - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|delegatorAddress|address|delegator의 주소| -|validatorAddress|address|validator의 주소| - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|shares|uint256|위임된 shares| -|balance|Coin|위임된 토큰의 양과 denom| - -`Coin`은 다음 필드를 가진 구조체입니다: - -|Name|Type|Description| -|---|---|---| -|denom|string|보상의 denom| -|amount|uint256|보상의 양| - -### `unbondingDelegation` - -Delegator와 validator 간의 언본딩 delegation 정보를 반환합니다. -언본딩 delegation을 찾을 수 없으면 빈 `UnbondingDelegationOutput`이 반환됩니다. - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|delegatorAddress|address|delegator의 주소| -|validatorAddress|address|validator의 주소| - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|unbondingDelegation|UnbondingDelegationOutput|언본딩 delegation의 정보| - -`UnbondingDelegationOutput`은 다음 필드를 가진 구조체입니다: - -|Name|Type|Description| -|---|---|---| -|validatorAddress|address|validator의 주소| -|delegatorAddress|address|delegator의 주소| -|entries|UnbondingDelegationEntry[]|언본딩 delegation의 항목들| - -`UnbondingDelegationEntry`는 다음 필드를 가진 구조체입니다: - -|Name|Type|Description| -|---|---|---| -|creationHeight|uint64|항목의 생성 높이| -|completionTime|uint64|항목의 완료 시간| -|initialBalance|Coin|항목의 초기 잔액| -|balance|Coin|항목의 잔액| - -### `validator` - -Validator 정보를 반환합니다. -Validator를 찾을 수 없으면 빈 `ValidatorOutput`이 반환됩니다. - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|validatorAddress|address|validator의 주소| - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|validator|Validator|validator의 정보| - -`Validator`는 다음 필드를 가진 구조체입니다: - -|Name|Type|Description| -|---|---|---| -|operatorAddress|address|validator의 주소| -|consensusPubkey|string|validator의 공개 키| -|jailed|bool|validator가 jailed 상태인지 여부| -|status|int32|validator의 상태| -|tokens|uint256|validator에게 위임된 스테이킹 토큰의 양| -|delegatorShares|uint256|delegation shares의 양| -|description|string|validator의 설명| -|unbondingHeight|int64|validator가 언본딩 중인 높이| -|unbondingTime|int64|validator가 언본딩 중인 시간| -|commission|uint256|validator가 보상받는 스테이킹 토큰의 수수료율| -|minSelfDelegation|uint256|validator의 최소 자체 위임 금액| - -### `validators` - -상태와 일치하는 모든 validator를 반환합니다. -Validator를 찾을 수 없으면 빈 `ValidatorsOutput`이 반환됩니다. - -`x/staking` 모듈에서 선언된 상태는 다음 중 하나일 수 있습니다: - -- 0 : "BOND_STATUS_UNSPECIFIED", 지정되지 않은 상태 -- 1 : "BOND_STATUS_UNBONDING", validator가 언본딩 중 -- 2 : "BOND_STATUS_UNBONDED", validator가 언본딩됨 -- 3 : "BOND_STATUS_BONDED", validator가 본딩됨 - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|status|string|validator의 상태| -|pageRequest|PageReq|페이지네이션 요청| - -`PageReq`는 다음 필드를 가진 구조체입니다: - -|Name|Type|Description| -|---|---|---| -|key|bytes|페이지의 키| -|offset|int64|페이지의 오프셋| -|limit|int64|페이지의 제한| -|countTotal|bool|결과의 총 개수를 세어야 하는지 여부| -|reverse|bool|결과를 역순으로 정렬할지 여부| - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|validators|Validator[]|validator들의 배열| -|pageResponse|PageResp|페이지네이션 응답 - -`PageResp`는 다음 필드를 가진 구조체입니다: - -|Name|Type|Description| -|---|---|---| -|nextKey|bytes|다음 페이지의 키| -|total|uint64|결과의 총 개수| - -### `redelegation` - -Delegator, 출발지 validator, 목적지 validator의 재위임 정보를 반환합니다. -재위임을 찾을 수 없으면 빈 `RedelegationOutput`이 반환됩니다. - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|delegatorAddress|address|delegator의 주소| -|srcValidatorAddress|address|출발지 validator의 주소| -|dstValidatorAddress|address|목적지 validator의 주소| - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|redelegation|RedelegationOutput|재위임의 정보| - -`RedelegationOutput`은 다음 필드를 가진 구조체입니다: - -|Name|Type|Description| -|---|---|---| -|delegatorAddress|address|delegator의 주소| -|validatorSrcAddress|address|출발지 validator의 주소| -|validatorDstAddress|address|목적지 validator의 주소| -|entries|RedelegationEntry[]|재위임의 항목들| - -`RedelegationEntry`는 다음 필드를 가진 구조체입니다: - -|Name|Type|Description| -|---|---|---| -|creationHeight|uint64|항목의 생성 높이| -|completionTime|uint64|항목의 완료 시간| -|initialBalance|Coin|항목의 초기 잔액| -|balance|Coin|항목의 잔액| - -### `redelegations` - -Delegator, 출발지 validator, 목적지 validator의 모든 재위임을 반환합니다. -재위임을 찾을 수 없으면 빈 `RedelegationResponse`와 `PageResp`가 반환됩니다. - -#### Inputs - -|Name|Type|Description| -|---|---|---| -|delegatorAddress|address|delegator의 주소| -|srcValidatorAddress|address|출발지 validator의 주소| -|dstValidatorAddress|address|목적지 validator의 주소| -|pageRequest|PageReq|페이지네이션 요청| - -#### Outputs - -|Name|Type|Description| -|---|---|---| -|response|RedelegationResponse[]|재위임들의 정보| -|pageResponse|PageResp|페이지네이션 응답| - -## 이벤트 - -### CreateValidator - -|Name|Type|Indexed|Description| -|---|---|---|---| -|valiAddr|address|Y|validator의 주소| -|value|uint256|N|validator에게 초기 자체 위임되는 스테이킹 토큰의 양| - -### EditValidator - -|Name|Type|Indexed|Description| -|---|---|---|---| -|valiAddr|address|Y|validator의 주소| -|commissionRate|int256|N|validator가 보상받는 스테이킹 토큰의 업데이트된 수수료율| -|minSelfDelegation|int256|N|validator의 업데이트된 최소 자체 위임 금액| - -### Delegate - -|Name|Type|Indexed|Description| -|---|---|---|---| -|delegatorAddr|address|Y|delegator의 주소| -|validatorAddr|string|Y|validator의 주소| -|amount|uint256|N|validator에게 위임되는 스테이킹 토큰의 양| -|newShares|uint256|N|delegation 이후의 delegation shares의 양| - -### Unbond - -|Name|Type|Indexed|Description| -|---|---|---|---| -|delegatorAddr|address|Y|delegator의 주소| -|validatorAddr|string|Y|validator의 주소| -|amount|uint256|N|validator로부터 언델리게이트된 스테이킹 토큰의 양| -|completionTime|uint256|N|언델리게이션의 완료 시간| - -### Redelegate - -|Name|Type|Indexed|Description| -|---|---|---|---| -|delegatorAddr|address|Y|delegator의 주소| -|validatorSrcAddress|address|Y|출발지 validator의 주소| -|validatorDstAddress|address|Y|목적지 validator의 주소| -|amount|uint256|N|재위임할 스테이킹 토큰의 양| -|completionTime|uint256|N|재위임의 완료 시간| +- [**스테이킹 사전 컴파일 참조**](/ko/reference/staking-module-api): `delegate`, `undelegate`, `redelegate`를 호출하고 유효성 검사기 상태를 읽습니다. +- [**시스템 트랜잭션**](/ko/explanation/system-transactions): 언본딩 완료가 이벤트로 EVM에 도달하는 방법을 알아봅니다. +- [**분배 모듈**](/ko/explanation/distribution-module): 여기서 관리되는 위임으로 얻은 보상을 인출합니다. diff --git a/docs/pages/ko/explanation/system-modules-overview.mdx b/docs/pages/ko/explanation/system-modules-overview.mdx index 3b02ceb..eab125d 100755 --- a/docs/pages/ko/explanation/system-modules-overview.mdx +++ b/docs/pages/ko/explanation/system-modules-overview.mdx @@ -1,39 +1,39 @@ --- source_path: explanation/system-modules-overview.mdx -source_sha: 9fceb608b81d160096165cf2420612413f756df2 +source_sha: e9d156bb03d4413c1981f308ba7c076759d9baa8 title: "시스템 모듈" -description: "Stable은 Cosmos-SDK 프로토콜 모듈을 사전 컴파일된 컨트랙트를 통해 EVM에 노출하므로, dApp이 staking, distribution, bank 작업을 다시 작성하지 않고도 호출할 수 있습니다." +description: "EVM에서 스테이킹, 분배, 뱅크 작업을 호출합니다. Stable은 Cosmos-SDK 프로토콜 모듈을 재작성 없이 사전 컴파일된 컨트랙트로 노출합니다." diataxis: "explanation" --- # 시스템 모듈 -Stable의 핵심 프로토콜 동작은 SDK 모듈인 `x/bank`, `x/distribution`, `x/staking`에 존재합니다. 이 동작을 EVM에서 접근 가능하게 하기 위해, Stable은 각 모듈을 고정된 주소의 **사전 컴파일된 컨트랙트(precompiled contract)**로 노출합니다. Solidity로 작성된 컨트랙트는 precompile을 직접 호출하고, EVM은 그 호출을 네이티브 SDK 핸들러로 라우팅합니다. Precompile은 프로토콜 수준에서 구현되므로 동등한 Solidity 재구현보다 훨씬 가스 효율적입니다. +Stable의 핵심 프로토콜 동작은 `x/bank`, `x/distribution`, `x/staking`과 같은 SDK 모듈에 있습니다. 이 동작을 EVM에서 접근 가능하도록 Stable은 각 모듈을 고정 주소의 **사전 컴파일된 컨트랙트**로 노출합니다. Solidity로 작성된 컨트랙트는 사전 컴파일을 직접 호출하며, EVM은 이 호출을 네이티브 SDK 핸들러로 라우팅합니다. 사전 컴파일은 프로토콜 수준에서 구현되므로, 동등한 Solidity 재구현보다 훨씬 더 가스 효율적입니다. ## 세 가지 모듈 -| 모듈 | Precompile 주소 | 목적 | +| 모듈 | 사전 컴파일 주소 | 목적 | | :--- | :--- | :--- | -| [Bank](/ko/explanation/bank-module) | `0x0000…1003` (STABLE) | 토큰 전송, 잔액 회계, allowance 관리, 권한이 부여된 컨트랙트를 위한 mint/burn. | -| [Distribution](/ko/explanation/distribution-module) | `0x0000…0801` | 스테이킹 보상 청구, 보상 조회, 출금 주소 관리. | -| [Staking](/ko/explanation/staking-module) | `0x0000…0800` | 위임, 위임 해제, 재위임, 검증자 조회. | -| [System transactions](/ko/explanation/system-transactions) | `0x0000…9999` | SDK 계층 작업(예: 언본딩 완료)을 위한 프로토콜에서 발생하는 EVM 이벤트. | +| [뱅크](/ko/explanation/bank-module) | `0x0000…1003` (STABLE) | 토큰 전송, 잔액 회계, 허용치 관리, 승인된 컨트랙트에 대한 mint/burn. | +| [분배](/ko/explanation/distribution-module) | `0x0000…0801` | 스테이킹 보상 청구, 보상 쿼리, 인출 주소 관리. | +| [스테이킹](/ko/explanation/staking-module) | `0x0000…0800` | 위임, 위임 해제, 재위임, 검증인 쿼리. | +| [시스템 트랜잭션](/ko/explanation/system-transactions) | `0x0000…9999` | SDK 계층 작업(예: 언본딩 완료)에 대해 프로토콜에서 발행하는 EVM 이벤트. | -위의 각 페이지는 해당 모듈이 무엇을 하는지, 언제 사용하는지, 그리고 ABI를 어디에서 찾을 수 있는지 설명합니다. +위 각 페이지는 모듈이 무엇을 하는지, 언제 사용해야 하는지, 그리고 해당 ABI를 어디서 찾을 수 있는지 설명합니다. -## 왜 Solidity가 아닌 precompile인가 +## Solidity가 아닌 사전 컴파일인 이유 두 가지 이유가 있습니다: -- **가스 효율성.** Precompile은 프로토콜의 네이티브 실행 경로에서 실행됩니다. 동등한 Solidity 컨트랙트는 동일한 로직을 훨씬 높은 가스 비용으로 재구현하게 됩니다. -- **단일 진실 공급원(Single source of truth).** Staking, distribution, 토큰 공급량은 프로토콜 수준의 상태입니다. 이를 precompile을 통해 노출하면 SDK와 어긋날 수 있는 중복된 Solidity 구현을 유지할 필요가 없어집니다. +- **가스 효율성.** 사전 컴파일은 프로토콜의 네이티브 실행 경로에서 실행됩니다. 동등한 Solidity 컨트랙트는 훨씬 더 높은 가스 비용으로 동일한 로직을 재구현할 것입니다. +- **단일 정보원.** 스테이킹, 분배, 토큰 공급은 프로토콜 수준의 상태입니다. 사전 컴파일을 통해 이를 노출함으로써 SDK에서 벗어날 수 있는 중복된 Solidity 구현을 유지할 필요가 없습니다. ## 권한 부여 -일부 precompile 메서드(`mint`, `burn`, 프로토콜 수준의 스테이킹 작업)는 호출자 권한 부여가 필요합니다. `x/precompile` 모듈은 온체인 화이트리스트를 유지하며, 등록되지 않은 컨트랙트의 호출은 revert됩니다. 이는 읽기/전송 메서드의 일반적인 EVM 사용을 막지 않으면서 권한이 필요한 작업을 거버넌스로 통제합니다. +일부 사전 컴파일 메서드(`mint`, `burn`, 프로토콜 수준 스테이킹 작업)는 호출자 권한 부여를 요구합니다. `x/precompile` 모듈은 온체인 화이트리스트를 유지하며, 등록되지 않은 컨트랙트의 호출은 되돌려집니다. 이는 읽기/전송 메서드의 일반적인 EVM 사용을 차단하지 않으면서 특권 작업을 거버넌스 제어가 가능하게 합니다. ## 다음 권장 사항 -- [**Bank 모듈**](/ko/explanation/bank-module) — 토큰 전송, allowance, mint/burn 권한 부여 모델을 이해합니다. -- [**Staking 모듈**](/ko/explanation/staking-module) — 위임과 검증자 관리가 어떻게 EVM에 도달하는지 확인합니다. -- [**System transactions**](/ko/explanation/system-transactions) — 언본딩 완료와 같은 프로토콜 수준의 이벤트가 어떻게 EVM 로그로 표면화되는지 알아봅니다. +- [**뱅크 모듈**](/ko/explanation/bank-module): 토큰 전송, 허용치, mint/burn 승인 모델을 이해합니다. +- [**스테이킹 모듈**](/ko/explanation/staking-module): 위임 및 검증인 관리가 EVM에 어떻게 도달하는지 확인합니다. +- [**시스템 트랜잭션**](/ko/explanation/system-transactions): 언본딩 완료와 같은 프로토콜 수준 이벤트가 EVM 로그로 어떻게 나타나는지 알아봅니다. diff --git a/docs/pages/ko/explanation/system-transactions.mdx b/docs/pages/ko/explanation/system-transactions.mdx index 478a785..e115904 100755 --- a/docs/pages/ko/explanation/system-transactions.mdx +++ b/docs/pages/ko/explanation/system-transactions.mdx @@ -1,355 +1,60 @@ --- source_path: explanation/system-transactions.mdx -source_sha: 59aa5ae83041e3012bd580b2771601277b1ddf1c -title: System Transactions -description: "dApp 가시성을 위해 SDK 계층 스테이킹 이벤트를 EVM 로그로 연결하는 시스템 트랜잭션." +source_sha: 0ca908e75feea70023fe71db75e2068f4c824b90 +title: "시스템 트랜잭션" +description: "시스템 트랜잭션은 Cosmos-SDK 이벤트를 EVM 로그에 연결하므로, 언본딩 완료와 같은 작업은 dApp이 구독할 수 있는 표준 이벤트로 나타납니다." +diataxis: "explanation" --- -# System Transactions +# 시스템 트랜잭션 -## 요약 +EVM 애플리케이션은 `eth_getLogs`와 같은 표준 인터페이스를 통해 온체인 활동을 구독합니다. 그러나 Stable에서 가장 중요한 작업 중 일부(예: 스테이킹 언본딩 완료)는 EVM 이벤트를 자연스럽게 방출하지 않는 SDK 모듈 내에서 발생합니다. **시스템 트랜잭션**은 이러한 가시성 격차를 해소합니다. 프로토콜 자체는 SDK 계층 작업에 대한 이벤트를 방출하는 EVM 트랜잭션을 제출하여 dApp이 이미 사용하는 동일한 로그 스트림을 통해 인덱싱할 수 있게 합니다. -시스템 트랜잭션은 Stable 프로토콜이 Stable SDK 작업에 대한 EVM 이벤트를 발생시킬 수 있는 방법을 제공합니다. 언본딩 완료와 같은 스테이킹 이벤트가 SDK 계층에서 발생하면 프로토콜은 해당 이벤트를 발생시키는 EVM 트랜잭션을 자동으로 생성하여 이러한 작업이 EVM 도구 및 애플리케이션에 완전히 표시되도록 합니다. +## 이것이 중요한 이유 -## 동기 +사용자의 토큰이 언제 언본딩을 완료하는지 추적하는 것을 생각해 봅시다. 시스템 트랜잭션이 없다면, dApp은 다음 중 하나를 해야 합니다. -Stable의 EVM 사용자와 애플리케이션은 `eth_getLogs`와 같은 표준 EVM 인터페이스를 통해 블록체인 이벤트를 모니터링할 것으로 기대합니다. 그러나 중요한 작업은 EVM 이벤트를 자연스럽게 발생시키지 않는 Stable SDK 모듈에서 발생합니다. 이는 가시성 격차를 만듭니다: EVM dapp은 사용자의 토큰이 언제 언본딩을 완료하는지 쉽게 추적할 수 없습니다. +- SDK 이벤트를 감시하고 자체 데이터베이스에 저장하는 별도의 인덱서를 실행합니다. 운영 오버헤드와 새로운 실패 지점이 발생합니다. +- REST 엔드포인트를 주기적으로 폴링합니다. 5–10초 지연, 더 높은 RPC 부하, 유지보수해야 할 두 가지 클라이언트 스택(web3 + REST)이 발생합니다. -시스템 트랜잭션은 이 격차를 해소합니다. 스테이킹 모듈이 언본딩 작업을 완료하면 Stable의 x/stable 모듈이 이벤트를 감지하고 StableSystem 프리컴파일 (`0x0000000000000000000000000000000000009999`)을 호출하는 시스템 트랜잭션을 생성합니다. 그런 다음 프리컴파일은 모든 dapp이 구독할 수 있는 적절한 EVM 이벤트를 발생시킵니다. 시스템 트랜잭션은 프로토콜만 사용할 수 있는 특수 발신자 주소(`0x8888888888888888888888888888888888888888`)로 실행됩니다. 이는 누구도 프로토콜 이벤트를 위조할 수 없도록 방지하면서 이벤트 발생을 무신뢰적이고 온체인에서 검증 가능하게 유지합니다. +시스템 트랜잭션은 dApp에 EVM 로그에 이미 사용하는 동일한 WebSocket 연결을 통해 실시간 이벤트 알림을 제공합니다. 별도의 인덱서가 필요 없고, REST 폴링도 필요 없습니다. -## 명세 +## 작동 방식 -시스템 트랜잭션은 세 가지 주요 구성 요소를 통해 작동합니다: x/stable 모듈의 EndBlocker, PrepareProposal 핸들러 및 StableSystem 프리컴파일입니다. - -### 아키텍처 개요 - -system-transaction-architecture - -### StableSystem 프리컴파일 - -StableSystem 프리컴파일은 `0x0000000000000000000000000000000000009999`에 있으며 EVM 이벤트를 발생시켜야 하는 프로토콜 수준 작업을 처리합니다. 현재 언본딩 완료 알림을 지원합니다. - -```solidity -interface IStableSystem { - /// @notice 대기 중인 언본딩 완료를 처리하고 EVM 이벤트를 발생시킵니다 - /// @param blockHeight 완료를 처리할 블록 높이 - /// @dev 시스템 트랜잭션에서만 호출 가능 (from = 0x8888888888888888888888888888888888888888) - /// @dev 호출당 최대 100개의 완료를 처리 - /// @dev 처리된 완료를 큐에서 자동으로 삭제 - function notifyUnbondingCompletions(int64 blockHeight) external; - - /// @notice 언본딩 작업이 완료될 때 발생 - /// @param delegator 토큰을 위임한 주소 - /// @param validator 토큰이 위임된 검증자 주소 - /// @param amount 언본딩을 완료한 토큰 양 (uusdc 단위) - event UnbondingCompleted( - address indexed delegator, - address indexed validator, - uint256 amount - ); - - /// @notice 호출자가 권한이 없음 (시스템 트랜잭션 발신자가 아님) - error Unauthorized(); -} +```text +1. 프로토콜 이벤트: SDK 계층 작업이 완료됩니다(예: 스테이킹 언본딩). +2. 감지: x/stable EndBlocker는 이벤트를 감지하고 상태에 대기시킵니다. +3. 시스템 TX: 다음 블록의 PrepareProposal에서 프로토콜은 StableSystem 사전 컴파일러를 + 호출하는 시스템 트랜잭션을 생성합니다. +4. EVM 방출: 사전 컴파일러는 대기 중인 항목을 처리하고 표준 + EVM 이벤트를 방출합니다. dApp은 eth_getLogs 및 구독을 통해 이를 확인합니다. ``` -### 시스템 트랜잭션 발신자 - -시스템 트랜잭션은 `0x8888888888888888888888888888888888888888`을 발신자 주소로 사용합니다. 이 주소는: - -- 서명 검증이 필요 없음 -- PrepareProposal에서 생성된 트랜잭션만 사용 가능 -- 사용자나 컨트랙트가 위조할 수 없음 -- SystemTxDecorator ante 핸들러를 통해 수수료 공제를 건너뜀 - -EVM은 `msg.sender == 0x8888888888888888888888888888888888888888`을 확인하여 시스템 트랜잭션을 인식합니다. 프리컴파일은 이를 사용하여 프로토콜 전용 작업을 제한할 수 있습니다. - -### 이벤트 기반 흐름 - -사용자의 언본딩 기간이 완료되면 다음과 같은 일이 발생합니다: - -1. **Stable SDK 계층:** 스테이킹 모듈의 EndBlocker가 언본딩을 완료하고 위임자 주소, 검증자 주소 및 금액과 함께 EventTypeCompleteUnbonding을 발생시킵니다. -2. **감지:** x/stable 모듈의 EndBlocker는 스테이킹 이후에 실행되며 블록의 이벤트 로그에서 언본딩 이벤트를 스캔합니다. 각 완료에 대해 위임자 주소, 검증자 주소, 금액 및 블록 높이를 포함하는 항목을 상태에 큐에 넣습니다. -3. **시스템 트랜잭션 생성**: 다음 블록의 PrepareProposal에서 앱은 대기 중인 모든 완료를 쿼리합니다. 있는 경우 현재 블록 높이로 StableSystem.notifyUnbondingCompletions(blockHeight)를 호출하는 시스템 트랜잭션을 생성합니다. 이 트랜잭션은 사용자 트랜잭션보다 먼저 블록 앞에 배치됩니다. -4. **실행:** 블록 실행 중에 시스템 트랜잭션이 먼저 실행됩니다. 프리컴파일은 해당 블록 높이에서 대기 중인 완료에 대한 상태를 쿼리하고, 각 완료에 대해 UnbondingCompleted 이벤트를 발생시키며(최대 100개), 큐에서 삭제합니다. -5. **EVM 가시성:** 이벤트는 트랜잭션 영수증과 로그에 나타나며, eth_getLogs 쿼리, 블록 탐색기 및 StableSystem 프리컴파일을 모니터링하는 모든 애플리케이션에 표시됩니다. - -### 배치 처리 - -블록이 너무 커지는 것을 방지하기 위해 시스템은 블록당 최대 100개의 언본딩 완료를 처리합니다. 150개의 완료가 큐에 들어가면: - -- 블록 N: 완료 0-99를 처리하는 시스템 트랜잭션 생성 -- 블록 N+1: 완료 100-149를 처리하는 시스템 트랜잭션 생성 - -프리컴파일은 calldata에서 완료 데이터를 받는 대신 상태를 직접 쿼리합니다. 이렇게 하면 트랜잭션 크기를 예측 가능하게 유지하고 데이터를 비싼 calldata에서 더 저렴한 상태 읽기로 이동합니다. - -## 사용 예시 - -가장 일반적인 사용 사례는 언본딩 기간이 완료될 때 사용자에게 알려야 하는 스테이킹 대시보드입니다. 다음은 언본딩 완료 리스너를 설정하는 방법입니다. - -```javascript -import { ethers } from 'ethers'; - -// StableSystem 프리컴파일 주소 -const STABLE_SYSTEM_ADDRESS = '0x0000000000000000000000000000000000009999'; - -// UnbondingCompleted 이벤트의 ABI -const STABLE_SYSTEM_ABI = [ - 'event UnbondingCompleted(address indexed delegator, address indexed validator, uint256 amount)' -]; - -// Stable 네트워크에 연결 -const provider = new ethers.JsonRpcProvider('https://rpc.testnet.stable.xyz'); -const stableSystem = new ethers.Contract( - STABLE_SYSTEM_ADDRESS, - STABLE_SYSTEM_ABI, - provider -); - -// 모든 언본딩 완료 구독 -stableSystem.on('UnbondingCompleted', (delegator, validator, amount, event) => { - console.log('언본딩 완료!'); - console.log('위임자:', delegator); - console.log('검증자:', validator); - console.log('금액:', ethers.formatEther(amount), '토큰'); - console.log('블록:', event.log.blockNumber); - console.log('트랜잭션 해시:', event.log.transactionHash); -}); - -``` - -이 리스너는 사용자의 언본딩이 완료될 때마다 실행됩니다. 프로덕션 dApp의 경우 일반적으로 특정 사용자에 대한 이벤트를 필터링합니다. - -### 특정 사용자에 대한 이벤트 필터링 - -특정 위임자 주소에 대한 이벤트만 받으려면 인덱싱된 이벤트 매개변수를 사용하여 필터를 만듭니다: - -```javascript -// 특정 사용자의 언본딩만 감시 -const userAddress = '0xabcd...'; - -const filter = stableSystem.filters.UnbondingCompleted(userAddress); - -stableSystem.on(filter, (delegator, validator, amount, event) => { - // 지정된 사용자의 언본딩에 대해서만 실행됨 - showNotification(`${ethers.formatEther(amount)} 토큰의 언본딩이 완료되었습니다!`); - refreshUserBalance(userAddress); -}); -``` - -검증자별 대시보드를 구축하는 경우 검증자별로 필터링할 수도 있습니다: - -```javascript -// 특정 검증자의 모든 언본딩 감시 -const validatorAddress = '0x1234...'; - -const validatorFilter = stableSystem.filters.UnbondingCompleted(null, validatorAddress); - -stableSystem.on(validatorFilter, (delegator, validator, amount) => { - updateValidatorStats(validator, amount); -}); -``` - -### 과거 이벤트 쿼리 - -dApp에서 과거 언본딩 완료 기록을 표시해야 하는 경우 블록 범위가 있는 이벤트 필터를 사용하여 과거 이벤트를 쿼리할 수 있습니다: - -```javascript -// 최근 1000개 블록에서 사용자의 모든 언본딩 가져오기 -const currentBlock = await provider.getBlockNumber(); -const filter = stableSystem.filters.UnbondingCompleted(userAddress); - -const events = await stableSystem.queryFilter( - filter, - currentBlock - 1000, - currentBlock -); - -const unbondingHistory = events.map(event => ({ - delegator: event.args.delegator, - validator: event.args.validator, - amount: ethers.formatEther(event.args.amount), - blockNumber: event.blockNumber, - txHash: event.transactionHash -})); - -console.log('최근 언본딩:', unbondingHistory); - -``` - -## 통합 가이드 - -### 단계 1: Stable System 컨트랙트 인터페이스 추가 - -먼저 StableSystem 프리컴파일 인터페이스를 프로젝트에 추가합니다. Foundry 또는 Hardhat을 사용하는 경우 새 인터페이스 파일을 생성합니다: - -```solidity -interface IStableSystem { - event UnbondingCompleted( - address indexed delegator, - address indexed validator, - uint256 amount - ); -} -``` - -Solidity 컨트랙트 없이 순수 프론트엔드 dApp을 구축하는 경우 이벤트에 대한 ABI 조각만 필요합니다: - -```javascript -const STABLE_SYSTEM_ABI = [ - 'event UnbondingCompleted(address indexed delegator, address indexed validator, uint256 amount)' -]; -``` - -### 단계 2: 이벤트 리스너 설정 - -ethers.js provider를 초기화하고 StableSystem 프리컴파일 주소를 가리키는 컨트랙트 인스턴스를 생성합니다. 프리컴파일은 Stable 테스트넷과 메인넷 모두에서 항상 `0x00000000000....0000009999`에 배포됩니다. - -*참고: 프리컴파일은 아직 Stable 메인넷에 배포되지 않았으며 v1.2.0 업그레이드 후에 제공됩니다.* - -```javascript -const provider = new ethers.JsonRpcProvider(RPC_URL); -const stableSystem = new ethers.Contract( - '0x0000000000000000000000000000000000009999', - STABLE_SYSTEM_ABI, - provider -); -``` - -### 단계 3: 애플리케이션 로직에서 이벤트 처리 - -이벤트를 구독하고 애플리케이션 상태를 그에 따라 업데이트합니다. 일반적인 패턴은 다음과 같습니다: - -- **잔액 업데이트**: 언본딩이 완료되면 사용자의 토큰 잔액을 새로 고침 -- **알림 시스템**: 사용자의 언본딩이 완료될 때 토스트 알림 표시 -- **대시보드 통계**: 실시간으로 스테이킹 지표 및 차트 업데이트 -- **트랜잭션 기록**: 완료된 언본딩을 사용자의 활동 피드에 추가 - -### 단계 4: 연결 문제 처리 - -이벤트 구독은 지속적인 websocket 연결에 의존하므로 프로덕션 dApp을 위한 재연결 로직을 구현합니다: - -```javascript -let reconnectAttempts = 0; -const MAX_RECONNECT_ATTEMPTS = 5; - -function setupEventListener() { - const provider = new ethers.WebSocketProvider('wss://rpc.testnet.stable.xyz'); - - provider.on('error', (error) => { - console.error('Provider 오류:', error); - if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) { - reconnectAttempts++; - setTimeout(() => setupEventListener(), 5000); - } - }); - - const stableSystem = new ethers.Contract( - '0x0000000000000000000000000000000000009999', - STABLE_SYSTEM_ABI, - provider - ); - - stableSystem.on('UnbondingCompleted', handleUnbonding); -} -``` - -## 왜 이 방법인가? - -### 커스텀 인덱서와 비교 - -이전에는 Stable SDK가 dApp 개발자에게 SDK 이벤트를 감시하고 데이터베이스에 저장하는 커스텀 인덱서를 실행하도록 요구했습니다. 이는 운영 오버헤드를 추가하고 잠재적인 실패 지점을 도입합니다. - -시스템 트랜잭션을 사용하면 별도의 인덱서 인프라가 필요하지 않습니다. 이벤트는 모든 RPC 노드가 이미 인덱싱하고 제공하는 EVM의 로그 시스템을 통해 기본적으로 사용할 수 있습니다. 모든 표준 web3 라이브러리는 추가 도구 없이 이러한 이벤트를 구독할 수 있습니다. - -### SDK 엔드포인트 폴링과 비교 - -시스템 트랜잭션이 없으면 EVM dApp은 언본딩 기간이 완료되었는지 확인하기 위해 주기적으로 Stable SDK REST 엔드포인트를 호출해야 합니다. 이는 여러 문제를 야기합니다: - -- **지연 시간 증가**: 5-10초의 폴링 간격은 사용자가 업데이트를 보기 전에 그만큼 기다려야 함을 의미합니다 -- **더 높은 부하**: 모든 dApp 인스턴스의 엔드포인트 폴링은 RPC 인프라의 부하를 증가시킵니다 -- **복잡성**: dApp은 web3 프로바이더(EVM 상호 작용용)와 Stable SDK REST 클라이언트(SDK 쿼리용)를 모두 처리해야 합니다 -- **실시간 업데이트 없음**: 폴링은 본질적으로 즉각적인 알림을 제공할 수 없습니다 - -시스템 트랜잭션은 dApp이 이미 EVM 상호 작용에 사용하는 동일한 websocket 연결을 통해 실시간 이벤트 알림을 제공합니다. 이는 개발자 경험을 단순화하고 인프라 비용을 줄입니다. - -## 보안 보증 - -### 무신뢰 이벤트 발생 - -시스템 트랜잭션은 검증자만 실행할 수 있는 `PrepareProposal` ABCI 단계에서 생성됩니다. 사용자가 제출한 트랜잭션은 EVM의 상태 전환 로직이 StableSystem 프리컴파일 주소로의 트랜잭션만 서명 검증을 건너뛸 수 있도록 강제하기 때문에 시스템 발신자 주소(`0x8888888888888888888888888888888888888888`)를 위조할 수 없습니다. - -이것은 다음을 의미합니다: - -- 사용자는 언본딩 완료 이벤트를 위조할 수 없습니다 -- 사용자는 자신의 트랜잭션에서 `notifyUnbondingCompletions`을 호출할 수 없습니다 -- `UnbondingCompleted` 이벤트를 발생시키는 유일한 방법은 Stable SDK 스테이킹 모듈에서 실제로 언본딩을 완료하는 것입니다 - -### 추가 신뢰 가정 없음 - -시스템 트랜잭션은 블록체인 합의에 이미 필요한 것 이상의 새로운 보안 가정을 도입하지 않습니다. 검증자가 블록을 올바르게 실행하고 있다고 신뢰한다면 시스템 트랜잭션 이벤트가 Stable SDK 상태 변경을 정확하게 반영한다고 신뢰할 수 있습니다. - -이벤트 발생 프로세스는 결정론적입니다: `EndBlock`에서 동일한 SDK 이벤트가 주어지면 모든 정직한 검증자는 `PrepareProposal` 중에 동일한 시스템 트랜잭션을 생성합니다. 합의 메커니즘은 검증자가 포함할 시스템 트랜잭션에 대해 합의하도록 보장합니다. - -### 블록 최종성 - -Stable 블록체인은 StableBFT의 합의 메커니즘을 통해 빠른 최종성을 사용합니다. 블록이 커밋되면 즉시 최종화되며 재구성될 수 없습니다. 이는 `UnbondingCompleted` 이벤트를 받으면 영구적이라고 신뢰할 수 있음을 의미합니다. - -확률적 최종성 체인에서처럼 여러 확인을 기다릴 필요가 없습니다. dApp은 이벤트를 받은 즉시 사용자 잔액을 업데이트하고 알림을 표시할 수 있습니다. - -## 성능 및 제한 사항 - -### 배치 크기 제약 - -각 블록은 시스템 트랜잭션을 통해 최대 100개의 언본딩 완료를 처리합니다. 이 제한은 높은 언본딩 활동 기간 동안 무제한 블록 크기를 방지하기 위해 존재합니다. - -실제로 블록당 100개의 완료는 평균 블록 시간이 0.7초라고 가정할 때 분당 약 9000개의 완료 처리량을 제공합니다. 일반적인 스테이킹 활동은 이 제한에 거의 도달하지 않습니다. 예외적인 상황에서는 완료가 완전히 처리되기 전에 여러 블록 동안 큐에 대기할 수 있습니다. - -### Gas 소비 - -시스템 트랜잭션은 실행 중에 gas를 소비하며, 이는 블록의 gas 제한에서 고려됩니다. gas 비용은 처리되는 완료 수에 따라 선형적으로 증가합니다: - -- 기본 함수 호출: 약 21,000 gas -- 이벤트 발생당: 약 3,000 gas -- 상태 읽기: 완료당 약 2,000 gas - -100개의 완료로 구성된 전체 배치는 약 521,000 gas를 소비합니다. Stable의 블록 gas 제한이 100,000,000이므로 이는 사용 가능한 블록 공간의 0.6% 미만을 나타냅니다. - -### 알림 지연 - -블록 N 동안 언본딩 기간이 완료되면: - -1. Stable 모듈의 `EndBlock`이 블록 N의 상태에서 완료를 큐에 넣습니다 -2. 블록 N+1의 `PrepareProposal`이 시스템 트랜잭션을 생성합니다 -3. 시스템 트랜잭션이 블록 N+1 동안 실행되어 이벤트를 발생시킵니다 - -이는 언본딩 완료와 EVM 이벤트 발생 사이에 1블록 지연(약 0.7초)이 있음을 의미합니다. 언본딩 기간 자체가 7일이기 때문에 이 지연은 허용 가능한 수준입니다. +시스템 트랜잭션은 사용자가 아닌 블록 제안 중에 검증자가 생성합니다. 사용자 트랜잭션보다 먼저 블록의 맨 앞에 착륙합니다. -### 고부하 시나리오 +## StableSystem 사전 컴파일러 -언본딩 완료가 블록당 100개보다 빠르게 도착하면 큐에 누적됩니다. 큐는 FIFO 순서로 처리되므로 가장 오래된 완료가 항상 먼저 알림을 받습니다. +이벤트는 `0x0000000000000000000000000000000000009999`의 `StableSystem` 사전 컴파일러를 통해 흐릅니다. 현재 스테이킹 언본딩에 대해 하나의 이벤트(`UnbondingCompleted`)를 방출합니다. 프로토콜은 동일한 패턴으로 다른 SDK 작업(검증자 수수료 변경, 거버넌스 실행)으로 확장하도록 설계되었습니다. -지속적인 고부하 동안 큐가 일시적으로 증가할 수 있습니다. 그러나 급증이 가라앉으면 완료가 적은 후속 블록이 점차 큐를 배출합니다. 시스템은 이벤트를 삭제하지 않고 급증을 처리하도록 설계되었습니다. +## 보안 모델 -## 향후 확장 +두 가지 속성은 이벤트 스트림의 신뢰성을 유지합니다. -시스템 트랜잭션 메커니즘은 모든 Stable SDK 작업을 EVM 이벤트로 전달하는 일반적인 패턴을 제공합니다. 현재 언본딩 완료에만 사용되지만 아키텍처는 추가 사용 사례를 포괄하도록 확장될 수 있습니다. +- **프로토콜 전용 발신자.** 시스템 트랜잭션은 `0x8888888888888888888888888888888888888888`를 발신자로 사용합니다. EVM 상태 전환 규칙은 이 주소에서 `StableSystem` 사전 컴파일러로의 트랜잭션만 서명 검증을 건너뛸 수 있도록 허용합니다. 사용자는 자신의 트랜잭션에서 이벤트를 위조하거나 제한된 사전 컴파일러 함수를 호출할 수 없습니다. +- **결정론적 방출.** 모든 정직한 검증자는 동일한 프로토콜 이벤트에 대해 동일한 시스템 트랜잭션을 생성합니다. 표준 합의 외에 추가적인 신뢰 가정은 없습니다. -### 스테이킹 작업 +## 배치 처리 -언본딩 외에도 다른 스테이킹 이벤트가 EVM 알림을 발생시킬 수 있습니다: +블록 크기를 제한하기 위해 각 블록은 최대 100개의 언본딩 완료를 처리합니다. Stable의 ~700ms 블록 시간에서 이는 분당 약 9,000개의 완료를 의미하며, 이는 일반적인 스테이킹 활동보다 훨씬 높습니다. 버스트가 블록당 제한을 초과하면 완료는 FIFO 순서로 대기열에 추가되고 후속 블록에 걸쳐 처리됩니다. -- 검증자의 수수료율 변경 -- 검증자 Jail 및 Unjail +SDK 이벤트와 EVM 방출 사이에는 한 블록(~700ms)의 지연이 있는데, 이는 7일 언본딩 기간 자체에 비해 무시할 수 있는 수준입니다. -### 거버넌스 실행 +## ABI를 찾는 곳 -거버넌스 제안이 통과되고 실행될 때 시스템 트랜잭션은 제안 ID 및 실행 결과와 함께 이벤트를 발생시킬 수 있습니다. 이를 통해 dApp은 거버넌스 모듈을 폴링하지 않고도 매개변수 변경 또는 업그레이드에 반응할 수 있습니다. +`StableSystem` 인터페이스, 이벤트 서명 및 발신자 권한 부여 규칙은 [시스템 트랜잭션 참조](/ko/reference/system-transactions-api)에 있습니다. -### 일반 이벤트 브리지 +## 다음 권장 사항 -이 패턴은 각 모듈이 어떤 SDK 이벤트를 EVM에 미러링해야 하는지 등록하는 구성 가능한 이벤트 브리지로 일반화될 수 있습니다. 이는 모듈별 커스텀 로직 없이 모든 Stable SDK 작업에 대한 포괄적인 가시성을 제공합니다. 핵심 아키텍처 원칙은 시스템 트랜잭션이 블록 제안 중에 검증자에 의해서만 생성되는 프로토콜 수준 기능으로 유지된다는 것입니다. +- [**시스템 트랜잭션 참조**](/ko/reference/system-transactions-api): `IStableSystem` 인터페이스, 가스 계산 및 권한 부여 규칙을 검토하세요. +- [**스테이킹 모듈**](/ko/explanation/staking-module): 시스템 트랜잭션 이벤트로 나타나는 SDK 작업을 확인하세요. +- [**시스템 모듈 개요**](/ko/explanation/system-modules-overview): 사전 컴파일러가 노출하는 모듈 목록으로 돌아갑니다. diff --git a/docs/pages/ko/explanation/technical-roadmap.mdx b/docs/pages/ko/explanation/technical-roadmap.mdx index 580c9b9..009398c 100755 --- a/docs/pages/ko/explanation/technical-roadmap.mdx +++ b/docs/pages/ko/explanation/technical-roadmap.mdx @@ -1,100 +1,75 @@ --- source_path: explanation/technical-roadmap.mdx -source_sha: 51096f595fa958dae93321c10dc7be09f153ba92 -title: "기술 로드맵" -description: "데이터베이스, 실행, 합의 및 USDT 특화 성능 개선을 다루는 Stable의 단계별 최적화 로드맵." +source_sha: 669bf747b8f3b656b8509625ece8a50946d431f8 +title: "로드맵" +description: "Stable의 단계별 최적화 로드맵: 현재 라이브 상태, 다음에 출시될 내용, 그리고 그 이후의 계획입니다." +diataxis: "explanation" --- -# 기술 로드맵 +# 로드맵 -## 모든 레이어를 최적화하기 위한 Stable의 접근법 - -사용자가 트랜잭션을 제출하기부터 결과를 받기까지의 라이프사이클은 여러 단계로 구성됩니다. 우선 트랜잭션은 RPC를 통해 전파되고, 멤풀에 저장되며, 블록에 포함된 다음, 합의를 통해 검증되고 실행되어, 마침내 데이터베이스에 결과 상태가 저장됩니다. 이러한 단계를 거쳐야만 사용자는 최종 결과를 받아볼 수 있습니다. - -이 중 어느 단계라도 최적화되지 않는다면, 전체 시스템의 성능이 악화됩니다. Stable은 트랜잭션 파이프라인의 각 단계를 최적화하여 성능을 극대화하고 레이턴시를 최소화하는 것을 목표로 합니다. - -Stable의 핵심 기술은 여러 페이즈에 걸쳐 출시될 것이며, 각각은 트랜잭션 완결성을 희생하지 않으면서 전반적인 초당 트랜잭션 수(TPS)를 증가시키도록 설계되었습니다. - -아래 섹션은 현재 블록체인 아키텍처 내 일반적인 병목과, Stable이 최적화하려고 하는 것들에 대해 설명합니다. +Stable은 세 단계를 거쳐 트랜잭션 파이프라인의 모든 계층(합의, 실행, 스토리지, RPC, USDT별 흐름)을 최적화합니다. 이 페이지에는 출시된 내용, 진행 중인 내용, 그리고 앞으로의 계획이 표시되어 있습니다. Technical Roadmap -## 페이즈 1 – USDT를 위한 기반 레이어 - -### StableBFT - -초기 Stable 블록체인은 StableBFT를 활용합니다. 이는 CometBFT를 기반으로 높은 처리량, 낮은 레이턴시, 그리고 강력한 신뢰성을 제공하기 위한 맞춤형 PoS 프로토콜입니다. 이는 결정론적인 완결성과 최대 1/3의 밸리데이터 장애 허용(fault tolerance)이라는 특징을 가지고 있습니다. 향후 Stable은 DAG 기반 합의로의 업그레이드를 통해 5배 빠른 합의 속도를 달성할 예정입니다. - -### USDT를 네이티브 가스로 - -Stable에서는 USDT0를 네이티브 가스 토큰으로 사용합니다. USDT0는 가스 결제와 가치 전송을 위한 네이티브 자산으로 동시에 기능하며, `approve`, `transfer`, `transferFrom`, `permit`을 지원하는 ERC20 토큰으로도 동작합니다. - -### Stable Pay & Stable Name - -Stable Pay은 탈중앙화 금융의 사용성을 크게 향상하기 위해 설계되었습니다. 현재 Web3 지갑들에는 가파른 학습 곡선 문제가 존재하며, Stable은 Web2.5 UX를 가진 지갑 경험을 도입하는 방식으로 이 문제를 해결합니다. 이를 통해 새로운 사용자들의 온보딩을 간소화하는 동시에, 기존 크립토 사용자들과도 호환될 수 있게 할 수 있습니다. 새로운 사용자들은 직관적인 디자인과 원활한 셋업 프로세스(소셜 로그인 등)를 통해 쉽게 온보딩할 수 있으며, 기존 크립토 유저들은 가지고 있던 지갑을 Stable에 그대로 가져와 마이그레이션 없이 사용할 수 있습니다. Stable Pay은 웹 앱과 모바일 앱 양쪽으로 제공되어, 모든 기기에서 안전하게 디지털 자산에 접근할 수 있습니다. - -지갑에 더해, Stable은 복잡하고 오류가 잦은 EVM 공개 주소 포맷을 고유하고 사람이 읽을 수 있는 형태로 바꾸는 Stable Name을 도입합니다. 사용자들은 긴 16진수 문자열을 관리할 필요 없이 Stable Name으로 간편하게 토큰을 주고받을 수 있습니다. 이 방식은 거래 상 오류를 크게 줄이고 크립토 자산과 상호작용할 때의 전반적인 경험을 증진하여, Stable을 블록체인 생태계로 진입하는 강력하고 사용자 중심적인 출발점으로 만들어줍니다. +## 1단계: USDT를 위한 기반 계층 -## 페이즈 2 – USDT를 위한 경험 레이어 +상태: **메인넷에 라이브.** -### 낙관적 병렬 실행 +### StableBFT: 라이브 -실제 운영 환경의 통계에 따르면, 전체 트랜잭션의 약 60~80%는 서로 겹치지 않는 상태를 다루기 때문에, 병렬로 안전하게 실행될 수 있습니다. 그러나 대부분의 블록체인 시스템은 여전히 트랜잭션을 순차적으로 처리하며, 이로 인해 불필요한 지연이 발생하고 있습니다. +CometBFT를 기반으로 구축된 맞춤형 PoS 합의 프로토콜입니다. 결정론적 완결성과 검증인의 1/3까지 비잔틴 결함 허용(BFT)을 제공합니다. 현재 구현은 [합의](/ko/explanation/consensus)를 참조하세요. -Stable은 이러한 한계를 극복하기 위해 낙관적 병렬 실행(Optimistic Parallel Execution) 모델을 채택합니다. 초기에는 상태 충돌이 없다는 가정 하에 트랜잭션을 병렬로 실행하고, 충돌이 감지되면 해당 트랜잭션만 롤백 후 순차적으로 재실행합니다. 이 방식은 정확성을 유지하면서도 처리량을 크게 향상시킬 수 있습니다. +### USDT를 기본 가스로: 라이브 -### State DB 최적화 +USDT0는 가스 지불 및 가치 이전을 위한 기본 자산이며, 동시에 ERC-20 서명(`approve`, `transfer`, `transferFrom`, `permit`)을 지원합니다. [가스 토큰으로서의 USDT](/ko/explanation/usdt-as-gas-token)를 참조하세요. -블록체인 성능의 주요 병목 중 하나는 느린 디스크 I/O입니다. 블록 실행 후 변경된 상태는 디스크에 기록되어야 하며, 기존 시스템에서는 상태 저장이 완료될 때까지 다음 블록 실행이 지연된다는 문제가 존재합니다. +### Stable Pay & Stable 이름: 진행 중 -Stable은 이를 해결하기 위해 상태 커밋과 상태 저장을 분리합니다. 밸리데이터 노드는 메모리에 최신 상태를 커밋하기만 하면 다음 블록 실행을 진행할 수 있고, 과거 상태는 디스크에 비동기적으로 저장됩니다. 이로 인해 실행에 대한 레이턴시를 줄일 수 있습니다. +Stable Pay는 기존 Web3 지갑과의 호환성을 유지하면서 신규 사용자의 온보딩을 단순화하도록 설계된 Web2.5 UX 지갑 경험입니다. Stable Name은 원시 EVM 주소를 사람이 읽을 수 있는 식별자로 대체하여 토큰을 주고받을 수 있는 사용자 친화적인 별칭 시스템입니다. -또한 `mmap`이라는 메모리 매핑 파일 I/O 메커니즘을 도입하여, 파일을 메모리 배열처럼 처리하는 방식으로 스토리지 성능을 높일 수 있습니다. 즉 실시간 상태 커밋은 메모리에서, 아카이브 상태는 디스크에 저장함으로써, Stable은 디스크 I/O 지연을 최소화하고 읽기/쓰기 처리량을 높입니다. +## 2단계: USDT를 위한 경험 계층 -### USDT 전송 집계 +상태: **개발 중.** 상태 DB 최적화는 v1.4.0 업그레이드에서 제공됩니다. 나머지 항목은 여전히 개발 중입니다. -많은 양의 USDT0 전송을 한 번에 처리하기 위해, Stable은 집계 메커니즘을 구현할 예정입니다. USDT0 전송 트랜잭션들을 그룹화하여 한 번에 처리함으로써, 트랜잭션 당 오버헤드를 줄이고 전반적인 처리량을 개선할 수 있습니다. +### 상태 DB 최적화: v1.4.0에서 제공 -### 보장된 블록스페이스 +Stable은 상태 커밋과 상태 스토리지를 분리합니다. 검증자는 최신 상태를 메모리에 커밋하고, 이력 상태는 디스크로 지연됩니다. `mmap`으로 구동되는 `MemDB` 및 `VersionDB`는 디스크 I/O에 블로킹 없이 실시간 커밋을 처리합니다. [스토리지 (StableDB)](/ko/explanation/stable-db)를 참조하세요. -블록체인 인프라를 사용하는 기업들은 예측 가능한 트랜잭션 레이턴시가 필요합니다. 하지만 네트워크 혼잡 시에는 이 예측 가능성이 무너질 수 있습니다. +### 낙관적 병렬 실행: 계획 중 -Stable은 이를 해결하기 위해 다음과 같은 방식으로 고정된 블록스페이스를 기업에 보장합니다: +실제 측정에 따르면 트랜잭션의 60-80%가 분리된 상태와 상호 작용하며 안전하게 병렬로 실행될 수 있습니다. Stable은 충돌이 없는 가정 하에 낙관적으로 트랜잭션을 실행하며, 충돌이 감지되면 롤백 및 순차 재실행을 수행합니다. 이는 정확성을 유지하면서 처리량을 향상시킵니다. -- 밸리데이터 단의 커스터마이징: 밸리데이터 노드가 기업을 위해 블록스페이스 일부를 할당합니다. -- 전용 RPC 노드: 보장된 트랜잭션은 별도의 멤풀과 API 엔드포인트를 통해 우선적으로 처리됩니다. +### USDT 전송 집계기: 계획 중 -이 모델은 혼잡하거나 적대적인 네트워크 환경에서도 기업의 핵심 운영에 필요한 성능을 안정적으로 제공합니다. +USDT0 전송을 그룹화하여 일괄 처리하는 집계 메커니즘으로, 트랜잭션당 오버헤드를 줄이고 전체 처리량을 향상시킵니다. [USDT 전송 집계기](/ko/explanation/usdt-transfer-aggregator)를 참조하세요. -## 페이즈 3 – USDT를 위한 풀스택 최적화 레이어 +### 보장된 블록 공간: 계획 중 -### Autobahn 기반의 StableBFT를 활용한 발전된 합의 알고리즘 +엔터프라이즈 파트너를 위한 예약된 블록 용량으로, 검증인 수준의 예약 및 전용 RPC 엔드포인트를 통해 강제됩니다. 네트워크 혼잡 시에도 중요한 지불 흐름에 대해 예측 가능한 대기 시간을 제공합니다. [보장된 블록 공간](/ko/explanation/guaranteed-blockspace)을 참조하세요. -1세대 DAG 기반 BFT 엔진(Narwhal, Tusk)은 데이터 전파와 합의를 분리함으로써 단일 제안자가 가지던 병목을 제거합니다. 그러나 이러한 시스템을 기존의 CometBFT 환경에 직접 적용하면, 높이(height) 기반 블록 처리나 전통적인 멤풀 구조와 충돌할 수 있습니다. +## 3단계: USDT를 위한 풀스택 최적화 계층 -Autobahn은 Stable의 합의 레이어와 더 자연스럽게 통합되는 ‘DAG 기반 PBFT’ 알고리즘을 제공합니다. Autobahn 기반의 StableBFT는 다음과 같은 장점을 가집니다. +상태: **계획 중.** -- 단일 리더 제한 제거를 통한 프로포절 병렬 처리 -- 데이터 전파와 트랜잭션 순서 합의의 분리를 통한 더 빠른 완결성 -- 네트워크 장애에 강한 견고한 BFT 구조 +### Autobahn의 StableBFT -이 발전된 합의 디자인은 내부 테스트의 통제된 환경 내에서 (합의 레이어 한정) 200,000 TPS를 달성하는 등 매우 높은 처리량을 지원합니다. +Stable의 CometBFT 기반 합의 계층과 자연스럽게 통합되는 DAG 기반 BFT 합의입니다. 현재 프로토콜에 대해서는 [StableBFT](/ko/explanation/consensus)를, 목표 아키텍처에 대해서는 [Autobahn](/ko/explanation/autobahn)을 참조하세요. 내부 POC(개념 증명)는 통제된 환경에서 20만 TPS 이상(합의만)을 시연했습니다. ### StableVM++ -StableVM++는 기존 Go 기반 EVM을 대체하는 고성능 C++ 실행 엔진입니다. 이는 최대 6배 빠른 실행 속도를 제공하여, EVM 트랜잭션 처리 성능을 획기적으로 향상시킬 것으로 기대됩니다. +Go 기반 EVM을 C++ 구현으로 대체하는 고성능 실행 엔진입니다. EVM 실행 속도에서 최대 6배 향상이 예상됩니다. ### 고성능 RPC -고성능 탈중앙화 애플리케이션은 빠르고 정확한 RPC와 인덱싱 서비스에 의존합니다. Stable은 이를 위해 다음을 포함한 고성능 RPC 스택을 개발합니다: +노드 수준 개선(실시간 체인 상태 처리), 노드 통합 인덱싱(저지연 애플리케이션 API), WebSocket을 통한 확장 가능한 pub/sub, 작업 유형별로 라우팅하는 하이브리드 로드 밸런서를 포함하는 완전한 RPC 스택입니다. 현재 분할 경로 아키텍처는 [고성능 RPC](/ko/explanation/high-performance-rpc)를 참조하세요. -- 노드 단 성능 향상: 즉각적인 RPC 응답을 위한 실시간 체인 상태 처리 -- 노드 통합형 인덱서: 지연 없는 API 제공을 위한 실시간 인덱싱 -- 확장 가능한 Pub/Sub 구조: 이벤트 구독 및 전달을 위한 견고한 웹소켓 아키텍처 -- 하이브리드 로드 밸런서: 요청 유형별 트래픽 분산으로 리소스 최적화 및 병목 최소화 +## 다음 권장 사항 -이러한 최적화를 통해 Stable은 dApp 및 기업 사용자에게 안정적이고 확장 가능한 엔드포인트를 제공합니다. \ No newline at end of file +- [**아키텍처 개요**](/ko/explanation/core-optimization-overview): 로드맵이 발전하는 스택의 현재 상태를 알아보세요. +- [**토크노믹스**](/ko/reference/tokenomics): 로드맵 전반에 걸쳐 검증인 인센티브에 자금을 지원하는 경제 모델을 검토하세요. +- [**기술 개요**](/ko/explanation/tech-overview): 아키텍처 요약으로 돌아가세요. diff --git a/docs/pages/ko/explanation/upcoming-use-cases.mdx b/docs/pages/ko/explanation/upcoming-use-cases.mdx index 466a56d..29bdf34 100644 --- a/docs/pages/ko/explanation/upcoming-use-cases.mdx +++ b/docs/pages/ko/explanation/upcoming-use-cases.mdx @@ -1,71 +1,71 @@ --- source_path: explanation/upcoming-use-cases.mdx -source_sha: 60bc4f5649c065fd4f2d42ce273fb2f4d47c5a26 -title: "다가오는 사용 사례" -description: "Stable에서 곧 등장할 결제 패턴: 보장된 정산, 기밀 결제, 에이전트 간 상거래." +source_sha: bbbfc76afcdf37c4b3634f515323f16cf0f08796 +title: "예정된 사용 사례" +description: "Stable에 곧 적용될 결제 패턴: 보장된 결제, 기밀 결제, 에이전트 간 상거래." diataxis: "explanation" --- -# 다가오는 사용 사례 +# 예정된 사용 사례 -Stable은 단순 전송과 API 과금을 넘어서는 결제 패턴을 향해 구축하고 있습니다. 아래 사례들은 시간이 보장된 정산, 프라이버시를 보존하는 결제, 자율 에이전트 상거래를 다룹니다. 일부는 초기 형태로 오늘날에도 작동하며, 다른 일부는 현재 개발 중인 Stable 기능에 의존합니다. +Stable은 단순한 이체와 API 청구를 넘어선 결제 패턴을 구축하고 있습니다. 아래 사례들은 시간 보장 결제, 개인 정보 보호 결제, 자율 에이전트 상거래를 다룹니다. 일부는 현재 초기 형태로 기능하며, 다른 사례들은 현재 개발 중인 Stable 기능에 의존합니다. -## 보장된 정산 +## 보장된 결제 -예약된 블록 용량으로 뒷받침되는 신뢰할 수 있는 결제 정산으로, 네트워크 상태와 관계없이 트랜잭션 포함을 보장합니다. +예약된 블록 용량으로 지원되는 안정적인 결제 정산으로, 네트워크 상황에 관계없이 트랜잭션 포함을 보장합니다. ### 개념 -일부 결제는 독립적인 전송이 아니라 시간이 정해진 정산 주기의 일부입니다. 이러한 흐름에서는 다음 상태 전환이 예정대로 진행될 수 있도록 주기가 마감되기 전에 정산이 완료되어야 합니다. 필요한 결제가 그 기간을 넘겨 지연되면 주기가 실패하거나, 다음 기간으로 넘어가거나, 수동 복구가 필요할 수 있습니다. +일부 결제는 독립적인 이체가 아닌 정해진 결제 주기의 일부입니다. 이러한 흐름에서는 다음 상태 전환이 예정대로 진행될 수 있도록 주기가 닫히기 전에 결제가 완료되어야 합니다. 필수 결제가 해당 기간을 지나 지연되면 주기가 실패하거나 다음 기간으로 롤백되거나 수동 복구가 필요할 수 있습니다. -Stable의 [보장된 블록스페이스](/ko/explanation/guaranteed-blockspace)는 적격 결제 흐름을 위해 실행 용량을 예약함으로써 이를 해결합니다. 목표는 단순히 더 빠른 정산이 아니라 정확한 타이밍 제약 내에서 운영상 신뢰할 수 있는 완료입니다. +Stable의 [보장된 블록 공간](/ko/explanation/guaranteed-blockspace)은 적격한 결제 흐름에 대한 실행 용량을 예약하여 이 문제를 해결합니다. 목표는 단순히 더 빠른 결제가 아니라 정확한 타이밍 제약 내에서 운영상 안정적인 완료입니다. ### 예상 시나리오 -토큰화된 자산 플랫폼이 몇 분마다 예정된 DvP(Delivery versus Payment) 정산을 실행합니다. 현금 부분은 배치로 제출되며, 현재 정산 주기가 마감되기 전에 전체 결제 배치가 포함된 경우에만 증권이 출고됩니다. 정상적인 조건에서는 이것이 즉시 청산됩니다. 버스트 트래픽 동안에는 부분 포함이 실패하거나 넘어간 정산 주기를 만들어냅니다. 보장된 정산을 통해 플랫폼은 결제 배치를 위한 용량을 예약하여 주기가 결정론적으로 마감될 수 있도록 합니다. +토큰화된 자산 플랫폼은 몇 분마다 DvP(지급 대 증권 인도) 결제를 예약합니다. 현금은 일괄적으로 제출되며, 현재 결제 주기가 닫히기 전에 전체 결제 일괄이 포함되어야만 증권이 발행됩니다. 일반적인 조건에서는 즉시 청산됩니다. 트래픽이 폭증하는 동안 부분적인 포함은 실패하거나 롤백된 결제 주기를 생성할 수 있습니다. 보장된 결제를 통해 플랫폼은 결제 일괄에 대한 용량을 예약하여 주기가 확정적으로 닫힐 수 있습니다. -### 무엇이 이를 가능하게 하는가 +### 가능하게 하는 요소 -보장된 블록스페이스는 온체인 결제를 일정을 잡을 수 있는 작업으로 전환합니다. 정산 주기는 엄격한 타이밍 가정으로 설계될 수 있고, 배치 결제는 단일 기간 내에서 원자적으로 커밋될 수 있으며, 상위 시스템은 블록 포함을 희망이 아닌 의존성으로 다룰 수 있습니다. +보장된 블록 공간은 온체인 결제를 스케줄링 가능한 작업으로 전환합니다. 결제 주기는 엄격한 타이밍 가정을 통해 설계될 수 있고, 일괄 결제는 단일 기간 내에 원자적으로 커밋될 수 있으며, 업스트림 시스템은 블록 포함을 희망 사항이 아닌 종속성으로 취급할 수 있습니다. ## 기밀 결제 -선택된 트랜잭션 세부 정보가 공개 관찰자로부터 보호되는 동시에 거래 당사자와 권한이 있는 감사자가 검증할 수 있는 프라이버시 보존 USDT0 전송입니다. +선택된 거래 세부 정보가 공개 관찰자로부터 보호되면서도 거래 당사자 및 공인 감사관에 의해 검증 가능한 개인 정보 보호 USDT0 이체. ### 개념 -표준 온체인 전송은 완전히 투명합니다. 누구나 발신자, 수신자, 금액을 볼 수 있습니다. 비즈니스 결제의 경우 이러한 투명성은 체인을 모니터링하는 누구에게나 상업적으로 민감한 정보를 노출할 수 있습니다. +표준 온체인 이체는 완전히 투명합니다. 누구나 발신자, 수신자 및 금액을 볼 수 있습니다. 비즈니스 결제의 경우 이러한 투명성은 체인을 모니터링하는 모든 사람에게 상업적으로 민감한 정보를 노출할 수 있습니다. -Stable은 영지식 암호화를 사용하는 프라이버시 계층인 [기밀 전송](/ko/explanation/confidential-transfer)을 개발하고 있으며, 이는 온체인 트랜잭션에 선택적 기밀성을 가능하게 합니다. 보호된 값은 관련 당사자와 권한이 있는 규제 감사자만 접근할 수 있습니다. +Stable은 온체인 트랜잭션에 대한 선택적 기밀성을 가능하게 하는 영지식 암호화를 사용하는 프라이버시 계층인 [기밀 전송](/ko/explanation/confidential-transfer)을 개발하고 있습니다. 보호된 값은 관련 당사자 및 공인 규제 감사관만 접근할 수 있습니다. ### 예상 시나리오 -대형 소매업체가 여러 공급업체와 재고 조달을 온체인으로 정산합니다. 투명한 체인에서는 경쟁사가 이러한 트랜잭션을 모니터링하여 공급업체 관계, 주문량, 도매 가격을 역설계할 수 있습니다. 기밀 전송을 통해 상업적으로 민감한 세부 정보가 보호되는 동시에 온체인 기록은 여전히 양 당사자와 권한이 있는 감사자를 위한 검증 가능한 정산 영수증 역할을 합니다. +대형 소매업체는 여러 공급업체와 온체인으로 재고 조달을 정산합니다. 투명한 체인에서는 경쟁업체가 이러한 거래를 모니터링하여 공급업체 관계, 주문량 및 도매 가격을 역설계할 수 있습니다. 기밀 전송을 사용하면 상업적으로 민감한 세부 정보는 보호되지만 온체인 기록은 양 당사자와 공인 감사관에게 검증 가능한 결제 영수증 역할을 합니다. ## 에이전트 간 결제 -트랜잭션 루프에서 사람의 승인이나 개입 없이 AI 에이전트 간에 자율적으로 시작되고 정산되는 결제입니다. +거래 루프에서 사람의 승인이나 개입 없이 AI 에이전트 간에 자율적으로 시작되고 정산되는 결제. ### 개념 -AI 에이전트가 더 많은 운영 작업을 맡게 되면서, 다른 에이전트로부터 서비스를 조달해야 할 것입니다. 현재 워크플로에서는 각 구매를 승인하거나, 공급업체를 선택하거나, 상대방이 신뢰할 수 있는지 검증하기 위해 사람이 루프에 있어야 합니다. 에이전트 간 결제는 에이전트가 단일 트랜잭션 루프 내에서 자율적으로 서비스를 찾고, 평가하고, 결제할 수 있도록 하여 이러한 병목 현상을 제거합니다. +AI 에이전트가 더 많은 운영 작업을 수행함에 따라 다른 에이전트로부터 서비스를 조달해야 할 것입니다. 현재 워크플로우에서는 각 구매를 승인하고, 공급업체를 선택하거나, 상대방이 신뢰할 수 있는지 확인하기 위해 인간이 개입해야 합니다. 에이전트 간 결제는 에이전트가 단일 거래 루프 내에서 서비스를 자율적으로 찾고, 평가하고, 비용을 지불하게 함으로써 이러한 병목 현상을 제거합니다. -이 패턴은 함께 작동하는 여러 신흥 프로토콜에 의존합니다: 에이전트 발견 및 신뢰([ERC-8004](https://eips.ethereum.org/EIPS/eip-8004)), 보안 통신([XMTP](https://xmtp.org)), 그리고 실시간으로 정산할 수 있는 결제 레일([x402](/ko/explanation/x402)). +이 패턴은 여러 신흥 프로토콜이 함께 작동하는 데 의존합니다. 에이전트 검색 및 신뢰([ERC-8004](https://eips.ethereum.org/EIPS/eip-8004)), 보안 통신([XMTP](https://xmtp.org)), 그리고 실시간으로 정산할 수 있는 결제 레일([x402](/ko/explanation/x402)). ### 예상 흐름 -1. **발견**: 구매자 에이전트가 ERC-8004 신원 레지스트리에 쿼리하여 필요한 기능(예: 이미지 생성)을 제공하는 에이전트를 찾습니다. 레지스트리는 관련 메타데이터와 함께 일치하는 에이전트 신원을 반환합니다. -2. **검증**: 구매자가 각 후보에 대해 ERC-8004 레지스트리를 확인합니다. 신원, 평판 점수, 검증 증명이 어떤 제공자가 거래하기에 충분히 신뢰할 수 있는지 결정합니다. -3. **협상**: 구매자가 XMTP를 통해 선택된 제공자에게 작업 매개변수를 보냅니다. 두 에이전트는 암호화된 메시징을 통해 가격, 마감일, 산출물 형식에 합의합니다. -4. **결제**: 구매자가 제공자의 HTTP 엔드포인트를 호출합니다. 제공자가 402로 응답합니다. 구매자가 ERC-3009 권한을 서명하고 결제 헤더와 함께 재시도합니다. 퍼실리테이터가 Stable에서 결제를 정산하고, 제공자가 결과를 반환합니다. -5. **평가**: 전달 후, 구매자가 ERC-8004 평판 레지스트리에 피드백을 게시하여 향후 상호작용을 위한 제공자의 점수를 업데이트합니다. +1. **검색**: 구매 에이전트는 ERC-8004 신원 레지스트리에 질의하여 필요한 기능(예: 이미지 생성)을 제공하는 에이전트를 찾습니다. 레지스트리는 관련 메타데이터와 함께 일치하는 에이전트 신원을 반환합니다. +2. **확인**: 구매자는 각 후보에 대한 ERC-8004 레지스트리를 확인합니다. 신원, 평판 점수 및 유효성 검사 증명은 거래하기에 충분히 신뢰할 수 있는 공급자를 결정합니다. +3. **협상**: 구매자는 선택된 공급자에게 XMTP를 통해 작업 매개변수를 보냅니다. 두 에이전트는 암호화된 메시징을 통해 가격, 마감일 및 결과물 형식에 동의합니다. +4. **결제**: 구매자는 공급자의 HTTP 엔드포인트를 호출합니다. 공급자는 402로 응답합니다. 구매자는 ERC-3009 승인을 서명하고 결제 헤더로 다시 시도합니다. 중개자는 Stable에서 결제를 정산하고, 공급자는 결과를 반환합니다. +5. **평가**: 배송 후 구매자는 ERC-8004 평판 레지스트리에 피드백을 게시하여 향후 상호 작용을 위해 공급자의 점수를 업데이트합니다. -### 무엇이 이를 가능하게 하는가 +### 가능하게 하는 요소 -에이전트 간 결제는 서비스 조달을 완전히 프로그래밍 가능한 루프로 전환합니다. 에이전트는 사람의 일정 조정이나 승인 대기열 없이 실시간으로 제공자를 비교하고, 공급업체를 전환하고, 결제를 정산할 수 있습니다. 이를 통해 에이전트가 지속적으로 서비스를 조달하고, 결제하고, 제공하는 자율 공급망을 머신 속도로 구축할 수 있게 되며, 수동 조정으로 지원할 수 있는 수준을 넘어 상거래를 확장합니다. +에이전트 간 결제는 서비스 조달을 완전히 프로그래밍 가능한 루프로 전환합니다. 에이전트는 인간의 스케줄링이나 승인 대기열 없이 공급자를 비교하고, 공급업체를 전환하며, 실시간으로 결제를 정산할 수 있습니다. 이를 통해 에이전트가 수동 조정이 지원할 수 있는 수준을 넘어 기계 속도로 서비스를 지속적으로 조달하고, 비용을 지불하고, 제공하는 자율 공급망을 구축할 수 있습니다. -## 다음 추천 +## 다음 권장 사항 -- [**보장된 블록스페이스**](/ko/explanation/guaranteed-blockspace) — 보장된 정산 뒤에 있는 프로토콜 수준의 메커니즘을 검토하세요. -- [**기밀 전송**](/ko/explanation/confidential-transfer) — Stable이 구축하고 있는 프라이버시 모델을 살펴보세요. -- [**x402**](/ko/explanation/x402) — 에이전트 간 흐름 뒤에 있는 정산 프로토콜을 이해하세요. +- [**보장된 블록 공간**](/ko/explanation/guaranteed-blockspace): 보장된 결제의 배후에 있는 프로토콜 수준 메커니즘을 검토합니다. +- [**기밀 전송**](/ko/explanation/confidential-transfer): Stable이 구축하고 있는 프라이버시 모델을 확인합니다. +- [**x402**](/ko/explanation/x402): 에이전트 간 흐름의 배후에 있는 결제 프로토콜을 이해합니다. diff --git a/docs/pages/ko/explanation/usdt-as-gas-token.mdx b/docs/pages/ko/explanation/usdt-as-gas-token.mdx index 143eeb2..3b1002b 100755 --- a/docs/pages/ko/explanation/usdt-as-gas-token.mdx +++ b/docs/pages/ko/explanation/usdt-as-gas-token.mdx @@ -1,97 +1,98 @@ --- source_path: explanation/usdt-as-gas-token.mdx -source_sha: b672e8cd0f0a20007892a2ef01a8ac79eda14c2d -title: USDT as Gas -description: "USDT0가 Stable의 네이티브 가스 토큰으로 기능하여 예측 가능한 거래 수수료를 제공하는 방식." +source_sha: 8097bf3fd47c99a316f073bd5a34afccef59988a +title: 가스비로 쓰이는 USDT +description: "USDT0가 어떻게 Stable의 네이티브 가스 토큰으로 기능하여 변동성 자산을 대체하고 예측 가능한 거래 수수료를 제공하는지 설명합니다." +diataxis: "explanation" --- -# USDT as Gas +# 가스비로 쓰이는 USDT -Stable은 USDT 스테이블코인을 중심으로 구축되었습니다. USDT의 옴니체인 표현인 USDT0은 Stable 생태계를 지원하는 핵심 자산입니다. +**수수료는 USDT0으로 지불합니다. 두 번째 토큰, 래핑, ETH 상당액을 유지할 필요가 없습니다.** USDT0는 네이티브 가스 토큰이자 동일한 잔액의 ERC-20 토큰 역할을 합니다. 결제 수단으로 이동하는 동일한 자산이 해당 거래를 이동하는 데 필요한 수수료를 지불합니다. 수수료는 변동성이 큰 네이티브 토큰이 아닌 달러로 표시됩니다. -## 요약 +이러한 설계는 이더리움과는 다른 행동적 차이를 가지며, 이는 잔액 의미론, 허용 범위 안전성 및 특정 opcode 가정에 영향을 미칩니다. 이더리움에서 계약을 포팅하는 경우 배포 전에 마이그레이션 체크리스트는 [Stable의 USDT0 동작](/ko/explanation/usdt0-behavior)을 참조하십시오. -Stable은 USDT0을 네이티브 가스 토큰으로 사용하는 EVM 호환 블록체인입니다. USDT0은 가스 지불 및 가치 전송을 위한 네이티브 자산이면서 동시에 `approve`, `transfer`, `transferFrom` 및 `permit`를 지원하는 ERC20 토큰으로 기능합니다. +## 개요 -이 설계는 예측 가능한 달러 표시 트랜잭션 비용을 가능하게 하고 사용자 경험을 단순화합니다. 그러나 이는 잔액 의미론, 허용 안전성 및 특정 opcode 가정에 영향을 미치는 이더리움과의 행동 차이를 도입합니다. +Stable은 USDT0를 네이티브 가스 토큰으로 사용하는 EVM 호환 블록체인입니다. USDT0는 가스 지불 및 가치 전송을 위한 네이티브 자산으로, 그리고 `approve`, `transfer`, `transferFrom`, `permit`을 지원하는 ERC-20 토큰으로 동시에 작동합니다. -본 문서는 Stable의 USDT0 가스 메커니즘을 명시하고, 결과적인 행동 차이를 설명하며, Stable에 배포된 스마트 컨트랙트에 필요하고 권장되는 개발 패턴을 정의합니다. +이 문서는 Stable의 USDT0 가스 메커니즘을 명시하고, 그로 인한 행동 차이를 설명하며, Stable에 배포되는 스마트 계약에 필요한 권장 개발 패턴을 정의합니다. -## 버전 참고사항 +## 버전 참고 -Stable v1.2.0에서 USDT0이 gUSDT를 대체하여 Stable의 네이티브 가스 토큰이 됩니다. 이 전환의 일부로: +Stable v1.2.0부터 USDT0는 gUSDT를 대체하여 Stable의 네이티브 가스 토큰이 됩니다. 이 전환 과정의 일부로: -- gUSDT가 폐지됩니다. -- 기존 gUSDT 잔액이 자동으로 USDT0으로 전환됩니다. -- 사용자와 애플리케이션은 더 이상 수수료를 지불하거나 가치를 이동하기 위해 래핑 및 언래핑 플로우가 필요하지 않습니다. +- gUSDT는 단계적으로 중단됩니다. +- 기존 gUSDT 잔액은 USDT0로 자동 변환됩니다. +- 사용자와 애플리케이션은 더 이상 수수료를 지불하거나 가치를 이동하기 위해 래핑 및 언래핑 흐름이 필요하지 않습니다. -v1.2.0 이후 USDT0은 다음 두 가지 역할을 합니다: +v1.2.0 이후에는 USDT0가 다음과 같은 역할을 모두 수행합니다. -- 네트워크 수수료 자산(가스), 그리고 -- `approve`, `permit`, `transfer` 및 `transferFrom`을 갖춘 표준 ERC20 토큰. +- 네트워크 수수료 자산(gas), 그리고 +- `approve`, `permit`, `transfer`, `transferFrom`을 지원하는 표준 ERC20 토큰. ## 네트워크 주소 -USDT0 토큰 컨트랙트 주소: +USDT0 토큰 계약 주소: - 테스트넷: [0x78cf24370174180738c5b8e352b6d14c83a6c9a9](https://testnet.stablescan.xyz/token/0x78cf24370174180738c5b8e352b6d14c83a6c9a9) - 메인넷: [0x779ded0c9e1022225f8e0630b35a9b54be713736](https://stablescan.xyz/token/0x779ded0c9e1022225f8e0630b35a9b54be713736) ## 용어 -- **Stable**: USDT0이 네이티브 가스 토큰인 EVM 호환 블록체인. -- **USDT0**: USDT의 옴니체인 버전으로 다음 두 가지로 기능합니다: +- **Stable**: USDT0가 네이티브 가스 토큰인 EVM 호환 블록체인. +- **USDT0**: 다음 두 가지 기능을 모두 수행하는 LayerZero의 Omnichain Fungible Token(OFT) 표준을 사용하는 USDT의 옴니체인 버전: - 가스 및 가치 전송에 사용되는 네이티브 자산, 그리고 - - approve 및 permit 기능을 가진 ERC20 토큰. -- **네이티브 잔액**: `address(x).balance`로 반환되는 USDT0으로 표시된 잔액. -- **가스 수수료**: EIP-1559 스타일 수수료 시장에서 계산된 USDT0으로 지불하는 트랜잭션 수수료. + - 허용 및 허가 의미론을 가진 ERC20 토큰. +- **네이티브 잔액**: `address(x).balance`가 반환하는 USDT0 단위의 잔액. +- **가스 수수료**: EIP-1559 스타일의 수수료 시장에서 계산되는 USDT0로 지불되는 거래 수수료. -## USDT0이란 무엇인가? +## USDT0란? -USDT0은 LayerZero의 옴니체인 대체 가능 토큰 (OFT) 표준을 사용하는 USDT의 옴니체인 표현입니다. USDT0은 USDT와 1:1로 페깅되어 있으며 전통적인 브리지 워크플로우나 래핑된 표현 없이 여러 블록체인을 이동하도록 설계되었습니다. +USDT0는 LayerZero의 Omnichain Fungible Token (OFT) 표준을 사용하는 USDT의 옴니체인 표현입니다. USDT0는 USDT와 1:1로 고정되어 있으며 전통적인 브릿지 워크플로우나 래핑된 표현 없이 여러 블록체인 간에 이동하도록 설계되었습니다. -체인 간에 USDT0을 전송할 때, 토큰은 일부 소스 체인에서 잠기거나(체인의 네이티브 USDT 지원에 따라) 소각된 후 LayerZero의 크로스체인 메시징을 통해 목적지 체인에서 발행됩니다. 이는 1:1 페그를 유지하면서 유동성을 분산된 체인 로컬 풀이 아닌 단일 상호 운용 가능한 자산으로 통합합니다. +USDT0를 체인 간에 전송할 때, 토큰은 일부 소스 체인(해당 체인의 네이티브 USDT 지원에 따라 다름)에 잠기거나 소각됩니다. 그런 다음 LayerZero의 교차 체인 메시징을 통해 대상 체인에서 발행됩니다. 이는 유동성을 분할된 체인 로컬 풀이 아닌 단일 상호 운용 가능한 자산으로 통합하면서 1:1 고정 가치를 유지합니다. -사용자에게 이는 더 빠른 온보딩, 운영 복잡성 감소 및 향상된 유동성 이동성을 가능하게 합니다. +사용자에게는 더 빠른 온보딩, 운영 복잡성 감소 및 향상된 유동성 이동성을 제공합니다. -## USDT0과 Stable +## USDT0 및 Stable -USDT0은 Stable의 온체인 경제와 일상적인 사용을 지원하는 핵심 자산입니다. 동일한 자산이 수수료 지불과 가치 전송 모두에 사용되기 때문에 Stable은 다음에 대한 마찰을 줄입니다: +USDT0는 Stable의 온체인 경제 및 일상적인 사용을 지원하는 핵심 자산입니다. 동일한 자산이 수수료 지불 및 가치 전송에 모두 사용되므로 Stable은 다음 사항에 대한 마찰을 줄입니다. -- **일반 사용자**: 더 간단한 온보딩과 더 적은 토큰 개념 +- **일반 사용자**: 더 간단한 온보딩 및 더 적은 토큰 개념 - **개발자**: 더 간단한 수수료 및 가치 흐름 -- **기업**: 단순화된 회계 및 재무 운영 +- **기업**: 간소화된 회계 및 재무 운영 -Stable은 또한 사용자가 LayerZero를 통해 다른 네트워크에서 USDT0을 온보딩할 수 있도록 하여 첫날부터 깊은 USDT 유동성에 액세스할 수 있습니다. +Stable은 또한 LayerZero를 통해 다른 네트워크에서 USDT0를 온보딩할 수 있도록 함으로써 첫날부터 깊이 있는 USDT 유동성에 액세스할 수 있습니다. ## 가정 및 전제 조건 -아래 내용의 경우 독자는 다음을 이해해야 합니다: +아래 내용을 이해하려면 다음을 이해해야 합니다. -- Solidity 실행 의미론 및 네이티브 가치 전송 -- ERC20 허용 메커니즘 및 허가 플로우 -- Checks-Effects-Interactions를 포함한 표준 스마트 컨트랙트 보안 패턴 +- 솔리디티 실행 의미론 및 네이티브 값 전송 +- ERC20 허용 메커니즘 및 허가 흐름 +- Checks-Effects-Interactions를 포함한 표준 스마트 계약 보안 패턴 ## 1. 가스 및 수수료 모델 ### 1.1 개요 -Stable은 모든 트랜잭션 수수료를 USDT0으로 표시합니다. 가스 가격 책정은 동적으로 조정되는 기본 수수료가 있는 EIP-1559 스타일 모델을 따릅니다. +Stable은 모든 거래 수수료를 USDT0로 표시합니다. 가스 가격 책정은 동적으로 조정되는 기본 수수료와 함께 EIP-1559 스타일 모델을 따릅니다. -트랜잭션 수수료는 다음과 같이 정의됩니다: +거래 수수료는 다음과 같이 정의됩니다. -``` +```text fee = gasUsed × baseFee ``` -트랜잭션은 표준 EIP-1559 매개변수를 사용하여 `maxFeePerGas`를 지정할 수 있습니다. +거래는 표준 EIP-1559 매개변수를 사용하여 `maxFeePerGas`를 지정할 수 있습니다. -*참고: Stable은 우선순위 팁을 지원하지 않습니다. `maxPriorityFeePerGas`를 설정하지 마세요. 그렇지 않으면 팁 금액이 손실됩니다.* +*참고: Stable은 우선 순위 팁을 지원하지 않습니다. `maxPriorityFeePerGas`를 설정하지 마십시오. 그렇지 않으면 팁 금액이 손실됩니다.* -### 1.2 트랜잭션 제출 +### 1.2 거래 제출 -클라이언트는 가장 최근 블록에서 최신 기본 수수료를 가져오고 `maxFeePerGas`를 계산할 때 안전 마진을 포함해야 합니다. +클라이언트는 최신 블록에서 최신 기본 수수료를 가져와 `maxFeePerGas`를 계산할 때 안전 마진을 포함해야 합니다. -예시(설명용): +예시 (설명용): ```javascript const block = await provider.getBlock("latest"); @@ -103,66 +104,66 @@ const maxFeePerGas = baseFee * 2n + maxPriorityFeePerGas; ### 1.3 USDT0 획득 -계정은 다음을 통해 USDT0을 얻습니다: +계정은 다음을 통해 USDT0를 얻습니다. -- 다른 지원되는 체인에서 USDT0 브리징 +- 다른 지원 체인에서 USDT0 브릿징 - Stable의 다른 계정으로부터 전송 받기 -## 2. Stable이 USDT0을 가스 토큰으로 활성화하는 방법 +## 2. Stable이 USDT0를 가스 토큰으로 사용하는 방법 -Stable은 사전 청구 및 환불 결산 모델을 사용하여 USDT0으로 가스를 청구합니다. +Stable은 선불 및 환불 정산 모델을 사용하여 USDT0로 가스를 청구합니다. -### 예시 트랜잭션 +### 거래 예시 -Alice가 Bob에게 100 USDT0을 보냅니다. +Alice가 Bob에게 100 USDT0를 보냅니다. -### 2.1 Ante-handler 단계 +### 2.1 사전 처리기 단계 -`MonoEVMAnteHandler`에서 트랜잭션 검증 중: +`MonoEVMAnteHandler`에서 거래 유효성 검사 중: 1. Alice의 USDT0 잔액을 읽습니다. -2. 프로토콜은 Alice가 다음을 커버할 수 있는지 확인합니다: - - 트랜잭션 가치(100 USDT0), 그리고 - - 최대 가능 가스 수수료(`gasWanted × fee`). -3. 최대 가스 수수료가 사전에 이체됩니다: - - `alice → fee_collector`로 USDT0. +2. 프로토콜은 Alice가 다음을 충당할 수 있는지 확인합니다. + - 거래 가치 (100 USDT0), 그리고 + - 최대 가능한 가스 수수료 (`gasWanted × fee`). +3. 최대 가스 수수료가 선불로 이체됩니다. + - `alice → fee_collector`로 USDT0 이체. ### 2.2 실행 단계 -`ApplyTransaction` 동안: +`ApplyTransaction` 실행 중: 1. EVM이 트랜잭션을 실행합니다. -2. 실제 가스 소비가 기록됩니다. -3. 가치 전송이 적용됩니다: - - `alice → bob`이 100 USDT0을 전송합니다. +2. 실제 가스 소모가 기록됩니다. +3. 값 전송이 적용됩니다. + - `alice → bob`으로 100 USDT0 전송. -### 2.3 결산 단계 +### 2.3 정산 단계 실행 후: -1. 프로토콜은 사전 청구된 수수료의 사용되지 않은 부분을 계산합니다: - ``` +1. 프로토콜은 선불된 수수료의 미사용 부분을 계산합니다. + ```text refund = (gasWanted − gasUsed) × baseFee ``` -2. 사용되지 않은 수수료가 환불됩니다: - - `fee_collector → alice`로 USDT0. +2. 미사용 수수료는 환불됩니다. + - `fee_collector → alice`로 USDT0 환불. -## 3. 잔액 의미론 및 행동 차이 +## 3. 잔액 의미론 및 동작 차이 -### 3.1 네이티브 잔액 가변성 +### 3.1 네이티브 잔액 변경 가능성 -이더리움에서는 컨트랙트의 네이티브 잔액이 일반적으로 컨트랙트 실행의 결과로만 변경됩니다. +이더리움에서 계약의 네이티브 잔액은 일반적으로 계약 실행 결과로만 변경됩니다. -Stable에서는 컨트랙트의 네이티브 USDT0 잔액이 `transferFrom` 및 `permit`를 포함한 ERC20 허용 기반 작업으로 인해 변경될 수도 있습니다. 이러한 작업은 컨트랙트 코드를 호출하지 않고도 컨트랙트의 네이티브 잔액을 줄일 수 있습니다. +Stable에서 계약의 네이티브 USDT0 잔액은 `transferFrom` 및 `permit`을 포함한 ERC20 허용 기반 작업으로 인해 변경될 수도 있습니다. 이러한 작업은 계약 코드를 호출하지 않고도 계약의 네이티브 잔액을 줄일 수 있습니다. -결과적으로 다음 가정은 Stable에서 유효하지 않습니다: -- 컨트랙트의 네이티브 잔액은 컨트랙트가 호출된 경우에만 감소할 수 있습니다. +결과적으로, Stable에서는 다음 가정이 유효하지 않습니다. +- 계약이 호출될 때만 계약의 네이티브 잔액이 줄어들 수 있습니다. -## 4. 컨트랙트 설계 요구 사항 +## 4. 계약 설계 요구사항 -### 4.1 금지된 패턴: 미러 잔액 회계 +### 4.1 금지된 패턴: 미러링된 잔액 회계 -컨트랙트는 네이티브 잔액을 미러링하기 위해 내부 변수에 의존해서는 안 됩니다. +계약은 내부 변수에 의존하여 네이티브 잔액을 미러링해서는 안 됩니다. 안전하지 않은 패턴의 예: @@ -174,19 +175,19 @@ function deposit() external payable { } ``` -허용 기반 전송을 통해 USDT0이 고갈되면 이러한 변수는 실제 네이티브 잔액과 달라질 수 있습니다. +이러한 변수는 허용 기반 전송을 통해 USDT0가 고갈되면 실제 네이티브 잔액과 달라질 수 있습니다. -### 4.2 필수 패턴: 실제 잔액 지불 능력 확인 +### 4.2 필수 패턴: 실시간 잔액 지불 능력 확인 -모든 네이티브 가치 전송은 전송 직전에 `address(this).balance`를 사용하여 지불 능력을 확인해야 합니다. +모든 네이티브 값 전송은 전송 직전에 `address(this).balance`를 사용하여 지불 능력(solvency)을 확인해야 합니다. -예시: +예: ```solidity require(address(this).balance >= amount, "insufficient balance"); ``` -출금은 Checks-Effects-Interactions 순서를 따라야 합니다: +인출은 Checks-Effects-Interactions 순서를 따라야 합니다. ```solidity uint256 amount = credit[msg.sender]; @@ -196,31 +197,31 @@ require(address(this).balance >= amount); payable(msg.sender).call{value: amount}(""); ``` -### 4.3 상태 진행은 잔액과 독립적이어야 함 +### 4.3 상태 진행은 잔액 독립적이어야 합니다. -진행, 마일스톤 또는 완료 조건에 의존하는 프로토콜 로직은 카운터나 에포크와 같은 비잔액 상태 변수를 사용하여 명시적으로 추적해야 합니다. +진행, 이정표 또는 완료 조건에 의존하는 프로토콜 논리는 카운터 또는 에포크와 같은 비잔액 상태 변수를 사용하여 이를 명시적으로 추적해야 합니다. -네이티브 잔액은 지불 시점의 지불 능력 확인에만 사용되어야 합니다. +네이티브 잔액은 지불 시 지불 능력 확인에만 사용되어야 합니다. ### 4.4 허용 노출 -사용자 자금을 보관하는 컨트랙트는 외부 주소에 USDT0 허용을 부여해서는 안 됩니다. +사용자 자금을 보관하는 계약은 외부 주소에 USDT0 허용권을 부여해서는 안 됩니다. -허용이 불가피한 경우 컨트랙트는: +허용이 불가피한 경우, 계약은 다음을 수행해야 합니다. - 정확한 금액만 승인 -- 사용 후 즉시 허용 재설정 -- 잔여 고갈 위험을 알려진 제한 사항으로 처리 +- 사용 직후 허용 재설정 +- 잔여 유출 위험을 알려진 제한 사항으로 처리 ## 5. 주소 상태 가정 ### 5.1 EXTCODEHASH -컨트랙트는 `EXTCODEHASH(addr) == 0x0`에 의존하여 주소가 한 번도 사용되지 않았다고 추론해서는 안 됩니다. +계약은 `EXTCODEHASH(addr) == 0x0`에 의존하여 주소가 사용된 적이 없다고 추론해서는 안 됩니다. -주소 사용에 대한 모든 개념은 컨트랙트 상태 내에서 명시적으로 추적되어야 합니다. +주소 사용에 대한 모든 개념은 계약 상태 내에서 명시적으로 추적해야 합니다. -예시: +예: ```solidity mapping(address => bool) public used; @@ -230,65 +231,71 @@ mapping(address => bool) public used; Stable에서: -- `address(0)`으로의 native value 전송은 실패합니다. -- `address(0)`으로의 ERC20 USDT0 전송도 실패합니다. +- `address(0)`로의 네이티브 USDT0 전송은 되돌려집니다. +- `address(0)`로의 ERC20 USDT0 전송도 되돌려집니다. -제로 주소로 전송하여 USDT0을 소각하는 지원되는 메커니즘은 없습니다. +제로 주소로 전송하여 USDT0를 소각하는 지원되는 메커니즘은 없습니다. -컨트랙트는 다음을 해야 합니다: +계약은 다음을 수행해야 합니다. -- `address(0)`을 수신자로 명시적으로 거부 -- 제로 주소 소각을 가정하는 모든 로직을 재설계 -- 되돌릴 수 없는 손실 의미론이 필요한 경우 명시적 싱크 컨트랙트 사용 +- 수신자로 `address(0)`를 명시적으로 거부 +- 제로 주소 소각을 가정하는 모든 논리 재설계 +- 되돌릴 수 없는 손실 의미가 필요한 경우 명시적인 싱크 계약 사용 ## 7. 테스트 요구 사항 -Stable 배포를 위한 테스트 스위트에는 다음이 포함되어야 합니다: +Stable 배포를 위한 테스트 스위트는 다음을 포함해야 합니다. -- 허용 기반 고갈 시나리오 (`approve` + `transferFrom`) -- 실제 네이티브 잔액을 사용한 지불 능력 시행 -- `EXTCODEHASH`에 의존하지 않는 주소 사용 로직 -- 제로 주소 전송에 대한 명시적 실패 케이스 +- 허용 기반 유출 시나리오(`approve` + `transferFrom`) +- 실제 네이티브 잔액을 사용한 지불 능력 강제 적용 +- `EXTCODEHASH`에 의존하지 않는 주소 사용 논리 +- 제로 주소 전송에 대한 명시적 실패 사례 ## 8. 마이그레이션 체크리스트 -이더리움에서 Stable로 컨트랙트를 마이그레이션 할 때: +이더리움에서 Stable로 계약을 포팅할 때: -- 컨트랙트 내부에서 변수로 네이티브 잔액을 미러링하는 로직 제거 +- 내부 네이티브 잔액 미러 제거 - 모든 지불 능력 확인을 `address(this).balance`로 교체 -- `address(0)`으로의 모든 네이티브 또는 ERC20 전송 제거 -- 모든 USDT0 `approve`에 대한 검사 -- `approve` 및 `permit` 기반 플로우를 다루는 테스트 추가 +- `address(0)`로의 모든 네이티브 또는 ERC20 전송 제거 +- 모든 USDT0 승인 감사 +- 허가 및 허용 기반 흐름을 다루는 테스트 추가 ## 9. 요약 -Stable의 USDT0을 가스 토큰으로 사용하면 예측 가능한 수수료와 통합 가치 회계를 제공하는 동시에 네이티브 잔액 동작에 대한 핵심 가정을 변경합니다. +Stable의 USDT0 가스 토큰 사용은 예측 가능한 수수료와 통합된 가치 회계를 제공하는 동시에 네이티브 잔액 동작에 대한 핵심 가정을 변경합니다. -Stable에서의 올바른 컨트랙트 설계는 다음을 필요로 합니다: +Stable에서 올바른 계약 설계는 다음을 필요합니다. -- USDT0을 이중 역할 자산으로 처리 -- 실제 잔액에 대한 지불 능력 시행 -- `approve` 기반 잔고 고갈 경로 회피 -- Ethereum invariant에 의거한 잔고에 대한 의존성 제거 +- USDT0를 이중 역할 자산으로 취급 +- 실제 잔액에 대한 지불 능력 강제 적용 +- 허용 기반 유출 경로 회피 +- 이더리움 특정 잔액 및 주소 가정에 대한 의존성 제거 ## FAQ -**현재 USDT0을 래핑된 네이티브 토큰으로 사용하고 있습니다. 업그레이드 후에는 어떤 토큰을 래핑된 네이티브로 처리해야 하나요?** +**현재 USDT0를 래핑된 네이티브 토큰으로 사용하고 있습니다. 이 업그레이드 후에 어떤 토큰을 래핑된 네이티브 토큰으로 간주해야 합니까?** -업그레이드 후 USDT0은 네이티브 토큰이자 ERC-20 토큰이 됩니다. USDT0을 직접 사용해야 하며, 래핑이나 언래핑은 더 이상 필요하지 않습니다. +업그레이드 후 USDT0는 네이티브 토큰이자 ERC-20 토큰이 됩니다. USDT0를 직접 사용해야 하며, 래핑 또는 언래핑은 더 이상 필요하지 않습니다. -**원래 USDT0 컨트랙트 주소(`0x779Ded0c9e1022225f8E0630b35a9b54bE713736`)는 어떻게 되나요?** +**원래 USDT0 계약 주소(`0x779Ded0c9e1022225f8E0630b35a9b54bE713736`)는 어떻게 됩니까?** -아무것도 변경되지 않습니다. 동일한 주소가 유효하며 계속해서 USDT0을 나타냅니다. +아무것도 변경되지 않습니다. 동일한 주소가 계속 유효하며 USDT0를 나타냅니다. -**업그레이드 후, 네이티브 토큰 주소는 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736`인가요 (`0x0000000000000000000000000000000000001000` 대신)?** +**업그레이드 후 네이티브 토큰 주소가 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736`입니까 ( `0x0000000000000000000000000000000000001000` 대신)?** -예. 업그레이드 후 네이티브 토큰 식별자/주소는 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736` 입니다. +예. 업그레이드 후 네이티브 토큰 식별자/주소는 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736`입니다. -**`0x0000000000000000000000000000000000001000`은 어떻게 되나요? 여전히 gUSDT의 토큰 주소로 사용되며, 우리 측에서 유지해야 하나요?** +**`0x0000000000000000000000000000000000001000`는 어떻게 됩니까? gUSDT의 토큰 주소로 여전히 사용됩니까? 그리고 우리 측에서 이를 유지해야 합니까?** 아니요. 제거할 수 있습니다. 업그레이드 후에는 사용되지 않습니다. -**DEX calldata의 경우, 프로토콜이 "네이티브 토큰" 식별자로 `0x0000000000000000000000000000000000001000` 사용을 중단하고 대신 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736`를 사용하게 되나요?** +**DEX 캘데이터의 경우, 프로토콜은 "네이티브 토큰" 식별자로 `0x0000000000000000000000000000000000001000` 대신 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736`를 사용하지 않게 됩니까?** 맞습니다. 업그레이드 후 DEX는 `0x779Ded0c9e1022225f8E0630b35a9b54bE713736`를 네이티브 토큰 식별자로 사용해야 합니다. + +## 다음 권장 사항 + +- [**첫 USDT0 전송하기**](/ko/tutorial/send-usdt0): 표준 EVM 도구를 사용하여 테스트넷에서 USDT0 전송을 제출하세요. +- [**가스 가격 책정**](/ko/reference/gas-pricing-api): Stable의 단일 구성 요소 수수료 모델에 대해 트랜잭션을 구축하세요. +- [**Stable에서 USDT0 동작**](/ko/explanation/usdt0-behavior): 이중 역할 자산 의미론, 잔액 조정 및 `EXTCODEHASH` 동작에 대해 계약을 감사하세요. diff --git a/docs/pages/ko/explanation/usdt-features-overview.mdx b/docs/pages/ko/explanation/usdt-features-overview.mdx index fb8c879..4465ba3 100755 --- a/docs/pages/ko/explanation/usdt-features-overview.mdx +++ b/docs/pages/ko/explanation/usdt-features-overview.mdx @@ -1,19 +1,43 @@ --- source_path: explanation/usdt-features-overview.mdx -source_sha: e87a73a1555cb99466a5e342be525e638b2e005a -title: 개요 -description: "네이티브 가스, 보장된 블록 공간, 전송 집계를 포함한 Stable의 USDT 특화 기능 개요." +source_sha: 67a8a81a92b665ffc6eb9a704a78524905a219dd +title: "개요" +description: "Stable의 5가지 USDT 특정 기능이 어떻게 함께 작동하여 스테이블코인 결제 흐름을 대규모로 실용화하는지 설명합니다." +diataxis: "explanation" --- # 개요 -## USDT 특화 기능 +Stable의 USDT 특정 기능은 독립적인 옵션 메뉴가 아닙니다. 이들은 결합됩니다. 각각의 기능은 스테이블코인 결제가 데모에서 프로덕션으로 전환될 때 나타나는 특정 마찰 요소를 제거합니다. 이 페이지에서는 다섯 가지 기능이 함께 존재하는 이유를 설명합니다. -Stable은 USDT를 위해 제작된 레이어 1 블록체인입니다. 프로토콜의 모든 구성 요소는 USDT 전송에서의 마찰을 최소화하고, 세계에서 가장 많이 사용되는 스테이블코인에 특화된 고성능 환경을 제공하기 위해 설계되었습니다. +## 마찰 스택 -핵심 인프라와 더불어, Stable은 전반적인 사용자 경험을 향상하기 위해 USDT에 특화된 여러 가지 기능들을 제공합니다: +대부분의 범용 체인에서 스테이블코인 결제 아키텍처는 다음과 같은 동일한 문제 스택에 부딪힙니다. -- **USDT를 가스 토큰으로 사용**: USDT0를 네이티브 가스 토큰으로 사용합니다. USDT0는 가스 결제와 가치 전송을 위한 네이티브 자산으로 동시에 기능하며, `approve`, `transfer`, `transferFrom`, `permit`을 지원하는 ERC20 토큰으로도 동작합니다. -- **보장된 블록스페이스:** 보장된 블록스페이스는 기관들에게 블록 용량의 일부를 고정적으로 보장해주기 위한 전용 블록스페이스 할당 모델입니다. 이를 통해 기관들은 트랜잭션의 레이턴시와 비용을 쉽게 예상할 수 있습니다. -- **USDT 전송 집계**: USDT0 전송을 분리 및 집계하여, 공정성을 훼손하거나 다른 트랜잭션에 영향을 주지 않으면서 처리량을 극대화하는 특수 메커니즘입니다. -- **기밀 전송**: Stable은 ZK 암호화 기술을 활용하여, 송신자 및 수신자의 주소는 온체인에서 그대로 보이되 금액은 숨겨지는 프라이빗 USDT 전송 기능을 도입할 계획입니다. 이로써 규제 준수 및 감사 가능성을 유지하면서 프라이버시를 확보할 수 있습니다. \ No newline at end of file +1. **사용자는 두 번째 토큰을 보유해야 합니다.** (ETH, SOL) 스테이블코인을 이동시키는 거래에 대해 가스를 지불하기 위해서입니다. 이는 온보딩 단계에서 전환율을 떨어뜨립니다. +2. **두 번째 토큰이 있더라도 사용자가 가스를 부담해야 합니다.** 이는 상인과 결제 앱이 필요로 하는 "1달러를 보내면 1달러"라는 사고방식을 깨뜨립니다. +3. **거래 비용은 네트워크 활동에 따라 변동합니다.** 급여, 재무 운영 및 일괄 결제는 비용 계획이나 포함을 계획할 수 없습니다. +4. **거래당 제한은 처리량을 제한합니다.** 처리량이 많은 USDT 흐름은 체인 전체의 경합을 유발하고 무관한 활동과 함께 성능이 저하됩니다. +5. **모든 거래는 공개적으로 관찰할 수 있습니다.** 공급자 결제, 급여 실행 및 재무 이동은 상업적으로 민감한 데이터를 유출합니다. + +## 기능 구성 방식 + +Stable은 전용 메커니즘으로 각 마찰을 해결합니다. + +| 마찰 | 메커니즘 | 페이지 | +| :--- | :--- | :--- | +| 별도 가스 토큰 | USDT0은 네이티브 가스 토큰입니다. | [가스로서의 USDT](/ko/explanation/usdt-as-gas-token) | +| 사용자가 가스비를 지불해야 함 | 거버넌스 승인 면제는 가스비를 충당합니다. | [가스 면제](/ko/explanation/gas-waiver) | +| 비용 및 포함 변동성 | 등록된 파트너를 위한 예약된 블록 용량 | [보장된 블록 공간](/ko/explanation/guaranteed-blockspace) | +| 처리량 제한 | 병렬화된 USDT0 전송 배치 | [USDT 전송 애그리게이터](/ko/explanation/usdt-transfer-aggregator) | +| 공개 금액 가시성 | ZK 암호화를 통한 선택적 개인 정보 보호 | [기밀 전송](/ko/explanation/confidential-transfer) | + +이들 중 하나라도 도움이 되지만, 함께 사용하면 Stable은 결제 팀이 기존 카드 네트워크와 동일한 방식으로 비용, 지연 시간 및 개인 정보 보호를 모델링할 수 있는 체인이 되며, 블록체인의 결제 최종성을 제공합니다. + +범용 EVM 체인과 Stable의 모든 차이점에 대해서는 [이더리움 비교](/ko/explanation/ethereum-comparison)를 참조하십시오. 이러한 기능을 통해 USDT가 처음부터 끝까지 이동하는 작업 예제를 보려면 [자금 흐름](/ko/explanation/flow-of-funds)을 참조하십시오. + +## 다음 권장 사항 + +- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token): ETH를 대체하여 가스 및 결제에 동시에 사용되는 자산에 대해 이해하십시오. +- [**자금 흐름**](/ko/explanation/flow-of-funds): 온램프에서 온체인 전송을 거쳐 오프램프 결제까지 USDT를 추적합니다. +- [**Stable로 브리징**](/ko/explanation/usdt0-bridging): USDT0이 다른 체인에서 Stable로 이동하는 방법을 확인하십시오. diff --git a/docs/pages/ko/explanation/usdt-transfer-aggregator.mdx b/docs/pages/ko/explanation/usdt-transfer-aggregator.mdx index dafac92..255f66d 100755 --- a/docs/pages/ko/explanation/usdt-transfer-aggregator.mdx +++ b/docs/pages/ko/explanation/usdt-transfer-aggregator.mdx @@ -1,75 +1,84 @@ --- source_path: explanation/usdt-transfer-aggregator.mdx -source_sha: 5bb6c55476a5ceeb97e510d458c977ec91c2a539 -title: "USDT 전송 집계" -description: "대용량 USDT0 전송을 병렬화된 방식으로 묶어 처리하는 USDT Transfer Aggregator 메커니즘." +source_sha: 23229418f878c0594cd6e8e891e188b95df6c4ec +title: "USDT 전송 애그리게이터" +description: "USDT 전송 애그리게이터는 고용량 USDT0 전송을 병렬화되고 내결함성을 가진 결제로 일괄 처리합니다." +diataxis: "explanation" --- -# USDT 전송 집계 +# USDT 전송 애그리게이터 -USDT 트랜잭션에 최적화된 블록체인으로써, Stable은 전반적인 시스템 반응성을 유지하면서도 매우 높은 수준의 토큰 전송량을 처리할 수 있도록 설계되었습니다. USDT 중심 성능과 일반 트랜잭션 다양성 간의 균형을 맞추기 위해, Stable은 USDT 전송 집계 메커니즘을 도입합니다. 이는 USDT0 전송을 고도로 병렬화되고 장애 허용적인 방식으로 번들링 및 처리하는 효율적이고 확장 가능한 솔루션입니다. +**USDT 전송 애그리게이터**는 각 전송을 순차적으로 처리하는 대신 USDT0 전송을 병렬화되고 내결함성을 가진 배치로 묶습니다. 이를 통해 USDT0 처리량을 나머지 실행 파이프라인과 분리하여 고용량 스테이블코인 활동이 다른 트랜잭션을 방해하지 않도록 합니다. -## 왜 USDT 전송 집계가 필요하나요? +:::note +**계획 중.** 애그리게이터는 장기적인 로드맵 항목입니다. 아래 내용은 목표 설계를 설명합니다. 시기N에 대한 정보는 [로드맵](/ko/explanation/technical-roadmap)을 참조하세요. +::: -대규모 USDT 사용을 지원하는 데 있어 핵심 과제는 처리량과 공정성을 동시에 최적화하는 것입니다: +## 존재하는 이유 -- 기존 ERC20 토큰 전송은 순차적으로 처리되므로, 높은 트랜잭션 부하 시 병목 현상이 발생합니다. -- 단순히 USDT0의 처리량을 우선시하면, 다른 트랜잭션이 밀려나 체인 전반의 성능이 저하될 수 있습니다. +두 가지 제약 사항이 서로 충돌합니다. -USDT 전송 집계 설계는 USDT0 전송을 타 트랜잭션과 분리하고 최적화함으로써, 나머지 실행 파이프라인에 영향을 주지 않고 이 문제를 해결합니다. +- 기존 ERC-20 전송은 순차적으로 처리됩니다. 높은 부하에서는 병목 현상이 발생합니다. +- 단순히 USDT0에 우선순위를 부여하면 다른 트랜잭션을 방해하고 전체 체인 성능을 저하시킬 수 있습니다. -## 병렬 집계 및 검증 +애그리게이터는 USDT0 전송을 전용 병렬 파이프라인으로 가져와서 다른 모든 작업에 대한 메인 실행 경로를 그대로 두는 방식으로 이를 해결합니다. -> *여기서 설명하는 내용은 현재 전략을 바탕으로 한 미래 지향적인 계획입니다. 모든 로드맵 항목과 마찬가지로, 더 많은 인사이트를 확보하고 새로운 우선순위에 따라 업데이트될 수 있습니다.* -> +## 병렬 집계 및 검증 -전송 집계 시스템의 핵심은 `MapReduce` 컴퓨팅 모델에서 영감을 받은 병렬 가능한 집계 및 검증 파이프라인입니다. 각 전송을 순차적으로 처리하는 대신, 시스템은 번들 단위로 연산을 수행하며, 계정 간 입출금을 집계한 후 잔액 업데이트를 실행합니다. +전송 집계 시스템의 핵심에는 `MapReduce` 계산 모델에서 영감을 받은 병렬화 가능한 집계 및 검증 파이프라인이 있습니다. 시스템은 각 전송을 순서대로 처리하는 대신, 균형 업데이트를 실행하기 전에 계정 간에 입력 및 출력을 집계하는 번들 수준 계산을 수행합니다. ### 주요 단계 -1. **계정 diff 집계** - - 각 전송은 송신자와 수신자에 매핑됩니다. - - 각 계정에 대해 토큰 이동의 순 변화(net movement)를 나타내는 diff 저널이 생성됩니다: - - 총 차감액(보냄): 음수 값 - - 총 수신액(받음): 양수 값 -2. **잔고 검증** - - 시스템은 전체 입력과 출력이 일치하는, 글로벌 잔액 불변성을 보장합니다. - - 각 계정의 순 변화는 병렬로 독립적으로 검증되어 잔액이 충분한지 확인됩니다. - - 잔액이 부족한 계정이 있어도 번들 실행을 멈추지 않고, 해당 계정을 별도로 표시합니다. -3. **병렬을 위한 MapReduce 모델** - - **Map 단계**: 모든 입출금 전송을 기반으로 각 계정의 순 델타(net delta)를 계산합니다. - - **Reduce 단계**: 이 델타들을 집계하여 최종 상태 업데이트를 결정합니다. - -## 기술적 하이라이트 +1. **계정 차이 집계** + - 각 전송은 발신자와 수신자에 매핑됩니다. + - 각 계정에 대해 순 토큰 이동을 나타내는 차이 저널이 생성됩니다. + - 총 차변(송금)에 대한 음수 값. + - 총 대변(수신)에 대한 양수 값. +2. **잔액 확인** + - 시스템은 총 입력이 총 출력과 같다는 전역 잔액 불변성을 보장합니다. + - 충분한 자금을 확인하기 위해 각 계정의 순 변경 사항은 병렬로 독립적으로 검증됩니다. + - 잔액이 부족한 계정은 번들을 중단하지 않고 플래그가 지정됩니다. +3. **병렬 처리를 위한 MapReduce 모델** + - **맵 단계**: 모든 들어오고 나가는 전송을 기반으로 각 계정의 순 델타를 계산합니다. + - **감소 단계**: 최종 상태 업데이트를 결정하기 위해 이러한 델타를 집계합니다. + +## 기술적 특징 ### 병렬 계산 모델 -- 프리컴파일 컨트랙트 내 병렬성을 활용하여 잔액 확인 및 diff 연산을 동시에 수행합니다. -- 기존의 순차적 ERC20 처리 대비 실행 시간을 대폭 단축할 수 있습니다. +- 선 컴파일된 계약에서 병렬 처리를 활용하여 잔액을 확인하고 차이를 동시에 계산합니다. +- 기존의 순차적인 ERC20 처리와 비교하여 실행 시간을 크게 단축합니다. + +### 종속성 분석 + +- 중복 전송(예: 동일한 계정에서 여러 번 전송)을 식별합니다. +- 계단식 오류를 최소화하기 위해 위험이 높은 전송(예: 자금 부족 가능성)을 미리 플래그 지정합니다. + +### 모듈형 오류 처리 -### 의존성 분석 +- 전송은 계정 수준에서 격리되므로 문제 있는 계정만 영향을 받습니다. +- 충돌하지 않는 전송은 정상적으로 실행되고 완료됩니다. -- 중복 전송(예: 동일 계정에서 다수 전송)을 식별합니다. -- 실패 가능성이 높은 전송(예: 잔액 부족 예상됨)을 사전 표시하여 연쇄적인 실패를 방지합니다. +### 선택적 오류 처리 -### 모듈식 실패 핸들링 +기존의 전송 처리는 블록 내에서 전체 또는 없음입니다. Stable의 집계 모델은 세분화된 계정별 오류 격리를 도입합니다. -- 전송은 계정 단위로 격리되므로, 문제가 있는 계정만 영향을 받습니다. -- 충돌 없는 전송은 정상적으로 실행 및 완료됩니다. +- 계정의 `현재 잔액 + 순 차이 < 0`인 경우, 시스템은 해당 계정의 전송만 실패로 표시합니다. +- 다른 계정을 포함하는 전송은 정상적으로 진행됩니다. +- 이 선택적 롤백 메커니즘은 유효하지 않거나 악의적인 전송이 전체 번들의 무결성을 손상시키지 않도록 합니다. -### 선택적 실패 처리 +## 제안자 주도 또는 평판 기반 정렬 -- 기존의 블록 내 전송 처리 방식은 성공 또는 실패 중 하나의 전체 처리 방식이었으나, Stable의 집계 모델은 계정별 실패 격리를 도입합니다: - - 특정 계정이 `현재 잔액 + 순 변화 < 0` 인 경우, 해당 계정의 전송만 실패로 처리합니다. - - 다른 계정이 포함된 전송은 정상적으로 진행됩니다. - - 이 선택적 롤백 메커니즘은, 잘못된 전송이나 악의적 전송이 전체 번들의 무결성을 해치지 않도록 보장합니다. +실행을 더욱 최적화하고 상태 충돌을 방지하기 위해 Stable은 집계된 전송에 대한 전처리 정렬 메커니즘을 통합합니다. -## 프로포저 혹은 평판 기반 정렬 +- **평판 기반 정렬**: 강력한 기록 또는 입증된 신뢰성을 가진 발신자는 우선 순위가 지정되어 실패 및 재정렬의 위험을 줄입니다. +- **제안자 기반 순서**: 트랜잭션은 충돌을 최소화하고 처리량을 최대화하도록 번들을 구성하는 신뢰할 수 있는 제안자 노드에 의해 정렬될 수 있습니다. +- **번들 전송 우선 순위 지정**: 집계된 USDT 전송은 일반 트랜잭션보다 우선 순위가 지정되어 종속성 충돌을 줄이고 더 깨끗한 실행 창을 확보합니다. -실행 최적화 및 상태 충돌 방지를 위해, Stable은 집계된 전송에 대해 사전 처리 순서 지정 메커니즘을 도입합니다: +Stable의 USDT 전송 애그리게이터는 일반 트랜잭션 처리를 저하시키지 않으면서 USDT0 전송의 처리량을 극대화하는 목표 최적화입니다. 병렬 실행, 모듈형 오류 처리, 스마트 정렬 전략을 결합하여 Stable은 스테이블코인 기반 경제를 위한 확장 가능한 기반을 제공합니다. 빠르고 빈번하며 마찰 없는 토큰 전송은 일반적입니다. -- **평판 기반 정렬**: 신뢰도 높은 이력 또는 검증된 신원을 가진 송신자는 우선 처리되어 실패 및 재정렬 위험이 줄어듭니다. -- **프로포저 기반 정렬**: 신뢰할 수 있는 프로포저 노드가 트랜잭션을 정렬하여 충돌을 최소화하고 처리량을 극대화합니다. -- **전송 번들 우선 처리**: 집계된 USDT 전송은 일반 트랜잭션보다 우선 순위로 처리되어 의존성 충돌을 줄이고 깔끔한 실행 윈도우를 확보됩니다. +## 다음 권장 사항 -Stable의 USDT 전송 집계 메커니즘은 USDT0 전송의 처리량을 극대화하면서도 일반 트랜잭션 처리 성능을 저해하지 않는 타겟형 최적화입니다. 병렬 실행, 모듈식 오류 처리, 스마트 정렬 전략을 결합함으로써, Stable은 빠르고 빈번하며 마찰 없는 토큰 전송이 일상화된 스테이블코인 기반 경제를 위한 확장 가능한 기반을 제공합니다. \ No newline at end of file +- [**결제 사용 사례**](/ko/explanation/payment-use-cases-overview): P2P, 구독, 종량제 등 집계된 처리량의 이점을 가장 많이 받는 결제 패턴을 확인하세요. +- [**실행**](/ko/explanation/execution): 애그리게이터가 구축되는 병렬 실행 엔진을 확인하세요. +- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token): 애그리게이터가 이동하는 자산 모델을 이해하세요. diff --git a/docs/pages/ko/explanation/usdt0-behavior.mdx b/docs/pages/ko/explanation/usdt0-behavior.mdx index 5117206..1723795 100644 --- a/docs/pages/ko/explanation/usdt0-behavior.mdx +++ b/docs/pages/ko/explanation/usdt0-behavior.mdx @@ -1,28 +1,28 @@ --- source_path: explanation/usdt0-behavior.mdx -source_sha: f89e6903b80296f17e2bf1fc9e76ab88b15175c6 -title: "Stable에서의 USDT0 동작" -description: "USDT0는 Stable에서 네이티브 자산과 ERC-20 토큰 양쪽 역할을 합니다. 잔액 조정, 허용량 안전성, 옵코드 동작에 대해 컨트랙트를 감사하세요." +source_sha: 17a1c5d1a4aae70266159154d52063d08fbb0378 +title: "Stable상의 USDT0 동작" +description: "USDT0은 Stable에서 네이티브 자산이자 ERC-20 토큰으로 작동합니다. 잔액 조정, 허용량 안전성, opcode 동작에 대해 컨트랙트를 감사합니다." diataxis: "explanation" --- -# Stable에서의 USDT0 동작 +# Stable상의 USDT0 동작 -**Ethereum에서 컨트랙트를 이식하는 경우, 배포하기 전에 이 페이지를 읽으세요.** Stable에서 USDT0는 네이티브 가스 토큰이자 동일한 잔액 위에 있는 ERC-20 토큰입니다. 그 결과 Ethereum에서 가정되던 네 가지 동작이 깨집니다: 컨트랙트로의 호출 없이도 컨트랙트의 네이티브 잔액이 변할 수 있고, `EXTCODEHASH`가 0과 빈 해시 사이를 오갈 수 있으며, 영주소 전송이 되돌려지고(revert), 단일 논리적 전송이 소수 잔액 조정으로 인해 여러 개의 `Transfer` 이벤트를 발생시킬 수 있습니다. +**이더리움에서 컨트랙트를 포팅하는 경우 배포 전에 이 페이지를 읽어보세요.** Stable의 USDT0은 네이티브 가스 토큰이자 동일한 잔액에 있는 ERC-20 토큰입니다. 결과적으로 이더리움에서 가정하는 네 가지 동작이 깨집니다. 컨트랙트의 네이티브 잔액은 컨트랙트 호출 없이 변경될 수 있고, `EXTCODEHASH`는 0과 빈 해시 사이를 오갈 수 있으며, 0주소 전송은 되돌려지고, 단일 논리 전송은 부분 잔액 조정으로 인해 여러 `Transfer` 이벤트를 발생시킬 수 있습니다. -이 페이지는 각 사례를 살펴보고 안전한 컨트랙트 패턴을 제시합니다. 한 섹션만 읽는다면 [마이그레이션 체크리스트](#migration-checklist)를 읽으세요. 이것이 Ethereum 컨트랙트를 여기로 이식하기 위한 요약본입니다. +이 페이지에서는 각 사례를 자세히 설명하고 안전한 컨트랙트 패턴을 제공합니다. 한 섹션만 읽는다면 [마이그레이션 체크리스트](#migration-checklist)를 읽어보세요. 이더리움 컨트랙트를 여기에 포팅하는 요약입니다. ## 이중 역할 개요 -Stable에서 USDT0는 네이티브 가스 토큰이자 ERC-20 토큰입니다. 이 이중 역할 모델은 잔액 동작, 컨트랙트 설계, 이벤트 처리에 영향을 미칩니다. 아래 섹션들은 이중 역할이 예상 동작을 변화시키는 모든 사례를 다룹니다. +Stable의 USDT0은 네이티브 가스 토큰이자 ERC-20 토큰입니다. 이 이중 역할 모델은 잔액 동작, 컨트랙트 설계 및 이벤트 처리에 영향을 미칩니다. 아래 섹션에서는 이중 역할로 인해 예상되는 동작이 변경되는 모든 경우를 설명합니다. -USDT0가 이런 방식으로 동작하는 배경에 대해서는 [가스로서의 USDT](/ko/explanation/usdt-as-gas-token)를 참조하세요. 실제 전송을 통해 동작을 체험하려면 [첫 USDT0 전송하기](/ko/tutorial/send-usdt0)를 참조하세요. +USDT0이 이러한 방식으로 작동하는 이유에 대한 배경 정보는 [USDT를 가스로](/ko/explanation/usdt-as-gas-token)를 참조하세요. 실제 전송을 통해 동작을 경험하려면 [첫 번째 USDT0 보내기](/ko/tutorial/send-usdt0)를 참조하세요. ## 잔액 조정 -USDT0는 네이티브 자산으로는 18 소수 자릿수를, ERC-20 토큰으로는 6 소수 자릿수를 사용합니다. 네이티브 전송과 ERC-20 전송은 동일한 기초 잔액에서 작동하지만, 12자리 정밀도 차이로 인해 전송이 정수 미만 정밀도를 포함할 경우 시스템은 소수 금액을 조정해야 합니다. +USDT0은 네이티브 자산으로 18자릿수를 사용하고 ERC-20 토큰으로 6자릿수를 사용합니다. 네이티브 전송과 ERC-20 전송은 동일한 기본 잔액에서 작동하지만, 12자릿수 정밀도 차이는 전송에 소수점 이하의 정밀도가 포함될 때 시스템이 소수 부분을 조정해야 함을 의미합니다. -``` +```text before 0.000001 USDT0 (ERC-20) + 0.000000000000000000 USDT0 (internal) // address(account).balance = 0.000001000000000000 @@ -36,34 +36,34 @@ after // USDT0.balanceOf(account) = 0.000000 ``` -이로 인해 `address(account).balance`와 `USDT0.balanceOf(account)`가 최대 0.000001 USDT0까지 차이날 수 있습니다. +이로 인해 `address(account).balance`와 `USDT0.balanceOf(account)`가 최대 0.000001 USDT0까지 차이가 날 수 있습니다. ## 이벤트 처리 -각 조정 전송은 추가적인 `Transfer` 이벤트를 발생시킵니다. 단일 논리적 USDT0 전송은 송신자와 수신자의 소수 잔액이 어떻게 영향을 받는지에 따라 최대 두 개의 추가 `Transfer` 이벤트를 생성할 수 있습니다: +각 조정 전송은 추가 `Transfer` 이벤트를 발생시킵니다. 단일 논리적 USDT0 전송은 발신자와 수신자의 소수 부분 잔액이 어떻게 영향을 받는지에 따라 최대 두 개의 추가 `Transfer` 이벤트를 생성할 수 있습니다. -- **송신자 조정**: 송신자의 소수 잔액이 부족하면 0.000001 USDT0가 송신자에서 리저브 주소로 이동됩니다. 이때 추가 `Transfer` 이벤트가 발생합니다. -- **수신자 조정**: 수신자의 소수 잔액이 넘치면 0.000001 USDT0가 리저브 주소에서 수신자로 이동됩니다. 이때 추가 `Transfer` 이벤트가 발생합니다. -- **양쪽 조정**: 동일한 전송에서 두 조건이 모두 발생하면 리저브를 우회합니다. 송신자는 메인 전송의 일부로 0.000001 USDT0를 수신자에게 직접 전송합니다. 추가 이벤트는 발생하지 않습니다. +- **발신자 조정**: 발신자의 소수 부분 잔액이 부족하면 0.000001 USDT0이 발신자에서 예약 주소로 이동됩니다. 이로 인해 추가 `Transfer` 이벤트가 발생합니다. +- **수신자 조정**: 수신자의 소수 부분 잔액이 오버플로우되면 0.000001 USDT0이 예약 주소에서 수신자로 이동됩니다. 이로 인해 추가 `Transfer` 이벤트가 발생합니다. +- **두 가지 조정 모두**: 동일한 전송에서 두 조건이 모두 발생하면 예약이 우회됩니다. 발신자는 메인 전송의 일부로 0.000001 USDT0을 수신자에게 직접 전송합니다. 추가 이벤트는 발생하지 않습니다. -이러한 보조 이벤트는 리저브 주소 `0x5113954bbC0eD721F1C68671EBa3d91e9e9bF7b5`와 관련됩니다. `Transfer` 이벤트를 재생하여 USDT0 잔액을 추적하는 인덱서 및 오프체인 서비스는 이 주소로 들어오고 나가는 전송을 필터링하거나 고려해야 합니다. +이러한 보조 이벤트는 예약 주소 `0x5113954bbC0eD721F1C68671EBa3d91e9e9bF7b5`와 관련이 있습니다. `Transfer` 이벤트를 다시 재생하여 USDT0 잔액을 추적하는 인덱서 및 오프체인 서비스는 이 주소로의 전송 및 이 주소로부터의 전송을 필터링하거나 고려해야 합니다. -## 컨트랙트 설계 요구사항 +## 컨트랙트 설계 요구 사항 ### 네이티브 잔액 가변성 -Ethereum에서 컨트랙트의 네이티브 잔액은 일반적으로 컨트랙트 실행의 결과로만 변경됩니다. Stable에서는 컨트랙트의 네이티브 USDT0 잔액이 `transferFrom` 및 `permit`을 포함한 ERC-20 허용량 기반 작업으로 인해 변경될 수도 있습니다. 이러한 작업은 어떤 컨트랙트 코드도 호출하지 않고 컨트랙트의 네이티브 잔액을 감소시킬 수 있습니다. +이더리움에서는 컨트랙트의 네이티브 잔액이 일반적으로 컨트랙트 실행의 결과로만 변경됩니다. Stable에서는 컨트랙트의 네이티브 USDT0 잔액이 ERC-20 허용 기반 작업(`transferFrom` 및 `permit` 포함)으로 인해 변경될 수도 있습니다. 이러한 작업은 컨트랙트 코드를 호출하지 않고도 컨트랙트의 네이티브 잔액을 줄일 수 있습니다. -그 결과 다음 가정은 Stable에서 유효하지 않습니다: +결과적으로 다음 가정은 Stable에서 유효하지 않습니다. -> 컨트랙트의 네이티브 잔액은 컨트랙트가 호출될 때만 감소할 수 있다. +> 컨트랙트가 호출될 때만 컨트랙트의 네이티브 잔액이 줄어들 수 있습니다. -### 네이티브 잔액을 미러링하지 마세요 +### 네이티브 잔액을 미러링하지 마십시오 -Ethereum에서는 내부 변수로 예치금을 추적하는 것이 일반적입니다. Stable에서는 ERC-20 `transferFrom`이 외부에서 네이티브 잔액을 고갈시킬 수 있기 때문에 이것이 안전하지 않습니다. +이더리움에서는 내부 변수를 사용하여 예금을 추적하는 것이 일반적입니다. Stable에서는 ERC-20 `transferFrom`이 네이티브 잔액을 외부에서 소모할 수 있으므로 이는 안전하지 않습니다. ```solidity -// UNSAFE on Stable +// Stable에서 UNSAFE uint256 public deposited; function deposit() external payable { @@ -71,9 +71,9 @@ function deposit() external payable { } ``` -### 전송 전에 항상 실제 잔액을 확인하세요 +### 전송 전에 항상 실제 잔액을 확인하십시오 -모든 네이티브 가치 전송은 내부 회계 변수가 아니라 전송 직전에 `address(this).balance`를 사용하여 지급능력(solvency)을 검증해야 합니다: +모든 네이티브 값 전송은 전송 직전에 `address(this).balance`를 사용하여 지급 능력을 확인해야 하며, 내부 회계 변수가 아닙니다. ```solidity // SAFE @@ -85,21 +85,21 @@ function withdraw() external { } ``` -### 상태 진행은 잔액에 독립적이어야 합니다 +### 상태 진행은 잔액 독립적이어야 합니다 -진행 상황, 마일스톤 또는 완료 조건에 의존하는 프로토콜 로직은 카운터나 에포크와 같은 잔액이 아닌 상태 변수를 사용하여 이를 명시적으로 추적해야 합니다. 네이티브 잔액은 지급 시점의 지급능력 검증에만 사용해야 합니다. +진행, 마일스톤 또는 완료 조건에 의존하는 프로토콜 로직은 카운터 또는 에포크와 같은 비잔액 상태 변수를 사용하여 명시적으로 추적해야 합니다. 네이티브 잔액은 지불 시점의 지급 능력 확인에만 사용해야 합니다. -### 영주소 전송 불가 +### 0주소 전송 금지 -Stable에서는 `address(0)`로의 네이티브 및 ERC-20 전송이 모두 되돌려집니다(revert). +Stable에서는 네이티브 및 ERC-20 전송을 `address(0)`으로 보내면 되돌려집니다. ```solidity -// REVERT on Stable +// Stable에서 REVERT payable(address(0)).call{value: amount}("") USDT0.transfer(address(0), amount); ``` -네이티브 USDT0를 보내는 컨트랙트 로직은 전송 호출 전에 수신자를 검증하고 `address(0)`을 명시적으로 거부해야 합니다: +네이티브 USDT0을 보내는 모든 컨트랙트 로직은 전송 호출 전에 수신자를 확인하고 `address(0)`을 명시적으로 거부해야 합니다. ```solidity // SAFE @@ -107,19 +107,19 @@ require(recipient != address(0), "zero address recipient"); payable(recipient).call{value: amount}(""); ``` -컨트랙트가 영주소 전송을 소각 메커니즘으로 사용하는 경우 재설계해야 합니다. 되돌릴 수 없는 손실 의미가 필요하다면 명시적인 싱크(sink) 컨트랙트를 사용하세요. +컨트랙트가 0주소 전송을 소각 메커니즘으로 사용하는 경우 재설계해야 합니다. 비가역적 손실 의미 체계가 필요한 경우 명시적 싱크 컨트랙트를 사용하십시오. ### EXTCODEHASH 동작 -Ethereum에서 `EXTCODEHASH` 옵코드는 다음을 반환합니다: +이더리움에서 `EXTCODEHASH` opcode는 다음을 반환합니다. -- **제로 해시** (`0x0000...`): 주소가 한 번도 사용된 적이 없는 경우(nonce=0, balance=0, 코드 없음). -- **빈 해시** (`0xc5d2…a470`, 빈 코드의 Keccak-256 해시): 주소는 존재하지만 코드가 없는 경우. +- **0 해시**(`0x0000...`): 주소가 한 번도 사용되지 않은 경우(nonce=0, balance=0, 코드 없음). +- **빈 해시**(`0xc5d2…a470`, 빈 코드의 Keccak-256 해시): 주소가 존재하지만 코드가 없는 경우. -Ethereum에서는 주소가 한 번 제로 해시에서 빈 해시로 전환되면 다시 제로 해시로 돌아갈 수 없습니다. Stable에서는 USDT0가 `permit()` 기반 승인을 지원하기 때문에, 주소가 트랜잭션을 보내지 않고도 승인을 생성할 수 있습니다. 이를 `transferFrom()`과 결합하면 nonce 증가 없이 네이티브 잔액 변경이 가능해지며, 잠재적으로 `EXTCODEHASH`가 제로 해시와 빈 해시 사이를 오갈 수 있게 됩니다. +이더리움에서 주소가 0 해시에서 빈 해시로 전환되면 다시 0 해시로 돌아갈 수 없습니다. Stable에서는 USDT0이 `permit()` 기반 승인을 지원하므로 주소는 트랜잭션을 보내지 않고도 승인을 생성할 수 있습니다. `transferFrom()`과 함께 사용하면 nonce 증가 없이 네이티브 잔액 변경이 가능하며, 이는 잠재적으로 `EXTCODEHASH`가 0 해시와 빈 해시 사이를 오갈 수 있도록 합니다. ```solidity -// UNSAFE on Stable +// Stable에서 UNSAFE function isUnusedAddress(address addr) public view returns (bool) { bytes32 codeHash; assembly { @@ -129,7 +129,7 @@ function isUnusedAddress(address addr) public view returns (bool) { } ``` -대신 명시적 추적을 사용하세요: +대신 명시적 추적을 사용하십시오. ```solidity // SAFE @@ -146,42 +146,42 @@ contract SafeAddressTracker { } ``` -## 테스트 요구사항 +## 테스트 요구 사항 -Stable 배포를 위한 테스트 스위트에는 다음이 포함되어야 합니다: +Stable 배포를 위한 테스트 스위트에는 다음이 포함되어야 합니다. -- 허용량 기반 고갈 시나리오 (`approve` + `transferFrom`) -- 실제 네이티브 잔액을 사용한 지급능력 강제 +- 허용 기반 소모 시나리오 (`approve` + `transferFrom`) +- 실제 네이티브 잔액을 사용한 지급 능력 강제 적용 - `EXTCODEHASH`에 의존하지 않는 주소 사용 로직 -- 영주소 전송에 대한 명시적 실패 케이스 +- 0주소 전송에 대한 명시적 오류 사례 ## 마이그레이션 체크리스트 -Ethereum에서 Stable로 컨트랙트를 이식할 때: +이더리움에서 Stable로 컨트랙트를 포팅할 때: -- 내부 네이티브 잔액 미러를 제거하세요 -- 모든 지급능력 검사를 `address(this).balance`로 교체하세요 -- `address(0)`로의 모든 네이티브 또는 ERC-20 전송을 제거하세요 -- 모든 USDT0 승인을 감사하세요 -- `permit` 및 허용량 기반 흐름을 다루는 테스트를 추가하세요 -- 오프체인 인덱서가 소수 잔액 조정으로 인한 보조 `Transfer` 이벤트를 처리하는지 검증하세요 +- 내부 네이티브 잔액 미러 제거 +- 모든 지급 능력 검사를 `address(this).balance`로 대체 +- `address(0)`으로의 모든 네이티브 또는 ERC-20 전송 제거 +- 모든 USDT0 승인 감사 +- `permit` 및 허용 기반 흐름을 다루는 테스트 추가 +- 오프체인 인덱서가 부분 잔액 조정에서 보조 `Transfer` 이벤트를 처리하는지 확인 -## 핵심 요약 +## 주요 시사점 -Stable에서 올바른 컨트랙트 설계를 위해서는 다음이 필요합니다: +Stable에서 올바른 컨트랙트 설계는 다음을 요구합니다. -- USDT0를 이중 역할 자산으로 취급하기 -- 실제 잔액에 대해 지급능력 강제하기 -- 허용량 기반 고갈 경로 피하기 -- Ethereum 특유의 잔액 및 주소 가정에 대한 의존 제거하기 +- USDT0을 이중 역할 자산으로 취급 +- 실제 잔액에 대한 지급 능력 강제 적용 +- 허용 기반 소모 경로 방지 +- 이더리움 특정 잔액 및 주소 가정에 대한 의존성 제거 -오프체인 서비스 및 인덱서는 다음을 수행해야 합니다: +오프체인 서비스 및 인덱서는 다음을 수행해야 합니다. -- 소수 잔액 조정으로 인한 보조 `Transfer` 이벤트 고려하기 -- 이벤트 기반 잔액 재구성 대신 직접 잔액 조회 사용하기 +- 부분 잔액 조정에서 보조 `Transfer` 이벤트 고려 +- 이벤트 기반 잔액 재구성 대신 직접 잔액 쿼리 사용 ## 다음 권장 사항 -- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token) — USDT0가 네이티브 자산과 ERC-20 토큰 양쪽으로 작동하는 이유를 이해하세요. -- [**첫 USDT0 전송하기**](/ko/tutorial/send-usdt0) — 테스트넷에서 네이티브 및 ERC-20 경로를 통해 USDT0 전송을 제출하세요. -- [**Ethereum 비교**](/ko/explanation/ethereum-comparison) — Ethereum에서 이식할 때의 모든 동작 차이를 검토하세요. +- [**USDT를 가스로 사용**](/ko/explanation/usdt-as-gas-token): USDT0이 네이티브 자산이면서 ERC-20 토큰으로 작동하는 이유를 이해합니다. +- [**첫 번째 USDT0 보내기**](/ko/tutorial/send-usdt0): 네이티브 및 ERC-20 경로를 통해 테스트넷에서 USDT0 전송을 제출합니다. +- [**이더리움 비교**](/ko/explanation/ethereum-comparison): 이더리움에서 포팅할 때의 모든 동작 차이점을 검토합니다. diff --git a/docs/pages/ko/explanation/usdt0-bridging.mdx b/docs/pages/ko/explanation/usdt0-bridging.mdx index 455a60a..ca933b9 100644 --- a/docs/pages/ko/explanation/usdt0-bridging.mdx +++ b/docs/pages/ko/explanation/usdt0-bridging.mdx @@ -1,151 +1,151 @@ --- source_path: explanation/usdt0-bridging.mdx -source_sha: a85e32a5812a12a5f3c2161fd245a44c27bde59d -title: "Stable로 브리징하기" -description: "Stable로 USDT0(OFT Mesh)와 네이티브 USDT(Legacy Mesh)를 전송하는 크로스체인 브리징 메커니즘." +source_sha: 5f1ebb65fed31c4fdb6210c4644248cff79ad5a7 +title: "Stable로 브리징" +description: "USDT0(OFT 메쉬) 및 네이티브 USDT(레거시 메쉬)의 USDT0(OFT Mesh) 및 네이티브 USDT의 Stable로의 크로스체인 브리징 메커니즘." diataxis: "explanation" --- -# Stable로 브리징하기 +# Stable로 브리징 -USDT는 소스 체인에서 어떤 형태를 취하는지에 따라 두 가지 브리지 경로 중 하나를 통해 Stable에 도달합니다. 두 경로 모두 사용자의 Stable 지갑으로 USDT0를 전달합니다. +USDT는 소스 체인에서 어떤 형태를 취하는지에 따라 두 가지 브릿지 경로 중 하나를 통해 Stable에 도달합니다. 두 경로 모두 사용자의 Stable 지갑으로 USDT0을 전송합니다. :::note -**두 가지 경로, 하나의 결과:** -- **OFT Mesh**: 소스 체인에 이미 USDT0가 있습니다. 소스에서 소각하고 Stable에서 발행합니다. 체인 간 1:1. 예시: Arbitrum, Ethereum, Optimism, Polygon, Unichain, Ink, Bera, Mantle, Hyperliquid, MegaETH(총 21개 체인). -- **Legacy Mesh**: 소스 체인에 네이티브 USDT만 있습니다. 허브 역할을 하는 Arbitrum을 통해 라우팅됩니다. 전송 금액에 0.03% 수수료가 부과됩니다. 예시: Tron, TON. +**두 가지 경로, 한 가지 결과:** +- **OFT 메쉬**: 소스 체인에 이미 USDT0이 있습니다. 소스에서 소각하고, Stable에서 발행합니다. 체인 간 1:1 교환입니다. 예: Arbitrum, Ethereum, Optimism, Polygon, Unichain, Ink, Bera, Mantle, Hyperliquid, MegaETH (총 21개 체인). +- **레거시 메쉬**: 소스 체인에는 네이티브 USDT만 있습니다. 허브로 Arbitrum을 통해 라우팅됩니다. 전송 금액의 0.03% 수수료가 부과됩니다. 예: Tron, TON. ::: -아래 섹션에서 각 경로를 자세히 설명합니다. +아래 섹션에서는 각 경로에 대해 자세히 설명합니다. -## USDT0 OFT Mesh vs Legacy Mesh +## USDT0 OFT 메쉬 vs 레거시 메쉬 -Stable은 두 개의 상호 보완적인 크로스체인 전송 네트워크에 참여합니다. +Stable은 두 가지 보완적인 크로스체인 전송 네트워크에 참여합니다. -### OFT Mesh +### OFT 메쉬 -USDT0를 지원하는 모든 체인은 OFT Mesh에 참여할 수 있습니다. OFT Mesh 내에서 USDT0 크로스체인 전송은 1:1 가치 비율을 유지합니다. 전송이 발생하면 소스 체인의 USDT0 토큰이 소각되고 동일한 양이 목적지 체인에서 발행됩니다. 현재 OFT Mesh 참여자는 Arbitrum, Bera, Conflux, Ethereum, Flare, Hedera, Hyperliquid, Ink, Mantle, MegaETH, Monad, Morph, MP1, Optimism, Plasma, Polygon, Rootstock, Sei, Stable, Tempo, Unichain, X Layer를 포함합니다. +USDT0을 지원하는 모든 체인은 OFT 메쉬에 참여할 수 있습니다. OFT 메쉬 내에서 USDT0 크로스체인 전송은 1:1 가치 비율을 유지합니다. 전송이 발생하면 소스 체인의 USDT0 토큰은 소각되고 대상 체인에는 동등한 양이 발행됩니다. 현재 OFT 메쉬 참여자는 Arbitrum, Bera, Conflux, Ethereum, Flare, Hedera, Hyperliquid, Ink, Mantle, MegaETH, Monad, Morph, MP1, Optimism, Plasma, Polygon, Rootstock, Sei, Stable, Tempo, Unichain 및 X Layer입니다. -### Legacy Mesh +### 레거시 메쉬 -네이티브 USDT(USDT0가 아닌)를 가진 모든 체인은 Legacy Mesh를 통해 라우팅할 수 있습니다. Legacy Mesh는 Arbitrum이 USDT0의 중앙 허브 역할을 하는 허브 앤 스포크 아키텍처를 따릅니다. 이 모델은 Arbitrum의 USDT0 유동성 풀을 활용합니다. USDT0 팀은 전송 금액에 0.03% 수수료를 부과합니다. 현재 Legacy Mesh 참여자는 Tron과 TON을 포함합니다. +네이티브 USDT만 있는 체인(USDT0 아님)은 레거시 메쉬를 통해 라우팅할 수 있습니다. 레거시 메쉬는 Arbitrum이 USDT0의 중앙 허브 역할을 하는 허브 앤 스포크 아키텍처를 따릅니다. 이 모델은 Arbitrum의 USDT0 유동성 풀을 활용합니다. USDT0 팀은 전송 금액에 대해 0.03%의 수수료를 부과합니다. 현재 레거시 메쉬 참여자는 Tron과 TON입니다. -Ethereum과 Arbitrum은 두 메시 모두에 참여합니다. 이러한 체인의 사용자는 OFT 경로(USDT0 소각/발행) 또는 Legacy 경로(Arbitrum 허브를 통한 네이티브 USDT 잠금)를 통해 브리징할 수 있습니다. +Ethereum과 Arbitrum은 두 메쉬 모두에 참여합니다. 이 체인의 사용자는 OFT 경로(USDT0 소각/발행) 또는 레거시 경로(Arbitrum 허브를 통해 네이티브 USDT 잠금)를 통해 브릿지할 수 있습니다. --- -## 경로 1: USDT0를 Stable로 브리징(OFT 지원 체인) +## 경로 1: Stable로 USDT0 브리징 (OFT 지원 체인) -이 경로는 사용자가 이미 Arbitrum이나 Ink 같은 OFT 지원 소스 체인에서 USDT0를 보유한 경우에 적용됩니다. +이 경로는 사용자가 이미 Arbitrum 또는 Ink와 같은 OFT 지원 소스 체인에 USDT0을 보유하고 있을 때 적용됩니다. -### 참여자 +### 액터 -| 이름 | 온체인? | 책임 주체 | +| 이름 | 온체인? | 책임 당사자 | | --- | --- | --- | -| User | N/A | User | -| USDT0 OUpgradable | ✅ | USDT0의 스마트 컨트랙트 | -| LayerZero Endpoint V2 | ✅ | LayerZero의 스마트 컨트랙트 | -| MessageLib Registry | ✅ | LayerZero의 스마트 컨트랙트 | +| 사용자 | N/A | 사용자 | +| USDT0 OUpgradable | ✅ | USDT0의 스마트 계약 | +| LayerZero Endpoint V2 | ✅ | LayerZero의 스마트 계약 | +| MessageLib Registry | ✅ | LayerZero의 스마트 계약 | | Executor | ❌ | LayerZero Labs | | USDT0 DVN | ❌ | USDT0 | | Canary DVN | ❌ | Canary | | LayerZero DVN | ❌ | LayerZero Labs | -### 흐름 다이어그램 +### 플로우 다이어그램 -USDT0를 Stable로 브리징: OFT Mesh 흐름 +USDT0을 Stable로 브리징: OFT 메쉬 플로우 ### 상세 단계 -#### 1. 전송 시작(온체인, 소스 체인) +#### 1. 전송 시작 (온체인, 소스 체인) -사용자는 소스 체인의 **USDT0 OUpgradable** 컨트랙트에서 `lzSend` 메서드를 호출합니다. 트랜잭션에는 메시지 페이로드, 목적지 LayerZero 엔드포인트 및 컨트랙트 주소, 그리고 가스 한도와 수수료 같은 구성 매개변수가 포함됩니다. +사용자는 소스 체인의 **USDT0 OUpgradable** 계약에서 `lzSend` 메서드를 호출합니다. 트랜잭션에는 메시지 페이로드, 대상 LayerZero 엔드포인트 및 계약 주소, 가스 한도 및 수수료와 같은 구성 매개변수가 포함됩니다. -#### 2. 패킷 생성(온체인, 소스 체인) +#### 2. 패킷 생성 (온체인, 소스 체인) -소스 LayerZero Endpoint는 OApp의 메시지를 패키징하고, 지정된 소스 MessageLib 컨트랙트를 사용하여 인코딩한 다음, Security Stack(DVN) 및 Executor로 전송하여 전송 트랜잭션을 완료합니다. +소스 LayerZero 엔드포인트는 OApp의 메시지를 패키징하고, 지정된 소스 MessageLib 계약을 사용하여 인코딩한 다음, Security Stack(DVN) 및 Executor로 전송하여 전송 트랜잭션을 완료합니다. -#### 3. 메시지 검증(오프체인, DVN) +#### 3. 메시지 확인 (오프체인, DVN) -분산형 검증자 네트워크(DVN)는 목적지 컨트랙트가 메시지를 실행하기 전에 독립적으로 검증합니다. OApp이 인증한 DVN만 검증을 수행할 수 있습니다. USDT0 브리징에서는 모든 메시지에 LayerZero Labs, Canary, USDT0라는 세 개의 DVN이 서명해야 합니다. 모든 경로의 표준 구성은 [LayerZeroScan의 USDT0 OApp](https://layerzeroscan.com/)을 참조하세요. +분산 검증자 네트워크(DVN)는 대상 계약이 메시지를 실행하기 전에 메시지를 독립적으로 확인합니다. OApp에 의해 승인된 DVN만 확인을 수행할 수 있습니다. USDT0 브리징은 모든 메시지에 대해 세 개의 DVN(LayerZero Labs, Canary, USDT0)이 서명해야 합니다. 모든 경로의 표준 구성은 [LayerZeroScan의 USDT0 OApp](https://layerzeroscan.com/)을 참조하십시오. -#### 4. 검증 가능으로 표시(온체인, Stable) +#### 4. 확인 가능으로 표시 (온체인, Stable) -필요한 모든 DVN이 메시지를 검증하면 목적지 MessageLib 컨트랙트가 이를 검증 가능으로 표시합니다. +필요한 모든 DVN이 메시지를 확인하면 대상 MessageLib 계약은 메시지를 확인 가능으로 표시합니다. -#### 5. 검증 커밋(오프체인, Executor) +#### 5. 확인 약정 (오프체인, Executor) -Executor는 검증된 메시지를 목적지 LayerZero Endpoint에 커밋하여 실행을 준비합니다. +Executor는 확인된 메시지를 대상 LayerZero 엔드포인트에 약정하여 실행을 준비합니다. -#### 6. 패킷 검증(온체인, Stable) +#### 6. 패킷 유효성 검사 (온체인, Stable) -목적지 LayerZero Endpoint는 Executor가 전달한 패킷이 DVN이 검증한 패킷과 일치하는지 확인합니다. +대상 LayerZero 엔드포인트는 Executor가 전달한 패킷이 DVN이 확인한 패킷과 일치하는지 확인합니다. -#### 7. 메시지 실행(오프체인, Executor) +#### 7. 메시지 실행 (오프체인, Executor) -Executor는 목적지 체인에서 `lzReceive`를 호출하여 Stable의 USDT0 OUpgradable 컨트랙트에 의한 메시지 처리를 트리거합니다. +Executor는 대상 체인에서 `lzReceive`를 호출하여 Stable의 USDT0 OUpgradable 계약에 의한 메시지 처리를 트리거합니다. -#### 8. 완료(온체인, Stable) +#### 8. 완료 (온체인, Stable) -Stable의 USDT0 OUpgradable 컨트랙트가 검증된 메시지를 처리하여 크로스체인 전송을 완료합니다. USDT0가 사용자의 주소로 발행됩니다. +Stable의 USDT0 OUpgradable 계약은 확인된 메시지를 처리하여 크로스체인 전송을 완료합니다. USDT0은 사용자의 주소로 발행됩니다. --- -## 경로 2: 네이티브 USDT를 Stable로 브리징(Legacy Mesh) +## 경로 2: 네이티브 USDT를 Stable로 브리징 (레거시 메쉬) -이 경로는 사용자가 Tron과 같은 Legacy Mesh 체인에서 네이티브 USDT를 보유한 경우에 적용됩니다. 전송은 Stable에 도달하기 전에 중간 허브인 Arbitrum을 통해 라우팅됩니다. +이 경로는 사용자가 Tron과 같은 레거시 메쉬 체인에 네이티브 USDT를 보유하고 있을 때 적용됩니다. 전송은 Stable에 도착하기 전에 Arbitrum을 중간 허브로 통과합니다. -### 참여자 +### 액터 -| 이름 | 온체인? | 책임 주체 | +| 이름 | 온체인? | 책임 당사자 | | --- | --- | --- | -| User | N/A | User | -| USDT Pool | ✅ | USDT0의 스마트 컨트랙트 | -| USDT0 Pool | ✅ | USDT0의 스마트 컨트랙트 | -| MultiHopComposer | ✅ | LayerZero의 스마트 컨트랙트 | -| USDT0 OUpgradable | ✅ | USDT0의 스마트 컨트랙트 | -| LayerZero Endpoint | ✅ | LayerZero의 스마트 컨트랙트 | -| MessageLib Registry | ✅ | LayerZero의 스마트 컨트랙트 | +| 사용자 | N/A | 사용자 | +| USDT Pool | ✅ | USDT0의 스마트 계약 | +| USDT0 Pool | ✅ | USDT0의 스마트 계약 | +| MultiHopComposer | ✅ | LayerZero의 스마트 계약 | +| USDT0 OUpgradable | ✅ | USDT0의 스마트 계약 | +| LayerZero Endpoint | ✅ | LayerZero의 스마트 계약 | +| MessageLib Registry | ✅ | LayerZero의 스마트 계약 | | USDT0 Legacy Mesh Operator | ❌ | USDT0 | | Executor | ❌ | LayerZero Labs | | USDT0 DVN | ❌ | USDT0 | | Canary DVN | ❌ | Canary | | LayerZero DVN | ❌ | LayerZero Labs | -### 흐름 다이어그램 +### 플로우 다이어그램 -Tron에서 Stable로 네이티브 USDT 브리징: Legacy Mesh 흐름 +Tron에서 Stable로 네이티브 USDT 브리징: 레거시 메쉬 플로우 ### 상세 단계 -#### 1. 전송 시작(온체인, Tron) +#### 1. 전송 시작 (온체인, Tron) -사용자는 브리지 트랜잭션을 시작하고 Tron의 **USDT Pool** 컨트랙트로 네이티브 USDT를 전송합니다. USDT는 풀에 잠깁니다. 그런 다음 USDT Pool 컨트랙트는 Tron의 LayerZero Endpoint 컨트랙트로 메시지를 전송합니다. +사용자는 브릿지 트랜잭션을 시작하고 네이티브 USDT를 Tron의 **USDT Pool** 계약으로 보냅니다. USDT는 풀에 잠깁니다. USDT Pool 계약은 Tron의 LayerZero Endpoint 계약으로 메시지를 보냅니다. -#### 2. Legacy Mesh로 메시지 전송(오프체인) +#### 2. 레거시 메쉬로 메시지 전송 (오프체인) -LayerZero Endpoint 컨트랙트는 메시지를 **USDT0 Legacy Mesh Operator**로 전송하고, 이는 메시지를 검증합니다. +LayerZero Endpoint 계약은 메시지를 **USDT0 Legacy Mesh Operator**로 전송하고, 이는 메시지를 확인합니다. -#### 3. MultiHop 전송 시작(온체인, Arbitrum) +#### 3. MultiHop 전송 시작 (온체인, Arbitrum) -USDT0 Legacy Mesh Operator는 Arbitrum의 LayerZero **MultiHopComposer** 컨트랙트에서 `lzCompose()` 메서드를 호출합니다. 추가적인 사용자 상호작용 없이 MultiHopComposer 컨트랙트는 Arbitrum에서 Stable로의 USDT0 발행 및 소각 브리지 전송을 수행합니다. +USDT0 Legacy Mesh Operator는 Arbitrum의 LayerZero **MultiHopComposer** 계약에서 `lzCompose()` 메서드를 호출합니다. 추가 사용자 상호작용 없이 MultiHopComposer 계약은 Arbitrum에서 Stable로 USDT0 발행 및 소각 브릿지 전송을 수행합니다. :::note -MultiHopComposer 컨트랙트는 완전히 무허가형이며 불변성을 보장하기 위해 `owner()`가 없습니다. +MultiHopComposer 계약은 완전 허가 없이 사용 가능하며, 불변성을 보장하기 위해 `owner()`가 없습니다. ::: -#### 4. USDT0를 Stable로 전송(온체인 및 오프체인) +#### 4. USDT0을 Stable로 전송 (온체인 및 오프체인) -나머지 단계는 [USDT0를 Stable로 브리징](#path-1--bridging-usdt0-to-stable-oft-supported-chains)(위의 1~8단계)과 정확히 동일한 경로를 따릅니다. Arbitrum의 USDT0 OUpgradable 컨트랙트가 LayerZero를 통해 전송하고, DVN이 검증하며, USDT0가 Stable에서 발행됩니다. +나머지 단계는 [USDT0을 Stable로 브리징](#path-1--bridging-usdt0-to-stable-oft-supported-chains) (위의 1-8단계)과 정확히 동일한 경로를 따릅니다. Arbitrum의 USDT0 OUpgradable 계약은 LayerZero를 통해 전송하고, DVN이 확인하며, USDT0은 Stable에 발행됩니다. -### 유의할 점 +### 참고 사항 - Arbitrum의 USDT0 유동성은 USDT0 팀이 관리합니다. -- Legacy Mesh는 전송 금액에 0.03% 수수료가 발생합니다. -- 사용자는 Arbitrum과 직접 상호작용할 필요가 없으며, MultiHop 흐름은 자동입니다. +- 레거시 메쉬는 전송 금액에 대해 0.03%의 수수료가 발생합니다. +- 사용자는 Arbitrum과 직접 상호작용할 필요가 없으며, MultiHop 흐름은 자동으로 이루어집니다. -## 다음 권장 사항 +## 다음 권장 항목 -- [**자금 흐름**](/ko/explanation/flow-of-funds) — 온램프부터 정산까지 USDT의 전체 라이프사이클을 확인하세요. -- [**브리지 튜토리얼**](/ko/tutorial/bridge-usdt0) — LayerZero OFT 어댑터를 사용하여 Sepolia에서 Stable 테스트넷으로 Test USDT를 브리징하세요. -- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token) — 자산이 Stable에 도달한 후 무엇을 하는지 이해하세요. +- [**자금 흐름**](/ko/explanation/flow-of-funds): 온램프에서 정산까지 USDT의 전체 수명 주기를 확인하세요. +- [**브릿지 튜토리얼**](/ko/tutorial/bridge-usdt0): LayerZero OFT 어댑터를 사용하여 Sepolia에서 Stable 테스트넷으로 테스트 USDT를 브릿지하세요. +- [**가스 토큰으로서의 USDT**](/ko/explanation/usdt-as-gas-token): 자산이 Stable에 도착한 후 어떤 역할을 하는지 이해하세요. diff --git a/docs/pages/ko/explanation/use-case-payments.mdx b/docs/pages/ko/explanation/use-case-payments.mdx index 08dd530..d860ca5 100644 --- a/docs/pages/ko/explanation/use-case-payments.mdx +++ b/docs/pages/ko/explanation/use-case-payments.mdx @@ -1,27 +1,27 @@ --- source_path: explanation/use-case-payments.mdx -source_sha: be885bce36996d4c407707fece27e6072a06046d -title: "결제 및 송금" -description: "Stable이 단일 자산 모델, 수수료 없는 UX, 즉각적인 완결성을 통해 P2P 결제와 가맹점 정산을 지원하는 방법." +source_sha: a5e26e7574265dccbb0f71370598384bdeeea5f6 +title: "결제 및 이체" +description: "Stable이 단일 자산 모델, 수수료 없는 UX, 즉각적인 완결성을 통해 P2P 결제 및 가맹점 정산을 지원하는 방법." diataxis: "explanation" --- -# 결제 및 송금 +# 결제 및 이체 -P2P 결제와 가맹점 정산을, 자금을 이동시키고 거래 비용을 지불하는 하나의 자산을 중심으로 구축했습니다. +자금을 이동하고 거래 비용을 지불하는 단일 자산을 중심으로 구축된 P2P 결제 및 가맹점 정산. ## 문제점 -범용 체인에서는 스테이블코인을 이동시키기 위해 사용자가 별도의 가스 토큰(ETH, SOL)을 보유해야 합니다. 이는 "1달러를 보내면 1달러를 받는다"는 사고 모델을 깨뜨리고, USDT만 보유한 지불자가 송금조차 제출할 수 없는 온보딩 단계에서 전환율을 떨어뜨립니다. +범용 체인에서 사용자는 스테이블코인을 이동하기 위해 별도의 가스 토큰(ETH, SOL)을 보유해야 합니다. 이는 "1달러를 보내면 1달러를 받는다"는 정신 모델을 깨고 온보딩 시 전환에 어려움을 줍니다. USDT만 가진 결제자는 이체 제출조차 할 수 없습니다. -## Stable의 해결 방식 +## Stable의 해결책 -- **USDT0는 가스 토큰이자 결제 자산입니다.** 사용자는 송금하거나 수신하는 데 단 하나의 자산만 필요합니다. [가스로서의 USDT](/ko/explanation/usdt-as-gas-token)를 참조하세요. -- **가스 면제(Gas waiver)를 통해 애플리케이션이 사용자를 대신해 가스를 부담할 수 있습니다.** 이를 통해 사용자가 두 번째 토큰을 다룰 필요 없이 수수료 없는 UX를 구현할 수 있습니다. [가스 면제](/ko/explanation/gas-waiver)를 참조하세요. -- **단일 슬롯 완결성(single-slot finality)은 정산이 즉각적임을 의미합니다.** 송금이 블록에 포함되면 곧바로 최종 확정됩니다. [이더리움 비교](/ko/explanation/ethereum-comparison)를 참조하세요. +- **USDT0는 가스 토큰이자 결제 자산입니다.** 사용자는 송금 또는 수신을 위해 하나의 자산만 있으면 됩니다. [가스용 USDT](/ko/explanation/usdt-as-gas-token)를 참조하세요. +- **가스 면제는 애플리케이션이 사용자를 대신하여 가스를 지불할 수 있도록 하여**, 사용자가 두 번째 토큰을 사용할 필요 없이 수수료가 없는 UX를 가능하게 합니다. [가스 면제](/ko/explanation/gas-waiver)를 참조하세요. +- **단일 슬롯 완결성은 정산이 즉시 이루어진다는 것을 의미합니다.** 일단 이체가 블록에 포함되면 즉시 확정됩니다. [이더리움 비교](/ko/explanation/ethereum-comparison)를 참조하세요. -## 다음 추천 항목 +## 다음 권장 사항 -- [**가스로서의 USDT**](/ko/explanation/usdt-as-gas-token) — 가스와 결제를 동시에 처리하며 ETH를 대체하는 자산을 이해하세요. -- [**가스 면제**](/ko/explanation/gas-waiver) — 애플리케이션이 거버넌스 승인을 받은 면제 주소를 통해 사용자 가스를 부담하는 방법을 알아보세요. -- [**이더리움 비교**](/ko/explanation/ethereum-comparison) — 이더리움에서 이전할 때 변경되는 사항(완결성, 가스 토큰, 우선순위 팁)을 검토하세요. +- [**가스용 USDT**](/ko/explanation/usdt-as-gas-token): ETH를 대체하여 가스 및 결제에 동시에 사용되는 자산을 이해합니다. +- [**가스 면제**](/ko/explanation/gas-waiver): 거버넌스 승인 면제 주소를 통해 애플리케이션이 사용자 가스를 처리하는 방법을 확인합니다. +- [**이더리움 비교**](/ko/explanation/ethereum-comparison): 이더리움에서 이전할 때 변경되는 사항(완결성, 가스 토큰, 우선순위 팁)을 검토합니다. diff --git a/docs/pages/ko/explanation/use-case-payroll.mdx b/docs/pages/ko/explanation/use-case-payroll.mdx index ec77b44..e601369 100644 --- a/docs/pages/ko/explanation/use-case-payroll.mdx +++ b/docs/pages/ko/explanation/use-case-payroll.mdx @@ -1,27 +1,27 @@ --- source_path: explanation/use-case-payroll.mdx -source_sha: ed009fb2792af92e0a8a47e182f31875bd4f6e60 +source_sha: 354e35fd7b7a6c13e98c31a2a409b2ba69fd1e35 title: "급여 및 대량 지급" -description: "Stable이 배치 정산, 예약된 블록스페이스, 가려진 금액을 통해 대량 지급을 처리하는 방법." +description: "Stable이 일괄 결제, 예약된 블록 공간 및 보호된 금액으로 대량 지불을 처리하는 방법." diataxis: "explanation" --- # 급여 및 대량 지급 -직원, 계약자, 공급업체에게 대규모로 지급하되, 예측 가능한 처리량, 예측 가능한 비용, 민감한 금액에 대한 프라이버시를 제공합니다. +예측 가능한 처리량, 예측 가능한 비용 및 민감한 금액에 대한 프라이버시를 통해 직원, 계약자 및 공급업체에게 대규모로 대금을 지급합니다. ## 문제점 -대량의 스테이블코인 지급은 공유 체인에서 트랜잭션당 처리량 한계에 부딪힙니다. 비용은 네트워크 혼잡도에 따라 변동하므로, 어제는 저렴하게 처리된 급여 실행이 오늘은 급등할 수 있습니다. 게다가 급여 및 공급업체 금액이 체인을 지켜보는 누구에게나 공개적으로 보이며, 이는 상업적으로 민감한 데이터를 유출합니다. +대량의 스테이블코인 지불은 공유 체인에서 트랜잭션당 처리량 제한에 부딪힙니다. 비용은 네트워크 혼잡에 따라 변동하므로 어제 저렴하게 처리되었던 급여 지급이 오늘 급등할 수 있습니다. 또한 급여 및 공급업체 금액은 체인을 모니터링하는 모든 사람에게 공개적으로 표시되어 상업적으로 민감한 데이터가 노출됩니다. ## Stable의 해결 방법 -- **USDT 전송 애그리게이터는 대량 전송을 병렬화된 정산 번들로 배치 처리하므로**, 단일 실행이 트랜잭션당 오버헤드에 병목되지 않습니다. [USDT 전송 애그리게이터](/ko/explanation/usdt-transfer-aggregator)를 참조하세요. -- **보장된 블록스페이스는 등록된 파트너에게 모든 블록에서 예약된 용량을 제공하므로**, 네트워크가 무엇을 하든 상관없이 포함 여부와 비용이 예측 가능하게 유지됩니다. [보장된 블록스페이스](/ko/explanation/guaranteed-blockspace)를 참조하세요. -- **컨피덴셜 전송은 영지식 암호화를 사용해 금액을 가리므로**, 급여 및 공급업체 실행이 민감한 숫자를 온체인에 공개하지 않습니다. [컨피덴셜 전송](/ko/explanation/confidential-transfer)을 참조하세요. +- **USDT 전송 애그리게이터는 대량 전송을 병렬화된 결제 번들로 일괄 처리하므로** 단일 실행이 트랜잭션당 오버헤드로 인해 병목 현상을 겪지 않습니다. [USDT 전송 애그리게이터](/ko/explanation/usdt-transfer-aggregator)를 참조하십시오. +- **보장된 블록 공간은 등록된 파트너에게 모든 블록에서 예약된 용량을 제공하므로** 네트워크에서 발생하는 다른 모든 것과 관계없이 포함 및 비용을 예측 가능하게 유지합니다. [보장된 블록 공간](/ko/explanation/guaranteed-blockspace)을 참조하십시오. +- **기밀 전송은 영지식 암호화를 사용하여 금액을 보호하므로** 급여 및 공급업체 실행이 민감한 숫자를 온체인에 게시하지 않습니다. [기밀 전송](/ko/explanation/confidential-transfer)을 참조하십시오. -## 다음 추천 사항 +## 다음 권장 사항 -- [**USDT 전송 애그리게이터**](/ko/explanation/usdt-transfer-aggregator) — 대량 USDT0 전송이 병렬화된 정산 번들로 배치 처리되는 방법을 이해하세요. -- [**보장된 블록스페이스**](/ko/explanation/guaranteed-blockspace) — 등록된 파트너가 모든 블록에서 예약된 용량을 확보하는 방법을 확인하세요. -- [**컨피덴셜 전송**](/ko/explanation/confidential-transfer) — ZK 암호화가 당사자의 감사 가능성을 유지하면서 전송 금액을 가리는 방법을 검토하세요. +- [**USDT 전송 애그리게이터**](/ko/explanation/usdt-transfer-aggregator): 대량 USDT0 전송이 병렬화된 결제 번들로 일괄 처리되는 방식을 이해합니다. +- [**보장된 블록 공간**](/ko/explanation/guaranteed-blockspace): 등록된 파트너가 모든 블록에서 예약된 용량을 확보하는 방법을 확인합니다. +- [**기밀 전송**](/ko/explanation/confidential-transfer): ZK 암호화가 당사자의 감사 가능성을 유지하면서 전송 금액을 보호하는 방법을 검토합니다. diff --git a/docs/pages/ko/explanation/use-case-private.mdx b/docs/pages/ko/explanation/use-case-private.mdx index b75d46e..646fb62 100644 --- a/docs/pages/ko/explanation/use-case-private.mdx +++ b/docs/pages/ko/explanation/use-case-private.mdx @@ -1,25 +1,25 @@ --- source_path: explanation/use-case-private.mdx -source_sha: 20cbf4e27161a85cc05ee6fac25c62038f669526 -title: "비공개 송금" -description: "Stable이 영지식 암호화를 사용하여 상업적으로 민감한 송금 금액을 보호하면서도 거래 당사자에 대한 감사 가능성을 유지하는 방법." +source_sha: 8f0641a2b202bf5867149966cfef72f010035339 +title: "프라이빗 이전" +description: "Stable이 상업적으로 민감한 이전 금액을 영지식 암호화를 사용하여 보호하는 동시에 당사자가 감사 가능한 상태를 유지하는 방법." diataxis: "explanation" --- -# 비공개 송금 +# 프라이빗 이전 -금액이 상업적으로 민감하여 외부에 공개되어서는 안 되는 자금 운용, 공급업체 결제, 급여 지급 등의 작업입니다. +금액이 상업적으로 민감하고 공개되어서는 안 되는 재무 운영, 공급업체 지불 및 급여 실행. -## 문제 +## 문제점 -모든 표준 EVM 송금은 공개적으로 관찰 가능합니다. 급여 지급이나 공급업체 정산은 누가 누구에게, 얼마를, 얼마나 자주 지급했는지와 같은 사업상 중요한 데이터를 온체인에 노출합니다. 경쟁자, 거래 상대방, 그리고 네트워크를 스크래핑하는 누구든 별도로 묻지 않고도 급여 구간, 공급업체 가격, 자금 운용 동향을 재구성할 수 있습니다. +모든 표준 EVM 이전은 공개적으로 관찰 가능합니다. 급여 실행 또는 공급업체 결제 시 비즈니스에 중요한 데이터가 온체인에 유출됩니다. 누가 누구에게 얼마를 얼마나 자주 지불했는지, 경쟁업체, 거래 상대방 및 네트워크를 스크랩하는 모든 사람이 요청하지 않고도 급여 밴드, 공급업체 가격 및 재무 이동을 재구성할 수 있습니다. -## Stable의 해결 방법 +## Stable이 해결하는 방법 -- **기밀 송금은 영지식 암호화를 사용하여 송금 금액을 보호**하면서도 컴플라이언스를 위해 거래 당사자에 대한 감사 가능성을 유지하므로, 민감한 수치가 감사 추적을 희생하지 않고도 비공개로 유지됩니다. [기밀 송금](/ko/explanation/confidential-transfer)을 참조하세요. -- **자금 흐름은 온램프부터 오프램프까지 전체 USDT 수명 주기에서 기밀 송금이 어디에 위치하는지** 보여줍니다. [자금 흐름](/ko/explanation/flow-of-funds)을 참조하세요. +- **기밀 이전은 영지식 암호화를 사용하여 이전 금액을 보호**하는 동시에 당사자가 규정 준수를 위해 감사 가능하도록 유지하므로, 민감한 숫자는 감사 내역을 희생하지 않고 비공개로 유지됩니다. [기밀 이전](/ko/explanation/confidential-transfer)을 참조하세요. +- **자금 흐름은 온램프에서 오프램프까지 전체 USDT 수명 주기에서 기밀 이전이 어디에 위치하는지 보여줍니다.** [자금 흐름](/ko/explanation/flow-of-funds)을 참조하세요. ## 다음 권장 사항 -- [**기밀 송금**](/ko/explanation/confidential-transfer) — ZK 암호화가 거래 당사자에 대한 감사 가능성을 유지하면서 송금 금액을 보호하는 방법을 살펴보세요. -- [**자금 흐름**](/ko/explanation/flow-of-funds) — 온램프에서 온체인 송금을 거쳐 오프램프 정산까지 USDT를 추적하세요. +- [**기밀 이전**](/ko/explanation/confidential-transfer): ZK 암호화가 이전 금액을 보호하는 동시에 당사자가 감사 가능한 상태를 유지하는 방법을 검토합니다. +- [**자금 흐름**](/ko/explanation/flow-of-funds): 온램프에서 온체인 이전, 오프램프 결제까지 USDT의 흐름을 추적합니다. diff --git a/docs/pages/ko/explanation/use-case-sponsored.mdx b/docs/pages/ko/explanation/use-case-sponsored.mdx index 2d68172..6b7d0ef 100644 --- a/docs/pages/ko/explanation/use-case-sponsored.mdx +++ b/docs/pages/ko/explanation/use-case-sponsored.mdx @@ -1,25 +1,25 @@ --- source_path: explanation/use-case-sponsored.mdx -source_sha: 1b76f6180d916d240582c1b5a275b8f34de0ec9a -title: "스폰서 및 가스리스 경험" -description: "Stable이 애플리케이션으로 하여금 사용자를 대신해 가스를 전액 부담하게 하여, 온보딩 시 가스 토큰을 확보할 필요가 없도록 하는 방법." +source_sha: 999da6d81c1f78260db57dbebeb5bd08c06a2679 +title: "스폰서 및 무가스 경험" +description: "Stable이 어떻게 애플리케이션이 사용자를 대신하여 가스를 전적으로 부담하게 함으로써, 온보딩에 가스 토큰 획득이 필요 없게 하는지 설명합니다." diataxis: "explanation" --- -# 스폰서 및 가스리스 경험 +# 스폰서 및 무가스 경험 -가스를 사용자 경험에서 완전히 제거하고 싶어하는 앱을 위한 것으로, 처음 사용하는 사용자가 별도의 자산을 먼저 확보하지 않고도 로그인하고 거래할 수 있게 합니다. +사용자 경험에서 가스를 완전히 제거하고자 하는 앱들은 첫 사용자도 두 번째 자산을 먼저 확보하지 않고도 로그인하여 거래할 수 있습니다. -## 문제 +## 문제점 -앱을 사용하기 전에 사용자에게 가스 토큰을 확보하도록 요구하면, 소비자 대상 제품의 전환율을 떨어뜨리는 온보딩 절벽이 생깁니다. USDT만(또는 아무것도) 가지고 온 신규 사용자는 트랜잭션을 제출할 수 없으며, 가스를 사기 위해 별도의 거래소로 유도하는 지점에서 대부분의 사용자가 이탈합니다. +앱을 사용하기 전에 사용자가 가스 토큰을 획득하도록 요구하는 것은 소비자 대상 제품의 전환율을 저해하는 온보딩 장애물을 만듭니다. USDT(또는 아무것도 없는)만 가지고 나타난 신규 사용자는 거래를 제출할 수 없으며, 가스를 구매하기 위해 별도의 거래소로 보내는 것은 대부분의 사용자가 이탈하는 지점입니다. -## Stable의 해결 방법 +## Stable이 해결하는 방법 -- **가스 면제: 거버넌스 승인을 받은 면제 주소가 사용자를 대신해 가스 가격이 0인 래퍼 트랜잭션을 제출**하므로, 앱이 가스를 처음부터 끝까지 부담하고 사용자는 무료 동작을 보게 됩니다. [가스 면제](/ko/explanation/gas-waiver)를 참조하세요. -- **EIP-7702 세션 키를 통해 dApp이 범위가 지정되고 시간 제한이 있는 권한을 보유**할 수 있으므로, 사용자가 매번 서명하지 않아도 사용자를 대신해 트랜잭션을 제출할 수 있습니다. [EIP-7702](/ko/explanation/eip-7702)를 참조하세요. +- **가스 면제: 거버넌스 승인 면제는 사용자를 대신하여 0 가스 가격으로 실행되는 래퍼 트랜잭션을 제출합니다.** 따라서 앱이 가스를 전적으로 부담하고 사용자는 무료 작업을 보게 됩니다. [가스 면제](/ko/explanation/gas-waiver)를 참조하세요. +- **EIP-7702 세션 키는 dApp이 범위가 지정된 시간 제한 권한을 보유하도록 합니다.** 따라서 dApp은 사용자가 각 트랜잭션에 서명하지 않고도 사용자를 대신하여 트랜잭션을 제출할 수 있습니다. [EIP-7702](/ko/explanation/eip-7702)를 참조하세요. -## 다음 추천 +## 다음 권장 사항 -- [**가스 면제**](/ko/explanation/gas-waiver) — 거버넌스 승인을 받은 면제가 가스 가격이 0인 래퍼 트랜잭션을 어떻게 제출하는지 확인하세요. -- [**EIP-7702**](/ko/explanation/eip-7702) — EOA가 범위가 지정되고 시간 제한이 있는 권한을 dApp에 어떻게 위임할 수 있는지 이해하세요. +- [**가스 면제**](/ko/explanation/gas-waiver): 거버넌스 승인 면제가 0 가스 가격으로 래퍼 트랜잭션을 제출하는 방법을 알아보세요. +- [**EIP-7702**](/ko/explanation/eip-7702): EOA가 dApp에 범위가 지정된 시간 제한 권한을 위임하는 방법을 이해하세요. diff --git a/docs/pages/ko/explanation/x402.mdx b/docs/pages/ko/explanation/x402.mdx index 5f3025b..8997374 100644 --- a/docs/pages/ko/explanation/x402.mdx +++ b/docs/pages/ko/explanation/x402.mdx @@ -1,59 +1,59 @@ --- source_path: explanation/x402.mdx -source_sha: ac981560e97b0d313b0161b1c62f92445042814a +source_sha: dd8747ecc00fbdce4e4a4514c28699826e04e4e4 title: "HTTP 엔드포인트 수익화" -description: "x402는 HTTP 위에 구축된 결제 프로토콜입니다. 서버가 결제를 요청하고, 클라이언트가 서명하며, 퍼실리테이터가 온체인에서 정산합니다. 계정도, API 키도, 구독도 필요 없습니다." +description: "x402는 HTTP 결제 프로토콜입니다. 서버가 결제를 요청하고, 클라이언트가 서명하며, 촉진자가 온체인에서 결제를 처리합니다. 계정, API 키 또는 구독이 필요 없습니다." diataxis: "explanation" --- # HTTP 엔드포인트 수익화 -x402는 HTTP 위에 구축된 결제 프로토콜입니다. 서버가 `402 Payment Required`와 결제 세부 정보로 응답하면, 클라이언트가 [ERC-3009](/ko/explanation/erc-3009) 인증을 서명하고, 퍼실리테이터가 이를 온체인에서 정산합니다. 전체 교환 과정은 표준 HTTP 헤더를 통해 이루어집니다. 클라이언트는 지갑만 있으면 됩니다. 회원 가입도, API 키도, 카드 등록도 필요 없습니다. +x402는 HTTP를 기반으로 구축된 결제 프로토콜입니다. 서버는 `402 Payment Required` 응답과 결제 세부 정보를 제공하고, 클라이언트는 [ERC-3009](/ko/explanation/erc-3009) 승인에 서명하며, 촉진자는 온체인에서 결제를 처리합니다. 전체 교환은 표준 HTTP 헤더를 통해 이루어집니다. 클라이언트는 지갑만 있으면 됩니다. 가입, API 키, 카드 등록이 필요 없습니다. -이는 클라이언트가 리소스나 서비스에 대해 서버에 지불하는 모든 시나리오에 적용됩니다. API 접근, 디지털 콘텐츠, 가맹점 결제, 또는 에이전트 간 결제 등이 그 예입니다. +이는 클라이언트가 리소스나 서비스에 대해 서버에 비용을 지불하는 모든 시나리오에 적용됩니다. API 접근, 디지털 콘텐츠, 상점 결제 또는 에이전트 간 결제 등입니다. ## x402와 MPP -x402는 원조 HTTP-402 결제 프로토콜입니다. [Machine Payments Protocol (MPP)](/ko/explanation/mpp)은 더 광범위한 IETF 트랙의 후속 프로토콜로, 결제 인텐트(세션, 구독), 멀티 레일 지원(카드, Lightning), 그리고 프로덕션 기능(본문 다이제스트 바인딩, 멱등성)을 추가합니다. MPP 클라이언트는 하위 호환성을 가지고 있어 변경 없이 x402 서버를 호출할 수 있습니다. +x402는 원래의 HTTP-402 결제 프로토콜입니다. [MPP(Machine Payments Protocol)](/ko/explanation/mpp)는 결제 의도(세션, 구독), 다중 결제 수단 지원(카드, 라이트닝), 생산 기능(본문 다이제스트 바인딩, 멱등성)을 추가한 더 광범위하고 IETF 트랙의 후속 프로토콜입니다. MPP 클라이언트는 하위 호환됩니다. 변경 없이 x402 서버를 호출할 수 있습니다. -오늘날 Stable에서 가장 직접적인 경로는 Semantic Pay 또는 Heurist를 통한 x402입니다. 동일한 USDT0 레일에서 MPP의 와이어 포맷을 사용하려면 [Stable에서 MPP 엔드포인트 구축하기](/ko/how-to/build-mpp-endpoint)를 참조하세요. +오늘날 Stable에서 가장 직접적인 경로는 Semantic Pay 또는 Heurist를 통한 x402입니다. 동일한 USDT0 레일에서 MPP의 와이어 포맷을 사용하려면 [Stable에서 MPP 엔드포인트 구축](/ko/how-to/build-mpp-endpoint)을 참조하십시오. -## 어떤 문제를 해결하나요? +## 어떤 문제를 해결하는가? -오늘날 인터넷에서 서비스에 비용을 지불하려면 모든 단계에서 사용자의 개입이 필요합니다. 계정에 가입하고, 로그인하고, 결제 수단을 등록해야 합니다. 이 모델은 다음과 같은 경우로 확장되지 않습니다. +오늘날 인터넷에서 서비스 비용을 지불하려면 모든 단계에서 사용자 개입이 필요합니다. 계정 가입, 로그인, 결제 수단 등록 등입니다. 이 모델은 다음과 같은 경우에 확장되지 않습니다. - 인프라 비용을 정당화하기에는 너무 작은 서비스 -- 카드 네트워크 수수료를 감당하기에는 너무 저렴한 거래 -- 가입 과정을 수행할 수 없는 자율 에이전트(AI, 봇, IoT 기기) +- 카드 네트워크 수수료에 비해 너무 저렴한 거래 +- 가입 절차를 수행할 수 없는 자율 에이전트(AI, 봇, IoT 장치) -x402를 사용하면 클라이언트는 지불하기 위해 지갑만 있으면 됩니다. +x402를 사용하면 클라이언트는 지갑만 있으면 결제할 수 있습니다. -| **측면** | **기존 청구 방식** | **x402 사용 시** | +| **측면** | **기존 청구** | **x402 사용 시** | | :--- | :--- | :--- | -| 계정 필요 | 예 | 아니오 | -| API 키 필요 | 예 | 아니오 | -| 실현 가능한 최소 가격 | 약 $0.30 (카드 처리 하한선) | 약 $0.001 (온체인) | -| 정산 시간 | 수일 (카드 네트워크) | 1초 미만 (Stable 기준) | -| PCI 준수 필요 | 예 | 아니오 | +| 계정 필요 | 예 | 아니요 | +| API 키 필요 | 예 | 아니요 | +| 최소 실행 가능 가격 | ~$0.30 (카드 처리 최소 금액) | ~$0.001 (온체인) | +| 정산 시간 | 며칠 (카드 네트워크) | 1초 미만 (Stable에서) | +| PCI 규정 준수 필요 | 예 | 아니요 | ## 작동 방식 ### 세 가지 역할 -**클라이언트**는 리소스를 필요로 하는 주체입니다. 웹 앱, 백엔드 서비스, CLI 도구, 또는 AI 에이전트일 수 있습니다. 클라이언트는 지갑(ERC-3009 인증을 서명할 수 있는 개인 키)만 있으면 됩니다. +**클라이언트**는 리소스가 필요한 주체입니다. 웹 앱, 백엔드 서비스, CLI 도구 또는 AI 에이전트가 될 수 있습니다. 클라이언트는 지갑(ERC-3009 승인에 서명할 수 있는 개인 키)만 있으면 됩니다. -**서버**는 리소스를 제공하는 주체입니다. 서버는 엔드포인트에 x402 미들웨어를 부착하여 무엇이 얼마인지 정의합니다. +**서버**는 리소스를 제공하는 주체입니다. 서버는 엔드포인트에 x402 미들웨어를 연결하여 비용과 금액을 정의합니다. -**퍼실리테이터**는 정산 서비스입니다. 서버로부터 서명된 결제를 받아 검증하고, 온체인 트랜잭션을 제출한 뒤 결과를 반환합니다. 퍼실리테이터는 클라이언트의 자금을 절대 보유하지 않습니다. 자금 이동은 토큰 컨트랙트 내에서 클라이언트로부터 서버로 직접 이루어집니다. +**촉진자**는 정산 서비스입니다. 서버로부터 서명된 결제를 받고, 이를 확인하고, 온체인 트랜잭션을 제출하고, 결과를 반환합니다. 촉진자는 클라이언트의 자금을 보관하지 않습니다. 토큰 계약 내에서 클라이언트에서 서버로 직접 전송됩니다. -Stable에서는 [Semantic Pay](https://x402.semanticpay.io)가 공개 퍼실리테이터를 운영합니다. +Stable에서는 [Semantic Pay](https://x402.semanticpay.io)가 공공 촉진자 역할을 합니다. ### 결제 흐름 -1. **클라이언트가 리소스를 요청합니다.** 클라이언트는 일반 HTTP 요청(GET, POST 등)을 서버로 전송합니다. -2. **서버가 402로 응답합니다.** 서버는 HTTP `402 Payment Required`와 함께 클라이언트가 필요로 하는 모든 정보를 담은 `PAYMENT-REQUIRED` 헤더를 반환합니다. 얼마를 지불해야 하는지, 어떤 토큰인지, 어떤 네트워크인지, 그리고 자금을 어디로 보내야 하는지를 포함합니다. -3. **클라이언트가 서명하고 재제출합니다.** 클라이언트는 결제 요구 사항을 읽고, 지정된 금액에 대해 ERC-3009 인증을 서명한 뒤, 서명된 인증을 담은 `PAYMENT-SIGNATURE` 헤더와 함께 원래 요청을 재제출합니다. -4. **퍼실리테이터가 검증하고 정산합니다.** 서버는 서명된 결제를 퍼실리테이터로 전달합니다. 퍼실리테이터는 서명을 검증하고, `transferWithAuthorization` 호출을 온체인에 제출하며, 확인이 완료되면 서버는 정산 영수증을 담은 `PAYMENT-RESPONSE` 헤더와 함께 요청된 리소스를 반환합니다. +1. **클라이언트가 리소스를 요청합니다.** 클라이언트는 서버에 일반 HTTP 요청(GET, POST 등)을 보냅니다. +2. **서버가 402로 응답합니다.** 서버는 HTTP `402 Payment Required`와 함께 클라이언트가 필요로 하는 모든 정보(지불할 금액, 토큰, 네트워크, 자금을 보낼 주소)를 포함하는 `PAYMENT-REQUIRED` 헤더를 반환합니다. +3. **클라이언트가 서명하고 다시 제출합니다.** 클라이언트는 결제 요구 사항을 읽고, 지정된 금액에 대한 ERC-3009 승인에 서명하며, 서명된 승인을 포함하는 `PAYMENT-SIGNATURE` 헤더와 함께 원래 요청을 다시 제출합니다. +4. **촉진자가 확인 및 정산합니다.** 서버는 서명된 결제를 촉진자에게 전달합니다. 촉진자는 서명을 검증하고, `transferWithAuthorization` 호출을 온체인에 제출하며, 확인되면 서버는 요청된 리소스를 정산 영수증을 포함하는 `PAYMENT-RESPONSE` 헤더와 함께 반환합니다. ### 세 가지 헤더 @@ -61,49 +61,49 @@ Stable에서는 [Semantic Pay](https://x402.semanticpay.io)가 공개 퍼실리 | **헤더** | **방향** | **내용** | | :--- | :--- | :--- | -| `PAYMENT-REQUIRED` | 서버에서 클라이언트로 | 결제 스킴, 토큰 주소, 금액, 수신자 주소, 네트워크 식별자 | -| `PAYMENT-SIGNATURE` | 클라이언트에서 서버로 | 클라이언트가 이체를 승인했음을 증명하는 서명된 ERC-3009 인증 | -| `PAYMENT-RESPONSE` | 서버에서 클라이언트로 | 트랜잭션 해시 및 확인 상태를 포함한 정산 결과 | +| `PAYMENT-REQUIRED` | 서버에서 클라이언트 | 결제 스키마, 토큰 주소, 금액, 수취인 주소, 네트워크 식별자 | +| `PAYMENT-SIGNATURE` | 클라이언트에서 서버 | 클라이언트가 전송을 승인했음을 증명하는 서명된 ERC-3009 승인 | +| `PAYMENT-RESPONSE` | 서버에서 클라이언트 | 트랜잭션 해시 및 확인 상태를 포함한 정산 결과 | -이 설계는 모든 HTTP 클라이언트, 모든 프로그래밍 언어, 그리고 커스텀 헤더를 지원하는 모든 인프라에서 작동합니다. +이 디자인은 모든 HTTP 클라이언트, 모든 프로그래밍 언어, 사용자 지정 헤더를 지원하는 모든 인프라와 함께 작동합니다. ## Stable의 x402 -x402 프로토콜은 HTTP를 통해 결제가 작동하는 방식을 정의합니다. Stable은 이를 프로덕션 환경에서 실용적으로 만드는 정산 환경을 제공합니다. +x402 프로토콜은 HTTP를 통한 결제 방법을 정의합니다. Stable은 생산 사용에 실용적으로 사용할 수 있는 정산 환경을 제공합니다. -### 1초 미만의 완결성 +### 1초 미만 확정성 -Stable의 합의는 1초 미만의 블록 완결성(약 700밀리초)을 제공하여, x402 퍼실리테이터가 트랜잭션을 실시간으로 검증하고 정산할 수 있게 합니다. 이는 AI 에이전트나 IoT 기기가 여러 소액 결제를 빠르게 연속으로 실행할 수 있는 고빈도 자동화 상호작용에서 매우 중요합니다. +Stable의 합의는 1초 미만의 블록 확정성(~700밀리초)을 제공하여 x402 촉진자가 실시간으로 트랜잭션을 확인하고 정산할 수 있도록 합니다. 이는 AI 에이전트 또는 IoT 장치가 빠른 연속으로 많은 소액 결제를 실행할 수 있는 고주파 자동 상호 작용에 중요합니다. ### 단일 자산 정산 -Stable에서 USDT0은 네이티브 가스 토큰이자 결제 토큰입니다. 전체 x402 결제 수명 주기는 USDT0만으로 실행됩니다. 클라이언트는 USDT0만 보유하고, 퍼실리테이터는 정산에 사용하는 것과 동일한 토큰으로 트랜잭션을 제출합니다. x402를 사용하는 AI 에이전트의 경우, 이는 에이전트 지갑이 단 하나의 자산만 관리하면 된다는 것을 의미합니다. +Stable에서 USDT0은 기본 가스 토큰이자 결제 토큰입니다. 전체 x402 결제 수명 주기는 USDT0만으로 실행됩니다. 클라이언트는 USDT0만 보유하며, 촉진자는 정산하는 토큰과 동일한 토큰을 사용하여 트랜잭션을 제출합니다. x402를 사용하는 AI 에이전트에게 이는 에이전트 지갑이 하나의 자산만 관리하면 된다는 것을 의미합니다. -### 마이크로 가격 책정 +### 마이크로-프라이싱 -가격은 USDT0 원자 단위(소수점 6자리)로 표시됩니다. 비용 매개변수 `"1000"`은 정확히 $0.001로 변환됩니다. 이 정밀도는 x402 서버가 센트 단위 이하로 가격을 설정할 수 있게 합니다. +가격은 USDT0 아토믹 단위(6자리 소수점)로 표시됩니다. `"1000"`의 비용 매개변수는 정확히 $0.001로 번역됩니다. 이 정밀도를 통해 x402 서버는 1센트 미만의 가격을 설정할 수 있습니다. ### 가스 면제 통합 -[가스 면제](/ko/how-to/integrate-gas-waiver)는 트랜잭션 비용을 완전히 제거합니다. x402 퍼실리테이터는 가스 면제 인프라를 사용하여 구매자나 판매자 어느 쪽에도 가스를 청구하지 않고 `transferWithAuthorization` 호출을 제출할 수 있습니다. 이는 Stable에서의 x402 마이크로페이먼트가 결제 금액 자체 외에는 어떠한 추가 부담도 발생하지 않음을 의미합니다. +[가스 면제](/ko/how-to/integrate-gas-waiver)는 거래 비용을 완전히 없앱니다. x402 촉진자는 가스 면제 인프라를 사용하여 구매자 또는 판매자에게 가스를 청구하지 않고 `transferWithAuthorization` 호출을 제출할 수 있습니다. 이는 Stable의 x402 소액 결제가 결제 금액 자체 외에 오버헤드가 없다는 것을 의미합니다. ## 인프라 ### Semantic Pay -[Semantic Pay](https://x402.semanticpay.io)는 Stable을 위한 공개 x402 퍼실리테이터를 제공합니다. 이는 서명 검증, 온체인 제출, 그리고 확인 추적을 처리합니다. Stable에서 x402를 통합하는 개발자는 자체 정산 인프라를 운영하지 않고도 미들웨어를 이 엔드포인트로 지정할 수 있습니다. +[Semantic Pay](https://x402.semanticpay.io)는 Stable용 공개 x402 촉진자를 제공합니다. 서명 확인, 온체인 제출 및 확인 추적을 처리합니다. Stable에서 x402를 통합하는 개발자는 자체 정산 인프라를 실행할 필요 없이 미들웨어를 이 엔드포인트로 지정할 수 있습니다. -**퍼실리테이터 엔드포인트:** `https://x402.semanticpay.io` +**촉진자 엔드포인트:** `https://x402.semanticpay.io` -### WDK (Wallet Development Kit) +### WDK (지갑 개발 키트) -AI 에이전트가 자율적으로 x402에 참여하려면 프로그래밍 방식으로 제어할 수 있는 지갑이 필요합니다. Tether의 오픈소스 WDK가 이를 제공합니다. +AI 에이전트가 x402에 자율적으로 참여하려면 프로그램적으로 제어할 수 있는 지갑이 필요합니다. Tether의 오픈 소스 WDK는 이를 제공합니다. -- **자기 수탁(Self-custody)**: WDK는 AI 에이전트가 중앙화된 API 인프라에 의존하지 않고 로컬에서 개인 키를 생성하고 저장할 수 있게 합니다. -- **x402 호환성**: WDK의 `WalletAccountEvm` 인스턴스는 x402 SDK가 요구하는 클라이언트 서명자 인터페이스를 기본적으로 충족하여, 에이전트가 402 HTTP 응답을 자동으로 가로채고, ERC-3009 인증을 서명하며, 요청을 재제출할 수 있게 합니다. +- **자체 관리**: WDK를 통해 AI 에이전트는 중앙 집중식 API 인프라에 의존하지 않고 로컬에서 개인 키를 생성하고 저장할 수 있습니다. +- **x402 호환성**: WDK의 `WalletAccountEvm` 인스턴스는 x402 SDK에서 요구하는 클라이언트 서명자 인터페이스를 기본적으로 충족하여 에이전트가 402 HTTP 응답을 자동으로 가로채고, ERC-3009 승인에 서명하고, 요청을 다시 제출할 수 있도록 합니다. -**참고 자료:** +**참조:** -- [ERC-3009 (Transfer With Authorization)](/ko/explanation/erc-3009): x402가 사용하는 온체인 정산 표준 -- [결제 사용 사례](/ko/explanation/payment-use-cases-overview): P2P, 구독, 인보이스, API 청구 패턴 -- [가스 면제](/ko/how-to/integrate-gas-waiver): 비용 없는 트랜잭션 제출 +- [ERC-3009 (승인을 통한 전송)](/ko/explanation/erc-3009): x402가 사용하는 온체인 정산 표준 +- [결제 사용 사례](/ko/explanation/payment-use-cases-overview): P2P, 구독, 인보이스 및 API 청구 패턴 +- [가스 면제](/ko/how-to/integrate-gas-waiver): 제로 비용 거래 제출 diff --git a/docs/pages/ko/how-to/account-abstraction.mdx b/docs/pages/ko/how-to/account-abstraction.mdx index feb04e4..b332275 100644 --- a/docs/pages/ko/how-to/account-abstraction.mdx +++ b/docs/pages/ko/how-to/account-abstraction.mdx @@ -1,39 +1,39 @@ --- source_path: how-to/account-abstraction.mdx -source_sha: 8eaa5c6ea2859611c839ed8d5c8acbe81f18c38a -title: "EIP-7702를 활용한 계정 추상화" -description: "EIP-7702 스마트 컨트랙트에 위임하여 기존 EOA에서 일괄 결제, 지출 한도, 세션 키를 구현합니다." +source_sha: 30e0b565660c81e67967daa2ddf0f0ceae7aa9ef +title: "EIP-7702를 사용한 계정 추상화" +description: "EIP-7702 스마트 계약에 위임하여 기존 EOA에서 배치 결제, 지출 한도 및 세션 키를 구현합니다." diataxis: "how-to" --- -# EIP-7702를 활용한 계정 추상화 +# EIP-7702를 사용한 계정 추상화 -이 가이드는 EOA에 EIP-7702를 적용하고 위임을 사용하여 세 가지 패턴, 즉 일괄 결제, 지출 한도, 세션 키를 구현하는 과정을 단계별로 설명합니다. EOA는 그 과정 내내 자신의 주소와 개인 키를 유지합니다. +이 가이드는 EIP-7702를 EOA에 적용하고 배치를 세 가지 패턴(일괄 결제, 지출 한도 및 세션 키)에 사용하는 방법을 설명합니다. EOA는 이 과정을 통해 주소와 개인 키를 유지합니다. :::note -**개념:** EIP-7702가 Stable에서 무엇을 가능하게 하는지와 보안 고려 사항에 대해서는 [EIP-7702](/ko/explanation/eip-7702)를 참조하세요. +**개념:** Stable에서 EIP-7702가 가능하게 하는 기능과 보안 고려 사항은 [EIP-7702](/ko/explanation/eip-7702)를 참조하세요. ::: -## 사전 요구 사항 +## 전제 조건 -- EOA와 스마트 컨트랙트 계정의 차이 이해(EOA는 기본적으로 코드가 없습니다). -- EVM 트랜잭션 유형에 대한 이해([EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)). +- EOA와 스마트 계약 계정의 차이점에 대한 이해(EOA는 기본적으로 코드가 없음). +- EVM 트랜잭션 유형([EIP-2718](https://eips.ethereum.org/EIPS/eip-2718))에 대한 친숙함. ## 개요 -EIP-7702는 `authorizationList`를 담는 새로운 트랜잭션 유형(`0x04`)을 도입합니다. 각 권한 부여는 EOA가 해당 트랜잭션에서 실행할 코드를 가진 스마트 컨트랙트를 지정합니다. 흐름은 다음과 같습니다: +EIP-7702는 `authorizationList`를 포함하는 새로운 트랜잭션 유형(`0x04`)을 도입합니다. 각 권한 부여는 EOA가 해당 트랜잭션에 대해 코드를 실행할 스마트 계약을 지정합니다. 흐름은 다음과 같습니다: -1. **위임 컨트랙트 선택 또는 배포**: EOA가 사용할 로직을 구현하는 표준 Solidity 컨트랙트입니다. 배포된 컨트랙트를 사용하거나 직접 배포할 수 있습니다. 가능하면 감사받은 컨트랙트를 사용하세요. -2. **권한 부여 서명**: EOA 소유자가 위임 컨트랙트를 승인하는 메시지에 서명합니다. -3. **EIP-7702 트랜잭션 제출**: 트랜잭션에 권한 부여가 포함되며, EOA는 실행 중에 위임 컨트랙트의 코드를 실행합니다. +1. **위임 계약 선택 또는 배포**: EOA가 사용하려는 로직을 구현하는 표준 Solidity 계약입니다. 배포된 계약을 사용하거나 직접 배포할 수 있습니다. 가능한 경우 감사된 계약을 사용하십시오. +2. **권한 부여 서명**: EOA 소유자가 위임 계약을 승인하는 메시지에 서명합니다. +3. **EIP-7702 트랜잭션 제출**: 트랜잭션에는 권한 부여가 포함되며, EOA는 실행 중에 위임자의 코드를 실행합니다. ## 사용 사례: 일괄 트랜잭션 -아래 단계는 `Multicall3`을 위임 컨트랙트로 사용하여 이 흐름을 단계별로 설명합니다. `Multicall3`은 여러 호출을 단일 트랜잭션으로 집계하는 널리 배포된 유틸리티 컨트랙트입니다. `Multicall3`을 EIP-7702 위임 대상으로 지정하면 EOA가 임의의 컨트랙트 상호작용(토큰 전송, 승인, 컨트랙트 읽기, 또는 이들의 조합)을 하나의 원자적 트랜잭션으로 일괄 처리할 수 있습니다. 일괄 결제는 그 한 가지 예입니다. 급여 지급을 위해 열 개의 별도 트랜잭션을 보내는 대신, EOA는 이를 한 번에 모두 실행합니다. +아래 단계는 `Multicall3`를 위임 계약으로 사용하여 이 흐름을 설명합니다. `Multicall3`는 여러 호출을 단일 트랜잭션으로 집계하는 널리 배포된 유틸리티 계약입니다. `Multicall3`를 EIP-7702 위임자로 지정하면 EOA는 임의의 계약 상호 작용(토큰 전송, 승인, 계약 읽기 또는 모든 조합)을 하나의 원자적 트랜잭션으로 일괄 처리할 수 있습니다. 일괄 결제가 한 예입니다. 급여 실행을 위해 열 개의 별도 트랜잭션을 보내는 대신 EOA는 모든 트랜잭션을 한 번에 실행합니다. -### 1단계: Multicall3을 위임 컨트랙트로 사용 +### 1단계: Multicall3를 위임 계약으로 사용 -`Multicall3`은 Stable에서 `0xcA11bde05977b3631167028862bE2a173976CA11`에 배포되어 있습니다. 이미 배포되어 널리 사용되고 있으므로 직접 위임 컨트랙트를 배포할 필요가 없습니다. EIP-7702 권한 부여에 서명하면 위임 대상에 EOA에 대한 완전한 실행 권한이 부여됩니다. +`Multicall3`는 Stable의 `0xcA11bde05977b3631167028862bE2a173976CA11`에 배포되어 있습니다. 이미 배포되어 널리 사용되고 있으므로 직접 위임 계약을 배포할 필요가 없습니다. EIP-7702 권한 부여에 서명하면 위임자는 EOA에 대한 전체 실행 권한을 얻습니다. ```solidity // Multicall3 interface (relevant functions only) @@ -48,7 +48,7 @@ interface IMulticall3 { bytes returnData; } - /// @notice Aggregate calls, allowing each to succeed or fail independently + /// @notice 여러 호출을 집계하여 각 호출이 독립적으로 성공 또는 실패하도록 허용합니다. function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); } @@ -56,7 +56,7 @@ interface IMulticall3 { ### 2단계: 권한 부여 서명 -EOA 소유자가 위임 컨트랙트를 지정하는 권한 부여에 서명합니다. 이 권한 부여는 EIP-7702 트랜잭션에 포함됩니다. +EOA 소유자는 위임 계약을 지정하는 권한 부여에 서명합니다. 이 권한 부여는 EIP-7702 트랜잭션에 포함됩니다. ```javascript // config.ts @@ -89,7 +89,7 @@ export async function signAuthorization() { ### 3단계: EIP-7702 트랜잭션 제출 -권한 부여를 `Multicall3.aggregate3` 호출과 결합합니다. 이 예시는 세 개의 USDT0 전송을 단일 트랜잭션으로 일괄 처리합니다. +권한 부여를 `Multicall3.aggregate3` 호출과 결합합니다. 이 예제는 단일 트랜잭션에서 세 개의 USDT0 전송을 일괄 처리합니다. ```javascript import { ethers } from "ethers"; @@ -122,34 +122,34 @@ async function main() { const signedAuth = await signAuthorization(); const tx = await wallet.sendTransaction({ - type: 4, // EIP-7702 transaction type - to: wallet.address, // call is directed at the EOA itself - data: batchData, // aggregate3 call to execute + type: 4, // EIP-7702 트랜잭션 유형 + to: wallet.address, // 호출은 EOA 자체로 향함 + data: batchData, // 실행할 aggregate3 호출 authorizationList: [signedAuth], maxPriorityFeePerGas: 0n, }); const receipt = await tx.wait(1); - console.log("Batch transactions executed in tx:", receipt.hash); + console.log("트랜잭션 일괄 처리됨:", receipt.hash); } ``` ```text -Batch transactions executed in tx: 0x... +일괄 트랜잭션이 tx에서 실행됨: 0x... ``` -EOA는 `Multicall3.aggregate3`을 통해 세 개의 호출을 모두 단일 원자적 트랜잭션으로 실행합니다. 위임은 명시적으로 변경되거나 해제될 때까지 지속됩니다. 이 예시는 일괄 결제를 보여주지만, 동일한 패턴이 컨트랙트 호출의 모든 조합에 적용됩니다. +EOA는 `Multicall3.aggregate3`를 통해 세 가지 호출을 단일 원자적 트랜잭션으로 실행합니다. 위임은 명시적으로 변경되거나 지워질 때까지 유지됩니다. 이 예는 일괄 결제를 보여주지만, 동일한 패턴은 모든 종류의 계약 호출 조합에 적용됩니다. ## 사용 사례: 지출 한도 -위임 컨트랙트는 계정 마이그레이션 없이 EOA에 트랜잭션당 또는 일일 상한을 적용할 수 있습니다. +위임 계약은 계정 마이그레이션 없이 EOA에 대한 트랜잭션당 또는 일일 한도를 강제할 수 있습니다. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; /// @title SpendingLimitExecutor -/// @notice Delegate contract that enforces daily spending caps +/// @notice 일일 지출 한도를 강제하는 위임 계약 contract SpendingLimitExecutor { mapping(address => uint256) public dailyLimit; mapping(address => uint256) public spentToday; @@ -174,25 +174,25 @@ contract SpendingLimitExecutor { spentToday[msg.sender] += value; require( spentToday[msg.sender] <= dailyLimit[msg.sender], - "daily limit exceeded" + "일일 한도 초과" ); (bool success,) = target.call{value: value}(data); - require(success, "call failed"); + require(success, "호출 실패"); } } ``` ## 사용 사례: 세션 키 -세션 키를 사용하면 dApp이 범위가 지정된 권한(시간 창과 허용된 대상 컨트랙트 집합) 내에서 EOA를 대신하여 트랜잭션을 실행할 수 있습니다. 이는 빈번한 온체인 상호작용이 그렇지 않으면 반복적인 지갑 승인을 요구하게 되는 dApp에 유용합니다. +세션 키를 사용하면 dApp이 EOA를 대신하여 범위가 지정된 권한(시간 창 및 허용되는 대상 계약 세트) 내에서 트랜잭션을 실행할 수 있습니다. 이는 빈번한 온체인 상호 작용이 반복적인 지갑 승인을 필요로 하는 dApp에 유용합니다. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; /// @title SessionKeyExecutor -/// @notice Delegate contract that grants scoped, time-limited access to a session key +/// @notice 세션 키에 범위가 지정된 시간 제한 액세스 권한을 부여하는 위임 계약 contract SessionKeyExecutor { struct Session { address key; @@ -204,7 +204,7 @@ contract SessionKeyExecutor { mapping(address => Session) public sessions; mapping(address => mapping(address => bool)) public allowedTargets; - /// @notice Register a session key with scoped permissions + /// @notice 범위가 지정된 권한으로 세션 키 등록 function startSession( address key, uint256 validUntil, @@ -223,7 +223,7 @@ contract SessionKeyExecutor { } } - /// @notice Execute a call using the session key + /// @notice 세션 키를 사용하여 호출 실행 function executeAsSessionKey( address owner, address target, @@ -232,40 +232,40 @@ contract SessionKeyExecutor { ) external { Session storage session = sessions[owner]; - require(msg.sender == session.key, "not session key"); - require(block.timestamp <= session.validUntil, "session expired"); - require(allowedTargets[owner][target], "target not allowed"); + require(msg.sender == session.key, "세션 키가 아님"); + require(block.timestamp <= session.validUntil, "세션 만료됨"); + require(allowedTargets[owner][target], "대상이 허용되지 않음"); uint256 beforeBalance = owner.balance; (bool success,) = target.call{value: value}(data); - require(success, "call failed"); + require(success, "호출 실패"); session.spent += owner.balance - beforeBalance; - require(session.spent <= session.spendingLimit, "budget exceeded"); + require(session.spent <= session.spendingLimit, "예산 초과"); } - /// @notice Revoke the active session + /// @notice 활성 세션 해지 function revokeSession() external { delete sessions[msg.sender]; } } ``` -## 중요 고려 사항 +## 중요한 고려 사항 -- **지속적인 위임**: 위임은 EOA가 명시적으로 변경하거나 해제할 때까지 지속됩니다. 단일 트랜잭션에 국한되지 않습니다. -- **가스 비용**: EIP-7702 트랜잭션은 권한 부여 처리로 인해 기본 가스가 약간 더 높지만, 위임이 여러 호출을 일괄 처리할 때 상쇄됩니다. -- **감사받은 위임 사용**: 악의적인 위임 컨트랙트는 EOA의 자산을 탈취할 수 있습니다. 감사받은 컨트랙트에만 위임하세요. +- **지속적인 위임**: 위임은 EOA가 명시적으로 변경하거나 지울 때까지 유지됩니다. 단일 트랜잭션에 국한되지 않습니다. +- **가스 비용**: EIP-7702 트랜잭션은 권한 부여 처리로 인해 기본 가스 비용이 약간 높지만, 위임자가 여러 호출을 일괄 처리할 때 상쇄됩니다. +- **감사된 위임자 사용**: 악의적인 위임 계약은 EOA의 자산을 소진할 수 있습니다. 감사된 계약에만 위임하십시오. -## 핵심 요점 +## 주요 내용 -- EIP-7702를 사용하면 EOA가 새로운 계정 유형으로 마이그레이션하지 않고도 스마트 컨트랙트 로직을 실행할 수 있습니다. -- Stable에서 EIP-7702는 기존 EOA에서 일괄 결제, 지출 한도, 범위가 지정된 세션 키를 가능하게 합니다. -- 위임은 명시적으로 변경될 때까지 지속됩니다. 항상 감사받은 위임 컨트랙트를 사용하세요. +- EIP-7702는 EOA가 새 계정 유형으로 마이그레이션하지 않고도 스마트 계약 로직을 실행할 수 있도록 합니다. +- Stable에서 EIP-7702는 기존 EOA에 일괄 결제, 지출 한도 및 범위가 지정된 세션 키를 활성화합니다. +- 위임은 명시적으로 변경될 때까지 유지됩니다. 항상 감사된 위임 계약을 사용하십시오. -## 다음 추천 +## 다음 권장 사항 -- [**구독 및 수금**](/ko/how-to/subscribe-and-collect) — SubscriptionManager를 사용하여 반복 구독 결제에 EIP-7702를 적용합니다. -- [**EIP-7702 개념**](/ko/explanation/eip-7702) — 배포하기 전에 위임 모델을 이해하세요. -- [**EIP-7702 레퍼런스**](/ko/reference/eip-7702-api) — `0x04` 트랜잭션 형식과 권한 부여 필드를 찾아보세요. +- [**구독 및 수집**](/ko/how-to/subscribe-and-collect): SubscriptionManager를 사용하여 EIP-7702를 정기 구독 결제에 적용합니다. +- [**EIP-7702 개념**](/ko/explanation/eip-7702): 위임 모델을 배포하기 전에 이해하십시오. +- [**EIP-7702 참조**](/ko/reference/eip-7702-api): `0x04` 트랜잭션 형식 및 권한 부여 필드를 찾아보십시오. diff --git a/docs/pages/ko/how-to/build-mpp-endpoint.mdx b/docs/pages/ko/how-to/build-mpp-endpoint.mdx index 8d38282..3d9227a 100644 --- a/docs/pages/ko/how-to/build-mpp-endpoint.mdx +++ b/docs/pages/ko/how-to/build-mpp-endpoint.mdx @@ -1,50 +1,50 @@ --- source_path: how-to/build-mpp-endpoint.mdx -source_sha: 6aff0597391159c025c805e5a95e17a1e9373acc +source_sha: d7b857d878cd4ce2044c0cb7796cfe8e2a7aae29 title: "Stable에서 MPP 엔드포인트 구축하기" -description: "viem을 기반으로 세 가지 커스텀 메서드 훅을 작성하여 MPP의 HTTP 402 흐름을 통해 Stable에서 USDT0 결제를 수락합니다." +description: "viem에 대해 세 가지 사용자 정의 메서드 훅을 작성하여 MPP의 HTTP 402 흐름을 통해 Stable에서 USDT0 결제를 수락합니다." diataxis: "how-to" --- # Stable에서 MPP 엔드포인트 구축하기 -이 가이드는 Stable에서 USDT0를 위한 커스텀 [MPP](/ko/explanation/mpp) 결제 메서드를 작성하고 MPP로 보호되는 엔드포인트를 제공하는 과정을 설명합니다. 구매자는 [ERC-3009](/ko/explanation/erc-3009) `transferWithAuthorization`에 서명하고, 서버는 `mppx`의 `verify()` 훅을 통해 이를 검증하며, 정산은 여러분이 제어하는 별도의 단계에서 이루어집니다. +이 가이드는 Stable에서 USDT0에 대한 사용자 정의 [MPP](/ko/explanation/mpp) 결제 메서드를 작성하고 MPP 게이트 엔드포인트를 제공하는 과정을 안내합니다. 구매자는 [ERC-3009](/ko/explanation/erc-3009) `transferWithAuthorization`에 서명하고, 서버는 `mppx`의 `verify()` 훅을 통해 이를 검증하며, 결제는 사용자가 제어하는 별도의 단계에서 이루어집니다. :::note -**개념:** MPP가 무엇이며 x402와 어떤 관련이 있는지는 [Machine Payments Protocol (MPP)](/ko/explanation/mpp)를 참고하세요. x402에 해당하는 내용은 [호출당 과금 API 구축하기](/ko/how-to/build-pay-per-call)를 참고하세요. +**개념:** MPP가 무엇이며 x402와 어떤 관련이 있는지 알아보려면 [기계 결제 프로토콜 (MPP)](/ko/explanation/mpp)을 참조하세요. x402에 해당하는 내용은 [호출당 지불 API 구축하기](/ko/how-to/build-pay-per-call)를 참조하세요. ::: :::note -이 예제는 Stable 메인넷을 사용합니다. 테스트할 때는 소액을 사용하세요. +이 예시는 Stable 메인넷을 사용합니다. 테스트 시 적은 금액을 사용하세요. ::: -## 무엇을 만들 것인가 +## 구축할 내용 -`402 Payment Required`와 MPP `WWW-Authenticate` 챌린지를 반환하고, `Authorization` 헤더에 담긴 서명된 자격 증명을 수락하여 이를 검증하고, USDT0에서 `transferWithAuthorization`을 정산한 후, `Payment-Receipt` 헤더와 함께 응답을 반환하는 HTTP 엔드포인트입니다. +MPP `WWW-Authenticate` 챌린지와 함께 `402 Payment Required`를 반환하고, `Authorization` 헤더에 서명된 자격 증명을 수락하고, 이를 검증하고, USDT0에서 `transferWithAuthorization`을 결제하고, `Payment-Receipt` 헤더와 함께 응답을 반환하는 HTTP 엔드포인트입니다. ```text -step 1. Client: GET /weather (no Authorization header) - Server: 402 Payment Required +step 1. 클라이언트: GET /weather (Authorization 헤더 없음) + 서버: 402 Payment Required WWW-Authenticate: Payment realm="...", challenges="[...usdt0-stable charge for $0.001...]" -step 2. Client signs an ERC-3009 authorization with their viem account +step 2. 클라이언트는 viem 계정으로 ERC-3009 승인에 서명합니다. -step 3. Client: GET /weather + Authorization header containing the serialized credential - Server: verify() validates the EIP-712 signature - Server: settle() submits transferWithAuthorization on Stable - (~700ms block confirmation) - Server: 200 OK { weather: "sunny" } +step 3. 클라이언트: GET /weather + 직렬화된 자격 증명이 포함된 Authorization 헤더 + 서버: verify()는 EIP-712 서명을 검증합니다. + 서버: settle()은 Stable에서 transferWithAuthorization을 제출합니다. + (~700ms 블록 확인) + 서버: 200 OK { weather: "sunny" } Payment-Receipt: reference="0x8f3a...", status="success" -step 4. Verify settlement on Stablescan +step 4. Stablescan에서 결제 확인 https://stablescan.xyz/tx/0x8f3a... ``` -## 사전 준비 +## 전제 조건 -- Stable에 자금이 있는 USDT0 지갑. [Faucet 사용하기](/ko/how-to/use-faucet) 또는 [USDT0 옮기기](/ko/tutorial/send-usdt0)를 참고하세요. -- `mppx`, `viem`, `zod`가 설치된 Node 20+. -- Stable의 판매자 계정(EOA). 기본 정산 경로에서는 판매자가 USDT0로 가스를 지불합니다. [Gas Waiver](#alternative-settle-through-the-gas-waiver) 섹션에서는 가스가 없는 변형을 보여줍니다. +- Stable에 자금을 지원받은 USDT0 지갑. [Faucet 사용하기](/ko/how-to/use-faucet) 또는 [USDT0 이동하기](/ko/tutorial/send-usdt0)를 참조하세요. +- `mppx`, `viem`, `zod`가 설치된 Node 20 이상. +- Stable의 판매자 계정 (EOA). 기본 결제 경로의 경우 판매자는 USDT0으로 가스비를 지불합니다. [대안: Gas Waiver를 통한 결제](#alternative-settle-through-the-gas-waiver) 섹션은 가스비 없는 버전을 보여줍니다. ```bash npm install mppx viem zod express @@ -52,7 +52,7 @@ npm install mppx viem zod express ## 1. 공유 스키마 정의 -`Method.from()`은 의도(intent)와 요청(Challenge) 및 자격 증명 페이로드에 대한 스키마를 선언합니다. 클라이언트와 서버 모두 이 정의를 임포트합니다. +`Method.from()`은 의도와 요청(Challenge) 및 자격 증명 페이로드에 대한 스키마를 선언합니다. 클라이언트와 서버 모두 이 정의를 가져옵니다. ```typescript // src/method.ts @@ -63,12 +63,12 @@ import { parseUnits } from "viem"; export const USDT0_STABLE = "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"; export const CHAIN_ID = 988; -// Request: the Challenge payload the server sends to the client. +// Request: 서버가 클라이언트에 보내는 Challenge 페이로드. const zRequest = z.pipe( z.object({ chainId: z.literal(CHAIN_ID), asset: z.literal(USDT0_STABLE), - amount: z.string(), // human-readable, e.g. "0.001" + amount: z.string(), // 사람이 읽을 수 있는 형식, 예: "0.001" decimals: z.literal(6), payTo: z.string().regex(/^0x[a-fA-F0-9]{40}$/), validAfter: z.number().int().nonnegative(), @@ -77,14 +77,14 @@ const zRequest = z.pipe( }), z.transform(({ amount, decimals, ...rest }) => ({ ...rest, - amount: parseUnits(amount, decimals).toString(), // atomic units + amount: parseUnits(amount, decimals).toString(), // 원자 단위 })), ); -// Credential payload: what the client returns after signing. +// Credential 페이로드: 서명 후 클라이언트가 반환하는 내용. const zPayload = z.object({ from: z.string().regex(/^0x[a-fA-F0-9]{40}$/), - signature: z.string().regex(/^0x[a-fA-F0-9]{130}$/), // 65-byte hex + signature: z.string().regex(/^0x[a-fA-F0-9]{130}$/), // 65-바이트 16진수 }); export const usdt0Stable = Method.from({ @@ -93,7 +93,7 @@ export const usdt0Stable = Method.from({ schema: { request: zRequest, credential: { payload: zPayload } }, }); -// EIP-712 domain + type, used by both client and server. +// 클라이언트와 서버 모두에서 사용되는 EIP-712 도메인 + 유형. export const EIP712_DOMAIN = { name: "USDT0", version: "1", @@ -118,9 +118,9 @@ usdt0Stable.name === "usdt0-stable" usdt0Stable.intent === "charge" ``` -## 2. 서버: 자격 증명 검증 +## 2. 서버: 자격 증명 확인 -`Method.toServer`는 `verify()`를 `mppx`에 연결합니다. 이 함수는 역직렬화된 자격 증명(챌린지 + 페이로드)을 받아서 유효하지 않은 증명에 대해 throw하거나 `Receipt`를 반환해야 합니다. +`Method.toServer`는 `verify()`를 `mppx`에 연결합니다. 함수는 역직렬화된 자격 증명 (챌린지 + 페이로드)을 수신하며, 유효하지 않은 증명이 있으면 예외를 발생시키거나 `Receipt`를 반환해야 합니다. ```typescript // src/server-method.ts @@ -153,9 +153,9 @@ export const usdt0StableServer = Method.toServer(usdt0Stable, { signature: signature as `0x${string}`, }); - if (!valid) throw new Error("Invalid ERC-3009 signature"); + if (!valid) throw new Error("유효하지 않은 ERC-3009 서명"); - // The Receipt's reference is filled in with the tx hash after settle(). + // Receipt의 참조는 settle() 후 tx 해시로 채워집니다. return Receipt.from({ method: usdt0Stable.name, reference: "pending", @@ -176,16 +176,16 @@ export const usdt0StableServer = Method.toServer(usdt0Stable, { ``` :::warning -`verify()`는 서명을 확인하지만 nonce의 고유성이나 권한이 이미 사용되었는지 여부는 확인하지 않습니다. 체인은 제출 시점에 두 가지를 모두 강제합니다. `transferWithAuthorization`은 이미 사용된 nonce에 대해 revert됩니다. 정산 단계는 이러한 revert를 서버가 클라이언트에 노출할 수 있는 오류로 변환합니다. +`verify()`는 서명을 확인하지만, nonce의 고유성이나 권한이 이미 사용되었는지 여부는 확인하지 않습니다. 체인은 제출 시 두 가지를 모두 강제합니다: `transferWithAuthorization`는 사용된 nonce에 대해 되돌립니다. settlement 단계는 이러한 되돌림을 서버가 클라이언트에 전달할 수 있는 오류로 변환합니다. ::: -## 3. 정산: `transferWithAuthorization` 제출 +## 3. 결제: `transferWithAuthorization` 제출 -정산은 의도적으로 `verify()`와 분리되어 있습니다. `verify()`가 반환된 후, 여러분의 운영 모델에 맞는 경로를 통해 권한을 온체인에 제출합니다. 권장 순서대로 세 가지 옵션이 있습니다. +결제는 의도적으로 `verify()`와 분리되어 있습니다. `verify()`가 반환된 후, 운영 모델에 맞는 경로를 통해 승인을 온체인으로 제출합니다. 세 가지 옵션은 권장 순서입니다. -### 기본: 서버가 직접 제출 +### 기본값: 서버가 직접 제출 -판매자의 EOA가 서명된 권한과 함께 `transferWithAuthorization`을 USDT0에 제출합니다. 판매자는 USDT0(Stable의 네이티브 가스 토큰)로 가스를 지불하므로, 관리해야 할 별도의 가스 토큰 잔액이 없습니다. +판매자의 EOA가 서명된 승인과 함께 `transferWithAuthorization`을 USDT0에 제출합니다. 판매자는 USDT0(Stable의 기본 가스 토큰)으로 가스비를 지불하므로 별도의 가스 토큰 잔액을 관리할 필요가 없습니다. ```typescript // src/settle.ts @@ -253,9 +253,9 @@ export async function settleDirect(credential: { { txHash: "0x8f3a1b2c..." } ``` -### 대안: Gas Waiver를 통한 정산 +### 대안: Gas Waiver를 통한 결제 -Stable의 [Gas Waiver](/ko/how-to/integrate-gas-waiver)를 사용하여 내부 트랜잭션을 `gasPrice = 0`으로 제출합니다. 판매자는 여전히 래핑 트랜잭션에 서명하지만 가스는 지불하지 않습니다. Waiver Server API 키가 필요합니다. +Stable의 [Gas Waiver](/ko/how-to/integrate-gas-waiver)를 사용하여 `gasPrice = 0`으로 내부 트랜잭션을 제출합니다. 판매자는 래핑 트랜잭션에 계속 서명하지만 가스비를 지불하지 않습니다. Waiver Server API 키가 필요합니다. ```typescript // src/settle-waiver.ts @@ -263,7 +263,7 @@ import { encodeFunctionData } from "viem"; import { USDT0_STABLE } from "./method"; import { USDT0_ABI } from "./settle"; -const WAIVER_SERVER = "https://waiver.stable.xyz"; // mainnet endpoint +const WAIVER_SERVER = "https://waiver.stable.xyz"; // 메인넷 엔드포인트 export async function settleViaWaiver( credential: { challenge: { request: any }; payload: { from: string; signature: string } }, @@ -280,7 +280,7 @@ export async function settleViaWaiver( const lines = (await res.text()).trim().split("\n"); const result = JSON.parse(lines[0]); - if (!result.success) throw new Error(`Settle failed: ${result.error?.message}`); + if (!result.success) throw new Error(`결제 실패: ${result.error?.message}`); return { txHash: result.txHash }; } ``` @@ -289,17 +289,17 @@ export async function settleViaWaiver( { txHash: "0x8f3a1b2c..." } ``` -게시 전에 서명된 내부 트랜잭션(`gasPrice: 0`, 인코딩된 `transferWithAuthorization` 호출)을 구성하는 방법은 [Gas waiver 프로토콜](/ko/reference/gas-waiver-api)을 참고하세요. +서명된 내부 트랜잭션(`gasPrice: 0`, 인코딩된 `transferWithAuthorization` 호출)을 게시하기 전에 빌드하는 방법에 대한 자세한 내용은 [Gas waiver protocol](/ko/reference/gas-waiver-api)을 참조하세요. -### 대안: x402 facilitator에 위임 +### 대안: x402 통신자에게 넘기기 -이미 x402 facilitator 통합([Semantic Pay](https://docs.semanticpay.io) 또는 [Heurist](https://docs.heurist.ai/x402-products/facilitator))을 운영 중이라면, 이를 정산 대상으로 재사용할 수 있습니다. `/settle`에 `paymentPayload`를 POST하면 facilitator가 온체인 호출을 제출합니다. +이미 x402 통신자 통합([Semantic Pay](https://docs.semanticpay.io) 또는 [Heurist](https://docs.heurist.ai/x402-products/facilitator))을 운영하고 있다면, 이를 결제 대상으로 재사용할 수 있습니다. `/settle`에 `paymentPayload`를 POST하면 통신자가 온체인 호출을 제출합니다. -정확한 `paymentPayload` 형태는 x402 미들웨어 내부에 있으며 와이어 수준에서 명시되지 않습니다. 가장 간단한 경로는 facilitator의 자체 SDK를 사용하여 페이로드를 구성하거나, 위의 직접 제출 경로를 고수하는 것입니다. facilitator는 MPP를 이해할 필요가 없으며, `transferWithAuthorization` 필드만 보게 됩니다. +정확한 `paymentPayload` 형식은 x402 미들웨어 내부이며 와이어 레벨에서 지정되지 않습니다. 가장 간단한 방법은 통신자의 자체 SDK를 사용하여 페이로드를 구축하거나 위에서 설명한 직접 제출 경로를 유지하는 것입니다. 통신자는 MPP를 말할 필요가 없습니다. `transferWithAuthorization` 필드만 봅니다. ## 4. 클라이언트: 자격 증명 서명 -`Method.toClient`는 `createCredential()`을 `mppx`에 연결합니다. 클라이언트는 Challenge를 읽고, 에이전트의 viem 계정으로 EIP-712 권한에 서명하며, 자격 증명을 직렬화합니다. +`Method.toClient`는 `createCredential()`을 `mppx`에 연결합니다. 클라이언트는 챌린지를 읽고, 에이전트의 viem 계정으로 EIP-712 승인에 서명하며, 자격 증명을 직렬화합니다. ```typescript // src/client-method.ts @@ -343,12 +343,12 @@ export function createUsdt0StableClient(privateKey: `0x${string}`) { ``` ```text -"eyJjaGFsbGVuZ2UiOnsi..." // base64-serialized credential, ~600 bytes +"eyJjaGFsbGVuZ2UiOnsi..." // base64 직렬화된 자격 증명, ~600바이트 ``` -## 5. 서버 연결하기 +## 5. 서버 연결 -`mppx`의 Express 미들웨어를 사용하여 Challenge를 발급하고, 들어오는 `Authorization` 헤더를 파싱하고, `verify()`를 실행하고, 정산 함수를 호출하고, `Payment-Receipt` 헤더를 내보냅니다. +`mppx`의 Express 미들웨어를 사용하여 챌린지를 발행하고, 들어오는 `Authorization` 헤더를 파싱하고, `verify()`를 실행하고, 결제 함수를 호출하고, `Payment-Receipt` 헤더를 내보냅니다. ```typescript // src/server.ts @@ -392,23 +392,23 @@ app.get( ); app.listen(PORT, () => { - console.log(`MPP server listening on http://localhost:${PORT}`); + console.log(`MPP 서버가 http://localhost:${PORT}에서 수신 중입니다`); }); ``` ```text -MPP server listening on http://localhost:4022 +MPP 서버가 http://localhost:4022에서 수신 중입니다 ``` -## 6. 전체 흐름을 끝까지 실행하기 +## 6. 전체 흐름 실행 -서버를 시작하고, Challenge를 확인하고, 클라이언트를 실행한 후, 정산을 확인합니다. +서버를 시작하고, 챌린지를 확인하고, 클라이언트를 실행하고, 결제를 확인합니다. :::warning -다음 단계는 Stable 메인넷에서 실제 USDT0 결제를 정산합니다. 전용 지갑과 소액을 사용하세요. +다음 단계는 Stable 메인넷에서 실제 USDT0 결제를 진행합니다. 전용 지갑과 소액을 사용하세요. ::: -### Challenge 확인하기 +### 챌린지 확인 ```bash curl -i http://localhost:4022/weather @@ -434,7 +434,7 @@ const client = Mppx.create({ }); const res = await fetch("http://localhost:4022/weather", { - // mppx wraps fetch with the 402 retry loop: + // mppx는 fetch를 402 재시도 루프와 함께 래핑합니다: ...client.fetchOptions(), }); @@ -451,18 +451,18 @@ npx tsx src/client.ts Payment-Receipt: reference="0x8f3a1b2c...", status="success", timestamp="2026-06-01T12:34:56.000Z" ``` -### Stablescan에서 확인하기 +### Stablescan에서 확인 -`https://stablescan.xyz/tx/0x8f3a1b2c...`를 열고 `transferWithAuthorization`이 여러분의 `PAY_TO` 주소로 정산되었는지 확인하세요. +`https://stablescan.xyz/tx/0x8f3a1b2c...`를 열고 `transferWithAuthorization`이 `PAY_TO` 주소로 결제되었는지 확인합니다. ## 방금 한 일 -- 구매자 측에서 관리할 가스 토큰 잔액 없이, 달러로 표시된 USDT0로 결제했습니다. +- USDT0으로 달러화된 결제를 구매자 측에서 가스 토큰 잔액을 관리할 필요 없이 지불했습니다. - 클라이언트-서버 홉에서 MPP의 `WWW-Authenticate` / `Authorization` / `Payment-Receipt` 와이어 형식을 사용했습니다. -- 동일한 HTTP 요청 수명 주기 내에서 Stable의 `transferWithAuthorization`으로 정산했습니다(~700ms 블록 타임). +- 동일한 HTTP 요청 수명 주기(~700ms 블록 시간)에서 `transferWithAuthorization`으로 Stable에서 결제를 완료했습니다. ## 다음 권장 사항 -- [**MPP 개념**](/ko/explanation/mpp) — MPP가 x402와 어떤 관련이 있는지, 그리고 다른 의도들이 어떻게 생겼는지 읽어보세요. -- [**MPP 세션**](/ko/explanation/mpp-sessions) — 요청당 정산이 너무 비쌀 때 오프체인 바우처로 마이크로페이먼트를 스트리밍하세요. -- [**Facilitators**](/ko/reference/agentic-facilitators) — 직접 제출하는 대신 Semantic Pay나 Heurist를 정산 대상으로 사용하세요. +- [**MPP 개념**](/ko/explanation/mpp): MPP가 x402와 어떤 관련이 있는지, 다른 의도가 어떻게 보이는지 알아보세요. +- [**MPP 세션**](/ko/explanation/mpp-sessions): 요청당 결제가 너무 비쌀 때 오프체인 바우처로 마이크로 결제를 스트리밍합니다. +- [**통신자**](/ko/reference/agentic-facilitators): 직접 제출하는 대신 Semantic Pay 또는 Heurist를 결제 대상으로 사용합니다. diff --git a/docs/pages/ko/how-to/build-p2p-payments.mdx b/docs/pages/ko/how-to/build-p2p-payments.mdx index 1c0b5a6..564b67b 100644 --- a/docs/pages/ko/how-to/build-p2p-payments.mdx +++ b/docs/pages/ko/how-to/build-p2p-payments.mdx @@ -1,26 +1,26 @@ --- source_path: how-to/build-p2p-payments.mdx -source_sha: cb21475c28be41c86374be5066e7b1c5c5261c56 -title: "P2P 결제 배우기" -description: "Stable에서 P2P 결제 앱을 구축합니다. 지갑을 생성하고, 잔액을 확인하고, USDT0를 보내고 받고, 거래 내역을 조회합니다." +source_sha: 57dc356587b68955bf9eac544e7b2bcf1b337bee +title: "P2P 결제 학습" +description: "Stable에서 P2P 결제 앱을 구축합니다. 지갑을 생성하고, 잔액을 확인하고, USDT0을 보내고 받으며, 거래 내역을 쿼리합니다." diataxis: "how-to" --- -# P2P 결제 배우기 +# P2P 결제 학습 -이 가이드는 Stable에서 P2P 결제 애플리케이션을 구축하는 과정을 안내합니다. 이 앱은 결제의 전체 수명 주기를 처리합니다. 발신자는 USDT0를 직접 전송하고, 수신자는 들어오는 결제를 실시간으로 감지하며, 양쪽 모두 자신의 거래 내역을 조회할 수 있습니다. 모바일 앱이든 웹 체크아웃이든 백엔드 서비스든, 모든 지갑이나 결제 인터페이스와 동일한 아키텍처입니다. +이 가이드는 Stable에서 P2P 결제 애플리케이션을 구축하는 과정을 안내합니다. 이 앱은 전체 결제 수명 주기를 처리합니다. 즉, 발신자는 USDT0을 직접 전송하고, 수신자는 실시간으로 들어오는 결제를 감지하며, 양측 모두 자신의 거래 내역을 쿼리할 수 있습니다. 모바일 앱, 웹 결제, 백엔드 서비스 등 모든 지갑 또는 결제 인터페이스와 동일한 아키텍처입니다. -미들웨어도 중개자도 없습니다. 개념적 개요는 [P2P 결제](/ko/reference/p2p-payments)를 참고하세요. ABI 작업을 건너뛰고 몇 줄로 작동하는 `transfer`에 도달하려면 [Stable SDK](/ko/explanation/sdk-overview)를 사용하세요. +미들웨어, 중개자 없음. 개념적 개요는 [P2P 결제](/ko/reference/p2p-payments)를 참조하십시오. ABI 작업을 건너뛰고 몇 줄 안에 작동하는 `transfer`를 사용하려면 [Stable SDK](/ko/explanation/sdk-overview)를 사용하십시오. ## 구축할 내용 -최소한의 결제 앱을 구성하는 다섯 개의 스크립트: +최소한의 결제 앱을 구성하는 다섯 가지 스크립트: -- `wallet.ts` — 지갑 생성 또는 복원. -- `getBalance.ts` — 현재 USDT0 잔액 조회. -- `send.ts` — 다른 주소로 USDT0 전송. -- `receive.ts` — 들어오는 결제를 실시간으로 감시. -- `history.ts` — 특정 주소의 과거 Transfer 이벤트 조회. +- `wallet.ts`: 지갑을 생성하거나 복원합니다. +- `getBalance.ts`: 현재 USDT0 잔액을 쿼리합니다. +- `send.ts`: 다른 주소로 USDT0을 보냅니다. +- `receive.ts`: 실시간으로 들어오는 결제를 모니터링합니다. +- `history.ts`: 주소에 대한 과거 전송 이벤트를 쿼리합니다. ### 데모 @@ -39,10 +39,10 @@ step 4. Bob receives payment (real-time event) tx: 0x8f3a...2d41 ``` -## 사전 요구 사항 +## 전제 조건 - Node.js 20 이상. -- 테스트넷 USDT0가 있는 개인 키 (지갑에 자금을 충전하려면 [빠른 시작](/ko/tutorial/quick-start) 참고). +- 테스트넷 USDT0이 있는 프라이빗 키 (지갑 자금 조달을 위해 [빠른 시작](/ko/tutorial/quick-start) 참조). ## 프로젝트 설정 @@ -55,7 +55,7 @@ npm init -y && npm install ethers dotenv added 2 packages, audited 3 packages in 1s ``` -모든 스크립트가 공유하는 `config.ts`를 생성합니다: +모든 스크립트에서 공유되는 `config.ts` 생성: ```typescript // config.ts @@ -71,24 +71,24 @@ export const provider = new ethers.JsonRpcProvider(STABLE_RPC); ## 1. 지갑 생성 또는 복원 -지갑은 시드 문구에서 파생된 키 쌍입니다. 새 사용자를 위해 하나를 생성하고 백업할 수 있도록 문구를 반환합니다. 돌아온 사용자는 동일한 문구로 지갑을 복원합니다. +지갑은 시드 구문에서 파생된 키 쌍입니다. 새 사용자를 위해 지갑을 생성하고 구문을 반환하여 백업할 수 있도록 합니다. 기존 사용자는 동일한 구문에서 지갑을 복원합니다. ```typescript // wallet.ts import { ethers } from "ethers"; import { provider } from "./config"; -/** Create a new wallet for a new user. */ +/** 새 사용자를 위한 새 지갑을 생성합니다. */ export function createWallet() { const wallet = ethers.Wallet.createRandom(provider); return { wallet, address: wallet.address, - seedPhrase: wallet.mnemonic!.phrase, // display to user for backup + seedPhrase: wallet.mnemonic!.phrase, // 백업을 위해 사용자에게 표시 }; } -/** Restore a wallet from a seed phrase (returning user). */ +/** 시드 구문에서 지갑을 복원합니다 (기존 사용자). */ export function restoreWallet(seedPhrase: string) { const wallet = ethers.Wallet.fromPhrase(seedPhrase, provider); return { wallet, address: wallet.address }; @@ -112,7 +112,7 @@ Seed phrase: liberty shoot ... (12 words) ## 2. 잔액 확인 -USDT0는 Stable의 네이티브 자산이므로, 잔액 조회는 Ethereum의 ETH와 정확히 동일하게 작동합니다. 네이티브 잔액은 소수점 18자리이며, 표시할 때는 `formatEther`를 사용합니다. +USDT0은 Stable의 기본 자산이므로 잔액 쿼리는 이더리움의 ETH와 똑같이 작동합니다. 기본 잔액은 18자리 소수이며, 표시를 위해 `formatEther`를 사용합니다. ```typescript // getBalance.ts @@ -141,7 +141,7 @@ Balance: 0.01 USDT0 ## 3. 결제 전송 -발신자는 전송을 직접 서명하고 제출합니다. Stable에서 USDT0는 네이티브 자산이므로, 단순한 value 전송이 가장 저렴한 경로입니다(21,000 가스). 이는 모든 결제 앱에서 "보내기"와 동일한 코드 경로입니다. +보내는 사람은 직접 이체를 서명하고 제출합니다. Stable에서 USDT0은 기본 자산이므로 간단한 가치 이체가 가장 저렴한 경로입니다 (21,000 가스). 이는 모든 결제 앱의 "보내기"와 동일한 코드 경로입니다. ```typescript // send.ts @@ -151,7 +151,7 @@ import { provider } from "./config"; export async function sendPayment( senderKey: string, recipient: string, - amount: string // e.g. "0.001" for 0.001 USDT0 + amount: string // 예시: 0.001 USDT0의 경우 "0.001" ) { const wallet = new ethers.Wallet(senderKey, provider); const block = await provider.getBlock("latest"); @@ -161,7 +161,7 @@ export async function sendPayment( to: recipient, value: ethers.parseEther(amount), maxFeePerGas: baseFee * 2n, - maxPriorityFeePerGas: 0n, // always 0 on Stable + maxPriorityFeePerGas: 0n, // Stable에서는 항상 0 }); console.log("Payment sent:", tx.hash); @@ -186,9 +186,9 @@ Payment sent: 0x8f3a...2d41 Payment settled ``` -## 4. 결제 실시간 수신 +## 4. 실시간으로 결제 수신 -수신자는 들어오는 `Transfer` 이벤트를 수신 대기합니다. 이는 전통적인 결제 앱의 푸시 알림과 동일합니다. Stable에서는 단일 슬롯 완결성(single-slot finality) 덕분에 수신자가 거의 즉시 결제를 확인할 수 있습니다. +수신자는 들어오는 `Transfer` 이벤트를 수신합니다. 이는 기존 결제 앱의 푸시 알림과 동일합니다. Stable에서는 단일 슬롯 완결성 덕분에 수신자는 결제를 거의 즉시 확인합니다. ```typescript // receive.ts @@ -233,12 +233,12 @@ Payment received: ``` :::note -USDT0는 Stable에서 네이티브 자산이면서 동시에 ERC-20 토큰이기 때문에, 네이티브 전송(value 전송)도 USDT0 ERC-20 컨트랙트에서 `Transfer` 이벤트를 발생시킵니다. 단일 이벤트 리스너로 두 가지 전송 방식을 모두 처리할 수 있습니다. +기본 전송(값 전송)은 Stable에서 USDT0이 기본 자산이자 ERC-20 토큰이므로 USDT0 ERC-20 계약에 `Transfer` 이벤트도 발행합니다. 단일 이벤트 리스너가 두 전송 방법을 모두 다룹니다. ::: -## 5. 거래 내역 조회 +## 5. 거래 내역 쿼리 -과거 `Transfer` 이벤트를 조회하여 은행 명세서나 모든 결제 앱의 거래 목록과 같은 거래 내역 화면을 구성합니다. +과거 `Transfer` 이벤트를 쿼리하여 은행 명세서 또는 모든 결제 앱의 거래 목록과 같은 거래 내역 보기를 구축합니다. ```typescript // history.ts @@ -298,11 +298,11 @@ received 0.01 USDT0 0xFaucet... 0x22b1...3f09 ``` :::warning -넓은 블록 범위(수백만 개의 블록)를 스캔하면 타임아웃이 발생하고 RPC 속도 제한을 초과할 수 있습니다. 프로덕션 환경에서는 페이지네이션 방식의 내역 조회를 위해 [Stablescan Etherscan 호환 API](https://stablescan.xyz)를 사용하세요 — 모든 거래가 이미 인덱싱되어 있습니다. +넓은 블록 범위(수백만 블록)를 스캔하면 시간 초과가 발생하고 RPC 속도 제한을 초과할 수 있습니다. 프로덕션 환경의 경우 페이지별 내역 쿼리에 [Stablescan Etherscan-compatible API](https://stablescan.xyz)를 사용하십시오. 모든 트랜잭션은 이미 색인화되어 있습니다. ::: -## 다음 추천 +## 다음 권장 사항 -- [**구독 및 수금**](/ko/how-to/subscribe-and-collect) — EIP-7702 위임을 사용한 풀 기반 정기 구독. -- [**인보이스로 결제하기**](/ko/how-to/pay-with-invoice) — ERC-3009와 결정론적 nonce로 인보이스를 정산합니다. -- [**첫 USDT0 보내기**](/ko/tutorial/send-usdt0) — 기본적인 네이티브 vs. ERC-20 전송 흐름을 참고하세요. +- [**구독 및 수집**](/ko/how-to/subscribe-and-collect): EIP-7702 위임을 통한 풀 방식 정기 구독. +- [**인보이스로 결제**](/ko/how-to/pay-with-invoice): ERC-3009 및 결정적 논스를 사용하여 인보이스 정산. +- [**첫 USDT0 전송**](/ko/tutorial/send-usdt0): 기본 네이티브 대 ERC-20 전송 흐름 참조. diff --git a/docs/pages/ko/how-to/build-pay-per-call.mdx b/docs/pages/ko/how-to/build-pay-per-call.mdx index 1006d7d..250e312 100644 --- a/docs/pages/ko/how-to/build-pay-per-call.mdx +++ b/docs/pages/ko/how-to/build-pay-per-call.mdx @@ -1,43 +1,43 @@ --- source_path: how-to/build-pay-per-call.mdx -source_sha: c51728a92a4f9ff299c86445d2b6b0f31cbe5d8c -title: "유료 호출 API 구축하기" -description: "Stable에서 x402를 사용해 요청별 USDT0 결제로 HTTP 엔드포인트를 수익화하세요. 서버 설정, 클라이언트 통합, 지출 제어를 다룹니다." +source_sha: 37e3f619a2a824cd05b1ff780d568b1b412d01ad +title: "종량제 API 구축" +description: "Stable에서 x402를 사용하여 요청당 USDT0 지불로 HTTP 엔드포인트를 수익화합니다. 서버 설정, 클라이언트 통합 및 지출 관리." diataxis: "how-to" --- -# 유료 호출 API 구축하기 +# 종량제 API 구축 -이 가이드는 x402로 API 엔드포인트를 수익화하는 과정을 안내합니다. 서버는 결제 핸들러를 추가하고, 클라이언트는 요청마다 비용을 지불하며, 정산은 HTTP 라이프사이클 내에서 이루어집니다. +이 가이드는 x402를 사용하여 API 엔드포인트를 수익화하는 방법을 안내합니다. 서버는 지불 핸들러를 추가하고, 클라이언트는 요청당 지불하며, 결제는 HTTP 수명 주기 내에서 이루어집니다. :::note -**개념:** x402 프로토콜과 Stable에 적합한 이유는 [x402](/ko/explanation/x402)를 참고하세요. 상위 수준의 사용 사례 모델은 [유료 호출 API](/ko/reference/pay-per-call)를 참고하세요. +**개념:** x402 프로토콜과 Stable에 적합한 이유에 대해서는 [x402](/ko/explanation/x402)를 참조하십시오. 상위 수준 사용 사례 모델에 대해서는 [종량제 API](/ko/reference/pay-per-call)를 참조하십시오. ::: :::note -Semantic 퍼실리테이터는 현재 메인넷에서만 작동합니다. 이 가이드의 예제는 Stable 메인넷을 사용합니다. 테스트 시에는 소액만 사용하세요. +시맨틱 촉진자는 현재 메인넷에서만 작동합니다. 이 가이드의 예제는 Stable 메인넷을 사용합니다. 테스트할 때는 소액을 사용하십시오. ::: -## 무엇을 구축하는가 +## 구축할 내용 -서버가 `402 Payment Required`로 응답하고, 클라이언트가 요청마다 결제하며, 퍼실리테이터가 HTTP 라이프사이클 내에서 USDT0를 온체인으로 정산하는 유료 HTTP API입니다. +서버가 `402 Payment Required`로 응답하고, 클라이언트가 요청당 지불하며, 촉진자가 HTTP 수명 주기 내에서 온체인 USDT0을 결제하는 유료 HTTP API. ### 데모 ```text -step 1. Client: GET /weather (no payment) +step 1. Client: GET /weather (지불 없음) Server: 402 Payment Required PAYMENT-REQUIRED: { amount: "1000", asset: USDT0, network: eip155:988 } -step 2. Client signs ERC-3009 authorization +step 2. 클라이언트가 ERC-3009 승인에 서명합니다. -step 3. Client: GET /weather + PAYMENT-SIGNATURE header - Server: forwards to facilitator → transferWithAuthorization settles on-chain - (~700ms block confirmation) +step 3. Client: GET /weather + PAYMENT-SIGNATURE 헤더 + Server: 촉진자로 포워딩 → transferWithAuthorization 온체인 결제 + (~700ms 블록 확인) Server: 200 OK { weather: "sunny", temperature: 70 } PAYMENT-SETTLE-RESPONSE: { txHash: "0x8f3a...", paid: "0.001 USDT0" } -step 4. Verify settlement on Stablescan +step 4. Stablescan에서 결제 확인 https://stablescan.xyz/tx/0x8f3a... ``` @@ -46,7 +46,7 @@ step 4. Verify settlement on Stablescan **판매자 (서버):** ```typescript -// --- Server --- +// --- 서버 --- app.use(paymentMiddleware({ "GET /weather": { price: { amount: "1000", asset: USDT0 }, @@ -58,13 +58,13 @@ app.use(paymentMiddleware({ }, }, resourceServer)); -// Routes not listed in the config are not gated. +// 구성에 나열되지 않은 경로는 게이트되지 않습니다. ``` **구매자 (클라이언트):** ```typescript -// --- Client --- +// --- 클라이언트 --- account = new WalletAccountEvm(seedPhrase, { provider: RPC }); client = new x402Client(); fetchWithPayment = wrapFetchWithPayment(fetch, client); @@ -76,16 +76,16 @@ inferenceResponse = fetchWithPayment("https://api.example.com/inference", { body: JSON.stringify({ prompt: "Hello" }), }); -// For each paid request: -// 1. Initial request returns 402 with PAYMENT-REQUIRED header -// 2. Client signs ERC-3009 authorization with wallet -// 3. Client retries with PAYMENT-SIGNATURE header -// 4. Facilitator settles on-chain, server returns the response +// 각 유료 요청에 대해: +// 1. 초기 요청은 PAYMENT-REQUIRED 헤더와 함께 402를 반환합니다. +// 2. 클라이언트는 지갑으로 ERC-3009 승인에 서명합니다. +// 3. 클라이언트는 PAYMENT-SIGNATURE 헤더로 재시도합니다. +// 4. 촉진자가 온체인으로 결제하고, 서버는 응답을 반환합니다. ``` -## 판매자: 유료 엔드포인트 설정하기 +## 판매자: 유료 엔드포인트 설정 -판매자는 어떤 라우트가 결제를 요구하는지 정의하기 위해 x402 미들웨어를 추가합니다. 결제 없이 요청이 도착하면, 미들웨어는 `402 Payment Required`와 결제 조건으로 응답합니다. 유효한 결제 헤더가 있으면, 미들웨어는 이를 퍼실리테이터로 전달하고 퍼실리테이터가 서명을 검증한 뒤 결제를 온체인으로 정산합니다. 판매자는 가격과 수령 주소만 구성하면 되고, 검증과 정산은 퍼실리테이터가 처리합니다. +판매자는 x402 미들웨어를 추가하여 지불이 필요한 경로를 정의합니다. 지불 없이 요청이 도착하면 미들웨어는 `402 Payment Required`와 지불 조건을 응답합니다. 유효한 지불 헤더가 있으면 미들웨어는 서명을 확인하고 온체인에서 지불을 결제하는 촉진자에게 전달합니다. 판매자는 가격과 수신 주소만 구성하고, 촉진자가 확인 및 결제를 처리합니다. ```bash npm install express @x402/express @x402/evm @x402/core @@ -93,21 +93,21 @@ npm install express @x402/express @x402/evm @x402/core ### 가격 책정 -각 라우트는 결제 금액을 USDT0 기본 단위(소수점 6자리), 네트워크, 자금을 수령할 주소로 지정합니다. 예를 들어 `"1000"`은 `$0.001`이고 `"50000"`은 `$0.05`입니다. +각 경로는 USDT0 기본 단위(6 소수점)로 지불 금액, 네트워크 및 자금을 수신할 주소를 지정합니다. 예를 들어, `"1000"`은 `$0.001`과 같고 `"50000"`은 `$0.05`와 같습니다. ```typescript price: { - amount: "1000", // base units (6 decimals) - asset: USDT0_STABLE, // USDT0 contract address - extra: { name: "USDT0", version: "1", decimals: 6 }, // EIP-712 domain info + amount: "1000", // 기본 단위 (6 소수점) + asset: USDT0_STABLE, // USDT0 계약 주소 + extra: { name: "USDT0", version: "1", decimals: 6 }, // EIP-712 도메인 정보 } ``` -`extra` 필드(`name`, `version`, `decimals`)는 구매자 클라이언트가 EIP-712 서명을 구성하는 데 사용되며, 온체인 USDT0 컨트랙트와 일치해야 합니다. +`extra` 필드(`name`, `version`, `decimals`)는 구매자의 클라이언트가 EIP-712 서명 구성을 위해 사용하며 온체인 USDT0 계약과 일치해야 합니다. -### 라우트 구성 +### 경로 구성 -라우트는 `METHOD /path` 형식으로 매핑됩니다. 각 라우트는 허용되는 결제 스킴, 네트워크, 가격, 자금을 수령할 주소(`payTo`)를 지정합니다. `description`과 `mimeType` 필드는 구매자와 AI 에이전트가 엔드포인트가 제공하는 것을 발견하는 데 도움이 됩니다. 구성에 나열되지 않은 라우트는 게이트되지 않으며 일반 Express 라우트처럼 동작합니다. +경로는 `METHOD /path` 형식을 사용하여 매핑됩니다. 각 경로는 허용되는 지불 방식, 네트워크, 가격 및 자금을 수신할 주소(`payTo`)를 지정합니다. `description` 및 `mimeType` 필드는 구매자와 AI 에이전트가 엔드포인트가 제공하는 것을 발견하는 데 도움이 됩니다. 구성에 나열되지 않은 경로는 게이트되지 않으며 일반 Express 경로처럼 작동합니다. ```typescript // server.ts @@ -130,7 +130,7 @@ const app = express(); app.use( paymentMiddleware( { - // Example 1: Configure a paid GET route + // 예제 1: 유료 GET 경로 구성 "GET /weather": { accepts: [ { @@ -144,10 +144,10 @@ app.use( payTo: PAY_TO, }, ], - description: "Weather data", + description: "날씨 데이터", mimeType: "application/json", }, - // Example 2: Configure a paid POST route + // 예제 2: 유료 POST 경로 구성 "POST /inference": { accepts: [ { @@ -161,7 +161,7 @@ app.use( payTo: PAY_TO, }, ], - description: "AI inference endpoint", + description: "AI 추론 엔드포인트", mimeType: "application/json", }, }, @@ -178,27 +178,27 @@ app.post("/inference", (req, res) => { res.json({ result: `Inference result for: ${prompt}` }); }); -// Not listed in the config, so no payment required. +// 구성에 나열되지 않아 지불이 필요하지 않습니다. app.get("/health", (req, res) => { res.json({ status: "ok", payTo: PAY_TO }); }); const PORT = process.env.PORT || 4021; app.listen(PORT, () => { - console.log(`Server listening at http://localhost:${PORT}`); - console.log(`GET /health - free`); - console.log(`GET /weather - $0.001 per request`); - console.log(`POST /inference - $0.05 per request`); + console.log(`서버가 http://localhost:${PORT}에서 수신 중입니다.`); + console.log(`GET /health - 무료`); + console.log(`GET /weather - 요청당 $0.001`); + console.log(`POST /inference - 요청당 $0.05`); }); ``` :::note -x402는 Hono(`@x402/hono`)와 Next.js(`@x402/next`)용 미들웨어도 제공합니다. 패턴은 동일합니다: 퍼실리테이터 클라이언트를 생성하고, EVM 스킴을 등록하고, 미들웨어를 적용합니다. +x402는 Hono(`@x402/hono`) 및 Next.js(`@x402/next`)용 미들웨어도 제공합니다. 패턴은 동일합니다. 촉진자 클라이언트를 만들고, EVM 스키마를 등록하고, 미들웨어를 적용합니다. ::: ## 구매자: 유료 요청하기 -구매자는 수동 결제 흐름을 거치지 않고도 유료 엔드포인트에 접근합니다. 구매자는 가스비를 지불하지 않습니다. 퍼실리테이터가 온체인으로 정산하며, 구매자는 결제 요구사항에 지정된 정확한 금액만 지불합니다. +구매자는 수동 결제 흐름을 거치지 않고 유료 엔드포인트에 액세스합니다. 구매자는 가스비를 지불하지 않습니다. 촉진자가 온체인으로 결제하며, 구매자는 결제 요구 사항에 명시된 정확한 금액만 지불합니다. ```bash npm install @x402/fetch @x402/evm @tetherto/wdk-wallet-evm @@ -214,17 +214,17 @@ const account = await new WalletManagerEvm(process.env.SEED_PHRASE!, { provider: "https://rpc.stable.xyz", }).getAccount(0); -console.log("Buyer address:", account.address); +console.log("구매자 주소:", account.address); -// USDT0 uses 6 decimals. A balance of 1000000 equals 1.00 USDT0. +// USDT0은 6 소수점을 사용합니다. 1000000의 잔액은 1.00 USDT0과 같습니다. const USDT0_STABLE = "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"; const balance = await account.getTokenBalance(USDT0_STABLE); -console.log("USDT0 balance:", Number(balance) / 1e6, "USDT0"); +console.log("USDT0 잔액:", Number(balance) / 1e6, "USDT0"); ``` ### x402에 연결하고 유료 요청하기 -`WalletAccountEvm`은 x402가 기대하는 서명자 인터페이스를 충족하므로, x402 클라이언트의 서명자로 직접 등록할 수 있습니다. 등록되면 x402 지원 클라이언트를 통해 전송된 요청은 402 결제 흐름을 자동으로 처리합니다. +`WalletAccountEvm`은 x402가 예상하는 서명자 인터페이스를 만족하므로 x402 클라이언트의 서명자로 직접 등록할 수 있습니다. 등록되면 x402 지원 클라이언트를 통해 전송된 요청은 402 지불 흐름을 자동으로 처리합니다. ```typescript import { x402Client, wrapFetchWithPayment } from "@x402/fetch"; @@ -236,64 +236,64 @@ const fetchWithPayment = wrapFetchWithPayment(fetch, client); const response = await fetchWithPayment("http://localhost:4021/weather"); const data = await response.json(); -console.log("Response:", data); +console.log("응답:", data); ``` -내부적으로 `fetchWithPayment`는 402 응답을 가로채고, 결제 요구사항(금액, 토큰, 네트워크, 수령인)을 파싱하며, WDK 지갑으로 ERC-3009 `transferWithAuthorization`에 서명하고, `PAYMENT-SIGNATURE` 헤더와 함께 요청을 재시도합니다. +내부적으로 `fetchWithPayment`는 402 응답을 가로채고, 지불 요구 사항(금액, 토큰, 네트워크, 수신자)을 구문 분석하고, WDK 지갑으로 ERC-3009 `transferWithAuthorization`에 서명하고, `PAYMENT-SIGNATURE` 헤더로 요청을 재시도합니다. :::note -Axios를 선호한다면, 동일한 자동 결제 처리를 위해 `@x402/axios`와 `wrapAxiosWithPayment`를 사용하세요. +Axios를 선호하는 경우 `@x402/axios`를 `wrapAxiosWithPayment`과 함께 사용하여 동일한 자동 결제 처리를 수행합니다. ::: -## 결제 흐름 테스트하기 +## 결제 흐름 테스트 -서버를 시작하고 유료 및 무료 라우트를 모두 검증합니다. +서버를 시작하고 유료 및 무료 경로를 모두 확인하십시오. :::warning -이 테스트 흐름은 Stable 메인넷에서 실행됩니다. 성공한 각 유료 요청은 호스팅된 퍼실리테이터를 통해 실제 USDT0 결제를 정산합니다. 전용 지갑과 소액만 사용하세요. +이 테스트 흐름은 Stable 메인넷에서 실행됩니다. 각 성공적인 유료 요청은 호스팅된 촉진자를 통해 실제 USDT0 결제를 처리합니다. 전용 지갑과 소액만 사용하십시오. ::: -### 1. 402 응답 확인하기 +### 1. 402 응답 확인 ```bash curl -i http://localhost:4021/weather ``` -응답은 가격, 자산, 네트워크를 포함하는 `PAYMENT-REQUIRED` 헤더와 함께 `402 Payment Required`여야 합니다. +응답은 가격, 자산 및 네트워크를 포함하는 `PAYMENT-REQUIRED` 헤더와 함께 `402 Payment Required`여야 합니다. -### 2. 클라이언트 실행하기 +### 2. 클라이언트 실행 ```bash npx tsx client.ts ``` -클라이언트는 전체 주기를 처리합니다: 402를 받고, 권한을 서명하고, 결제와 함께 재시도하고, 응답을 출력합니다. +클라이언트는 전체 주기를 처리합니다. 402를 수신하고, 승인에 서명하고, 지불로 재시도하고, 응답을 인쇄합니다. ### 3. 영수증 읽기 -성공한 유료 요청 후, 구매자는 서버 응답에서 `PAYMENT-SETTLE-RESPONSE` 헤더를 읽고 정산 영수증을 파싱할 수 있습니다. +성공적인 유료 요청 후 구매자는 서버 응답에서 `PAYMENT-SETTLE-RESPONSE` 헤더를 읽고 결제 영수증을 구문 분석할 수 있습니다. ```typescript -// (continued) client.ts +// (계속) client.ts import { x402HTTPClient } from "@x402/fetch"; const httpClient = new x402HTTPClient(client); const receipt = httpClient.getPaymentSettleResponse( (name) => response.headers.get(name), ); -console.log("Payment receipt:", JSON.stringify(receipt, null, 2)); +console.log("결제 영수증:", JSON.stringify(receipt, null, 2)); ``` -## 라이브 퍼실리테이터 없이 테스트하기 +## 라이브 촉진자 없이 테스트 -Semantic 퍼실리테이터는 메인넷 전용이므로, 현재 서버를 테스트넷 퍼실리테이터로 연결할 수 없습니다. 실제 결제를 정산하지 않고 서버 로직, 라우트 핸들러, 미들웨어 동작을 반복 개발하려면, 퍼실리테이터 클라이언트를 스텁으로 대체하세요. +시맨틱 촉진자는 메인넷 전용이므로 현재 테스트넷 촉진자에 서버를 연결할 수 없습니다. 실제 결제를 하지 않고 서버 로직, 경로 핸들러 및 미들웨어 동작을 반복하기 위해 촉진자 클라이언트를 스텁 처리합니다. ```typescript // server.test.ts import { x402ResourceServer } from "@x402/express"; import { ExactEvmScheme } from "@x402/evm/exact/server"; -// Stub facilitator: accepts any signature, returns a fake settlement. +// 스텁 촉진자: 모든 서명을 수락하고 가짜 결제를 반환합니다. const stubFacilitatorClient = { verify: async () => ({ isValid: true, payer: "0xMockPayer" }), settle: async () => ({ @@ -307,26 +307,26 @@ export const testResourceServer = new x402ResourceServer(stubFacilitatorClient a .register("eip155:988", new ExactEvmScheme()); ``` -스텁에 대해 유닛 테스트를 실행하여 다음을 검증합니다: +스텁에 대해 단위 테스트를 실행하여 다음을 검증하십시오. -- 402 응답에 올바른 `PAYMENT-REQUIRED` 페이로드가 포함됩니다. -- 유효한 `PAYMENT-SIGNATURE` 헤더가 있는 요청이 핸들러에 도달합니다. -- 헤더가 누락되었거나 형식이 잘못된 요청은 핸들러 실행 전에 거부됩니다. +- 402 응답에는 올바른 `PAYMENT-REQUIRED` 페이로드가 포함됩니다. +- 유효한 `PAYMENT-SIGNATURE` 헤더가 있는 요청은 핸들러에 도달합니다. +- 누락되거나 잘못된 헤더가 있는 요청은 핸들러가 실행되기 전에 거부됩니다. -실제 정산을 실행할 준비가 되면, `HTTPFacilitatorClient`로 다시 전환하고 소액으로 메인넷에서 실행하세요. +실제 결제를 실행할 준비가 되면 `HTTPFacilitatorClient`로 다시 전환하고 소액으로 메인넷에서 실행하십시오. :::warning -스텁 정산은 미들웨어 동작만 검증합니다. 실제 네트워크 지연이나 동시 결제 상황에서 라우트 핸들러가 멱등성을 갖는지는 증명하지 않습니다. 출시 전에 항상 소액으로 라이브 메인넷 테스트를 마무리하세요. +스텁 결제는 미들웨어 동작만 확인합니다. 이는 경로 핸들러가 실제 네트워크 지연 또는 동시 결제에서 멱등성을 입증하지 못합니다. 항상 출시 전에 소액으로 라이브 메인넷 테스트를 완료하십시오. ::: -## 고급: 라이프사이클 훅 +## 고급: 수명 주기 훅 -x402는 흐름의 주요 지점에서 결제 처리를 가로채고 커스터마이징할 수 있는 훅을 제공합니다. 예를 들어, 서버는 검증 전에 로직을 실행하여(예: API 키 또는 구독자 상태 확인) 승인된 요청에 대해 결제를 우회할 수 있고, 클라이언트는 서명 전에 지출 한도를 적용할 수 있습니다. +x402는 흐름의 주요 지점에서 결제 처리를 가로채고 사용자 정의할 수 있는 훅을 제공합니다. 예를 들어, 서버는 확인 전에 논리를 실행하여 (예: API 키 또는 구독자 상태 확인) 승인된 요청에 대한 결제를 우회할 수 있으며, 클라이언트는 서명하기 전에 지출 한도를 적용할 수 있습니다. -전체 훅 레퍼런스와 예제는 [x402 라이프사이클 훅](https://x402.semanticpay.io/docs/hooks)을 참고하세요. +전체 훅 참조 및 예제는 [x402 수명 주기 훅](https://x402.semanticpay.io/docs/hooks)을 참조하십시오. -## 다음 추천 +## 다음 권장 사항 -- [**x402 개념**](/ko/explanation/x402) — 프로토콜과 그것이 적용되는 위치를 이해하세요. -- [**ERC-3009**](/ko/explanation/erc-3009) — x402가 사용하는 정산 표준을 검토하세요. -- [**MCP 서버로 결제하기**](/ko/how-to/pay-with-mcp) — AI 클라이언트가 프롬프트를 통해 호출할 수 있도록 이 API를 MCP 도구로 래핑하세요. +- [**x402 개념**](/ko/explanation/x402): 프로토콜과 적합한 위치를 이해합니다. +- [**ERC-3009**](/ko/explanation/erc-3009): x402가 사용하는 결제 표준을 검토합니다. +- [**MCP 서버로 결제**](/ko/how-to/pay-with-mcp): 이 API를 MCP 도구로 랩핑하여 AI 클라이언트가 프롬프트를 통해 호출할 수 있도록 합니다. diff --git a/docs/pages/ko/how-to/create-wallet.mdx b/docs/pages/ko/how-to/create-wallet.mdx index 1a1cf90..93eb7c4 100644 --- a/docs/pages/ko/how-to/create-wallet.mdx +++ b/docs/pages/ko/how-to/create-wallet.mdx @@ -1,26 +1,26 @@ --- source_path: how-to/create-wallet.mdx -source_sha: 282b1f16baf49a0e39d7df989136218e3727fad2 +source_sha: 0735e9a5c8737cb5606dd4ea1d7406859b371377 title: "지갑 생성하기" -description: "ethers.js 또는 Tether WDK를 사용해 새로운 Stable 지갑을 생성하거나 시드 문구로 복구합니다." +description: "ethers.js 또는 Tether WDK를 사용하여 새로운 Stable 지갑을 생성하거나 시드 구문으로 지갑을 복원합니다." diataxis: "how-to" --- # 지갑 생성하기 -Stable 지갑은 이더리움 표준 키 쌍입니다. EVM 계정을 생성하는 모든 지갑 라이브러리는 수정 없이 Stable에서 작동합니다. 이 가이드에서는 두 가지 경로를 소개합니다: 대부분의 애플리케이션을 위한 ethers.js, 그리고 에이전트와 결제를 위한 턴키 방식의 자가 수탁(self-custody) 계층을 원하는 통합을 위한 Tether의 [WDK (Wallet Development Kit)](https://github.com/tetherto/wdk)입니다. +Stable 지갑은 이더리움 표준 키 페어입니다. EVM 계정을 생성하는 모든 지갑 라이브러리는 수정 없이 Stable에서 작동합니다. 이 가이드는 두 가지 경로를 보여줍니다: 대부분의 애플리케이션에 적합한 ethers.js, 그리고 에이전트 및 결제를 위한 턴키 자체 보관 레이어를 원하는 통합을 위한 Tether의 [WDK(Wallet Development Kit)](https://github.com/tetherto/wdk). :::note -등록도, Stable 전용 계정 설정도 필요 없습니다. 지갑은 [테스트넷 포셋](/ko/how-to/use-faucet)이나 메인넷 전송으로부터 즉시 USDT0를 받을 수 있습니다. +등록도, Stable 특정 계정 설정도 필요하지 않습니다. 지갑은 [테스트넷 수도꼭지](/ko/how-to/use-faucet) 또는 메인넷 전송을 통해 USDT0를 즉시 받을 수 있습니다. ::: -## 사전 준비 사항 +## 필수 조건 - Node.js 20 이상. ## 옵션 1: ethers.js -라이브러리를 설치하고 키 쌍을 생성합니다. +라이브러리를 설치하고 키 페어를 생성합니다. ```bash npm install ethers @@ -32,17 +32,17 @@ import { ethers } from "ethers"; const provider = new ethers.JsonRpcProvider("https://rpc.testnet.stable.xyz"); -/** Create a new wallet for a new user. */ +/** 새 사용자를 위한 새 지갑을 생성합니다. */ export function createWallet() { const wallet = ethers.Wallet.createRandom(provider); return { wallet, address: wallet.address, - seedPhrase: wallet.mnemonic!.phrase, // show to the user once for backup + seedPhrase: wallet.mnemonic!.phrase, // 백업을 위해 사용자에게 한 번만 보여줍니다. }; } -/** Restore a wallet from a seed phrase (returning user). */ +/** 시드 구문으로 지갑을 복원합니다(재방문 사용자). */ export function restoreWallet(seedPhrase: string) { const wallet = ethers.Wallet.fromPhrase(seedPhrase, provider); return { wallet, address: wallet.address }; @@ -65,12 +65,12 @@ Seed phrase: liberty shoot ... (12 words) ``` :::warning -프로덕션 환경에서는 시드 문구를 절대 평문으로 로그에 남기거나 저장하지 마세요. 저장 시 암호화하거나 시크릿 매니저를 사용하세요. `ethers.Wallet.createRandom`은 호출당 한 번만 문구를 반환합니다 — 이를 잃어버리면 자금을 복구할 수 없습니다. +프로덕션 환경에서 시드 구문을 일반 텍스트로 기록하거나 저장하지 마십시오. 저장 시 암호화하거나 비밀 관리자를 사용하십시오. `ethers.Wallet.createRandom`은 호출당 한 번씩 구문을 반환합니다. 잃어버리면 자금을 복구할 수 없습니다. ::: ## 옵션 2: Tether WDK -WDK는 키 파생, 서명, 트랜잭션 제출을 하나의 인터페이스로 감쌉니다. 일반적인 계정 흐름을 재구현하지 않고 자가 수탁을 원할 때 적합한 선택이며, 에이전트 결제를 위한 [x402](/ko/how-to/build-pay-per-call)와 직접 통합됩니다. +WDK는 키 도출, 서명 및 트랜잭션 제출을 단일 인터페이스로 래핑합니다. 일반적인 계정 흐름을 재구현하지 않고도 자체 보관을 원할 때 올바른 선택이며, 에이전트 결제를 위해 [x402](/ko/how-to/build-pay-per-call)와 직접 통합됩니다. ```bash npm install @tetherto/wdk @tetherto/wdk-wallet-evm @@ -88,7 +88,7 @@ function initWdk(seedPhrase: string) { }); } -/** Create a new wallet for a new user. */ +/** 새 사용자를 위한 새 지갑을 생성합니다. */ export async function createWallet() { const seedPhrase = WDK.getRandomSeedPhrase(); const wdk = initWdk(seedPhrase); @@ -96,11 +96,11 @@ export async function createWallet() { return { account, address: await account.getAddress(), - seedPhrase, // show to the user once for backup + seedPhrase, // 백업을 위해 사용자에게 한 번만 보여줍니다. }; } -/** Restore a wallet from a seed phrase (returning user). */ +/** 시드 구문으로 지갑을 복원합니다(재방문 사용자). */ export async function restoreWallet(seedPhrase: string) { const wdk = initWdk(seedPhrase); const account = await wdk.getAccount("stable", 0); @@ -117,19 +117,19 @@ Address: 0xAlice...1234 Seed phrase: liberty shoot ... (12 words) ``` -## 지갑에 자금 충전하기 +## 지갑에 자금 조달 -지갑이 트랜잭션을 처리하려면 가스용 USDT0가 필요합니다. 테스트넷에서는 포셋에 요청하세요: +지갑이 거래를 시작하기 전에 가스용 USDT0가 필요합니다. 테스트넷에서는 수도꼭지에서 요청합니다: ```bash open https://faucet.stable.xyz ``` -주소를 붙여넣고 버튼을 선택해 1 테스트넷 USDT0(수천 건의 네이티브 전송에 충분한 양)를 받으세요. 메인넷의 경우, 지원되는 거래소나 브리지에서 USDT0를 전송하세요. [Stable로 브리징하기](/ko/explanation/usdt0-bridging)를 참조하세요. +주소를 붙여넣고 버튼을 선택하여 1개의 테스트넷 USDT0 (수천 건의 기본 전송에 충분함)을 받으세요. 메인넷의 경우 지원되는 모든 거래소 또는 브리지에서 USDT0를 보내십시오. [Stable로 브리징](/ko/explanation/usdt0-bridging)을 참조하십시오. -## 잔액 확인하기 +## 잔액 확인 -네이티브 USDT0는 18자리 소수를 사용합니다. 네이티브 잔액이 가스가 지불되는 잔액입니다. +기본 USDT0는 18자릿수를 사용합니다. 기본 잔액은 가스가 지불되는 잔액입니다. ```typescript // balance.ts @@ -148,8 +148,8 @@ npx tsx balance.ts Balance: 1.0 USDT0 ``` -## 다음 권장 단계 +## 다음에 권장되는 사항 -- [**EIP-7702로 위임하기**](/ko/how-to/account-abstraction) — 이 지갑에 일괄 결제, 지출 한도, 세션 키를 추가하세요. -- [**첫 USDT0 보내기**](/ko/tutorial/send-usdt0) — 동일한 잔액에서의 네이티브 및 ERC-20 전송. -- [**테스트넷 지갑에 자금 충전하기**](/ko/how-to/use-faucet) — 더 큰 테스트 잔액을 위한 포셋 및 Sepolia 브리지 옵션. +- [**EIP-7702로 위임하기**](/ko/how-to/account-abstraction): 이 지갑에 배치 결제, 지출 한도 및 세션 키를 추가합니다. +- [**첫 USDT0 전송하기**](/ko/tutorial/send-usdt0): 동일한 잔액에서 기본 및 ERC-20 전송. +- [**테스트넷 지갑에 자금 조달하기**](/ko/how-to/use-faucet): 더 큰 테스트 잔액을 위한 수도꼭지 및 Sepolia 브리지 옵션. diff --git a/docs/pages/ko/how-to/develop-with-ai.mdx b/docs/pages/ko/how-to/develop-with-ai.mdx index 3f12f5c..24d9f33 100644 --- a/docs/pages/ko/how-to/develop-with-ai.mdx +++ b/docs/pages/ko/how-to/develop-with-ai.mdx @@ -1,22 +1,22 @@ --- source_path: how-to/develop-with-ai.mdx -source_sha: 621ff15f63c34d76a39e5a45a36987add8833dbd +source_sha: 2dca54cdd89b846903b46f9688a1a3367b258907 title: "AI로 개발하기" -description: "MCP 서버, 에이전트 스킬, 일반 텍스트 문서를 설정하여 AI 에디터와 코딩 에이전트가 Stable 위에서 직접 빌드할 수 있도록 하세요." +description: "AI 편집기와 코딩 에이전트가 Stable에서 직접 구축할 수 있도록 MCP 서버, 에이전트 스킬 및 일반 텍스트 문서를 설정합니다." diataxis: "how-to" --- -Stable은 MCP 서버, 에이전트 스킬, 일반 텍스트 문서 파일을 제공하여 AI 에디터와 코딩 에이전트가 Stable과 직접 작업할 수 있도록 합니다. 이 페이지에서는 각 구성 요소를 워크플로에 연결하는 방법, MCP를 지원하지 않는 AI 도구를 위한 복사-붙여넣기 가능한 컨텍스트 블록, 일반적인 작업을 위한 시작 프롬프트를 다룹니다. +Stable은 AI 편집기와 코딩 에이전트가 Stable과 직접 작업할 수 있도록 MCP 서버, 에이전트 스킬 및 일반 텍스트 문서 파일을 제공합니다. 이 페이지에서는 각 부분을 워크플로우에 연결하는 방법, MCP가 아닌 AI 도구를 위한 복사 붙여넣기 가능한 컨텍스트 블록 및 일반적인 작업을 위한 시작 프롬프트에 대해 설명합니다. ## MCP 서버 -Stable은 두 개의 MCP 서버를 운영합니다. **Docs MCP**는 이 문서 사이트에서 개념, 가이드, 코드 스니펫, 컨트랙트 레퍼런스를 검색합니다. **Runtime MCP**는 잔액 조회, 트랜잭션 시뮬레이션, 실행을 위해 Stable 체인과 상호작용합니다. +Stable은 두 개의 MCP 서버를 실행합니다. **문서 MCP**는 이 문서 사이트에서 개념, 가이드, 코드 스니펫 및 계약 참조를 검색합니다. **런타임 MCP**는 잔액 조회, 트랜잭션 시뮬레이션 및 실행을 위해 Stable 체인과 상호 작용합니다. 두 서버 모두 MCP 호환 클라이언트에 추가할 수 있습니다. ### Cursor -MCP 설정 파일을 열고 다음을 추가하세요: +MCP 구성 파일을 열고 다음을 추가합니다. ```json { @@ -31,7 +31,7 @@ MCP 설정 파일을 열고 다음을 추가하세요: } ``` -Cursor를 재시작합니다. "Stable에서 USDT0를 어떻게 보내나요?"라고 물어 확인하세요. +Cursor를 다시 시작합니다. "Stable에서 USDT0를 어떻게 보내나요?"라고 질문하여 확인합니다. ### Claude Code @@ -40,13 +40,13 @@ claude mcp add stable-docs https://docs.stable.xyz/mcp claude mcp add stable-runtime https://runtime.stable.xyz/mcp ``` -"Gas Waiver 통합 단계에 대해 Stable 문서를 검색해줘."라고 물어 확인하세요. +"가스 면제 통합 단계를 위해 Stable 문서를 검색해줘."라고 질문하여 확인합니다. ## 에이전트 스킬 -에이전트 스킬은 Docs MCP와 Runtime MCP를 결합한 사전 정의된 워크플로입니다. "세 개의 주소로 100 USDT0를 보내줘"와 같은 작업을 AI에 요청하면, 스킬이 전체 시퀀스를 처리합니다: 관련 문서 조회, 주소 및 파라미터 확인, 잔액 점검, 트랜잭션 시뮬레이션, 승인 후 실행. +에이전트 스킬은 Docs MCP와 Runtime MCP를 결합한 사전 정의된 워크플로입니다. AI에게 "100 USDT0를 세 주소로 보내"와 같은 작업을 수행하도록 요청하면, 스킬은 관련 문서를 찾아보고, 주소와 매개변수를 해결하고, 잔액을 확인하고, 트랜잭션을 시뮬레이션하고, 승인 후 실행하는 전체 시퀀스를 처리합니다. -스킬은 Claude Code 플러그인으로 제공됩니다. +스킬은 Claude Code 플러그인으로 사용할 수 있습니다. ### 설치 @@ -54,161 +54,165 @@ claude mcp add stable-runtime https://runtime.stable.xyz/mcp claude plugin add stable-xyz/agent-skills ``` -또는 Claude Code 마켓플레이스에서 설치하세요. +또는 Claude Code 마켓플레이스에서 설치합니다. -전체 스킬 정의와 소스는 [agent-skills 저장소](https://github.com/stable-xyz/agent-skills)를 참고하세요. +전체 스킬 정의 및 소스는 [agent-skills 리포지토리](https://github.com/stable-xyz/agent-skills)를 참조하세요. ## 일반 텍스트 문서 -MCP를 지원하지 않는 AI 도구를 위해, Stable 문서는 정적 텍스트 파일로 제공됩니다. +MCP를 지원하지 않는 AI 도구를 위해 Stable 문서는 정적 텍스트 파일로 제공됩니다. -| **파일** | **URL** | **내용** | +| **파일** | **URL** | **콘텐츠** | | :--- | :--- | :--- | -| `llms.txt` | [https://docs.stable.xyz/llms.txt](https://docs.stable.xyz/llms.txt) | 제목과 설명이 포함된 페이지 인덱스 | -| `llms-full.txt` | [https://docs.stable.xyz/llms-full.txt](https://docs.stable.xyz/llms-full.txt) | 단일 파일로 된 전체 문서 | +| `llms.txt` | [https://docs.stable.xyz/llms.txt](https://docs.stable.xyz/llms.txt) | 제목 및 설명이 있는 페이지 색인 | +| `llms-full.txt` | [https://docs.stable.xyz/llms-full.txt](https://docs.stable.xyz/llms-full.txt) | 단일 파일의 전체 문서 | -이 파일들은 정적 스냅샷입니다. 가장 최신 내용을 위해서는 Docs MCP를 사용하세요. +이 파일은 정적 스냅샷입니다. 가장 최신 콘텐츠를 이용하려면 Docs MCP를 사용하세요. ### Cursor -1. **Settings > Features > Docs**로 이동합니다. -2. **Add**를 선택하고 `https://docs.stable.xyz/llms-full.txt`를 입력합니다. -3. 채팅에서 `@Stable`로 참조합니다. +1. **설정 > 기능 > 문서**로 이동합니다. +2. **추가**를 선택하고 `https://docs.stable.xyz/llms-full.txt`를 입력합니다. +3. `@Stable`로 채팅에서 참조합니다. ### 기타 도구 -`llms-full.txt`를 다운로드하여 프로젝트 컨텍스트나 시스템 프롬프트에 포함하세요. +`llms-full.txt`를 다운로드하여 프로젝트 컨텍스트 또는 시스템 프롬프트에 포함합니다. ## Stable 컨텍스트 블록 -이것을 모든 AI 채팅이나 시스템 프롬프트 상단에 붙여넣으세요. 모델이 첫 시도에 올바른 Stable 코드를 생성하는 데 필요한 모든 것을 제공합니다. +이것을 AI 채팅 또는 시스템 프롬프트의 맨 위에 붙여넣으세요. 모델이 처음 시도에서 올바른 Stable 코드를 생성하는 데 필요한 모든 것을 제공합니다. ````markdown -# Stable chain context +# Stable 체인 컨텍스트 -Stable is a Layer 1 where USDT0 is the native gas token. Fully EVM-compatible. -All standard EVM tools (Hardhat, Foundry, ethers.js, viem) work unchanged once -you adjust three gas fields (see Behavioral differences below). +Stable은 USDT0가 기본 가스 토큰인 레이어 1입니다. 완전 EVM 호환입니다. +모든 표준 EVM 도구(Hardhat, Foundry, ethers.js, viem)는 +세 가지 가스 필드를 조정하면 변경 없이 작동합니다(아래 행동 차이점 참조). -## Network +## 네트워크 -| Field | Mainnet | Testnet | +| 필드 | 메인넷 | 테스트넷 | | :-------------- | :--------------------------------------- | :----------------------------------------- | -| Chain ID | 988 | 2201 | +| 체인 ID | 988 | 2201 | | RPC | https://rpc.stable.xyz | https://rpc.testnet.stable.xyz | -| Explorer | https://stablescan.xyz | https://testnet.stablescan.xyz | -| Currency symbol | USDT0 | USDT0 | - -## USDT0 contract addresses - -- Mainnet: 0x779ded0c9e1022225f8e0630b35a9b54be713736 -- Testnet: 0x78cf24370174180738c5b8e352b6d14c83a6c9a9 - -## Behavioral differences from Ethereum - -1. **Gas token is USDT0, not ETH.** The `value` field in native transfers - carries USDT0. Fees are denominated in USDT0. -2. **`maxPriorityFeePerGas` is always 0.** No tip-based ordering. Set it - explicitly to `0n` or validators will reject or ignore tip components. -3. **USDT0 has a dual role**: native asset (18 decimals) AND ERC-20 (6 decimals) - on the same balance. `address(x).balance` reports 18-decimal wei; - `USDT0.balanceOf(x)` reports 6-decimal units. Values may differ by up to - 0.000001 USDT0 due to fractional reconciliation. Never mirror native - balance in an internal variable; always query at payout time. -4. **Transfer events are emitted for native transfers too.** A single Transfer - event listener on the USDT0 ERC-20 contract covers both transfer paths. -5. **Single-slot finality (~700ms).** Once a block is committed, it cannot - be reorged. No need to wait multiple confirmations. -6. **Gas Waiver** lets applications cover gas: user signs with `gasPrice = 0`, - a governance-registered waiver wraps and submits. Contracts must be on - the waiver's AllowedTarget policy. -7. **EIP-7702** is supported for delegating an EOA to a contract (type-4 tx). -8. **Precompile addresses**: Bank `0x...1003`, Distribution `0x...0801`, +| 탐색기 | https://stablescan.xyz | https://testnet.stablescan.xyz | +| 통화 기호 | USDT0 | USDT0 | + +## USDT0 계약 주소 + +- 메인넷: 0x779ded0c9e1022225f8e0630b35a9b54be713736 +- 테스트넷: 0x78cf24370174180738c5b8e352b6d14c83a6c9a9 + +## 이더리움과의 행동 차이점 + +1. **가스 토큰은 ETH가 아닌 USDT0입니다.** 네이티브 전송의 `value` 필드는 + USDT0를 전달합니다. 수수료는 USDT0로 표시됩니다. +2. **`maxPriorityFeePerGas`는 항상 0입니다.** 팁 기반 순서 지정이 없습니다. + 이를 명시적으로 `0n`으로 설정해야 합니다. 그렇지 않으면 유효성 검사자가 + 팁 구성 요소를 거부하거나 무시합니다. +3. **USDT0에는 이중 역할이 있습니다**: 네이티브 자산(18 decimals) 및 + ERC-20(6 decimals)이 동일한 잔액에 있습니다. `address(x).balance`는 + 18자리 wei를 보고합니다. `USDT0.balanceOf(x)`는 6자리 단위를 보고합니다. + 분수 조정으로 인해 값이 최대 0.000001 USDT0까지 다를 수 있습니다. + 내부 변수에 네이티브 잔액을 복제하지 마십시오. 항상 지급 시점에 쿼리하세요. +4. **네이티브 전송에 대해서도 전송 이벤트가 발생합니다.** USDT0 ERC-20 계약에 대한 + 단일 전송 이벤트 리스너는 두 전송 경로를 모두 다룹니다. +5. **단일 슬롯 완결성 (~700ms).** 블록이 커밋되면 재구성할 수 없습니다. + 여러 확인을 기다릴 필요가 없습니다. +6. **가스 면제**를 통해 애플리케이션이 가스를 처리할 수 있습니다. 사용자는 + `gasPrice = 0`으로 서명하고, 거버넌스에 등록된 면제가 서명을 래핑하고 제출합니다. + 계약은 면제의 AllowedTarget 정책에 있어야 합니다. +7. **EIP-7702**는 EOA를 계약에 위임하는 것을 지원합니다(유형-4 트랜잭션). +8. **사전 컴파일된 주소**: Bank `0x...1003`, Distribution `0x...0801`, Staking `0x...0800`, StableSystem `0x...9999`. -## Common mistakes to avoid - -- Copying Ethereum priority-fee constants (2 gwei tips, etc.) — has no effect - on Stable and can be rejected by wallets. -- Using `ethers.parseUnits(x, 18)` for ERC-20 USDT0 amounts. ERC-20 uses 6 - decimals; native transfers use 18. -- Mirroring native balance in a `uint256 deposited` variable — USDT0 - allowance-based operations (transferFrom, permit) can reduce a contract's - native balance without invoking its code. -- Sending native or ERC-20 USDT0 to `address(0)` — both revert on Stable. -- Assuming `EXTCODEHASH == 0` means an address is unused. On Stable, - permit-based approvals can change state without incrementing nonce. -- Writing `value: ethers.parseEther(amount, "ether")` and expecting ETH - semantics. That transfer sends USDT0. +## 피해야 할 일반적인 오류 + +- 이더리움 우선 순위 요금 상수(2 gwei 팁 등)를 복사하는 것. + 이는 Stable에 영향을 미치지 않으며 지갑에서 거부될 수 있습니다. +- ERC-20 USDT0 금액에 `ethers.parseUnits(x, 18)`을 사용하는 것. + ERC-20은 6자리를 사용하고, 네이티브 전송은 18자리를 사용합니다. +- `uint256 deposited` 변수에 네이티브 잔액을 복제하는 것. + USDT0 승인 기반 작업(transferFrom, permit)은 코드 호출 없이 + 계약의 네이티브 잔액을 줄일 수 있습니다. +- `address(0)`으로 네이티브 또는 ERC-20 USDT0를 보내는 것. + 둘 다 Stable에서 되돌아갑니다. +- `EXTCODEHASH == 0`이 주소가 사용되지 않음을 의미한다고 가정하는 것. + Stable에서는 허용 기반 승인이 nonce를 증가시키지 않고 상태를 변경할 수 있습니다. +- `value: ethers.parseEther(amount, "ether")`를 작성하고 ETH 의미를 기대하는 것. + 해당 전송은 USDT0를 보냅니다. ```` ## 시작 프롬프트 -위의 컨텍스트 블록을 로드한 후 다음 중 아무거나 AI 에디터에 복사하세요. +위 컨텍스트 블록을 로드한 후 AI 편집기에 다음 중 아무거나 복사하여 붙여넣으세요. -### 컨트랙트 배포 +### 계약 배포하기 ```text -Use Foundry to scaffold a project called `stable-escrow`. Write a minimal -Escrow contract in Solidity ^0.8.24 with deposit() and withdraw(amount) -functions that transfer USDT0 natively. Use address(this).balance for -solvency checks (never mirror the balance in a uint256). Reject -address(0) recipients. Then produce a deployment command using -`forge create` pointed at Stable testnet (RPC https://rpc.testnet.stable.xyz, -chain ID 2201). +Foundry를 사용하여 `stable-escrow`라는 프로젝트를 스캐폴드합니다. +Solidity ^0.8.24로 minimal Escrow 계약을 작성하고, +deposit() 및 withdraw(amount) 함수를 사용하여 USDT0를 네이티브 방식으로 전송합니다. +지불 능력을 확인하기 위해 address(this).balance를 사용하고 +(uint256에 잔액을 복제하지 마십시오), address(0) 수신자를 거부합니다. +그런 다음 `forge create`를 사용하여 Stable 테스트넷 +(RPC https://rpc.testnet.stable.xyz, 체인 ID 2201)에 +배포 명령을 생성합니다. ``` ### USDT0 보내기 ```text -Write a TypeScript script using ethers v6 that sends 0.001 USDT0 natively -from the wallet loaded from PRIVATE_KEY. Use base-fee-only EIP-1559 gas -(maxPriorityFeePerGas = 0n, maxFeePerGas = 2 * baseFeePerGas). Target -Stable testnet. Log the tx hash and a Stablescan explorer URL. +PRIVATE_KEY에서 로드된 지갑에서 0.001 USDT0를 네이티브 방식으로 보내는 +ethers v6를 사용한 TypeScript 스크립트를 작성합니다. +기본 수수료만 있는 EIP-1559 가스를 사용합니다 +(maxPriorityFeePerGas = 0n, maxFeePerGas = 2 * baseFeePerGas). +Stable 테스트넷을 대상으로 합니다. +트랜잭션 해시 및 Stablescan 탐색기 URL을 기록합니다. ``` ### EIP-7702 위임 설정 ```text -Write a TypeScript script using ethers v6 that: -1. Signs an EIP-7702 authorization delegating my EOA to Multicall3 at - 0xcA11bde05977b3631167028862bE2a173976CA11 on Stable testnet - (chain ID 2201). -2. Sends a type-4 transaction with authorizationList: [signedAuth], - to: wallet.address (self-call), and data that invokes aggregate3() - to batch three USDT0 transfers (100, 200, 150 USDT0 with 6 decimals). -3. Use maxPriorityFeePerGas: 0n. +ethers v6를 사용하여 다음을 수행하는 TypeScript 스크립트를 작성합니다. +1. Stable 테스트넷(체인 ID 2201)에서 0xcA11bde05977b3631167028862bE2a173976CA11에 있는 + Multicall3에 내 EOA를 위임하는 EIP-7702 승인을 서명합니다. +2. authorizationList: [signedAuth], to: wallet.address (자체 호출) 및 + 세 개의 USDT0 전송(100, 200, 150 USDT0, 6자리)을 일괄 처리하기 위해 + aggregate3()를 호출하는 데이터를 사용하여 유형-4 트랜잭션을 보냅니다. +3. maxPriorityFeePerGas: 0n를 사용합니다. ``` -### 구독 컨트랙트 빌드 +### 구독 계약 구축 ```text -Write a SubscriptionManager Solidity contract for EIP-7702 delegation on -Stable. It runs on a subscriber's EOA. Expose: +Stable에서 EIP-7702 위임을 위한 SubscriptionManager Solidity 계약을 작성합니다. +이 계약은 구독자의 EOA에서 실행됩니다. 다음을 노출합니다. - subscribe(bytes32 subId, address provider, uint256 amount, uint256 interval) - callable only when msg.sender == address(this) (subscriber on their own EOA). - - collect(bytes32 subId) callable only by the registered provider, only - when block.timestamp >= nextChargeAt; advances nextChargeAt by interval - and transfers USDT0 to the provider. Use IERC20 USDT0 at the testnet - address 0x78cf24370174180738c5b8e352b6d14c83a6c9a9. - - cancelSubscription(bytes32 subId) callable only by the subscriber. -Emit events for SubscriptionCreated, SubscriptionCollected, SubscriptionCancelled. + msg.sender == address(this) (자신의 EOA의 구독자)일 때만 호출 가능합니다. + - collect(bytes32 subId) 등록된 공급자만 호출 가능하며, + block.timestamp >= nextChargeAt일 때만 호출 가능합니다. + nextChargeAt을 interval만큼 진행하고 USDT0를 공급자에게 전송합니다. + 테스트넷 주소 0x78cf24370174180738c5b8e352b6d14c83a6c9a9에 있는 IERC20 USDT0를 사용합니다. + - cancelSubscription(bytes32 subId) 구독자만 호출 가능합니다. +SubscriptionCreated, SubscriptionCollected, SubscriptionCancelled 이벤트를 발생시킵니다. ``` -### x402 호출당 결제 API 빌드 +### x402 유료 통화 API 구축 ```text -Write an Express server in TypeScript that exposes GET /weather priced -at $0.001 USDT0 (amount: "1000", 6 decimals) using @x402/express, -@x402/evm/exact/server, and HTTPFacilitatorClient pointed at -https://x402.semanticpay.io/. Use Stable mainnet (CAIP-2 eip155:988, -USDT0 at 0x779Ded0c9e1022225f8E0630b35a9b54bE713736). The handler should -return { weather: "sunny", temperature: 70 }. Read PAY_TO_ADDRESS from -env. Print the configured routes on startup. +@x402/express, @x402/evm/exact/server 및 +https://x402.semanticpay.io/를 가리키는 HTTPFacilitatorClient를 사용하여 +$0.001 USDT0(금액: "1000", 6자리)으로 가격이 책정된 GET /weather를 노출하는 +TypeScript Express 서버를 작성합니다. +Stable 메인넷(CAIP-2 eip155:988, USDT0 0x779Ded0c9e1022225f8E0630b35a9b54bE713736)을 사용합니다. +핸들러는 { weather: "sunny", temperature: 70 }을 반환해야 합니다. +PAY_TO_ADDRESS를 env에서 읽습니다. 시작 시 구성된 경로를 인쇄합니다. ``` ## 다음 권장 사항 -- [**MCP 서버로 결제하기**](/ko/how-to/pay-with-mcp) — 유료 API를 MCP 도구로 래핑하여 AI 클라이언트가 호출하고 결제할 수 있도록 합니다. -- [**빠른 시작**](/ko/tutorial/quick-start) — AI 컨텍스트와 첫 트랜잭션 실행을 5분 만에 함께 진행합니다. -- [**Ethereum과의 차이점**](/ko/explanation/ethereum-comparison) — 컨텍스트 블록의 gas 및 USDT0 시맨틱에 대한 심층 분석. +- [**MCP 서버로 결제하기**](/ko/how-to/pay-with-mcp): 유료 API를 MCP 도구로 래핑하여 AI 클라이언트가 호출하고 결제할 수 있도록 합니다. +- [**빠른 시작**](/ko/tutorial/quick-start): 5분 안에 AI 컨텍스트를 첫 번째 트랜잭션 실행과 페어링합니다. +- [**이더리움과의 차이점**](/ko/explanation/ethereum-comparison): 컨텍스트 블록의 가스 및 USDT0 의미론에 대한 심층 분석. diff --git a/docs/pages/ko/how-to/index-contract.mdx b/docs/pages/ko/how-to/index-contract.mdx index 0668c1e..9bfc2ab 100644 --- a/docs/pages/ko/how-to/index-contract.mdx +++ b/docs/pages/ko/how-to/index-contract.mdx @@ -1,20 +1,20 @@ --- source_path: how-to/index-contract.mdx -source_sha: 5293e991b87b99d0da868102a910d03d70bde96b +source_sha: b32b9a67615217f86bfd96c7ff8bb192ee87454b title: "컨트랙트 이벤트 인덱싱" -description: "ethers.js watchContractEvent로 Stable의 스마트 컨트랙트 이벤트를 구독하고 실시간 이벤트 스트림을 구축합니다." +description: "ethers.js watchContractEvent를 사용하여 Stable에서 스마트 컨트랙트 이벤트를 구독하고 실시간 이벤트 스트림을 구축하세요." diataxis: "how-to" --- # 컨트랙트 이벤트 인덱싱 -인덱싱은 온체인 이벤트를 애플리케이션이 반응할 수 있는 데이터로 변환합니다: 잔액 업데이트, 거래 내역, UI 알림 등이 그 예입니다. 이 가이드에서는 ethers.js를 사용해 배포된 Stable 컨트랙트의 이벤트를 구독하는 방법과, 서비스가 오프라인 상태일 때 발생한 이벤트를 놓치지 않도록 과거 이벤트를 백필하는 방법을 설명합니다. +인덱싱은 온체인 이벤트를 애플리케이션이 반응할 수 있는 데이터(잔액 업데이트, 거래 내역, UI 알림)로 변환합니다. 이 가이드는 ethers.js를 사용하여 배포된 Stable 컨트랙트에서 이벤트를 구독하는 방법과 서비스가 오프라인일 때 발생한 이벤트를 놓치지 않도록 기록 이벤트를 백필하는 방법을 보여줍니다. -## 사전 준비 +## 전제 조건 -- Stable 테스트넷 또는 메인넷에 배포된 컨트랙트. 필요하다면 [배포](/ko/tutorial/smart-contract)와 [검증](/ko/how-to/verify-contract)을 참고하세요. +- Stable 테스트넷 또는 메인넷에 배포된 컨트랙트. 필요한 경우 [배포](/ko/tutorial/smart-contract) 및 [확인](/ko/how-to/verify-contract)을 참조하십시오. - Node.js 20 이상. -- 컨트랙트 주소와 인덱싱하려는 이벤트의 ABI. +- 컨트랙트 주소 및 인덱싱하려는 이벤트의 ABI. ## 1. 설치 및 구성 @@ -38,7 +38,7 @@ export const CONTRACT_ABI = [ ## 2. 실시간 이벤트 구독 -WebSocket 프로바이더를 사용하면 검증자가 각 블록을 확정하는 즉시 이벤트를 받을 수 있습니다. WebSocket은 폴링 오버헤드를 피하고 알림 지연 시간을 블록 타임(Stable에서 약 0.7초)에 가깝게 유지합니다. +유효성 검사기가 각 블록을 확정하자마자 이벤트를 수신할 수 있도록 WebSocket 공급자를 사용하십시오. WebSocket은 폴링 오버헤드를 방지하고 알림 대기 시간을 블록 시간(~Stable에서 0.7초)에 가깝게 유지합니다. ```typescript // watchLive.ts @@ -57,7 +57,7 @@ contract.on("NumberUpdated", (caller, oldValue, newValue, event) => { console.log(" block: ", event.log.blockNumber); }); -console.log("Listening for NumberUpdated events..."); +console.log("NumberUpdated 이벤트 청취 중..."); ``` ```bash @@ -65,7 +65,7 @@ npx tsx watchLive.ts ``` ```text -Listening for NumberUpdated events... +NumberUpdated 이벤트 청취 중... NumberUpdated: caller: 0x1234...abcd oldValue: 0 @@ -76,9 +76,9 @@ NumberUpdated: 호출자가 컨트랙트를 호출하면 이벤트가 실시간으로 도착합니다. -## 3. 과거 이벤트 백필 +## 3. 기록 이벤트 백필 -서비스가 시작될 때는 보통 오프라인 상태일 때 발생한 이벤트를 따라잡아야 합니다. 블록 범위와 함께 `queryFilter`를 사용하세요. +서비스가 시작될 때 일반적으로 오프라인 중에 발생한 이벤트를 따라잡아야 합니다. 블록 범위를 사용하여 `queryFilter`를 사용하십시오. ```typescript // backfill.ts @@ -89,7 +89,7 @@ const provider = new ethers.JsonRpcProvider(STABLE_TESTNET_RPC); const contract = new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, provider); const latest = await provider.getBlockNumber(); -const fromBlock = Math.max(0, latest - 10_000); // last ~10k blocks +const fromBlock = Math.max(0, latest - 10_000); // 지난 ~1만 블록 const events = await contract.queryFilter( contract.filters.NumberUpdated(), @@ -101,12 +101,12 @@ for (const event of events) { console.log( `[block ${event.blockNumber}]`, event.args.caller, - "set number to", + "숫자를 다음으로 설정:", event.args.newValue.toString() ); } -console.log(`Backfilled ${events.length} events from block ${fromBlock} to ${latest}`); +console.log(`${fromBlock}에서 ${latest}까지 ${events.length}개의 이벤트를 백필했습니다.`); ``` ```bash @@ -114,19 +114,19 @@ npx tsx backfill.ts ``` ```text -[block 1282351] 0x1234...abcd set number to 10 -[block 1283092] 0xef01...2345 set number to 25 -[block 1284371] 0x1234...abcd set number to 42 -Backfilled 3 events from block 1282351 to 1284371 +[block 1282351] 0x1234...abcd 숫자를 10으로 설정 +[block 1283092] 0xef01...2345 숫자를 25로 설정 +[block 1284371] 0x1234...abcd 숫자를 42로 설정 +1282351에서 1284371까지 3개의 이벤트를 백필했습니다. ``` :::warning -넓은 블록 범위(수백만 블록)는 RPC 속도 제한을 초과하고 타임아웃이 발생할 수 있습니다. 프로덕션 인덱서의 경우 10k 블록 단위로 페이지네이션하거나, 인덱싱된 과거 쿼리를 위해 [Stablescan의 Etherscan 호환 API](/ko/how-to/build-p2p-payments#transaction-history)를 사용하세요. +넓은 블록 범위(수백만 블록)는 RPC 속도 제한을 초과하고 시간 초과될 수 있습니다. 프로덕션 인덱서의 경우 10,000 블록 창으로 페이지 매김하거나 색인화된 기록 쿼리에 [Stablescan의 Etherscan 호환 API](/ko/how-to/build-p2p-payments#transaction-history)를 사용하십시오. ::: -## 4. 인덱싱된 인수로 이벤트 필터링 +## 4. 인덱싱된 인수에 따라 이벤트 필터링 -`indexed` 매개변수가 있는 이벤트(위의 `caller` 등)는 서버 측에서 필터링할 수 있습니다. 모든 이벤트를 읽고 앱에서 필터링하는 대신 필터 값을 전달하세요. +`indexed` 매개변수(위의 `caller`와 같은)가 있는 이벤트는 서버 측에서 필터링할 수 있습니다. 모든 이벤트를 읽고 앱에서 필터링하는 대신 필터 값을 전달합니다. ```typescript // watchUser.ts @@ -140,10 +140,10 @@ const userAddress = "0x1234...abcd"; const filter = contract.filters.NumberUpdated(userAddress); contract.on(filter, (caller, oldValue, newValue, event) => { - console.log(`${caller} set number to ${newValue.toString()}`); + console.log(`${caller}가 숫자를 ${newValue.toString()}로 설정했습니다.`); }); -console.log(`Watching NumberUpdated for ${userAddress}...`); +console.log(`${userAddress}의 NumberUpdated를 지켜보고 있습니다...`); ``` ```bash @@ -151,13 +151,13 @@ npx tsx watchUser.ts ``` ```text -Watching NumberUpdated for 0x1234...abcd... -0x1234...abcd set number to 42 +0x1234...abcd의 NumberUpdated를 지켜보고 있습니다... +0x1234...abcd가 숫자를 42로 설정했습니다. ``` ## 연결 끊김 처리 -WebSocket 연결은 끊길 수 있습니다. 프로덕션 인덱서의 경우 이벤트를 놓치지 않도록 재연결 로직을 구현하세요. +WebSocket 연결이 끊길 수 있습니다. 프로덕션 인덱서의 경우 이벤트를 놓치지 않도록 재연결 로직을 구현하십시오. ```typescript // resilientWatch.ts @@ -172,11 +172,11 @@ function setupWatcher() { const contract = new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, provider); contract.on("NumberUpdated", (caller, oldValue, newValue) => { - console.log(`${caller} set number to ${newValue.toString()}`); + console.log(`${caller}가 숫자를 ${newValue.toString()}로 설정했습니다.`); }); provider.websocket.onerror = (err: any) => { - console.error("Provider error:", err); + console.error("공급자 오류:", err); if (reconnectAttempts < MAX_RECONNECT) { reconnectAttempts++; setTimeout(setupWatcher, 5000); @@ -187,8 +187,8 @@ function setupWatcher() { setupWatcher(); ``` -## 다음 추천 +## 다음 권장 사항 -- [**언본딩 완료 추적**](/ko/how-to/track-unbonding) — 프로토콜에서 발생하는 시스템 트랜잭션 이벤트(언본딩 완료)를 인덱싱합니다. -- [**P2P 결제 앱 구축**](/ko/how-to/build-p2p-payments) — USDT0 Transfer 이벤트에 인덱싱을 적용하고 결제 내역 화면을 구축합니다. -- [**JSON-RPC 레퍼런스**](/ko/reference/json-rpc-api) — Stable이 지원하는 `eth_getLogs` 및 관련 메서드를 확인합니다. +- [**언본딩 완료 추적**](/ko/how-to/track-unbonding): 프로토콜에서 발행한 시스템 트랜잭션 이벤트(언본딩 완료)를 인덱싱합니다. +- [**P2P 결제 앱 구축**](/ko/how-to/build-p2p-payments): USDT0 전송 이벤트에 인덱싱을 적용하고 결제 내역 보기를 구축합니다. +- [**JSON-RPC 참조**](/ko/reference/json-rpc-api): Stable이 지원하는 `eth_getLogs` 및 관련 메서드를 확인하십시오. diff --git a/docs/pages/ko/how-to/index-validator-data.mdx b/docs/pages/ko/how-to/index-validator-data.mdx index 3fe5f1e..625b3bb 100644 --- a/docs/pages/ko/how-to/index-validator-data.mdx +++ b/docs/pages/ko/how-to/index-validator-data.mdx @@ -1,46 +1,46 @@ --- source_path: how-to/index-validator-data.mdx -source_sha: c61d0583cb63d1cacdebaa8d836bd6c30e3a66eb -title: "검증자 데이터 인덱싱" -description: "stabled를 실행하지 않고도 Stable 프리컴파일과 이벤트 로그에서 직접 검증자 신원, 참여일, 스테이크, 커미션, 가동 시간, 투표 이력을 읽어옵니다." +source_sha: 87a9f18c6cafd38834304736db22ff3c0297f2ce +title: "검증인 데이터 인덱싱" +description: "stabled를 실행하지 않고도 Stable 프리컴파일러 및 이벤트 로그에서 직접 검증인 ID, 가입 날짜, 스테이크, 수수료, 가동 시간 및 투표 기록을 읽습니다." diataxis: "how-to" --- -# 검증자 데이터 인덱싱 +# 검증인 데이터 인덱싱 -검증자 데이터는 온체인에 존재하며 표준 EVM JSON-RPC로 읽을 수 있습니다. 스테이킹, 슬래싱, 거버넌스 프리컴파일을 통해 현재 상태를 조회하고, 이들의 이벤트 로그로부터 이력을 재구성합니다. 즉, 인덱서나 분석 플랫폼은 노드의 `stabled` CLI나 Cosmos REST에 접근하지 않고도 `eth_call`과 `eth_getLogs`만으로 필요한 모든 것을 읽습니다. +검증인 데이터는 온체인에 있으며 표준 EVM JSON-RPC를 통해 읽을 수 있습니다. 스테이킹, 슬래싱 및 거버넌스 프리컴파일러를 통해 현재 상태를 쿼리하고, 해당 이벤트 로그로부터 기록을 재구성합니다. 이는 인덱서 또는 분석 플랫폼이 노드의 `stabled` CLI 또는 Cosmos REST에 액세스하지 않고 `eth_call` 및 `eth_getLogs`를 통해 필요한 모든 것을 읽는다는 의미입니다. :::note -**개념:** 스테이킹 모듈이 추적하는 내용과 위임이 작동하는 방식은 [스테이킹 모듈](/ko/explanation/staking-module)을 참조하세요. 메서드별 입력과 출력은 [스테이킹 프리컴파일 참조](/ko/reference/staking-module-api)를 참조하세요. +**개념:** 스테이킹 모듈이 추적하는 내용과 위임이 작동하는 방식은 [스테이킹 모듈](/ko/explanation/staking-module)을 참조하세요. 메서드별 입력 및 출력은 [스테이킹 프리컴파일러 참조](/ko/reference/staking-module-api)를 참조하세요. ::: ## 각 데이터 포인트의 출처 | **데이터 포인트** | **출처** | **읽는 방법** | | :--- | :--- | :--- | -| 검증자 이름, 신원, 웹사이트 | 스테이킹 프리컴파일 `validators()` | `description.moniker` 및 관련 필드 | -| 스테이크(본딩된 토큰) | 스테이킹 프리컴파일 `validators()` | `tokens` 필드 | -| 커미션 | 스테이킹 프리컴파일 `validators()` | `commission` 필드 | -| 시간에 따른 스테이크 변화 | 스테이킹 프리컴파일 이벤트 | `Delegate`, `Unbond`, `Redelegate` 로그 | -| 참여일 | 스테이킹 프리컴파일 이벤트 | `CreateValidator` 로그 → 블록 타임스탬프 | -| 가동 시간 | 슬래싱 프리컴파일 `getSigningInfos()` | `(signedBlocksWindow − missedBlocksCounter) / signedBlocksWindow` | -| 투표 이력(집계) | 거버넌스 프리컴파일 `getTallyResult()` | 제안별 집계 | -| 투표 이력(검증자별) | 거버넌스 프리컴파일 이벤트 | `Vote`, `VoteWeighted` 로그, voter = operator 주소 | +| 검증인 이름, ID, 웹사이트 | 스테이킹 프리컴파일러 `validators()` | `description.moniker` 및 관련 필드 | +| 스테이크 (본딩된 토큰) | 스테이킹 프리컴파일러 `validators()` | `tokens` 필드 | +| 수수료 | 스테이킹 프리컴파일러 `validators()` | `commission` 필드 | +| 시간 경과에 따른 스테이크 변경 | 스테이킹 프리컴파일러 이벤트 | `Delegate`, `Unbond`, `Redelegate` 로그 | +| 가입 날짜 | 스테이킹 프리컴파일러 이벤트 | `CreateValidator` 로그 → 블록 타임스탬프 | +| 가동 시간 | 슬래싱 프리컴파일러 `getSigningInfos()` | `(signedBlocksWindow − missedBlocksCounter) / signedBlocksWindow` | +| 투표 기록(집계) | 거버넌스 프리컴파일러 `getTallyResult()` | 제안별 집계 | +| 투표 기록(검증인별) | 거버넌스 프리컴파일러 이벤트 | `Vote`, `VoteWeighted` 로그, 투표자 = 운영자 주소 | -## 프리컴파일 주소 +## 프리컴파일러 주소 | **모듈** | **주소** | **용도** | | :--- | :--- | :--- | -| Staking | `0x0000000000000000000000000000000000000800` | 검증자 집합, 스테이크, 커미션, 위임 이벤트 | -| Distribution | `0x0000000000000000000000000000000000000801` | 보상 및 커미션 인출 | -| Gov | `0x0000000000000000000000000000000000000805` | 제안, 집계, 투표 로그 | -| Slashing | `0x0000000000000000000000000000000000000806` | 서명 정보 및 가동 시간 | +| 스테이킹 | `0x0000000000000000000000000000000000000800` | 검증인 세트, 스테이크, 수수료, 위임 이벤트 | +| 분배 | `0x0000000000000000000000000000000000000801` | 보상 및 수수료 인출 | +| 거버넌스 | `0x0000000000000000000000000000000000000805` | 제안, 집계 및 투표 로그 | +| 슬래싱 | `0x0000000000000000000000000000000000000806` | 서명 정보 및 가동 시간 | -`https://rpc.stable.xyz`에서 메인넷(Chain ID `988`)에 연결하세요. 엔드포인트와 제한 사항은 [메인넷 정보](/ko/reference/mainnet-information)를 참조하세요. +[`https://rpc.stable.xyz`](https://rpc.stable.xyz)에서 메인넷(체인 ID `988`)에 연결하세요. 엔드포인트 및 제한 사항은 [메인넷 정보](/ko/reference/mainnet-information)를 참조하세요. -## 검증자 이름, 스테이크, 커미션 +## 검증인 이름, 스테이크 및 수수료 -스테이킹 프리컴파일에서 `validators()`를 호출하여 현재 검증자 집합을 읽습니다. 본딩 상태를 전달하여 필터링하세요(예: `BOND_STATUS_BONDED`). 각 항목은 검증자의 `description`(`moniker` 포함), `tokens`(본딩된 스테이크), `commission`을 노출합니다. +스테이킹 프리컴파일러에서 `validators()`를 호출하여 현재 검증인 세트를 읽습니다. 필터링할 본드 상태를 전달합니다(예: `BOND_STATUS_BONDED`). 각 항목은 검증인의 `description`(`moniker` 포함), `tokens`(본딩된 스테이크) 및 `commission`을 노출합니다. ```typescript // validators.ts @@ -52,7 +52,7 @@ const client = createPublicClient({ transport: http("https://rpc.stable.xyz"), }); -// See the staking precompile reference for the full validators() ABI and structs. +// `validators()` ABI 및 structs에 대한 자세한 내용은 스테이킹 프리컴파일러 참조를 확인하세요. const validators = await client.readContract({ address: STAKING_PRECOMPILE, abi: stakingAbi, @@ -70,11 +70,11 @@ StableNode-01 4500000000000000000000000 50000000000000000 StableNode-02 3900000000000000000000000 100000000000000000 ``` -`tokens`와 `commission` 값은 18자리 소수로 스케일링되어 있습니다. `commission`을 1e18로 나누면 분수 형태의 비율을 얻을 수 있습니다(예: 5%의 경우 `0.05`). 전체 `Validator` 구조체와 `BOND_STATUS_*` 값은 [스테이킹 프리컴파일 참조](/ko/reference/staking-module-api#validators)를 참조하세요. +`tokens` 및 `commission` 값은 18자리까지 스케일링됩니다. `commission`을 1e18로 나누어 비율을 분수(예: 5%의 경우 `0.05`)로 얻습니다. 완전한 `Validator` 구조체 및 `BOND_STATUS_*` 값에 대해서는 [스테이킹 프리컴파일러 참조](/ko/reference/staking-module-api#validators)를 참조하세요. -## 시간에 따른 스테이크 변화 +## 시간 경과에 따른 스테이크 변경 -`validators()`는 스냅샷을 반환합니다. 스테이크가 어떻게 이동했는지 추적하려면 스테이킹 프리컴파일의 위임 이벤트를 인덱싱하세요. `Delegate`, `Unbond`, `Redelegate`는 인덱싱된 `validatorAddr`과 `amount`를 담고 있으므로, 모든 스테이크 변화를 검증자와 블록에 귀속시킬 수 있습니다. +`validators()`는 스냅샷을 반환합니다. 스테이크가 어떻게 이동했는지 추적하려면 스테이킹 프리컴파일러의 위임 이벤트를 인덱싱합니다. `Delegate`, `Unbond`, `Redelegate`는 인덱싱된 `validatorAddr`과 `amount`를 포함하므로 모든 스테이크 변경을 검증인 및 블록에 귀속시킬 수 있습니다. ```typescript // stakeChanges.ts @@ -96,11 +96,11 @@ console.log(`${logs.length} delegations indexed`); 1842 delegations indexed ``` -`Unbond`와 `Redelegate`는 동일한 형태를 따르며 추가로 `completionTime`을 담고 있습니다. 정확한 시그니처는 스테이킹 참조의 [이벤트 섹션](/ko/reference/staking-module-api#events)을 참조하세요. +`Unbond` 및 `Redelegate`도 동일한 형태를 따르며 추가로 `completionTime`을 포함합니다. 정확한 서명은 스테이킹 참조의 [이벤트 섹션](/ko/reference/staking-module-api#events)을 참조하세요. -## 참여일 +## 가입 날짜 -검증자의 참여일은 해당 검증자의 `CreateValidator` 이벤트의 블록 타임스탬프입니다. 이 이벤트는 검증자 주소로 인덱싱되어 있으므로, 단일 검증자를 필터링하거나 전체 집합을 훑은 다음, `eth_getBlockByNumber`로 각 로그의 `blockNumber`를 타임스탬프로 변환할 수 있습니다. +검증인의 가입 날짜는 `CreateValidator` 이벤트의 블록 타임스탬프입니다. 이벤트는 검증인 주소로 인덱싱되므로 단일 검증인을 필터링하거나 전체 세트를 스캔한 다음 각 로그의 `blockNumber`를 `eth_getBlockByNumber`를 사용하여 타임스탬프로 변환합니다. ```typescript // joinDate.ts @@ -125,26 +125,26 @@ for (const log of logs) { ``` :::warning -제네시스 검증자에는 `CreateValidator` 이벤트가 없습니다. 이들은 트랜잭션이 아니라 제네시스 블록에서 생성되었으므로 로그가 존재하지 않습니다. 이들의 참여일은 체인 제네시스인 **2025-10-29**로 취급하세요. 제네시스 이후에 참여한 모든 검증자에 대해 `CreateValidator`를 인덱싱하고, 제네시스 집합은 제네시스 검증자 목록에서 백필하세요. +제네시스 검증인은 `CreateValidator` 이벤트가 없습니다. 이들은 제네시스 블록에서 생성되었으므로 트랜잭션이 아니므로 로그가 존재하지 않습니다. 이들의 가입 날짜는 체인의 제네시스: **2025-10-29**로 취급합니다. 제네시스 이후에 가입한 모든 사람에 대해 `CreateValidator`를 인덱싱하고 제네시스 검증인 목록에서 제네시스 세트를 백필합니다. ::: ## 가동 시간 -슬래싱 프리컴파일(`0x...806`)에서 `getSigningInfos()`를 사용하여 서명 정보를 읽습니다. 각 레코드는 `signedBlocksWindow`(슬라이딩 윈도우의 크기)와 `missedBlocksCounter`(윈도우 내에서 놓친 블록 수)를 보고합니다. 가동 시간을 다음과 같이 계산하세요: +슬래싱 프리컴파일러(`0x...806`)에서 `getSigningInfos()`를 사용하여 서명 정보를 읽습니다. 각 레코드는 `signedBlocksWindow`(슬라이딩 윈도우 크기) 및 `missedBlocksCounter`(그 안에 누락된 블록)를 보고합니다. 가동 시간은 다음과 같이 계산합니다. ```text -uptime = (signedBlocksWindow − missedBlocksCounter) / signedBlocksWindow +가동 시간 = (signedBlocksWindow - missedBlocksCounter) / signedBlocksWindow ``` -`signedBlocksWindow`가 `10000`이고 `missedBlocksCounter`가 `25`인 검증자는 윈도우 동안 99.75%의 가동 시간을 갖습니다. 이는 누적 가동 시간이 아니라 롤링 수치입니다. 가동 시간 이력을 추적하려면 고정된 간격으로 카운터를 스냅샷하고 각 측정값을 저장하세요. +`signedBlocksWindow`가 `10000`이고 `missedBlocksCounter`가 `25`인 검증기는 윈도우 기간 동안 99.75%의 가동 시간을 갖습니다. 이는 평생 가동 시간이 아니라 롤링 수치입니다. 가동 시간 기록을 추적하려면 고정된 간격으로 카운터를 스냅샷하고 각 읽기를 저장합니다. :::note -슬래싱 프리컴파일은 Cosmos EVM `x/slashing` 인터페이스를 따릅니다. 해당 주소는 [시스템 모듈 프리컴파일 표](/ko/how-to/use-system-modules#whats-exposed)에 나열되어 있습니다. 정확한 메서드 ABI는 체인의 프리컴파일 인터페이스에서 생성하세요. +슬래싱 프리컴파일러는 Cosmos EVM `x/slashing` 인터페이스를 따릅니다. 주소는 [시스템 모듈 프리컴파일러 테이블](/ko/how-to/use-system-modules#whats-exposed)에 나열되어 있습니다. 체인의 프리컴파일러 인터페이스에서 정확한 메서드 ABI를 생성합니다. ::: -## 투표 이력 +## 투표 기록 -거버넌스 데이터에는 두 가지 계층이 있습니다. 제안의 집계 결과는 거버넌스 프리컴파일(`0x...805`)에서 `getTallyResult()`를 호출하세요. 누가 무엇에 투표했는지는 `Vote`와 `VoteWeighted` 이벤트 로그를 인덱싱하세요. 이 로그의 voter 주소는 검증자의 operator 주소이므로, 투표를 검증자에 직접 조인할 수 있습니다. +거버넌스 데이터는 두 가지 계층으로 구성됩니다. 제안의 총 결과를 얻으려면 거버넌스 프리컴파일러(`0x...805`)에서 `getTallyResult()`를 호출합니다. 누가 무엇에 투표했는지 확인하려면 `Vote` 및 `VoteWeighted` 이벤트 로그를 인덱싱합니다. 이 로그의 투표자 주소는 검증인의 운영자 주소이므로 투표를 검증인에게 직접 연결할 수 있습니다. ```typescript // votes.ts @@ -168,15 +168,15 @@ console.log(`${logs.length} votes indexed across all proposals`); 38 votes indexed across all proposals ``` -지금까지의 모든 제안(제안 #1부터 #7까지)에 대해 라이브 투표 로그가 확인되었습니다. 제안별 최종 집계만 필요할 때는 `getTallyResult()`를 사용하고, 검증자별 레코드가 필요할 때는 이벤트 로그를 사용하세요. +라이브 투표 로그는 현재까지의 모든 제안(제안 #1 ~ #7)에 대해 확인되었습니다. 제안별 최종 개수만 필요할 때는 `getTallyResult()`를 사용하고, 검증인별 기록이 필요할 때는 이벤트 로그를 사용하세요. :::note -거버넌스 프리컴파일은 Cosmos EVM `x/gov` 인터페이스를 따릅니다. 해당 주소는 [시스템 모듈 프리컴파일 표](/ko/how-to/use-system-modules#whats-exposed)에 나열되어 있습니다. 정확한 메서드 ABI와 `VoteOption` 열거형은 체인의 프리컴파일 인터페이스에서 생성하세요. +거버넌스 프리컴파일러는 Cosmos EVM `x/gov` 인터페이스를 따릅니다. 주소는 [시스템 모듈 프리컴파일러 테이블](/ko/how-to/use-system-modules#whats-exposed)에 나열되어 있습니다. 체인의 프리컴파일러 인터페이스에서 정확한 메서드 ABI 및 `VoteOption` enum을 생성합니다. ::: -## 다음 추천 +## 다음 권장 사항 -- [**스테이킹 프리컴파일 참조**](/ko/reference/staking-module-api) — 전체 validators(), 위임 메서드, 이벤트 시그니처를 찾아보세요. -- [**검증자 생성**](/ko/how-to/run-validator) — 동기화된 노드를 검증자로 등록하여 위 데이터에 나타나게 하세요. -- [**인덱서 및 분석**](/ko/reference/indexers) — 이미 정규화된 Stable 데이터를 제공하는 인덱싱 제공자를 둘러보세요. -- [**메인넷 정보**](/ko/reference/mainnet-information) — 인덱싱을 시작하기 전에 Chain ID, RPC 엔드포인트, 속도 제한을 확인하세요. +- [**스테이킹 프리컴파일러 참조**](/ko/reference/staking-module-api): 전체 `validators()`, 위임 메서드 및 이벤트 서명을 찾아봅니다. +- [**검증인 생성**](/ko/how-to/run-validator): 동기화된 노드를 검증인으로 등록하여 위 데이터에 나타나도록 합니다. +- [**인덱서 및 분석**](/ko/reference/indexers): 이미 정규화된 Stable 데이터를 제공하는 인덱싱 제공업체를 찾아봅니다. +- [**메인넷 정보**](/ko/reference/mainnet-information): 인덱싱을 시작하기 전에 체인 ID, RPC 엔드포인트 및 속도 제한을 확인합니다. diff --git a/docs/pages/ko/how-to/integrate-gas-waiver.mdx b/docs/pages/ko/how-to/integrate-gas-waiver.mdx index eca01e2..01796ac 100644 --- a/docs/pages/ko/how-to/integrate-gas-waiver.mdx +++ b/docs/pages/ko/how-to/integrate-gas-waiver.mdx @@ -1,52 +1,52 @@ --- source_path: how-to/integrate-gas-waiver.mdx -source_sha: 95a46a35ec56b9f823fb443aeb2693a9b0248e18 +source_sha: eaaf45d02173e1ce6279849d803d73014dbb7696 title: "가스 없는 트랜잭션 활성화" -description: "서명된 InnerTx 페이로드를 Waiver Server API에 제출하여 가스 없는 트랜잭션을 활성화하도록 Stable Gas Waiver를 통합하세요." +description: "서명된 InnerTx 페이로드를 Waiver Server API에 제출하여 Stable Gas Waiver를 통합하여 가스 없는 트랜잭션을 활성화합니다." diataxis: "how-to" --- # 가스 없는 트랜잭션 활성화 -Gas Waiver는 Stable에서 가스 없는 트랜잭션을 가능하게 합니다. Gas Waiver를 사용하면 애플리케이션이 사용자를 대신해 가스 수수료를 부담하므로, 사용자는 가스용 USDT0을 보유하지 않고도 컨트랙트와 상호작용할 수 있습니다. +Gas Waiver는 Stable에서 가스 없는 트랜잭션을 가능하게 합니다. Gas Waiver를 사용하면 애플리케이션이 사용자를 대신하여 가스 요금을 지불하므로 사용자는 가스 비용으로 USDT0를 보유하지 않고도 컨트랙트와 상호 작용할 수 있습니다. -이 가이드는 Waiver Server API를 통한 통합을 다룹니다. +이 가이드에서는 Waiver Server API를 통해 통합하는 방법을 다룹니다. :::note -**개념:** Gas Waiver가 무엇인지, 왜 존재하는지, 거버넌스 승인 waiver가 어떻게 작동하는지에 대해서는 [Gas waiver](/ko/explanation/gas-waiver)를 참조하세요. 전체 프로토콜 사양(래퍼 트랜잭션 형식, 마커 주소, 실행 시맨틱, 보안 모델)은 [Gas waiver protocol](/ko/reference/gas-waiver-api)을 참조하세요. +**개념:** Gas Waiver가 무엇인지, 왜 존재하는지, 거버넌스 승인된 Waiver가 어떻게 작동하는지에 대해서는 [Gas waiver](/ko/explanation/gas-waiver)를 참조하십시오. 전체 프로토콜 사양(래퍼 트랜잭션 형식, 마커 주소, 실행 의미 체계, 보안 모델)에 대해서는 [Gas waiver protocol](/ko/reference/gas-waiver-api)을 참조하십시오. ::: -## 사전 준비 사항 +## 필수 조건 - Stable 팀이 발급한 Waiver Server용 API 키 -- 대상 컨트랙트 주소가 waiver의 `AllowedTarget` 정책에 등록되어 있어야 합니다 +- 대상 컨트랙트 주소는 Waiver의 `AllowedTarget` 정책에 등록되어야 합니다. ## Waiver Server -**Base URL:** +**기본 URL:** - 메인넷: TBD - 테스트넷: `https://waiver.testnet.stable.xyz` -**Authorization:** `Bearer ` +**인증:** `Bearer ` ## 개요 -통합 흐름은 세 단계로 구성됩니다: +통합 흐름은 세 단계로 구성됩니다. -1. **InnerTx 빌드**: 사용자가 `gasPrice = 0`으로 트랜잭션에 서명합니다. -2. **Waiver Server에 제출**: 서명된 트랜잭션을 Waiver Server API에 제출합니다. -3. **응답 처리**: waiver 서버가 트랜잭션을 래핑하고 브로드캐스트합니다. 스트리밍된 결과를 처리하고 트랜잭션 해시를 사용자에게 표시합니다. +1. **InnerTx 빌드**: 사용자는 `gasPrice = 0`으로 트랜잭션에 서명합니다. +2. **Waiver Server에 제출**: 서명된 트랜잭션을 Waiver Server API에 제출합니다. +3. **응답 처리**: Waiver Server가 트랜잭션을 래핑하고 브로드캐스트합니다. 스트리밍된 결과를 처리하고 트랜잭션 해시를 사용자에게 표시합니다. ## 1단계: 사용자의 InnerTx 생성 -사용자는 `gasPrice = 0`으로 표준 트랜잭션에 서명합니다. `to` 주소와 메서드 셀렉터는 waiver의 `AllowedTarget` 정책에 의해 허용되어야 합니다. +사용자는 `gasPrice = 0`으로 표준 트랜잭션에 서명합니다. `to` 주소와 메서드 선택기는 Waiver의 `AllowedTarget` 정책에 의해 허용되어야 합니다. ```typescript // config.ts export const CONFIG = { RPC_URL: "https://rpc.testnet.stable.xyz", - CHAIN_ID: 2201, // 988 for mainnet + CHAIN_ID: 2201, // 메인넷의 경우 988 WAIVER_SERVER: "https://waiver.testnet.stable.xyz", USDT0_ADDRESS: "0x78Cf24370174180738C5B8E352B6D14c83a6c9A9", }; @@ -88,7 +88,7 @@ const signedInnerTx = await userWallet.signTransaction(innerTx); ``` :::warning -`gasPrice`는 반드시 `0`이어야 합니다. 0이 아니면 waiver 서버가 트랜잭션을 거부합니다. +`gasPrice`는 `0`이어야 합니다. 0이 아닌 경우 Waiver Server는 트랜잭션을 거부합니다. ::: ## 2단계: Waiver Server에 제출 @@ -112,7 +112,7 @@ const response = await fetch(`${CONFIG.WAIVER_SERVER}/v1/submit`, { ### 배치 제출 -단일 요청으로 여러 개의 서명된 트랜잭션을 제출할 수 있습니다: +단일 요청으로 여러 개의 서명된 트랜잭션을 제출할 수 있습니다. ```typescript body: JSON.stringify({ @@ -120,11 +120,11 @@ body: JSON.stringify({ }) ``` -각 결과 라인에는 배열 내 트랜잭션의 위치에 해당하는 `index` 필드가 포함됩니다. +각 결과 줄에는 배열 내 트랜잭션의 위치에 해당하는 `index` 필드가 포함됩니다. ## 3단계: 응답 처리 -응답은 NDJSON(개행으로 구분된 JSON)으로 스트리밍됩니다. 각 라인은 제출된 하나의 트랜잭션에 해당합니다. +응답은 NDJSON(줄바꿈으로 구분된 JSON)으로 스트리밍됩니다. 각 줄은 제출된 하나의 트랜잭션에 해당합니다. ```typescript const reader = response.body.getReader(); @@ -162,13 +162,13 @@ while (true) { | **코드** | **설명** | | :--- | :--- | -| `PARSE_ERROR` | 트랜잭션 파싱 실패 | -| `INVALID_REQUEST` | 잘못된 형식의 요청 본문 | +| `PARSE_ERROR` | 트랜잭션 구문 분석 실패 | +| `INVALID_REQUEST` | 잘못된 요청 본문 | | `BATCH_SIZE_EXCEEDED` | 배치 크기가 허용된 최대치를 초과함 | -| `VALIDATION_FAILED` | 트랜잭션 검증 실패 (예: 잘못된 서명, 허용되지 않은 대상) | -| `BROADCAST_FAILED` | 체인으로의 브로드캐스트 실패 | +| `VALIDATION_FAILED` | 트랜잭션 유효성 검사 실패 (예: 유효하지 않은 서명, 허용되지 않는 대상) | +| `BROADCAST_FAILED` | 체인으로 브로드캐스트 실패 | | `RATE_LIMITED` | 속도 제한 초과 | -| `QUEUE_FULL` | 서버 큐가 가득 참 | +| `QUEUE_FULL` | 서버 큐가 용량에 도달함 | | `TIMEOUT` | 요청 시간 초과 | ## API 레퍼런스 @@ -179,7 +179,7 @@ while (true) { ### POST `/v1/submit` -서명된 inner 트랜잭션의 배치를 제출합니다. 인증: 필수 (Bearer). +서명된 내부 트랜잭션 배치를 제출합니다. 인증: 필수 (Bearer). **요청 본문:** @@ -189,21 +189,21 @@ while (true) { } ``` -응답은 NDJSON으로 스트리밍됩니다. 각 라인은 제출된 트랜잭션 인덱스에 해당합니다. +응답은 NDJSON으로 스트리밍됩니다. 각 줄은 제출된 트랜잭션 인덱스에 해당합니다. ### GET `/v1/submit` 스트리밍 제출을 위한 WebSocket 인터페이스. 인증: 필수 (Bearer). -## 핵심 요약 +## 요점 -- Gas Waiver는 서버 측 통합입니다. 백엔드가 서명된 사용자 트랜잭션을 Waiver Server에 제출합니다. 사용자는 Waiver Server와 직접 상호작용하지 않습니다. -- 사용자가 항상 InnerTx에 서명하므로 서명 무결성이 유지됩니다. waiver는 사용자의 트랜잭션을 수정할 수 없습니다. -- 대상 컨트랙트는 waiver의 `AllowedTarget` 목록에 있어야 합니다. +- Gas Waiver는 서버 측 통합입니다. 백엔드가 서명된 사용자 트랜잭션을 Waiver Server에 제출합니다. 사용자는 Waiver Server와 직접 상호 작용하지 않습니다. +- 사용자는 항상 InnerTx에 서명하여 서명 무결성을 보존합니다. Waiver는 사용자의 트랜잭션을 수정할 수 없습니다. +- 대상 컨트랙트는 Waiver의 `AllowedTarget` 목록에 있어야 합니다. -## 다음 추천 +## 다음에 권장되는 내용 -- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions) — 데모 중심의 흐름과 영수증에서 제로 가스를 검증하는 방법을 확인하세요. -- [**자체 호스팅 Gas Waiver**](/ko/how-to/self-hosted-gas-waiver) — 호스팅된 API 없이 자체 waiver를 실행하세요. -- [**Gas waiver protocol**](/ko/reference/gas-waiver-api) — 전체 래퍼 트랜잭션 사양 및 거버넌스 모델. -- [**Stable SDK**](/ko/explanation/sdk-overview) — 타입이 지정된 클라이언트를 사용해 사용자 트랜잭션에 서명한 후 Waiver Server에 제출하세요. +- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions): 데모 중심 흐름과 영수증에서 제로 가스를 확인하는 방법을 참조하십시오. +- [**셀프 호스팅 Gas Waiver**](/ko/how-to/self-hosted-gas-waiver): 호스팅된 API 없이 자체 Waiver를 실행합니다. +- [**Gas Waiver 프로토콜**](/ko/reference/gas-waiver-api): 전체 래퍼 트랜잭션 사양 및 거버넌스 모델. +- [**Stable SDK**](/ko/explanation/sdk-overview): 유형이 지정된 클라이언트를 사용하여 Waiver Server에 제출할 사용자 트랜잭션에 서명합니다. diff --git a/docs/pages/ko/how-to/pay-with-invoice.mdx b/docs/pages/ko/how-to/pay-with-invoice.mdx index 7e8cbac..d01e4c3 100644 --- a/docs/pages/ko/how-to/pay-with-invoice.mdx +++ b/docs/pages/ko/how-to/pay-with-invoice.mdx @@ -1,72 +1,72 @@ --- source_path: how-to/pay-with-invoice.mdx -source_sha: 7c09e8018dbc151950875e9df186903fe8674032 -title: "인보이스로 결제하기" -description: "인보이스 메타데이터에서 파생된 결정적 nonce를 사용하여 ERC-3009로 Stable에서 인보이스를 정산하세요. 온체인 이벤트를 통해 대사 처리합니다." +source_sha: b7c9e4ad00713067eaea4c312ff14a82656e23bb +title: "송장으로 결제하기" +description: "송장 메타데이터에서 파생된 결정론적 논스를 사용하여 ERC-3009로 Stable에서 송장을 결제합니다. 온체인 이벤트를 통해 조정합니다." diataxis: "how-to" --- -# 인보이스로 결제하기 +# 송장으로 결제하기 -이 가이드는 인보이스 메타데이터에서 파생된 결정적 nonce를 사용하여 [ERC-3009](/ko/explanation/erc-3009)로 온체인에서 인보이스를 정산하는 과정을 안내합니다. nonce는 각 결제를 해당 인보이스에 연결하고 이중 결제를 방지합니다. +이 가이드는 송장 메타데이터에서 파생된 결정론적 논스를 사용하여 [ERC-3009](/ko/explanation/erc-3009)로 온체인에서 송장을 결제하는 방법을 안내합니다. 논스는 각 결제를 송장과 연결하고 이중 결제를 방지합니다. :::note -**개념:** 인보이스 정산 모델과 전통적인 B2B 인보이스 발행과의 비교는 [인보이스 정산](/ko/reference/invoices)을 참조하세요. +**개념:** 송장 결제 모델 및 기존 B2B 송장과의 비교에 대해서는 [송장 결제](/ko/reference/invoices)를 참조하세요. ::: -## 무엇을 만들게 되나요 +## 구현할 기능 -전체 인보이스 라이프사이클: 구매자가 오프체인에서 ERC-3009 인가에 서명하고, 공급업체가 이를 온체인에 제출하며, 대사 처리는 결과로 생성된 `AuthorizationUsed` 이벤트를 결정적 nonce로 인보이스에 다시 매칭합니다. +전체 송장 수명 주기: 구매자는 오프체인에서 ERC-3009 승인을 서명하고, 판매자는 온체인에 제출하며, 조정은 결정론적 논스를 통해 결과 `AuthorizationUsed` 이벤트를 송장에 다시 일치시킵니다. ### 데모 ```text -step 1. Invoice issued - number: INV-2026-001234 - amount: 5000 USDT0 - dueDate: 2026-04-30 - -step 2. Buyer signs authorization (off-chain, no gas) - nonce: 0xa1b2...c3d4 (from invoice metadata) - signature: 0xf0e9...1234 - -step 3. Vendor submits transferWithAuthorization - tx: 0x8f3a...2d41 - amount: 5000 USDT0 transferred to vendor - -step 4. Reconciliation - AuthorizationUsed(nonce=0xa1b2...) → invoice INV-2026-001234 - Transfer event verified for correct amount and parties - ERP: marked PAID at block 1284371 +단계 1. 송장 발행 + 번호: INV-2026-001234 + 금액: 5000 USDT0 + 기한: 2026-04-30 + +단계 2. 구매자가 승인 서명 (오프체인, 가스 없음) + 논스: 0xa1b2...c3d4 (송장 메타데이터에서) + 서명: 0xf0e9...1234 + +단계 3. 판매자가 transferWithAuthorization 제출 + 거래: 0x8f3a...2d41 + 금액: 5000 USDT0이 판매자에게 전송됨 + +단계 4. 조정 + AuthorizationUsed(nonce=0xa1b2...) → 송장 INV-2026-001234 + 올바른 금액 및 당사자에 대해 검증된 전송 이벤트 + ERP: 블록 1284371에 PAID로 표시됨 ``` ## 개요 **구매자:** -``` -─── Buyer ─────────────────────────────────────────── +```text +─── 구매자 ─────────────────────────────────────────── nonce = getInvoiceNonce(invoice) authorization = { from: buyer, to: vendor, value: amount, nonce, ... } signature = signTypedData(authorization) -// Option A: Buyer submits the transaction directly. +// 옵션 A: 구매자가 거래를 직접 제출합니다. usdt0.transferWithAuthorization(authorization, signature) -// Option B: Buyer sends {authorization, signature} to the vendor. -// The vendor (or a facilitator) submits on the buyer's behalf. +// 옵션 B: 구매자가 {authorization, signature}를 판매자에게 보냅니다. +// 판매자(또는 촉진자)가 구매자를 대신하여 제출합니다. ``` -**공급업체:** +**판매자:** -``` -─── Vendor ────────────────────────────────────────── -// If Option B: submit transferWithAuthorization using the buyer's signature +```text +─── 판매자 ────────────────────────────────────────── +// 옵션 B인 경우: 구매자의 서명을 사용하여 transferWithAuthorization 제출 -// Reconcile via AuthorizationUsed event +// AuthorizationUsed 이벤트를 통해 조정 on AuthorizationUsed(authorizer, nonce): invoice = nonceToInvoice.get(nonce) - transferLog = receipt.logs.find(Transfer matching invoice.buyer, invoice.vendor, invoice.amount) + transferLog = receipt.logs.find(송장.구매자, 송장.판매자, 송장.금액과 일치하는 전송) if transferLog: erpSystem.markPaid(invoice.id, txHash, settledAt) ``` @@ -102,17 +102,17 @@ export const TRANSFER_WITH_AUTHORIZATION_TYPE = { }; export interface Invoice { - number: string; // e.g. "INV-2026-001234" - vendor: string; // vendor wallet address - buyer: string; // buyer wallet address - amount: bigint; // amount in USDT0 atomic units (6 decimals) - dueDate: number; // Unix timestamp + number: string; // 예: "INV-2026-001234" + vendor: string; // 판매자 지갑 주소 + buyer: string; // 구매자 지갑 주소 + amount: bigint; // USDT0 원자 단위 (6진수) 금액 + dueDate: number; // Unix 타임스탬프 } ``` -## 1단계: 결정적 nonce 생성 +## 1단계: 결정론적 논스 생성 -구매자와 공급업체 모두 인보이스 메타데이터로부터 동일한 nonce를 독립적으로 계산할 수 있습니다. 외부 레지스트리가 필요하지 않습니다. +구매자와 판매자 모두 송장 메타데이터에서 동일한 논스를 독립적으로 계산할 수 있습니다. 외부 레지스트리는 필요하지 않습니다. ```typescript // nonce.ts @@ -132,7 +132,7 @@ export function getInvoiceNonce(invoice: Invoice): string { ); } -// Example +// 예시 const invoice: Invoice = { number: "INV-2026-001234", vendor: "0xVendorAddress", @@ -142,13 +142,13 @@ const invoice: Invoice = { }; const nonce = getInvoiceNonce(invoice); -// Same input always produces the same nonce. -// This nonce is consumed on-chain upon payment, preventing double payment. +// 동일한 입력은 항상 동일한 논스를 생성합니다. +// 이 논스는 결제 시 온체인에서 사용되며 이중 결제를 방지합니다. ``` -## 2단계: 인가에 서명 (구매자) +## 2단계: 승인 서명 (구매자) -구매자는 1단계의 결정적 nonce를 사용하여 ERC-3009 `transferWithAuthorization`에 서명합니다. +구매자는 1단계에서 얻은 결정론적 논스를 사용하여 ERC-3009 `transferWithAuthorization`에 서명합니다. ```typescript // sign-invoice.ts @@ -165,7 +165,7 @@ const buyerWallet = new ethers.Wallet(process.env.BUYER_KEY!, provider); async function signInvoiceAuthorization(invoice: Invoice) { const nonce = getInvoiceNonce(invoice); - const gracePeriod = 30 * 24 * 60 * 60; // 30 days after due date + const gracePeriod = 30 * 24 * 60 * 60; // 기한 후 30일 const authorization = { from: invoice.buyer, @@ -188,11 +188,11 @@ async function signInvoiceAuthorization(invoice: Invoice) { ## 3단계: 트랜잭션 제출 -제출하는 주체에 따라 두 가지 옵션이 있습니다. +누가 제출하는지에 따라 두 가지 옵션이 있습니다. ### 옵션 A: 구매자가 제출 -구매자가 `transferWithAuthorization` 트랜잭션을 직접 제출하고 가스를 지불합니다. 구매자가 결제 실행 시점과 방법을 제어할 때 사용합니다. 예를 들어 구매자의 회계 시스템이 내부 승인 흐름에 연결된 tx 해시를 필요로 하는 경우입니다. +구매자가 `transferWithAuthorization` 트랜잭션을 직접 제출하고 가스를 지불합니다. 구매자의 회계 시스템이 내부 승인 흐름과 연결된 트랜잭션 해시를 필요로 하는 경우와 같이 구매자가 결제가 실행되는 시기와 방법을 제어할 때 사용합니다. ```typescript // pay.ts @@ -227,14 +227,14 @@ async function payInvoice( const receipt = await tx.wait(1); console.log("Invoice paid, tx:", receipt.hash); - // The nonce is now consumed; the same invoice cannot be paid twice. + // 논스는 이제 사용되었으므로 동일한 송장을 두 번 결제할 수 없습니다. return { txHash: receipt.hash, blockNumber: receipt.blockNumber }; } ``` -### 옵션 B: 공급업체가 제출 +### 옵션 B: 판매자가 제출 -구매자는 API, 이메일 또는 어떤 채널을 통해서든 `{authorization, signature}`를 공급업체에 보냅니다. 공급업체(또는 퍼실리테이터)가 구매자를 대신하여 트랜잭션을 제출하므로 구매자는 가스를 관리할 필요가 없습니다. 공급업체가 동일한 요청 흐름 내에서 동기 확인을 필요로 할 때 사용합니다. +구매자는 API, 이메일 또는 기타 채널을 통해 `{authorization, signature}`를 판매자에게 보냅니다. 판매자(또는 촉진자)는 구매자를 대신하여 트랜잭션을 제출하므로 구매자는 가스를 관리할 필요가 없습니다. 동일한 요청 흐름 내에서 판매자가 동기식 확인을 필요로 하는 경우에 사용합니다. ```typescript // settle.ts @@ -273,12 +273,12 @@ async function settleInvoice( } ``` -## 4단계: 온체인 이벤트를 통한 대사 처리 (공급업체) +## 4단계: 온체인 이벤트를 통해 조정 (판매자) -누가 트랜잭션을 제출했든 관계없이, 모든 인보이스 결제는 결정적 nonce를 담은 `AuthorizationUsed` 이벤트를 발생시킵니다. 공급업체는 이 이벤트를 수신하고 nonce로 대기 중인 인보이스에 매칭합니다. nonce가 인보이스 메타데이터에서 파생되므로 매칭은 정확합니다. +누가 트랜잭션을 제출했는지에 관계없이 모든 송장 결제는 결정론적 논스를 포함하는 `AuthorizationUsed` 이벤트를 발생시킵니다. 판매자는 이 이벤트를 수신하고 논스를 통해 보류 중인 송장과 일치시킵니다. 논스는 송장 메타데이터에서 파생되므로 정확한 일치가 가능합니다. :::note -nonce로 매칭하면 어떤 인보이스가 결제되었는지 식별할 수 있지만, 공급업체는 동일한 트랜잭션 내의 `Transfer` 이벤트도 검증하여 올바른 금액이 올바른 수취인에게 전송되었는지 확인해야 합니다. 아래 코드는 이 검증을 포함합니다. +논스로 일치시키면 어떤 송장이 결제되었는지 식별할 수 있지만, 판매자는 올바른 금액이 올바른 수신자에게 전송되었는지 확인하기 위해 동일한 트랜잭션에서 `Transfer` 이벤트를 확인해야 합니다. 아래 코드는 이 확인을 포함합니다. ::: ```typescript @@ -296,8 +296,8 @@ const usdt0 = new ethers.Contract( provider, ); -// Build a lookup map: nonce -> invoice. -// In production, this comes from your invoice database. +// 조회 맵 구축: 논스 -> 송장 +// 실제 환경에서는 송장 데이터베이스에서 가져옵니다. const invoices: Invoice[] = [ { number: "INV-2026-001234", @@ -315,7 +315,7 @@ for (const inv of invoices) { usdt0.on("AuthorizationUsed", async (authorizer: string, nonce: string, event: any) => { const invoice = nonceToInvoice.get(nonce); - if (!invoice) return; // not one of our invoices + if (!invoice) return; // 우리의 송장이 아닌 경우 const receipt = await event.getTransactionReceipt(); @@ -332,20 +332,20 @@ usdt0.on("AuthorizationUsed", async (authorizer: string, nonce: string, event: a ); if (!transferLog) { - console.error("No matching Transfer event for invoice:", invoice.number); + console.error("송장과 일치하는 전송 이벤트 없음:", invoice.number); return; } - // All checks passed - console.log(`Invoice ${invoice.number} PAID`); - console.log(" tx:", receipt.hash); - console.log(" settled at block:", receipt.blockNumber); + // 모든 확인 통과 + console.log(`송장 ${invoice.number} 결제 완료`); + console.log(" 거래:", receipt.hash); + console.log(" 블록에서 결제 완료:", receipt.blockNumber); - // In production: update your ERP/accounting system here + // 실제 환경: 여기에서 ERP/회계 시스템 업데이트 // erpSystem.markPaid(invoice.number, receipt.hash, receipt.blockNumber); }); -console.log("Listening for invoice settlements..."); +console.log("송장 결제를 기다리는 중..."); ``` ```bash @@ -353,25 +353,25 @@ npx tsx reconcile.ts ``` ```text -Listening for invoice settlements... -Invoice INV-2026-001234 PAID - tx: 0x8f3a...2d41 - settled at block: 1284371 +송장 결제를 기다리는 중... +송장 INV-2026-001234 결제 완료 + 거래: 0x8f3a...2d41 + 블록에서 결제 완료: 1284371 ``` ## 실패한 결제 처리 -제출된 `transferWithAuthorization`은 여러 가지 이유로 되돌려질(revert) 수 있습니다. 각각을 감지하여 공급업체나 구매자에게 표시함으로써 인보이스를 재시도하거나 마감할 수 있도록 합니다. +제출된 `transferWithAuthorization`은 여러 가지 이유로 되돌려질 수 있습니다. 송장이 재시도되거나 닫힐 수 있도록 각 원인을 공급업체 또는 구매자에게 감지하고 알립니다. -| **Revert 사유** | **원인** | **복구 방법** | +| **되돌리기 사유** | **원인** | **복구** | | :--- | :--- | :--- | -| `FiatTokenV2: invalid signature` | 서명이 인가 필드와 일치하지 않습니다. | 인보이스 데이터를 변경하지 않은 상태로 구매자에게 재서명을 요청하세요. | -| `FiatTokenV2: authorization is used or canceled` | nonce가 이미 소비되었거나(이중 제출) 구매자가 취소했습니다. | 인보이스를 이미 결제됨으로 표시하고, nonce로 원래 tx를 조회하세요. | -| `FiatTokenV2: authorization is not yet valid` | `validAfter` 이전에 제출되었습니다. | `validAfter`까지 기다리거나 새 인가를 발급하세요. | -| `FiatTokenV2: authorization is expired` | `validBefore` 이후에 제출되었습니다. | 확장된 기간으로 새 인가를 발급하세요. | -| `FiatTokenV2: transfer amount exceeds balance` | 구매자의 USDT0 잔액이 부족합니다. | 구매자에게 지갑에 자금을 채우도록 알린 후 동일한 서명으로 재시도하세요. | +| `FiatTokenV2: invalid signature` | 서명이 승인 필드와 일치하지 않습니다. | 구매자에게 변경되지 않은 송장 데이터로 다시 서명하도록 요청합니다. | +| `FiatTokenV2: authorization is used or canceled` | 논스가 이미 사용되었거나(이중 제출) 구매자가 취소했습니다. | 송장을 이미 결제된 것으로 표시하고 논스로 원본 거래를 조회합니다. | +| `FiatTokenV2: authorization is not yet valid` | `validAfter` 이전에 제출되었습니다. | `validAfter`까지 기다리거나 새 승인을 발급합니다. | +| `FiatTokenV2: authorization is expired` | `validBefore` 이후에 제출되었습니다. | 기간이 연장된 새 승인을 발급합니다. | +| `FiatTokenV2: transfer amount exceeds balance` | 구매자의 USDT0 잔액이 부족합니다. | 구매자에게 지갑에 자금을 지원하도록 알린 다음 동일한 서명을 재시도합니다. | -revert를 포착하고 재시도하기 전에 분류하세요. +오류를 분류한 후 재시도를 위해 되돌리기를 catch합니다. ```typescript // retry.ts @@ -388,7 +388,7 @@ async function submitWithRetry( const reason = err?.info?.error?.message || err?.reason || err?.message || ""; if (reason.includes("authorization is used or canceled")) { - // Lookup the original tx by AuthorizationUsed event; mark invoice paid. + // AuthorizationUsed 이벤트를 통해 원본 거래를 조회하고 송장을 결제된 것으로 표시합니다. throw new Error("ALREADY_PAID"); } if (reason.includes("authorization is expired")) { @@ -406,11 +406,11 @@ async function submitWithRetry( ``` :::warning -오류를 분류하지 않고 실패한 제출을 절대 재시도하지 마세요. 되돌려진 transferWithAuthorization에 대한 무분별한 재시도는 구매자가 잔액을 충전한 후 검증을 통과할 수 있으며, 이는 구매자의 최신 의도와 일치하지 않을 수 있습니다. +오류를 분류하지 않고 실패한 제출을 재시도하지 마십시오. 되돌려진 transferWithAuthorization에 대한 맹목적인 재시도는 구매자가 잔액을 충전한 후 유효성 검사를 통과할 수 있으며, 이는 구매자의 최신 의도와 일치하지 않을 수 있습니다. ::: -## 다음 추천 +## 다음 권장 사항 -- [**인보이스 정산 개념**](/ko/reference/invoices) — 결정적 nonce 대사 처리 모델을 이해하세요. -- [**ERC-3009**](/ko/explanation/erc-3009) — 이 흐름의 기반이 되는 서명된 인가 표준을 검토하세요. -- [**가스 없는 트랜잭션 활성화**](/ko/how-to/integrate-gas-waiver) — Gas Waiver와 결합하여 정산 경로에서 가스를 제거하세요. +- [**송장 결제 개념**](/ko/reference/invoices): 결정론적-논스 조정 모델을 이해합니다. +- [**ERC-3009**](/ko/explanation/erc-3009): 이 흐름의 기반이 되는 서명된 승인 표준을 검토합니다. +- [**가스 없는 트랜잭션 활성화**](/ko/how-to/integrate-gas-waiver): 가스 면제와 결합하여 결제 경로에서 가스를 제거합니다. diff --git a/docs/pages/ko/how-to/pay-with-mcp.mdx b/docs/pages/ko/how-to/pay-with-mcp.mdx index 23d298b..27e9da2 100644 --- a/docs/pages/ko/how-to/pay-with-mcp.mdx +++ b/docs/pages/ko/how-to/pay-with-mcp.mdx @@ -1,46 +1,46 @@ --- source_path: how-to/pay-with-mcp.mdx -source_sha: 355c978d02f66d687a3bee1cb0f49dc3558381a9 +source_sha: bdf458199e0866324d1f3d08253609bea9b2236f title: "MCP 서버로 결제하기" -description: "x402가 활성화된 API를 MCP 서버를 통해 AI 클라이언트에 연결합니다. 사용자는 지갑이나 결제 흐름을 직접 관리하지 않고 프롬프트를 통해 API 호출 비용을 지불합니다." +description: "MCP 서버를 통해 x402 지원 API를 AI 클라이언트에 연결합니다. 사용자는 지갑이나 결제 흐름을 직접 관리할 필요 없이 프롬프트를 통해 API 호출 비용을 지불합니다." diataxis: "how-to" --- # MCP 서버로 결제하기 -이 가이드는 x402가 활성화된 API를 [MCP](https://modelcontextprotocol.io) 도구에 연결하여 AI 클라이언트가 자연어 프롬프트를 통해 이를 호출하고 비용을 지불할 수 있도록 하는 방법을 보여줍니다. 이는 [호출당 결제 API 구축하기](/ko/how-to/build-pay-per-call)의 서버를 기반으로 합니다. +이 가이드에서는 x402가 활성화된 API를 [MCP](https://modelcontextprotocol.io) 도구에 연결하여 AI 클라이언트가 자연어 프롬프트를 통해 API를 호출하고 비용을 지불하는 방법을 보여줍니다. 이 가이드는 [종량제 API 구축](/ko/how-to/build-pay-per-call)의 서버를 기반으로 합니다. -## 구축할 내용 +## 무엇을 구축할 것인가 -x402로 결제하는 엔드포인트를 도구로 감싸는 MCP 서버입니다. AI 클라이언트가 자연어 프롬프트를 입력하면 각 도구 호출이 x402 결제 요청을 트리거하고, 정산은 Stablescan에서 확인할 수 있습니다. 사용자는 지갑 프롬프트를 전혀 보지 않습니다. +x402 유료 API를 도구로 래핑하는 MCP 서버를 구축합니다. AI 클라이언트가 자연어 프롬프트를 입력하면 각 도구 호출이 유료 x402 요청을 트리거하고, 정산은 Stablescan에서 확인할 수 있습니다. 사용자는 지갑 프롬프트를 볼 필요가 없습니다. ### 데모 ```text -step 1. User in Claude: "Pull financials for ACME Corp and assess credit risk." +1단계. Claude의 사용자: "ACME Corp의 재무 데이터를 가져와 신용 위험을 평가해 줘." -step 2. Client calls get_company_financials("ACME") - → MCP handler: fetchWithPayment("/financials?ticker=ACME") - → 402 Payment Required → sign ERC-3009 → retry - → Facilitator settles $0.01 USDT0 on-chain +2단계. 클라이언트가 get_company_financials("ACME")를 호출합니다. + → MCP 핸들러: fetchWithPayment("/financials?ticker=ACME") + → 402 결제 필요 → ERC-3009 서명 → 다시 시도 + → Facilitator가 $0.01 USDT0를 온체인에서 정산합니다. → tx: 0x8f3a...aaaa → 200 OK { revenue, debt_ratio, cash_flow } -step 3. Client calls assess_credit_risk(financials) - → MCP handler: fetchWithPayment("/credit-risk", POST) - → Facilitator settles $0.05 USDT0 on-chain +3단계. 클라이언트가 assess_credit_risk(financials)를 호출합니다. + → MCP 핸들러: fetchWithPayment("/credit-risk", POST) + → Facilitator가 $0.05 USDT0를 온체인에서 정산합니다. → tx: 0x9bc4...bbbb → 200 OK { score: 72, rating: "moderate" } -step 4. Claude responds: - "ACME Corp has a credit risk score of 72 (moderate). Revenue is stable - but debt-to-equity ratio is elevated at 1.8x..." +4단계. Claude가 응답합니다. + "ACME Corp의 신용 위험 점수는 72점(보통)입니다. 매출은 안정적이지만, + 부채-자본 비율은 1.8배로 높습니다..." ``` 두 `tx` 값 모두 [https://stablescan.xyz](https://stablescan.xyz)에서 확인할 수 있습니다. :::note -**에이전트 지갑 자금 충전**: MCP 서버는 사용자가 제어하는 시드 문구로 결제에 서명합니다. 서버를 시작하기 전에 해당 지갑에 메인넷의 USDT0를 충전하세요. `$0.10` 이상의 잔액이면 여러 번의 유료 호출을 처리할 수 있으며, `$1.00`면 확장 테스트에 충분합니다. 필요에 따라 지갑 주소로 표준 USDT0 전송을 사용해 충전하세요. +**에이전트 지갑 자금 조달**: MCP 서버는 사용자가 제어하는 시드 문구로 결제에 서명합니다. 서버를 시작하기 전에 해당 지갑에 메인넷에서 USDT0를 채워 넣으세요. 최소 $0.10의 잔액이면 여러 유료 호출을 감당할 수 있으며, $1.00는 확장된 테스트에 충분합니다. 필요에 따라 표준 USDT0를 해당 지갑 주소로 이체하여 충전하세요. ::: ## 개요 @@ -48,8 +48,8 @@ step 4. Claude responds: **MCP 서버:** ```typescript -// --- MCP Server --- -// Bridge x402-enabled APIs to MCP tools +// --- MCP 서버 --- +// x402 지원 API를 MCP 도구에 연결합니다. tools = { "get_company_financials": { handler: (ticker) => @@ -67,30 +67,30 @@ tools = { **사용자 (AI 클라이언트를 통해):** -``` -─── AI Client ─────────────────────────────────────── -User: "Pull financials for ACME Corp and assess their credit risk." - -Client calls get_company_financials tool - → MCP server sends x402 paid request - → Facilitator settles USDT0 on-chain - → API returns financial data - -Client calls assess_credit_risk tool with the result - → MCP server sends x402 paid request - → Facilitator settles USDT0 on-chain - → API returns risk assessment - → Client responds with the combined result +```text +─── AI 클라이언트 ─────────────────────────────────────── +사용자: "ACME Corp의 재무 데이터를 가져와 신용 위험을 평가해 줘." + +클라이언트가 get_company_financials 도구를 호출합니다. + → MCP 서버가 x402 유료 요청을 보냅니다. + → Facilitator가 USDT0를 온체인에서 정산합니다. + → API가 재무 데이터를 반환합니다. + +클라이언트가 결과와 함께 assess_credit_risk 도구를 호출합니다. + → MCP 서버가 x402 유료 요청을 보냅니다. + → Facilitator가 USDT0를 온체인에서 정산합니다. + → API가 위험 평가를 반환합니다. + → 클라이언트가 결합된 결과로 응답합니다. ``` -## 사전 준비 +## 전제 조건 -- 실행 중인 x402 서버 ([호출당 결제 API 구축하기](/ko/how-to/build-pay-per-call) 참고). +- 실행 중인 x402 서버 ( [종량제 API 구축](/ko/how-to/build-pay-per-call) 참조). - MCP 호환 AI 클라이언트 (Claude Desktop, Claude Code 등). -## 1단계: MCP 서버 생성하기 +## 1단계: MCP 서버 생성 -MCP 서버는 AI 클라이언트와 x402가 활성화된 API 사이의 브리지 역할을 합니다. 각 도구는 x402 클라이언트 SDK를 사용해 유료 요청을 보내고 결과를 반환합니다. +MCP 서버는 AI 클라이언트와 x402 지원 API 간의 다리 역할을 합니다. 각 도구는 x402 클라이언트 SDK를 사용하여 유료 요청을 하고 결과를 반환합니다. ```bash npm install @modelcontextprotocol/sdk @x402/fetch @x402/evm @tetherto/wdk-wallet-evm @@ -105,7 +105,7 @@ import { x402Client, wrapFetchWithPayment } from "@x402/fetch"; import { registerExactEvmScheme } from "@x402/evm/exact/client"; import { z } from "zod"; -// --- Wallet and x402 client --- +// --- 지갑 및 x402 클라이언트 --- const account = await new WalletManagerEvm(process.env.SEED_PHRASE!, { provider: "https://rpc.stable.xyz", }).getAccount(0); @@ -114,10 +114,10 @@ const client = new x402Client(); registerExactEvmScheme(client, { signer: account }); const fetchWithPayment = wrapFetchWithPayment(fetch, client); -// --- x402 API base URL --- +// --- x402 API 기본 URL --- const API_BASE = process.env.API_BASE || "http://localhost:4021"; -// --- MCP server --- +// --- MCP 서버 --- const server = new McpServer({ name: "x402-payments", version: "1.0.0", @@ -125,8 +125,8 @@ const server = new McpServer({ server.tool( "get_company_financials", - "Get company financial data by ticker (paid endpoint, $0.01 per call)", - { ticker: z.string().describe("Company ticker symbol (e.g. ACME)") }, + "티커로 회사 재무 데이터 가져오기 (유료 엔드포인트, 호출당 $0.01)", + { ticker: z.string().describe("회사 티커 심볼 (예: ACME)") }, async ({ ticker }) => { const response = await fetchWithPayment(`${API_BASE}/financials?ticker=${ticker}`); const data = await response.json(); @@ -136,8 +136,8 @@ server.tool( server.tool( "assess_credit_risk", - "Assess credit risk from financial data (paid endpoint, $0.05 per call)", - { financials: z.string().describe("JSON string of company financial data") }, + "재무 데이터로 신용 위험 평가 (유료 엔드포인트, 호출당 $0.05)", + { financials: z.string().describe("회사 재무 데이터의 JSON 문자열") }, async ({ financials }) => { const response = await fetchWithPayment(`${API_BASE}/credit-risk`, { method: "POST", @@ -151,28 +151,28 @@ server.tool( server.tool( "check_balance", - "Check the USDT0 balance of the payment wallet", + "결제 지갑의 USDT0 잔액 확인", {}, async () => { const USDT0_STABLE = "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"; const balance = await account.getTokenBalance(USDT0_STABLE); const formatted = (Number(balance) / 1e6).toFixed(2); return { - content: [{ type: "text", text: `Wallet balance: ${formatted} USDT0` }], + content: [{ type: "text", text: `지갑 잔액: ${formatted} USDT0` }], }; }, ); -// --- Start --- +// --- 시작 --- const transport = new StdioServerTransport(); await server.connect(transport); ``` -각 도구 핸들러는 `fetchWithPayment`를 호출하며, 이는 전체 x402 결제 주기를 자동으로 처리합니다. AI 클라이언트는 도구 이름, 설명, 매개변수만 봅니다. +각 도구 핸들러는 `fetchWithPayment`를 호출하며, 이는 전체 x402 결제 주기를 자동으로 처리합니다. AI 클라이언트는 도구 이름, 설명 및 매개변수만 볼 수 있습니다. -## 2단계: AI 클라이언트 설정하기 +## 2단계: AI 클라이언트 구성 -AI 클라이언트의 설정에 MCP 서버를 추가합니다. +MCP 서버를 AI 클라이언트 구성에 추가합니다. **Claude Desktop** (`claude_desktop_config.json`): @@ -183,7 +183,7 @@ AI 클라이언트의 설정에 MCP 서버를 추가합니다. "command": "npx", "args": ["tsx", "/path/to/mcp-server.ts"], "env": { - "SEED_PHRASE": "your seed phrase here", + "SEED_PHRASE": "여기에 시드 문구 입력", "API_BASE": "https://api.example.com" } } @@ -197,45 +197,45 @@ AI 클라이언트의 설정에 MCP 서버를 추가합니다. claude mcp add x402-payments -- npx tsx /path/to/mcp-server.ts ``` -설정 후 AI 클라이언트를 재시작하세요. 도구들이 사용 가능한 도구 목록에 나타나야 합니다. +설정 후 AI 클라이언트를 다시 시작하십시오. 도구는 사용 가능한 도구 목록에 나타나야 합니다. :::warning -MCP 설정의 시드 문구는 실제 자금을 제어합니다. 평문 설정 파일에 저장하는 대신 OS 키체인이나 시크릿 매니저를 사용해 안전하게 보관하세요. +MCP 구성의 시드 문구는 실제 자금을 제어합니다. 일반 텍스트 구성 파일 대신 OS 키체인 또는 비밀 관리자를 사용하여 안전하게 저장하십시오. ::: -## 3단계: 프롬프트 입력 및 사용하기 +## 3단계: 프롬프트 입력 및 사용 -설정이 완료되면 AI 클라이언트는 사용자의 프롬프트를 통해 유료 API를 호출할 수 있습니다: +구성되면 AI 클라이언트는 사용자의 프롬프트를 통해 유료 API를 호출할 수 있습니다. -**사용자:** "ACME Corp의 재무 정보를 가져와서 신용 위험을 평가해줘." +**사용자:** "ACME Corp의 재무 데이터를 가져와 신용 위험을 평가해 줘." -1. 클라이언트가 `get_company_financials("ACME")`를 호출: x402를 통해 $0.01 결제. 매출, 부채 비율, 현금 흐름 등을 반환합니다. -2. 클라이언트가 `assess_credit_risk(financials)`를 호출: x402를 통해 $0.05 결제. 위험 점수, 등급, 핵심 요인을 반환합니다. -3. 클라이언트 응답: "ACME Corp의 신용 위험 점수는 72점(중간)입니다. 매출은 안정적이지만 부채비율이 1.8배로 다소 높습니다..." +1. 클라이언트가 `get_company_financials("ACME")`를 호출합니다: x402를 통해 $0.01 지불. 수익, 부채 비율, 현금 흐름 등을 반환합니다. +2. 클라이언트가 `assess_credit_risk(financials)`를 호출합니다: x402를 통해 $0.05 지불. 위험 점수, 등급, 주요 요인을 반환합니다. +3. 클라이언트가 응답합니다: "ACME Corp의 신용 위험 점수는 72점(보통)입니다. 매출은 안정적이지만, 부채-자본 비율은 1.8배로 높습니다..." -개별 도구도 단독으로 작동합니다: +개별 도구도 자체적으로 작동합니다. -- "ACME Corp의 재무 정보를 가져와줘"는 `get_company_financials`를 호출합니다 ($0.01). -- "이 데이터의 신용 위험을 평가해줘"는 `assess_credit_risk`를 호출합니다 ($0.05). -- "USDT0가 얼마나 남았어?"는 `check_balance`를 호출합니다. +- "ACME Corp의 재무 데이터를 가져와"는 `get_company_financials`($0.01)를 호출합니다. +- "이 데이터에 대한 신용 위험을 평가해 줘"는 `assess_credit_risk`($0.05)를 호출합니다. +- "USDT0 잔액이 얼마나 남았나요?"는 `check_balance`를 호출합니다. -사용자는 지갑, 서명, 결제 흐름과 상호작용하지 않습니다. MCP 서버가 각 도구 호출에 대한 결제를 투명하게 처리합니다. +사용자는 지갑, 서명 또는 결제 흐름과 상호 작용하지 않습니다. MCP 서버는 각 도구 호출에 대한 결제를 투명하게 처리합니다. -## 지출 제어 +## 지출 통제 -예기치 않은 지출을 방지하려면 MCP 서버에 제어 장치를 추가하는 것을 고려하세요. +예기치 않은 지출을 방지하려면 MCP 서버에 통제 기능을 추가하는 것을 고려하십시오. ```typescript -const MAX_PER_CALL = 100_000; // $0.10 in base units -const MAX_PER_SESSION = 5_000_000; // $5.00 in base units +const MAX_PER_CALL = 100_000; // 기본 단위로 $0.10 +const MAX_PER_SESSION = 5_000_000; // 기본 단위로 $5.00 let sessionSpent = 0n; function checkSpendingLimit(amount: bigint) { if (amount > BigInt(MAX_PER_CALL)) { - throw new Error(`Amount exceeds per-call limit of $${MAX_PER_CALL / 1e6}`); + throw new Error(`금액이 호출당 제한인 $${MAX_PER_CALL / 1e6}을 초과합니다.`); } if (sessionSpent + amount > BigInt(MAX_PER_SESSION)) { - throw new Error(`Session spending limit of $${MAX_PER_SESSION / 1e6} reached`); + throw new Error(`세션 지출 한도인 $${MAX_PER_SESSION / 1e6}에 도달했습니다.`); } sessionSpent += amount; } @@ -243,8 +243,8 @@ function checkSpendingLimit(amount: bigint) { 이러한 제한은 서버 측에서 실행됩니다. AI 클라이언트는 이를 수정하거나 우회할 수 없습니다. -## 다음 추천 +## 다음 권장 사항 -- [**호출당 결제 API 구축하기**](/ko/how-to/build-pay-per-call) — 이 MCP 서버가 브리지하는 x402 서버를 설정합니다. -- [**x402 개념**](/ko/explanation/x402) — 이러한 결제 뒤에 있는 정산 프로토콜을 살펴봅니다. -- [**AI로 개발하기**](/ko/how-to/develop-with-ai) — Stable의 Docs 및 Runtime MCP 서버를 동일한 AI 클라이언트에 연결합니다. +- [**종량제 API 구축**](/ko/how-to/build-pay-per-call): 이 MCP 서버가 연결하는 x402 서버를 설정합니다. +- [**x402 개념**](/ko/explanation/x402): 이러한 결제 뒤에 있는 정산 프로토콜을 검토합니다. +- [**AI로 개발**](/ko/how-to/develop-with-ai): Stable의 Docs 및 Runtime MCP 서버를 동일한 AI 클라이언트에 연결합니다. diff --git a/docs/pages/ko/how-to/production-readiness.mdx b/docs/pages/ko/how-to/production-readiness.mdx index dd12b86..0bcb101 100644 --- a/docs/pages/ko/how-to/production-readiness.mdx +++ b/docs/pages/ko/how-to/production-readiness.mdx @@ -1,30 +1,30 @@ --- source_path: how-to/production-readiness.mdx -source_sha: 4789a197ff1efd758012e442307c58c105ac716a -title: "프로덕션 준비 상태" -description: "메인넷에 배포하기 전 통합을 검증하세요: 보안, 신뢰성, 운영, 그리고 에스컬레이션 경로." +source_sha: 99ec4061509a9a91f28a5a835a51015abb204503 +title: "프로덕션 준비" +description: "메인넷에 출시하기 전에 통합을 검증하세요: 보안, 안정성, 운영 및 에스컬레이션 방법." diataxis: "how-to" --- -# 프로덕션 준비 상태 +# 프로덕션 준비 -테스트넷에서 메인넷으로 전환하기 전에 아래 각 섹션을 순서대로 검토하세요. +테스트넷에서 메인넷으로 전환하기 전에 아래 각 섹션을 진행하세요. -## 출시 전 확인사항 +## 출시 전 -- **네트워크 대상.** 애플리케이션이 테스트넷이 아닌 메인넷 값을 읽습니다: chain ID `988`, RPC `https://rpc.stable.xyz`, 익스플로러 `https://stablescan.xyz`. 전체 구성은 [Connect](/ko/reference/connect)에 있습니다. -- **컨트랙트 검증.** 배포된 컨트랙트가 [stablescan.xyz](https://stablescan.xyz)에서 검증되어 사용자와 파트너가 검사할 수 있습니다. -- **메인넷 자금 조달 경로.** 프로덕션 지갑이 USDT0를 확보할 수 있는 문서화된 방법이 있습니다: 직접, LayerZero를 통한 브리지, 또는 커스터디언. 파우셋은 테스트넷 전용입니다. -- **환경 격리.** 키, RPC 자격 증명, 서명 경로가 테스트넷과 메인넷 간에 분리되어 있습니다. +- **네트워크 대상.** 애플리케이션이 테스트넷 값이 아닌 메인넷 값을 읽습니다: 체인 ID `988`, RPC `https://rpc.stable.xyz`, 익스플로러 `https://stablescan.xyz`. 전체 구성은 [연결](/ko/reference/connect)에 있습니다. +- **계약 검증.** 배포된 계약은 [stablescan.xyz](https://stablescan.xyz)에서 검증되어 사용자와 파트너가 검사할 수 있습니다. +- **메인넷 자금 조달 경로.** 프로덕션 지갑이 USDT0을 획득하는 문서화된 방법이 있습니다: 직접, LayerZero를 통한 브릿지 또는 관리인. faucets는 테스트넷 전용입니다. +- **환경 격리.** 키, RPC 자격 증명 및 서명 경로는 테스트넷과 메인넷 간에 분리되어 있습니다. ## 보안 점검 -USDT0의 이중 역할 동작은 이더리움에서 가져온 몇 가지 가정을 무너뜨립니다. 아래 각 항목을 검증해야 합니다. 전체 목록은 [마이그레이션 체크리스트](/ko/explanation/usdt0-behavior)에 있습니다. +USDT0의 이중 역할 동작은 이더리움에서 가져온 몇 가지 가정을 깨뜨립니다. 아래 각 항목은 검증되어야 합니다. 전체 목록은 [마이그레이션 체크리스트](/ko/explanation/usdt0-behavior)에 있습니다. -**지급 능력(solvency) 점검은 미러가 아닌 실제 네이티브 잔액을 읽습니다.** +**지불 능력 확인은 미러가 아닌 실제 네이티브 잔액을 읽습니다.** :::warning -입금된 네이티브 값을 내부 변수에서 추적하는 것은 안전하지 않습니다. 외부 `USDT0.transferFrom` 호출은 어떤 컨트랙트 코드도 실행하지 않고 컨트랙트의 네이티브 잔액을 고갈시킬 수 있습니다. +내부 변수에 예치된 네이티브 값을 추적하는 것은 안전하지 않습니다. 외부 `USDT0.transferFrom` 호출은 계약 코드를 호출하지 않고도 계약의 네이티브 잔액을 고갈시킬 수 있습니다. ::: ```solidity @@ -38,12 +38,12 @@ function withdraw() external { } ``` -**Allowance 기반 고갈 경로가 테스트로 다뤄집니다.** 모든 `approve` / `transferFrom` / `permit` 경로에는 컨트랙트의 네이티브 잔액 고갈을 시도하는 테스트가 있습니다. +**허용량 기반 드레인 경로는 테스트로 다룹니다.** 모든 `approve` / `transferFrom` / `permit` 경로에는 계약의 네이티브 잔액을 고갈시키려는 테스트가 있습니다. -**제로 주소 전송은 호출 전에 거부됩니다.** +**영주소 전송은 호출 전에 거부됩니다.** :::warning -Stable에서는 네이티브 및 ERC-20 전송 모두 `address(0)`로의 전송 시 revert됩니다. 수신자를 명시적으로 검증하세요. 그렇지 않으면 트랜잭션이 실패합니다. +Stable에서 `address(0)`로의 네이티브 및 ERC-20 전송은 모두 되돌려집니다. 수신자를 명시적으로 검증하지 않으면 트랜잭션이 실패합니다. ::: ```solidity @@ -51,30 +51,30 @@ require(recipient != address(0), "zero address recipient"); payable(recipient).call{value: amount}(""); ``` -**주소 재사용 감지는 `EXTCODEHASH`에 의존하지 않습니다.** Permit 기반 승인은 nonce 증가 없이 네이티브 잔액을 변경하므로 `EXTCODEHASH`가 제로 해시와 빈 해시 사이를 오갈 수 있습니다. 대신 명시적 추적을 사용하세요. +**주소 재사용 감지는 `EXTCODEHASH`에 의존하지 않습니다.** 허용량 기반 승인은 논스 증가 없이 네이티브 잔액을 변경하므로 `EXTCODEHASH`는 제로 해시와 빈 해시 사이를 오갈 수 있습니다. 대신 명시적 추적을 사용하세요. -## 성능 및 신뢰성 +## 성능 및 안정성 -- **RPC 이중화.** 프로덕션 트래픽에는 페일오버 계획이 있습니다. 서드파티 제공업체는 [RPC 제공업체](/ko/reference/rpc-providers)에 나열되어 있습니다. -- **가스 추정.** 트랜잭션은 `maxPriorityFeePerGas`를 `0`으로 설정하고 현재 base fee로부터 `maxFeePerGas`를 계산합니다. [가스 가격 책정](/ko/reference/gas-pricing-api)을 참조하세요. -- **블록 시간.** 블록은 약 0.7초마다 생성되며 단일 슬롯 최종성을 가집니다. 폴링 간격과 확인 임계값을 이 주기에 맞춰 조정합니다. -- **재시도.** 일시적인 RPC 오류는 멱등적으로 재시도됩니다. 금전적으로 민감한 플로우의 경우 다운스트림 상태 변경 전에 영수증 또는 로그를 통해 포함 여부를 검증합니다. +- **RPC 중복성.** 프로덕션 트래픽에는 페일오버 계획이 있습니다. 타사 제공업체는 [RPC 제공업체](/ko/reference/rpc-providers)에 나열되어 있습니다. +- **가스 추정.** 트랜잭션은 `maxPriorityFeePerGas`를 `0`으로 설정하고 현재 기본 수수료에서 `maxFeePerGas`를 계산합니다. [가스 가격 책정](/ko/reference/gas-pricing-api)을 참조하세요. +- **블록 시간.** 블록은 단일 슬롯 완결성으로 약 0.7초마다 생성됩니다. 폴링 간격 및 확인 임계값은 이 주기에 맞게 조정됩니다. +- **재시도.** 일시적인 RPC 오류는 멱등적으로 재시도됩니다. 금융적으로 민감한 흐름의 경우, 수신 또는 로그를 통해 포함이 확인된 후 다운스트림 상태가 변경됩니다. ## 운영 소유권 -- **모니터링.** 자체 노드를 운영하는 경우 알림이 블록 생성, 피어 상태, RPC 지연 시간을 감시합니다. [모니터링](/ko/how-to/monitor-node)을 참조하세요. 서드파티 RPC를 사용하는 경우 제공업체 SLA와 페일오버 텔레메트리를 추적하세요. -- **업그레이드.** 노드 운영자가 업그레이드를 일정에 맞춰 진행할 수 있도록 프로토콜 릴리스를 추적합니다. [메인넷 버전 히스토리](/ko/reference/mainnet-version-history)를 참조하세요. -- **런북.** 컨트랙트 일시 중지, 키 교체, RPC 제공업체 전환에 대한 롤백 절차가 존재합니다. +- **모니터링.** 자체 노드를 운영하는 경우, 경고는 블록 생산, 피어 상태 및 RPC 대기 시간을 모니터링합니다. [노드 모니터링](/ko/how-to/monitor-node)을 참조하세요. 타사 RPC를 사용하는 경우, 제공업체 SLA 및 페일오버 텔레메트리를 추적하세요. +- **업그레이드.** 프로토콜 릴리스는 노드 운영자가 업그레이드를 예약할 수 있도록 추적됩니다. [메인넷 버전 기록](/ko/reference/mainnet-version-history)을 참조하세요. +- **런북.** 계약 일시 중지, 키 순환 및 RPC 제공업체 전환을 위한 롤백 절차가 존재합니다. ## 지원 및 에스컬레이션 -- [개발자 지원](/ko/reference/developer-assistance): FAQ 및 참조 자료 포인터. -- [Discord](https://discord.gg/stablexyz): 커뮤니티 지원 및 프로토콜 업데이트. -- `bizdev@stable.xyz`: 파트너십 및 통합 관련 논의. +- [개발자 지원](/ko/reference/developer-assistance): FAQ 및 참조 포인터. +- [디스코드](https://discord.gg/stablexyz): 커뮤니티 지원 및 프로토콜 업데이트. +- `bizdev@stable.xyz`: 파트너십 및 통합 대화. ## 다음 권장 사항 -- [**USDT0 동작**](/ko/explanation/usdt0-behavior) — 전체 마이그레이션 체크리스트와 컨트랙트 설계 요구사항을 읽어보세요. -- [**메인넷 정보**](/ko/reference/mainnet-information) — 메인넷 체인 매개변수와 버전 히스토리를 확인하세요. -- [**RPC 제공업체**](/ko/reference/rpc-providers) — 이중화를 위한 서드파티 RPC 제공업체를 선택하세요. -- [**모니터링**](/ko/how-to/monitor-node) — 블록 생성 및 RPC 상태에 대한 메트릭과 알림을 연결하세요. +- [**USDT0 동작**](/ko/explanation/usdt0-behavior): 전체 마이그레이션 체크리스트 및 계약 설계 요구 사항을 읽어보세요. +- [**메인넷 정보**](/ko/reference/mainnet-information): 메인넷 체인 매개변수 및 버전 기록을 확인하세요. +- [**RPC 제공업체**](/ko/reference/rpc-providers): 중복성을 위해 타사 RPC 제공업체를 선택하세요. +- [**모니터링**](/ko/how-to/monitor-node): 블록 생산 및 RPC 상태에 대한 지표 및 경고를 연결하세요. diff --git a/docs/pages/ko/how-to/run-validator.mdx b/docs/pages/ko/how-to/run-validator.mdx index 880a2c8..6ff54c7 100644 --- a/docs/pages/ko/how-to/run-validator.mdx +++ b/docs/pages/ko/how-to/run-validator.mdx @@ -1,25 +1,25 @@ --- source_path: how-to/run-validator.mdx -source_sha: 2ce47d3b037076ab9550319f91845149a6b98f83 -title: "검증자 생성하기" -description: "동기화된 Stable 노드를 활성 검증자로 승격하기: 키 준비, 스테이킹 프리컴파일로 등록, 검증, 그리고 자기 위임." +source_sha: d00aabfde18ce379eb65d00c6fc12306a7c631a5 +title: "검증인 생성" +description: "동기화된 Stable 노드를 활성 검증인으로 승격시키세요: 키 준비, 스테이킹 사전 컴파일에 등록, 확인 및 자체 위임." diataxis: "how-to" --- -검증자는 온체인에 등록되고 스테이크를 본딩한 동기화된 풀 노드입니다. 먼저 노드를 설치하고 동기화한 다음, 스테이킹 프리컴파일(`0x0000000000000000000000000000000000000800`)에서 `createValidator`를 호출하여 등록합니다. 이 페이지에서는 등록 단계를 다룹니다. 노드 자체에 대해서는 [노드 설치하기](/ko/how-to/install-node)와 [노드 구성](/ko/reference/node-configuration)을 참조하세요. +검증인은 온체인에 등록되고 스테이크를 보증한 동기화된 전체 노드입니다. 먼저 노드를 설치하고 동기화한 다음, 스테이킹 사전 컴파일(`0x0000000000000000000000000000000000000800`)에서 `createValidator`를 호출하여 등록합니다. 이 페이지에서는 등록 단계를 다룹니다. 노드 자체에 대해서는 [노드 설치](/ko/how-to/install-node) 및 [노드 구성](/ko/reference/node-configuration)을 참조하세요. :::warning -노드가 완전히 동기화된 후에만 등록하세요. 따라잡기 전에 서명하는 검증자는 이중 서명을 하여 세트에서 영구적으로 제거(tombstone)될 수 있습니다. 시작하기 전에 `config.toml`에서 `double_sign_check_height = 2` 또는 그 이상으로 설정하세요(자세한 내용은 [노드 구성](/ko/reference/node-configuration#consensus-configuration) 참조). `1`로 설정하면 검사를 수행하지 않습니다. +노드가 완전히 동기화된 후에만 등록하세요. 따라잡기 전에 서명하는 검증인은 이중 서명으로 인해 영구적으로 세트에서 제거될 수 있습니다(tombstoned). 시작하기 전에 `config.toml`에서 `double_sign_check_height = 2` 이상으로 설정하세요( [노드 구성](/ko/reference/node-configuration#consensus-configuration) 참조). `1`로 설정하면 확인을 수행하지 않습니다. ::: -## 사전 요구사항 +## 전제 조건 -- 메인넷(Chain ID `988`)에서 완전히 동기화된 풀 노드. [노드 설치하기](/ko/how-to/install-node) 참조. -- `~/.stabled/config/config.toml`에서 `double_sign_check_height`가 `2` 또는 그 이상으로 설정됨. -- 프리컴파일 호출에 사용되는 `cast`를 위한 [Foundry](https://book.getfoundry.sh/) 설치. -- 검증자의 EVM 주소에 USDT0로 입금된 스테이킹 금액. +- 메인넷(체인 ID `988`)에 완전히 동기화된 전체 노드. [노드 설치](/ko/how-to/install-node)를 참조하세요. +- `~/.stabled/config/config.toml`에 `double_sign_check_height`가 `2` 이상으로 설정되어 있습니다. +- `cast`에 설치된 [Foundry](https://book.getfoundry.sh/)는 사전 컴파일을 호출하는 데 사용됩니다. +- 검증인의 EVM 주소에 USDT0으로 스테이킹 금액이 자금 지원되었습니다. -진행하기 전에 노드가 따라잡았는지 확인하세요. `catching_up`은 반드시 `false`여야 합니다. +노드가 더 진행하기 전에 따라잡았는지 확인하세요. `catching_up`은 `false`여야 합니다. ```bash curl -s localhost:26657/status | jq '.result.sync_info.catching_up' @@ -29,54 +29,54 @@ curl -s localhost:26657/status | jq '.result.sync_info.catching_up' false ``` -## 1단계: 검증자 키 준비 +## 1단계: 검증인 키 준비 -오퍼레이터 계정을 생성한 다음, `createValidator`에 필요한 두 가지 값인 합의 공개 키(base64)와 검증자의 EVM 주소를 읽습니다. +운영자 계정을 생성한 다음 `createValidator`에 필요한 두 가지 값(합의 공개 키(base64)와 검증인의 EVM 주소)을 읽습니다. ```bash -# Create the validator operator account +# 검증인 운영자 계정 생성 stabled keys add validator -# Consensus public key (base64) — save this +# 합의 공개 키 (base64) — 저장하세요. stabled comet show-validator | jq .key -# Derive the validator's EVM address (0x form) +# 검증인의 EVM 주소 (0x 형식) 파생 stabled keys parse $(stabled keys show validator -a) ``` ```text "AbCd...base64PubKey...==" # ... -# then, evm address is 0xCAEA59C7476C87D0FF6BE6F04DA207601D5BE7D0 +# 그러면 EVM 주소는 0xCAEA59C7476C87D0FF6BE6F04DA207601D5BE7D0입니다. ``` :::warning -`~/.stabled/config/priv_validator_key.json`을 오프라인으로 백업하고, 동일한 키로 두 개의 노드를 절대 실행하지 마세요. 하나의 키로 두 인스턴스가 서명하는 것은 이중 서명이며 영구적인 슬래시로 이어집니다. +`~/.stabled/config/priv_validator_key.json`을 오프라인으로 백업하고 동일한 키로 두 개의 노드를 실행하지 마세요. 하나의 키로 서명하는 두 인스턴스는 이중 서명이며 영구적인 슬래시를 초래합니다. ::: ## 2단계: 환경 설정 ```bash -# Staking precompile contract address +# 스테이킹 사전 컴파일 계약 주소 export STAKING_ADDRESS="0x0000000000000000000000000000000000000800" -# Mainnet EVM RPC +# 메인넷 EVM RPC export RPC_URL="https://rpc.stable.xyz" -# Your operator private key and validator EVM address +# 운영자 개인 키 및 검증인 EVM 주소 export PRIVATE_KEY="your_private_key_here" export VALIDATOR_ADDRESS="0xYourValidatorAddress" -# Consensus pubkey from Step 1 +# 1단계의 합의 공개 키 export PUBKEY="AbCd...base64PubKey...==" -# Self-delegation amount in wei (18 decimals). 1000000000000000000 = 1 token +# wei 단위의 자체 위임 금액 (18 Decimal). 1000000000000000000 = 1 토큰 export AMOUNT="1000000000000000000" ``` -## 3단계: 검증자 생성 +## 3단계: 검증인 생성 -스테이킹 프리컴파일에서 `createValidator`를 호출합니다. 이 함수는 `description` 튜플, `commissionRates` 튜플, 최소 자기 위임, 검증자 주소, 합의 공개 키, 그리고 본딩 금액을 받습니다. `cast`로 인코딩하여 전송하세요. +스테이킹 사전 컴파일에 `createValidator`를 호출합니다. 이 함수는 `description` 튜플, `commissionRates` 튜플, 최소 자체 위임, 검증인 주소, 합의 공개 키 및 보증 금액을 사용합니다. 이를 `cast`로 인코딩하고 보냅니다. ```bash # createValidator( @@ -98,33 +98,33 @@ cast send "$STAKING_ADDRESS" \ ```text transactionHash 0x4f...c2 -status 1 (success) +status 1 (성공) ``` -커미션 튜플은 `(rate, maxRate, maxChangeRate)`이며, 각각 18자리 소수로 스케일됩니다. 예제는 10% 비율(`100000000000000000`), 20% 상한선, 그리고 1% 최대 일일 변경률을 설정합니다. `maxRate`와 `maxChangeRate`는 생성 시 고정되며 나중에 수정할 수 없습니다. 성공적인 호출은 `CreateValidator` 이벤트를 발생시킵니다. 모든 필드에 대해서는 [스테이킹 프리컴파일 레퍼런스](/ko/reference/staking-module-api#createvalidator)를 참조하세요. +수수료 튜플은 `(rate, maxRate, maxChangeRate)`이며, 각 18진수로 스케일링됩니다. 예제는 10%의 비율(`100000000000000000`), 20%의 상한선, 1%의 최대 일일 변경률을 설정합니다. `maxRate` 및 `maxChangeRate`는 생성 시 고정되며 나중에 편집할 수 없습니다. 성공적인 호출은 `CreateValidator` 이벤트를 발생시킵니다. 모든 필드는 [스테이킹 사전 컴파일 참조](/ko/reference/staking-module-api#createvalidator)를 참조하세요. -## 4단계: 검증 +## 4단계: 확인 -스테이킹 프리컴파일에서 다시 읽어 검증자가 등록되고 본딩되었는지 확인한 다음, 블록에 서명하고 있는지 확인하세요. +검증인이 등록되고 보증되었는지 확인하려면 스테이킹 사전 컴파일에서 다시 읽은 다음 블록을 서명하고 있는지 확인합니다. ```bash -# Read your validator's on-chain record +# 검증인의 온체인 기록 읽기 cast call "$STAKING_ADDRESS" \ "validator(address)" "$VALIDATOR_ADDRESS" \ --rpc-url "$RPC_URL" -# Confirm the node reports validator info +# 노드가 검증인 정보를 보고하는지 확인 curl -s localhost:26657/status | jq '.result.validator_info' ``` ```text -# validator() returns the moniker, tokens, commission, and a bonded status (3) -# validator_info shows your consensus address with non-zero voting power +# validator()는 모니커, 토큰, 수수료 및 보증 상태(3)를 반환합니다. +# validator_info는 0이 아닌 투표 권한이 있는 합의 주소를 보여줍니다. ``` -## 자기 위임 추가 +## 자체 위임 추가 -생성 후 자신의 검증자에 더 많은 스테이크를 본딩하려면, 동일한 프리컴파일에서 `delegate`를 호출하세요. +생성 후 자신의 검증기에 더 많은 스테이크를 보증하려면 동일한 사전 컴파일에 `delegate`를 호출합니다. ```bash cast send "$STAKING_ADDRESS" \ @@ -135,20 +135,20 @@ cast send "$STAKING_ADDRESS" \ ``` ```text -status 1 (success) +status 1 (성공) ``` ## 등록 후 -검증자를 건강하게 유지하고 네트워크 업그레이드에 대비하세요: +검증인을 건전하게 유지하고 네트워크 업그레이드에 대비합니다. -- [노드 모니터링하기](/ko/how-to/monitor-node)의 Prometheus 및 Grafana 스택으로 **서명과 누락된 블록을 모니터링**하세요. -- 업그레이드 높이를 놓치지 않도록 **업그레이드를 자동화**하세요. [노드 설치하기](/ko/how-to/install-node#cosmovisor-setup-recommended-for-automatic-upgrades)와 [노드 업그레이드하기](/ko/how-to/upgrade-node)의 Cosmovisor 설정을 참조하세요. -- [노드 문제 해결하기](/ko/how-to/troubleshoot-node)로 **문제를 진단**하세요(동기화되지 않음, 서명하지 않음). +- [**노드 모니터링**](/ko/how-to/monitor-node)에서 Prometheus 및 Grafana 스택으로 **서명 및 놓친 블록을 모니터링**합니다. +- 업그레이드 높이를 놓치지 않도록 **업그레이드를 자동화**합니다. [노드 설치](/ko/how-to/install-node#cosmovisor-setup-recommended-for-automatic-upgrades) 및 [노드 업그레이드](/ko/how-to/upgrade-node)의 Cosmovisor 설정을 참조하세요. +- [**노드 문제 해결**](/ko/how-to/troubleshoot-node)으로 **문제 진단**(동기화 안 됨, 서명 안 됨). ## 다음 권장 사항 -- [**스테이킹 프리컴파일 레퍼런스**](/ko/reference/staking-module-api) — 전체 createValidator, delegate, editValidator 시그니처와 구조체를 찾아보세요. -- [**노드 구성**](/ko/reference/node-configuration) — 등록하기 전에 double_sign_check_height 및 기타 검증자 핵심 구성을 설정하세요. -- [**노드 모니터링하기**](/ko/how-to/monitor-node) — 서명, 누락된 블록, 리소스 사용량을 추적하여 슬래시 전에 문제를 포착하세요. -- [**검증자 데이터 인덱싱하기**](/ko/how-to/index-validator-data) — 검증자가 활성화되면 온체인에서 스테이크, 가동 시간, 투표 이력을 읽으세요. +- [**스테이킹 사전 컴파일 참조**](/ko/reference/staking-module-api): createValidator, delegate 및 editValidator의 전체 서명 및 구조를 찾아봅니다. +- [**노드 구성**](/ko/reference/node-configuration): 등록하기 전에 double_sign_check_height 및 기타 검증인에게 중요한 구성을 설정합니다. +- [**노드 모니터링**](/ko/how-to/monitor-node): 문제를 슬래시하기 전에 문제를 파악할 수 있도록 서명, 놓친 블록 및 리소스 사용량을 추적합니다. +- [**검증인 데이터 색인**](/ko/how-to/index-validator-data): 검증인이 활성화되면 온체인에서 스테이크, 가동 시간 및 투표 기록을 읽습니다. diff --git a/docs/pages/ko/how-to/sdk-with-viem.mdx b/docs/pages/ko/how-to/sdk-with-viem.mdx index 30f1a90..a5131fa 100644 --- a/docs/pages/ko/how-to/sdk-with-viem.mdx +++ b/docs/pages/ko/how-to/sdk-with-viem.mdx @@ -1,20 +1,20 @@ --- source_path: how-to/sdk-with-viem.mdx -source_sha: c80565f060bd79708a5811def2e3b67fa2cedab9 +source_sha: 48be50a291feef6843b9074ab105a81c375d5845 title: "viem과 함께 SDK 사용하기" -description: "@stablechain/sdk로 서명하는 세 가지 방법: 프라이빗 키 Account, 브라우저 Transport, 또는 미리 구성된 viem WalletClient." +description: "@stablechain/sdk로 세 가지 방법으로 서명할 수 있습니다: 프라이빗 키 계정, 브라우저 트랜스포트, 또는 미리 빌드된 viem WalletClient." diataxis: "how-to" --- # viem과 함께 SDK 사용하기 -`@stablechain/sdk`는 viem 기반으로 만들어졌습니다. `createStable`은 세 가지 서명 모드를 지원하며, 코드가 실행되는 위치에 따라 하나를 선택합니다: 프라이빗 키를 사용하는 서버 측, 사용자 지갑을 사용하는 브라우저 측, 또는 이미 구성한 `WalletClient`(예: wagmi 앱에서)를 사용하는 방식입니다. +`@stablechain/sdk`는 viem 위에 구축됩니다. `createStable`은 세 가지 서명 모드를 허용하며, 코드가 실행되는 위치에 따라 하나를 선택합니다: 프라이빗 키를 이용한 서버 측, 사용자 지갑을 이용한 브라우저 측, 또는 이미 구성한 `WalletClient`(예: wagmi 앱)를 이용한 방식입니다. -이 가이드에서는 각 모드를 처음부터 끝까지 보여줍니다. +이 가이드는 각 모드를 처음부터 끝까지 보여줍니다. ## 서버 측: 프라이빗 키 `Account` -viem의 `privateKeyToAccount`를 사용해 백엔드가 보유한 프라이빗 키로 서명합니다. +viem의 `privateKeyToAccount`를 사용하여 백엔드에서 보유한 프라이빗 키로 서명합니다. ```ts import "dotenv/config"; @@ -43,7 +43,7 @@ console.log(txHash); ## 브라우저 측: 지갑에서 가져온 `Transport` -`custom(window.ethereum)`(또는 모든 EIP-1193 프로바이더)을 `transport`로 전달합니다. SDK가 `WalletClient`를 구성하고 프로바이더에서 서명자 주소를 읽어옵니다. +`custom(window.ethereum)` (또는 모든 EIP-1193 프로바이더)를 `transport`로 전달합니다. SDK는 `WalletClient`를 구축하고 프로바이더에서 서명자 주소를 읽습니다. ```ts import { createStable, Network } from "@stablechain/sdk"; @@ -68,12 +68,12 @@ const { txHash } = await stable.transfer({ ``` :::warning -`transfer`, `bridge`, `swap`는 `switchChain`을 호출해 지갑을 올바른 네트워크로 전환합니다. 사용자가 거부하면 SDK는 `phase: "switch_chain"`과 함께 `StableTransactionError`를 발생시킵니다. 이를 잡아서 사용자에게 재시도를 표시하세요. +`transfer`, `bridge`, 및 `swap`은 지갑을 올바른 네트워크에 연결하기 위해 `switchChain`을 호출합니다. 사용자가 거절하면 SDK는 `StableTransactionError`를 `phase: "switch_chain"`과 함께 발생시킵니다. 이를 포착하고 사용자에게 재시도를 표시해야 합니다. ::: -## 직접 만든 `WalletClient` 사용하기 +## 자체 `WalletClient` 가져오기 -이미 `WalletClient`가 있는 경우(예: wagmi 또는 커스텀 서명자에서), 직접 전달하세요. 이는 `account` 및 `transport`보다 우선합니다. +_이미_ `WalletClient`를 가지고 있는 경우(예: wagmi 또는 사용자 지정 서명자에서 가져온 경우) 직접 전달합니다. 이는 `account` 및 `transport`보다 우선합니다. ```ts import { createStable, Network } from "@stablechain/sdk"; @@ -99,16 +99,16 @@ const { txHash } = await stable.transfer({ from, to: "0xRecipient", amount: 5 }) 0x8f3a...2d41 ``` -## 모드 선택하기 +## 모드 선택 | **모드** | **사용 시점** | | :--- | :--- | -| `account` | 백엔드 서비스, 스크립트, 에이전트 — 키를 보유한 모든 곳. | -| `transport` | 사용자가 MetaMask 또는 wagmi 없는 커스텀 플로우로 서명하는 브라우저 앱. | -| `walletClient` | 이미 구성된 `WalletClient`가 있는 경우(wagmi, RainbowKit, ConnectKit). | +| `account` | 백엔드 서비스, 스크립트, 에이전트, 키를 보유하고 있는 곳 어디든. | +| `transport` | MetaMask 또는 wagmi가 없는 사용자 지정 흐름으로 사용자가 서명하는 브라우저 앱. | +| `walletClient` | 이미 구성된 `WalletClient`가 있는 경우 (wagmi, RainbowKit, ConnectKit). | ## 다음 권장 사항 -- [**wagmi와 함께 사용하기**](/ko/how-to/sdk-with-wagmi) — wagmi 훅을 통해 SDK를 React 앱에 연결합니다. -- [**SDK 레퍼런스**](/ko/reference/sdk) — 모든 설정 필드, 메서드, 열거형, 에러 클래스. -- [**SDK 빠른 시작**](/ko/tutorial/sdk-quickstart) — 테스트넷에서 첫 transfer, bridge, swap을 실행합니다. +- [**wagmi와 함께 사용**](/ko/how-to/sdk-with-wagmi): wagmi Hooks를 통해 SDK를 React 앱에 연결합니다. +- [**SDK 참조**](/ko/reference/sdk): 모든 구성 필드, 메서드, ENUM, 오류 클래스. +- [**SDK 빠른 시작**](/ko/tutorial/sdk-quickstart): 테스트넷에서 첫 번째 전송, 브릿지, 스왑을 실행합니다. diff --git a/docs/pages/ko/how-to/sdk-with-wagmi.mdx b/docs/pages/ko/how-to/sdk-with-wagmi.mdx index 611eeca..9036fad 100644 --- a/docs/pages/ko/how-to/sdk-with-wagmi.mdx +++ b/docs/pages/ko/how-to/sdk-with-wagmi.mdx @@ -1,6 +1,6 @@ --- source_path: how-to/sdk-with-wagmi.mdx -source_sha: d3266e146435bf079104ad0d84f274096f220701 +source_sha: 396745c5590db9fb3f8b0677d67b69579aeeb55a title: "wagmi와 함께 SDK 사용하기" description: "wagmi의 useWalletClient, useAccount, useChainId 훅을 사용하여 @stablechain/sdk를 React 앱에 연결합니다." diataxis: "how-to" @@ -8,13 +8,13 @@ diataxis: "how-to" # wagmi와 함께 SDK 사용하기 -`createStable`은 viem `WalletClient`를 받는데, 이는 wagmi의 `useWalletClient`가 반환하는 것과 정확히 일치합니다. 평소처럼 wagmi를 통해 지갑을 연결한 다음, 지갑 클라이언트가 변경될 때마다 `StableClient`를 메모이즈합니다. +`createStable`은 wagmi의 `useWalletClient`가 반환하는 것과 정확히 같은 viem `WalletClient`를 받습니다. 평소처럼 wagmi를 통해 지갑을 연결한 다음, 지갑 클라이언트가 변경될 때마다 `StableClient`를 메모이제이션합니다. -이 가이드는 wagmi v2와 `@tanstack/react-query`를 전제로 합니다. +이 가이드는 wagmi v2와 `@tanstack/react-query`를 가정합니다. ## 1. wagmi 구성하기 -wagmi 설정에 Stable을 추가합니다. viem은 두 네트워크 모두에 대한 체인 정의를 제공합니다. +Stable을 wagmi 구성에 추가합니다. viem은 두 네트워크에 대한 체인 정의를 제공합니다. ```ts import { http, createConfig } from "wagmi"; @@ -35,9 +35,9 @@ export const wagmiConfig = createConfig({ WagmiConfig { chains: [988, 2201], connectors: [injected] } ``` -## 2. `StableClient`를 반환하는 훅 만들기 +## 2. `StableClient`를 반환하는 훅 빌드하기 -현재 `WalletClient`에 대해 `StableClient`를 메모이즈합니다. 지갑 클라이언트의 식별자가 변경되면 다시 생성합니다. +현재 `WalletClient`에 대해 `StableClient`를 메모이제이션합니다. 지갑 클라이언트 아이덴티티가 변경될 때마다 다시 생성합니다. ```tsx import { useMemo } from "react"; @@ -55,7 +55,7 @@ export function useStable(network: Network = Network.Mainnet): StableClient | nu ``` :::warning -`useWalletClient()`는 사용자가 연결하기 전에는 `undefined`를 반환합니다. SDK 메서드를 호출하기 전에 항상 가드를 두어야 합니다. 그렇지 않으면 구조 분해된 `walletClient`가 falsy가 되어 `createStable`이 서명자를 갖지 못합니다. +`useWalletClient()`는 사용자가 연결하기 전에는 `undefined`를 반환합니다. SDK 메서드를 호출하기 전에 항상 보호 장치를 두어야 합니다. 그렇지 않으면 구조 분해된 `walletClient`가 거짓이 되고 `createStable`에 서명자가 없게 됩니다. ::: ## 3. 컴포넌트에서 사용하기 @@ -92,9 +92,9 @@ export function PayButton() { Sent: 0x8f3a...2d41 ``` -## 4. React에서 브리지와 스왑하기 +## 4. React에서 브릿지 및 스왑하기 -동일한 `stable` 인스턴스가 브리지와 스왑을 처리합니다. effect나 `useQuery`에서 견적을 가져온 다음, 클릭 시 실행합니다. +동일한 `stable` 인스턴스가 브릿지 및 스왑을 처리합니다. effect 또는 `useQuery`에서 견적을 가져온 다음 클릭 시 실행합니다. ```tsx const stable = useStable(Network.Mainnet); @@ -123,11 +123,11 @@ const onSwap = async () => { ``` :::note -`useQuery`로 견적을 캐싱하는 것이 잘 작동합니다. `quoteSwap` / `quoteBridge`를 쿼리 함수로 전달하고 캐시된 `quote`를 `swap` / `bridge`로 전달하세요. SDK는 견적이 제공되면 내부 견적 호출을 건너뜁니다. +`useQuery`로 견적을 캐싱하는 것은 잘 작동합니다. `quoteSwap` / `quoteBridge`를 쿼리 함수로 전달하고 캐시된 `quote`를 `swap` / `bridge`에 전달합니다. SDK는 견적이 제공되면 내부 견적 호출을 건너뜁니다. ::: ## 다음 권장 사항 -- [**SDK 레퍼런스**](/ko/reference/sdk) — 모든 메서드, 설정 필드, 오류 클래스. -- [**viem과 함께 사용하기**](/ko/how-to/sdk-with-viem) — 세 가지 서명 모드를 나란히 비교합니다. -- [**SDK 빠른 시작**](/ko/tutorial/sdk-quickstart) — 테스트넷에서 첫 전송, 브리지, 스왑을 실행해 보세요. +- [**SDK 참조**](/ko/reference/sdk): 모든 메서드, 구성 필드 및 오류 클래스. +- [**viem과 함께 사용하기**](/ko/how-to/sdk-with-viem): 세 가지 서명 모드를 나란히 비교합니다. +- [**SDK 퀵스타트**](/ko/tutorial/sdk-quickstart): 테스트넷에서 첫 번째 전송, 브릿지 및 스왑을 실행합니다. diff --git a/docs/pages/ko/how-to/self-hosted-gas-waiver.mdx b/docs/pages/ko/how-to/self-hosted-gas-waiver.mdx index 728bcdc..b9b696c 100644 --- a/docs/pages/ko/how-to/self-hosted-gas-waiver.mdx +++ b/docs/pages/ko/how-to/self-hosted-gas-waiver.mdx @@ -1,39 +1,39 @@ --- source_path: how-to/self-hosted-gas-waiver.mdx -source_sha: 60e5bccdb2641ffd0f4c1184d8dfb6e642990c73 +source_sha: c054baff79a39314af7a4aaa087bd4525dfc7f12 title: "자체 호스팅 가스 면제" -description: "Stable에서 직접 가스 면제 인프라를 운영하세요. 거버넌스를 통해 면제 주소를 등록하고, 래퍼 트랜잭션을 구성하며, 호스팅된 Waiver Server API 없이 직접 브로드캐스트합니다." +description: "Stable에서 자체 가스 면제 서비스를 운영하세요. 거버넌스를 통해 면제 주소를 등록하고, 래퍼 트랜잭션을 구축하며, 호스팅된 서버 없이 브로드캐스트할 수 있습니다." diataxis: "how-to" --- # 자체 호스팅 가스 면제 -자체 호스팅 가스 면제를 사용하면 호스팅된 Waiver Server API 대신 직접 면제 인프라를 운영할 수 있습니다. 온체인 거버넌스를 통해 면제 주소를 등록한 다음, 래퍼 트랜잭션을 네트워크에 직접 브로드캐스트합니다. +자체 호스팅 가스 면제를 통해 호스팅된 면제 서버 API를 사용하는 대신 자체 면제 인프라를 운영할 수 있습니다. 온체인 거버넌스를 통해 면제 주소를 등록한 다음, 래퍼 트랜잭션을 네트워크에 직접 브로드캐스트합니다. -이 가이드에서는 면제 주소 등록, 서명된 사용자 트랜잭션 수집, 래퍼 트랜잭션 구성, 그리고 브로드캐스트 방법을 다룹니다. +이 가이드는 면제 주소 등록, 서명된 사용자 트랜잭션 수집, 래퍼 트랜잭션 구성 및 브로드캐스트를 다룹니다. :::note -**개념:** 가스 면제가 무엇이며 왜 존재하는지에 대해서는 [가스 면제](/ko/explanation/gas-waiver)를 참조하세요. 전체 프로토콜 사양(래퍼 트랜잭션 메커니즘, 권한 부여, 정책 확인, 실행 의미론, 보안 모델)에 대해서는 [가스 면제 프로토콜](/ko/reference/gas-waiver-api)을 참조하세요. +**개념:** 가스 면제가 무엇이고 왜 필요한지에 대한 내용은 [가스 면제](/ko/explanation/gas-waiver)를 참조하세요. 전체 프로토콜 사양(래퍼 트랜잭션 메커니즘, 권한 부여, 정책 확인, 실행 의미론, 보안 모델)은 [가스 면제 프로토콜](/ko/reference/gas-waiver-api)을 참조하세요. ::: -호스팅된 Waiver Server API 통합 경로에 대해서는 [가스 비용 없는 트랜잭션 활성화](/ko/how-to/integrate-gas-waiver)를 참조하세요. +호스팅된 면제 서버 API 통합 경로는 [가스 무료 트랜잭션 활성화](/ko/how-to/integrate-gas-waiver)를 참조하세요. -## 사전 요구사항 +## 전제 조건 -- 검증자 거버넌스를 통해 온체인에 등록된 면제 주소. -- 대상 컨트랙트에 대해 구성된 `AllowedTarget` 정책. +- 검증인 거버넌스를 통해 온체인에 등록된 면제 주소. +- 대상 계약에 대해 구성된 `AllowedTarget` 정책. ## 개요 자체 호스팅 흐름: -1. `gasPrice = 0`인 **서명된 InnerTx를 사용자로부터 수집**합니다. -2. **WrapperTx를 구성**합니다: InnerTx를 RLP 인코딩하고 마커 주소로 전송되는 트랜잭션으로 래핑합니다. +1. 사용자의 `gasPrice = 0`인 **서명된 InnerTx를 수집**합니다. +2. **WrapperTx를 구성합니다**: InnerTx를 RLP 인코딩하고, 마커 주소로 전송되는 트랜잭션에 래핑합니다. 3. `eth_sendRawTransaction`을 통해 WrapperTx를 **브로드캐스트**합니다. -## 1단계: 사용자의 InnerTx 수집 +## 1단계: 사용자 InnerTx 수집 -사용자는 `gasPrice = 0`으로 트랜잭션에 서명합니다. `to` 주소와 메서드 셀렉터는 면제의 `AllowedTarget` 정책과 일치해야 합니다. +사용자는 `gasPrice = 0`인 트랜잭션에 서명합니다. `to` 주소와 메서드 선택자는 면제자의 `AllowedTarget` 정책과 일치해야 합니다. ```typescript // config.ts @@ -84,7 +84,7 @@ const signedInnerTx = await userWallet.signTransaction(innerTx); ## 2단계: WrapperTx 구성 -서명된 InnerTx를 RLP 인코딩하고 마커 주소로 전송되는 트랜잭션으로 래핑합니다. `gasLimit`은 내부 실행과 래핑 오버헤드를 모두 충당해야 합니다. +서명된 InnerTx를 RLP 인코딩하고 마커 주소로 전송되는 트랜잭션에 래핑합니다. `gasLimit`은 내부 실행과 래핑 오버헤드를 모두 포함해야 합니다. ```typescript // constructWrapper.ts @@ -110,12 +110,12 @@ const signedWrapperTx = await waiverWallet.signTransaction(wrapperTx); ``` :::warning -`InnerTx.gasPrice`와 `WrapperTx.gasPrice` 모두 `0`이어야 합니다. `WrapperTx.value` 또한 `0`이어야 합니다. 이러한 조건 중 하나라도 충족되지 않으면 검증자가 트랜잭션을 거부합니다. +`InnerTx.gasPrice`와 `WrapperTx.gasPrice`는 모두 `0`이어야 합니다. `WrapperTx.value`도 `0`이어야 합니다. 이 조건 중 하나라도 충족되지 않으면 검증인이 트랜잭션을 거부합니다. ::: ## 3단계: 브로드캐스트 -표준 JSON-RPC를 통해 서명된 WrapperTx를 제출합니다. +서명된 WrapperTx를 표준 JSON-RPC를 통해 제출합니다. ```typescript // broadcast.ts @@ -131,14 +131,14 @@ Wrapper tx broadcast: 0x... Confirmed: true ``` -## 핵심 요점 +## 주요 요점 -- 자체 호스팅 면제에는 온체인 검증자 거버넌스를 통해 등록된 면제 주소가 필요합니다. -- WrapperTx는 RLP 인코딩된 InnerTx를 데이터로 하여 마커 주소(`0x...f333`)로 전송됩니다. +- 자체 호스팅 면제는 온체인 검증인 거버넌스를 통해 등록된 면제 주소를 필요로 합니다. +- WrapperTx는 RLP 인코딩된 InnerTx를 데이터로 사용하여 마커 주소(`0x...f333`)로 전송됩니다. - InnerTx와 WrapperTx 모두 `gasPrice = 0` 및 `value = 0`이어야 합니다. -## 다음 추천 +## 다음 권장 사항 -- [**가스 면제 개념**](/ko/explanation/gas-waiver) — 직접 운영하기 전에 메커니즘을 이해하세요. -- [**가스 면제 프로토콜**](/ko/reference/gas-waiver-api) — 마커 라우팅, 권한 부여, 실행 의미론에 대한 전체 프로토콜 사양을 참조하세요. -- [**가스 비용 없는 트랜잭션 활성화**](/ko/how-to/integrate-gas-waiver) — 자체 호스팅 대신 호스팅된 Waiver Server API를 사용하세요. +- [**가스 면제 개념**](/ko/explanation/gas-waiver): 자체 서비스를 운영하기 전에 메커니즘을 이해하세요. +- [**가스 면제 프로토콜**](/ko/reference/gas-waiver-api): 마커 라우팅, 권한 부여 및 실행 의미론에 대한 전체 프로토콜 사양을 참조하세요. +- [**가스 없는 트랜잭션 활성화**](/ko/how-to/integrate-gas-waiver): 자체 호스팅 대신 호스팅된 면제 서버 API를 사용하세요. diff --git a/docs/pages/ko/how-to/subscribe-and-collect.mdx b/docs/pages/ko/how-to/subscribe-and-collect.mdx index b12fc23..45ceadd 100644 --- a/docs/pages/ko/how-to/subscribe-and-collect.mdx +++ b/docs/pages/ko/how-to/subscribe-and-collect.mdx @@ -1,22 +1,22 @@ --- source_path: how-to/subscribe-and-collect.mdx -source_sha: c1fe3d6efad8671b22584ae67ffc3cdbf929337d +source_sha: a381dc34ff14359750a205ac7aca9d960486455a title: "구독 및 수금" -description: "EIP-7702 위임을 사용하여 Stable에서 풀 기반 구독 결제를 구축하세요. 구독자 인증을 설정하고 청구 주기 수금을 자동화하세요." +description: "EIP-7702 위임을 사용하여 Stable에서 풀 기반 구독 결제를 구축합니다. 구독자 권한 부여를 설정하고 청구 주기 수금을 자동화합니다." diataxis: "how-to" --- # 구독 및 수금 -이 가이드는 구독자가 한 번 인증하면 서비스 제공자가 EIP-7702 계정 추상화를 통해 각 청구 주기마다 자동으로 수금하는 구독 결제 시스템을 구축하는 과정을 안내합니다. +이 가이드는 EIP-7702 계정 추상화를 통해 구독자가 한 번만 승인하면 서비스 제공자가 각 청구 주기를 자동으로 수금하는 구독 결제 시스템을 구축하는 방법을 안내합니다. :::note -**개념:** 구독 모델, 트레이드오프, 카드 등록 청구와의 비교에 대해서는 [구독 청구](/ko/reference/subscriptions)를 참조하세요. +**개념**: 구독 모델, 장단점 및 카드 저장 청구와의 비교에 대한 자세한 내용은 [구독 청구](/ko/reference/subscriptions)를 참조하세요. ::: -## 무엇을 만들게 되나요 +## 구축할 내용 -전체 구독 라이프사이클: 구독자가 한 번 위임 및 구독하고, 제공자가 일정에 따라 수금하며(반복 동작을 증명하기 위해 두 번째 주기 표시), 구독자가 취소합니다. +전체 구독 라이프사이클: 구독자는 한 번 위임하고 구독하며, 제공자는 일정에 따라 수금하고 (반복 동작을 증명하기 위해 두 번째 주기 표시), 구독자는 취소합니다. ### 데모 @@ -46,7 +46,7 @@ step 5. Subscriber cancels **구독자:** -``` +```text ─── Subscriber ─────────────────────────────────────── // One-time setup: delegate EOA to the subscription contract signAuthorization(delegateContract) @@ -61,7 +61,7 @@ sendTransaction({ to: self, data: cancelSubscription(subscriptionId) }) **서비스 제공자:** -``` +```text ─── Service Provider ──────────────────────────────── // Each billing cycle: collect payment from subscriber's EOA // The delegate contract verifies caller, billing schedule, and amount @@ -71,14 +71,14 @@ sendTransaction({ to: subscriberEOA, data: collect(subscriptionId) }) // The contract reverts if called before the interval has elapsed ``` -## 위임 컨트랙트 +## 위임 계약 -구독 청구는 구독자의 EOA를 청구 조건을 강제하는 컨트랙트로 위임하여 작동합니다. EIP-7702를 통해 구독자의 계정은 일시적으로 컨트랙트 로직을 획득하므로, 서비스 제공자는 구독자가 매번 서명할 필요 없이 각 청구 주기마다 결제를 수금할 수 있습니다. +구독 청구는 구독자의 EOA를 청구 조건을 강제하는 계약에 위임하여 작동합니다. EIP-7702를 통해 구독자의 계정은 일시적으로 계약 로직을 얻게 되어 서비스 제공업체가 구독자가 매번 서명할 필요 없이 각 청구 주기마다 결제를 수금할 수 있습니다. -기존에 배포된 컨트랙트를 사용하거나 직접 배포할 수 있습니다. 아래 예시는 세 가지 작업을 지원하는 최소한의 `SubscriptionManager` 컨트랙트입니다: +기존에 배포된 계약을 사용하거나 직접 배포할 수 있습니다. 아래 예시는 세 가지 작업을 지원하는 최소한의 `SubscriptionManager` 계약입니다. - `subscribe`: `subscriptionId`에 대한 청구 조건을 등록합니다. -- `collect`: 제공자가 해당 `subscriptionId`에 대해 다음 예정된 결제를 수금합니다. +- `collect`: 제공자가 해당 `subscriptionId`에 대한 다음 예정 결제를 가져옵니다. - `cancelSubscription`: 구독자가 특정 구독을 취소합니다. ```solidity @@ -180,7 +180,7 @@ contract SubscriptionManager { ``` :::note -이 컨트랙트는 테스트 목적의 참조 구현으로 제공됩니다. 위임 컨트랙트는 구독자의 EOA에 대한 완전한 실행 권한을 가지므로, 프로덕션에서는 감사 및 검증된 컨트랙트를 사용하세요. EIP-7702 위임 및 보안에 대한 자세한 내용은 [EIP-7702](/ko/explanation/eip-7702)를 참조하세요. +이 계약은 테스트를 위한 참조 구현으로 제공됩니다. 위임 계약은 구독자의 EOA에 대한 완전한 실행 권한을 가지므로, 프로덕션에서는 감사 및 확인된 계약을 사용하십시오. EIP-7702 위임 및 보안에 대한 자세한 내용은 [EIP-7702](/ko/explanation/eip-7702)를 참조하십시오. ::: ## 구성 @@ -198,9 +198,9 @@ export const provider = new ethers.JsonRpcProvider(STABLE_TESTNET_RPC); export const subscriberWallet = new ethers.Wallet(process.env.SUBSCRIBER_KEY!, provider); ``` -## 1단계: 구독자의 EOA 위임 (EIP-7702) +## 1단계: 구독자의 EOA 위임(EIP-7702) -구독자는 EIP-7702 인증에 서명하여 자신의 EOA를 `SubscriptionManager`로 위임합니다. 이후 구독자의 EOA는 위임 컨트랙트의 로직을 실행합니다. +구독자는 EIP-7702 승인을 서명하여 자신의 EOA를 `SubscriptionManager`에 위임합니다. 이 후 구독자의 EOA는 위임 계약의 로직을 실행합니다. ```typescript // delegate.ts @@ -235,7 +235,7 @@ Delegation tx: 0x7702...aaaa ## 2단계: 구독 등록 (구독자) -구독자는 자신의 EOA에서 `subscribe()`를 호출합니다. EOA가 위임되어 있으므로 이는 `SubscriptionManager.subscribe`를 실행합니다. +구독자는 자신의 EOA에서 `subscribe()`를 호출합니다. EOA가 위임되었으므로 `SubscriptionManager.subscribe`가 실행됩니다. ```typescript // subscribe.ts @@ -283,7 +283,7 @@ Subscription ID: 0xfedc...9876 ## 3단계: 결제 수금 (서비스 제공자) -각 청구 주기마다 서비스 제공자는 구독자의 EOA에서 `collect(subscriptionId)`를 호출합니다. 위임 로직은 USDT0를 전송하기 전에 호출자, 청구 일정, 금액을 검증합니다. +각 청구 주기마다 서비스 제공자는 구독자의 EOA에서 `collect(subscriptionId)`를 호출합니다. 위임 논리는 발신자, 청구 일정 및 금액을 확인한 후 USDT0를 전송합니다. ```typescript // collect.ts @@ -322,11 +322,11 @@ Payment collected, tx: 0x8f3a...2d41 Gas used: 52000 ``` -`collect()` 호출은 Stable에서 대략 **50k-55k 가스**(21k 기본 + 7702 위임 오버헤드 + ERC-20 `transfer`)가 소요됩니다. 1 gwei 기본 수수료 기준으로, 이는 제공자가 청구 주기당 약 `0.000050 USDT0`를 지불하는 것입니다. +`collect()` 호출 비용은 Stable에서 약 **50k-55k 가스** (21k 기본 + 7702 위임 오버헤드 + ERC-20 `transfer`)입니다. 1 gwei의 기본 수수료를 기준으로 제공자가 결제하는 청구 주기당 약 `0.000050 USDT0`입니다. ## 4단계: 구독 취소 (구독자) -구독자는 자신의 EOA에서 `cancelSubscription(subscriptionId)`를 호출하여 해당 특정 구독에 대한 청구 접근 권한을 취소합니다. +구독자는 자신의 EOA에서 `cancelSubscription(subscriptionId)`를 호출하여 해당 특정 구독에 대한 청구 액세스를 취소합니다. ```typescript // cancel.ts @@ -359,33 +359,33 @@ Subscription cancelled, tx: 0xdef0...5678 ## 보안 모델 -구독자는 위임 컨트랙트가 자신의 EOA에서 자금을 인출하도록 인증하는 것입니다. 그 인증이 정확히 무엇을 포함하는지, 그리고 노출을 어떻게 제한할지 이해하세요. +구독자는 위임 계약이 자신의 EOA에서 자금을 인출하는 것을 승인합니다. 이 승인이 무엇을 포함하는지, 그리고 노출을 제한하는 방법을 정확히 이해해야 합니다. -**구독자가 인증하는 것.** `SubscriptionManager`에 위임함으로써 구독자는 컨트랙트의 로직에 자신의 EOA에 대한 완전한 실행 권한을 부여합니다. 위임은 컨트랙트에 코딩된 조건 하에서만 자금을 전송할 수 있습니다: 호출자가 등록된 제공자이고, 간격이 경과했으며, 금액이 저장된 구독과 일치하는 경우입니다. 컨트랙트 코드가 그러한 동작을 허용하지 않기 때문에, 다른 주소로 전송하거나 간격 검사를 우회할 수 없습니다. +**구독자가 승인하는 것.** `SubscriptionManager`에게 위임함으로써, 구독자는 계약의 로직에 자신의 EOA에 대한 완전한 실행 권한을 부여합니다. 위임은 코드에 따라 등록된 제공자가 호출하고, 간격이 경과했으며, 금액이 저장된 구독과 일치하는 경우에만 자금을 전송할 수 있습니다. 계약 코드가 그러한 작업을 허용하지 않으므로 다른 주소로 전송하거나 간격 확인을 우회할 수 없습니다. **완화해야 할 실패 모드.** -- **악의적인 위임 업그레이드**: `SubscriptionManager`가 관리자에 의해 구현이 변경될 수 있는 프록시인 경우, 인증은 사실상 해당 관리자를 신뢰하는 것입니다. 불변 컨트랙트 또는 투명하고 타임락이 적용된 업그레이드를 가진 프록시에만 위임하세요. -- **제공자 침해**: 제공자의 키가 유출되면, 공격자는 주기당 금액까지 조기 결제를 수금할 수 있습니다. 구독자는 구독별로 `spendingLimit`을 설정하고 인증되지 않은 `SubscriptionCollected` 이벤트를 모니터링해야 합니다. -- **위임 교체**: 다른 위임으로 다시 구독하면 구독 상태가 지워집니다. 기능별로 하나의 위임을 사용하는 대신, 단일 위임 하에서 여러 함수(구독, 일괄 결제, 지출 한도)를 지원하는 모듈식 위임을 사용하세요. -- **재생 가능한 서명**: 모든 서명은 구독자의 EOA에 연결된 EIP-7702 nonce를 사용하므로, 체인 간 또는 위임 간에 재생할 수 없습니다. +- **악의적인 위임 업그레이드**: `SubscriptionManager`가 관리자가 구현을 변경할 수 있는 프록시인 경우, 승인은 사실상 관리자를 신뢰하는 것입니다. 투명하고 타임락된 업그레이드가 있는 변경 불가능한 계약이나 프록시에만 위임하십시오. +- **제공자 침해**: 제공자의 키가 유출되면 공격자는 주기당 금액까지 조기 결제를 수금할 수 있습니다. 구독자는 구독별 `spendingLimit`를 설정하고 무단 `SubscriptionCollected` 이벤트를 모니터링해야 합니다. +- **위임 교체**: 다른 위임으로 다시 구독하면 구독 상태가 지워집니다. 기능별로 하나의 위임을 사용하는 대신, 단일 위임 하에서 여러 기능(구독, 일괄 결제, 지출 한도)을 지원하는 모듈식 위임을 사용하십시오. +- **재생 가능한 서명**: 모든 서명은 구독자의 EOA에 연결된 EIP-7702 논스를 사용하므로 체인 간 또는 위임 간에 재생되지 않습니다. -**권장 가드레일.** +**권장 보호 장치.** -- 프로덕션 사용 전에 위임 컨트랙트를 감사하세요. -- 구독별 금액을 구독자의 잔액 대비 작게 유지하세요. -- `SubscriptionCreated` / `SubscriptionCollected` 이벤트를 모니터링하고 구독자에게 표시하세요. -- 구독자에게 자신의 EOA에서 `cancelSubscription(subscriptionId)`을 호출하는 명확한 "취소" UI를 제공하세요. +- 프로덕션 사용 전에 위임 계약을 감사하십시오. +- 구독자의 잔액에 비해 구독당 금액을 작게 유지하십시오. +- `SubscriptionCreated` / `SubscriptionCollected` 이벤트를 모니터링하고 구독자에게 표시하십시오. +- 구독자에게 자신의 EOA에서 `cancelSubscription(subscriptionId)`를 호출하는 명확한 "취소" UI를 제공하십시오. -## 중요한 고려 사항 +## 중요 고려사항 -- **지속적인 위임**: EIP-7702 위임은 구독자가 명시적으로 변경하거나 지울 때까지 지속됩니다. 각 청구 주기마다 재위임이 필요하지 않습니다. -- **EOA당 단일 위임**: 구독자가 나중에 다른 컨트랙트로 위임하면, 구독 위임 로직이 교체되어 수금이 실패합니다. 단일 위임 하에서 여러 함수(구독, 일괄 결제, 지출 한도, 세션 키)를 지원하는 모듈식 위임 컨트랙트를 사용하세요. -- **일정 동작**: 이 예시는 각 성공적인 수금마다 `nextChargeAt`을 한 간격씩 진행합니다. 둘 이상의 청구 기간이 경과한 경우, 반복적인 `collect()` 호출로 한 번에 한 기간씩 따라잡을 수 있습니다. 제품에 다른 정책이 필요한 경우 로직을 확장하세요. -- **감사된 위임 사용**: 감사를 받은 컨트랙트에만 위임하세요. +- **영구 위임**: EIP-7702 위임은 구독자가 명시적으로 변경하거나 해제할 때까지 유지됩니다. 각 청구 주기마다 재위임할 필요가 없습니다. +- **EOA당 하나의 위임**: 구독자가 나중에 다른 계약에 위임하면 구독 위임 로직이 교체되어 수금이 실패합니다. 단일 위임 하에서 여러 기능(구독, 일괄 결제, 지출 한도, 세션 키)을 지원하는 모듈식 위임 계약을 사용하십시오. +- **일정 동작**: 이 예시는 각 성공적인 수금 시 `nextChargeAt`를 한 간격만큼 진행합니다. 하나 이상의 청구 기간이 경과한 경우, 반복되는 `collect()` 호출은 한 번에 한 기간씩 따라잡을 수 있습니다. 제품에 다른 정책이 필요한 경우 로직을 확장하십시오. +- **감사된 위임 사용**: 감사된 계약에만 위임하십시오. ## 다음 권장 사항 -- [**구독 청구 개념**](/ko/reference/subscriptions) — 풀 기반 청구 모델을 이해하세요. -- [**계정 추상화**](/ko/how-to/account-abstraction) — 일괄 결제, 지출 한도, 세션 키가 하나의 위임 하에서 어떻게 결합되는지 확인하세요. -- [**EIP-7702 개념**](/ko/explanation/eip-7702) — 이를 가능하게 하는 위임 모델을 검토하세요. +- [**구독 청구 개념**](/ko/reference/subscriptions): 풀 기반 청구 모델을 이해합니다. +- [**계정 추상화**](/ko/how-to/account-abstraction): 일괄 결제, 지출 한도 및 세션 키가 단일 위임 하에 어떻게 결합되는지 확인합니다. +- [**EIP-7702 개념**](/ko/explanation/eip-7702): 이를 가능하게 하는 위임 모델을 검토합니다. diff --git a/docs/pages/ko/how-to/track-unbonding.mdx b/docs/pages/ko/how-to/track-unbonding.mdx index 9a7b4c3..a6bb57d 100644 --- a/docs/pages/ko/how-to/track-unbonding.mdx +++ b/docs/pages/ko/how-to/track-unbonding.mdx @@ -1,34 +1,34 @@ --- source_path: how-to/track-unbonding.mdx -source_sha: 33d66c8fbb264a445f511902164794ff3796e785 -title: "언본딩 완료 추적하기" -description: "시스템 트랜잭션을 통해 StableSystem 프리컴파일이 발생시키는 UnbondingCompleted 이벤트를 구독합니다. 사용자 또는 검증자별로 필터링하고 과거 이벤트를 조회합니다." +source_sha: 5c4d430a5edb73996ba773710b260c58025a04d8 +title: "언본딩 완료 추적" +description: "시스템 트랜잭션을 통해 StableSystem 사전 컴파일러가 내보내는 UnbondingCompleted 이벤트를 구독하세요. 사용자 또는 검증인별로 필터링하고 과거 이벤트를 쿼리하세요." diataxis: "how-to" --- -# 언본딩 완료 추적하기 +# 언본딩 완료 추적 -언본딩 기간이 완료되면, 프로토콜은 시스템 트랜잭션을 통해 `StableSystem` 프리컴파일(`0x0000000000000000000000000000000000009999`)에서 `UnbondingCompleted` 이벤트를 발생시킵니다. 이를 통해 dApp은 커스텀 인덱서를 실행하거나 REST 엔드포인트를 폴링하지 않고도 사용자에게 실시간으로 알리고 잔액을 업데이트할 수 있습니다. +언본딩 기간이 완료되면 프로토콜은 시스템 트랜잭션을 통해 `StableSystem` 사전 컴파일러 (`0x0000000000000000000000000000000000009999`)를 통해 `UnbondingCompleted` 이벤트를 내보냅니다. 이를 통해 dApp은 사용자 지정 인덱서를 실행하거나 REST 엔드포인트를 폴링하지 않고도 사용자에게 알리고 실시간으로 잔액을 업데이트할 수 있습니다. :::note -**개념:** 시스템 트랜잭션이 SDK 계층의 이벤트를 EVM으로 연결하는 방식과 그 중요성에 대해서는 [시스템 트랜잭션](/ko/explanation/system-transactions)을 참고하세요. +**개념:** 시스템 트랜잭션이 SDK 계층 이벤트를 EVM에 연결하는 방법과 그것이 중요한 이유에 대해서는 [시스템 트랜잭션](/ko/explanation/system-transactions)을 참조하세요. ::: -## 사전 요구 사항 +## 전제 조건 - [시스템 트랜잭션](/ko/explanation/system-transactions)에 대한 이해. -- [스테이킹](/ko/explanation/staking-module), 특히 `undelegate`와 언본딩 프로세스에 대한 이해. -- 표준 web3 라이브러리(예: [ethers.js](https://docs.ethers.org/) v6)를 사용한 컨트랙트 이벤트 구독 및 필터링 경험. +- [스테이킹](/ko/explanation/staking-module), 특히 `undelegate` 및 언본딩 프로세스에 대한 숙지. +- 표준 web3 라이브러리 (예: [ethers.js](https://docs.ethers.org/) v6)를 사용한 컨트랙트 이벤트 구독 및 필터링 경험. ## 개요 -- **컨트랙트 인스턴스 설정**: StableSystem 프리컴파일을 위한 컨트랙트 인스턴스를 생성합니다. -- **애플리케이션에서 이벤트 처리**: 애플리케이션 로직에 따라 실시간 이벤트를 구독하거나 과거 데이터를 조회합니다. +- **컨트랙트 인스턴스 설정**: StableSystem 사전 컴파일러에 대한 컨트랙트 인스턴스를 생성합니다. +- **애플리케이션에서 이벤트 처리**: 애플리케이션 로직에 따라 실시간 이벤트를 구독하거나 과거 데이터를 쿼리합니다. - **연결 문제 처리**: 지속적인 WebSocket 구독을 위한 재연결 로직을 구현합니다. ## 1단계: 컨트랙트 인스턴스 설정 -`UnbondingCompleted` 이벤트 ABI를 사용하여 `StableSystem` 프리컴파일을 위한 컨트랙트 인스턴스를 생성합니다. +`UnbondingCompleted` 이벤트 ABI를 사용하여 `StableSystem` 사전 컴파일러에 대한 컨트랙트 인스턴스를 생성합니다. ```typescript // config.ts @@ -51,11 +51,11 @@ export const stableSystem = new ethers.Contract( ## 2단계: 애플리케이션에서 이벤트 처리 -애플리케이션 로직에 따라 실시간 이벤트를 구독하거나, 과거 데이터를 조회하거나, 둘 다 수행합니다. +애플리케이션 로직에 따라 실시간 이벤트를 구독하거나 과거 데이터를 쿼리하거나 둘 다 수행합니다. ### 실시간 구독 -언본딩이 완료될 때 실시간 알림을 받기 위해 `UnbondingCompleted` 이벤트를 구독합니다. 잔액 업데이트 트리거, 알림 전송, 또는 대시보드 통계 새로고침에 유용합니다. +언본딩이 완료될 때 실시간 알림을 위해 `UnbondingCompleted` 이벤트를 구독합니다. 잔액 업데이트 트리거, 알림 전송 또는 대시보드 통계 새로고침에 유용합니다. ```typescript // subscribeBasic.ts @@ -73,7 +73,7 @@ stableSystem.on("UnbondingCompleted", (delegator, validator, amount, event) => { ### 사용자별 필터링 -특정 위임자 주소에 대한 이벤트만 수신하려면, 인덱싱된 이벤트 매개변수를 사용하여 필터를 생성합니다. +특정 위임자 주소에 대한 이벤트만 수신하려면 인덱싱된 이벤트 매개변수를 사용하여 필터를 생성합니다. ```typescript // subscribeByUser.ts @@ -91,7 +91,7 @@ stableSystem.on(filter, (delegator, validator, amount, event) => { }); ``` -### 검증자별 필터링 +### 검증인별 필터링 ```typescript // subscribeByValidator.ts @@ -108,9 +108,9 @@ stableSystem.on(validatorFilter, (delegator, validator, amount) => { }); ``` -### 과거 데이터 조회 +### 과거 쿼리 -dApp이 과거의 언본딩 완료 내역을 표시해야 하는 경우, 블록 범위와 함께 이벤트 필터를 사용하여 과거 이벤트를 조회합니다. +dApp에서 과거 언본딩 완료 기록을 표시해야 하는 경우 블록 범위가 있는 이벤트 필터를 사용하여 과거 이벤트를 쿼리합니다. ```typescript // queryHistory.ts @@ -144,7 +144,7 @@ const history = await getUnbondingHistory( ## 3단계: 연결 문제 처리 -이벤트 구독은 지속적인 WebSocket 연결에 의존합니다. 프로덕션 dApp을 위해 재연결 로직을 구현하세요. +이벤트 구독은 지속적인 WebSocket 연결에 의존합니다. 프로덕션 dApp을 위한 재연결 로직을 구현합니다. ```typescript // subscribeWithReconnection.ts @@ -181,8 +181,8 @@ function setupEventListener() { setupEventListener(); ``` -## 다음 추천 항목 +## 다음 권장 사항 -- [**시스템 트랜잭션 개념**](/ko/explanation/system-transactions) — 프로토콜 수준의 이벤트가 EVM에 도달하는 방식을 이해합니다. -- [**스테이킹 모듈 개념**](/ko/explanation/staking-module) — 위임 및 언본딩 흐름을 검토합니다. -- [**스테이킹 프리컴파일 레퍼런스**](/ko/reference/staking-module-api) — 여기서 추적하는 이벤트를 트리거하는 메서드를 찾아봅니다. +- [**시스템 트랜잭션 개념**](/ko/explanation/system-transactions): 프로토콜 수준 이벤트가 EVM에 도달하는 방식을 이해합니다. +- [**스테이킹 모듈 개념**](/ko/explanation/staking-module): 위임 및 언본딩 흐름을 검토합니다. +- [**스테이킹 사전 컴파일러 참조**](/ko/reference/staking-module-api): 여기서 추적된 이벤트를 트리거하는 메서드를 찾아봅니다. diff --git a/docs/pages/ko/how-to/troubleshoot-node.mdx b/docs/pages/ko/how-to/troubleshoot-node.mdx index 9161404..a0ed233 100755 --- a/docs/pages/ko/how-to/troubleshoot-node.mdx +++ b/docs/pages/ko/how-to/troubleshoot-node.mdx @@ -1,16 +1,16 @@ --- source_path: how-to/troubleshoot-node.mdx -source_sha: f4b7701fdfef056c1aa8bd46ae494c7f6d73d775 +source_sha: 138c5c2eb1a61666718ce625d0553a298a454c03 title: 문제 해결 가이드 -description: "일반적인 Stable 노드 연결, 동기화, 성능 문제에 대한 진단 스크립트와 해결책." +description: "Stable 노드 연결, 동기화 및 성능 문제에 대한 진단 스크립트 및 해결책입니다." diataxis: "how-to" --- -이 종합 가이드는 Stable 노드의 일반적인 문제를 진단하고 해결하는 데 도움을 줍니다. +이 종합 가이드는 Stable 노드에서 발생하는 일반적인 문제를 진단하고 해결하는 데 도움을 줍니다. ## 빠른 진단 -### 노드 상태 점검 스크립트 +### 노드 상태 확인 스크립트 ```bash #!/bin/bash @@ -52,14 +52,14 @@ ss -tulpn | grep ${SERVICE_NAME} || echo "No ${SERVICE_NAME} ports found" echo -e "\n=== Diagnostics Complete ===" ``` -## 일반적인 문제와 해결책 +## 일반적인 문제 및 해결책 ### 노드가 시작되지 않음 #### 문제: 바이너리를 찾을 수 없음 **오류 메시지:** -``` +```text stabled: command not found ``` @@ -78,7 +78,7 @@ sudo chmod +x /usr/bin/stabled #### 문제: 권한 거부됨 **오류 메시지:** -``` +```text Error: open /home/user/.stabled/config/config.toml: permission denied ``` @@ -93,10 +93,10 @@ chmod 600 ~/.stabled/config/*.json chmod 644 ~/.stabled/config/*.toml ``` -#### 문제: 주소가 이미 사용 중 +#### 문제: 주소가 이미 사용 중임 **오류 메시지:** -``` +```text Error: listen tcp 0.0.0.0:26657: bind: address already in use ``` @@ -118,7 +118,7 @@ sed -i 's/laddr = "tcp:\/\/0.0.0.0:26657"/laddr = "tcp:\/\/0.0.0.0:26658"/' ~/.s **증상:** - 블록 높이가 증가하지 않음 -- 1분 이상 새 블록이 없음 +- 1분 이상 새로운 블록이 없음 **해결책:** ```bash @@ -139,7 +139,7 @@ sudo systemctl start ${SERVICE_NAME} #### 문제: "wrong Block.Header.AppHash" 오류 **오류 메시지:** -``` +```text panic: Wrong Block.Header.AppHash. Expected XXXX, got YYYY ``` @@ -172,7 +172,7 @@ sudo systemctl start ${SERVICE_NAME} #### 문제: 느린 동기화 속도 **증상:** -- 분당 100블록 미만 +- 분당 100 블록 미만 - 높은 CPU/디스크 사용량 **해결책:** @@ -201,10 +201,10 @@ sudo systemctl restart ${SERVICE_NAME} ### 피어 연결 문제 -#### 문제: 연결되는 피어가 없음 +#### 문제: 연결하는 피어가 없음 **증상:** -``` +```text "n_peers": 0 ``` @@ -233,10 +233,10 @@ sudo systemctl restart ${SERVICE_NAME} ### 합의 문제 -#### 문제: 업그레이드 후 "AppHash mismatch" +#### 문제: 업그레이드 후 "AppHash 불일치" **오류 메시지:** -``` +```text panic: AppHash mismatch ``` @@ -261,10 +261,10 @@ sudo systemctl start ${SERVICE_NAME} ### 데이터베이스 문제 -#### 문제: "database corruption" +#### 문제: "데이터베이스 손상" **오류 메시지:** -``` +```text Error initializing database: resource temporarily unavailable ``` @@ -288,10 +288,10 @@ rm -rf ~/.stabled/data sudo systemctl start ${SERVICE_NAME} ``` -#### 문제: "too many open files" +#### 문제: "너무 많은 열린 파일" **오류 메시지:** -``` +```text accept: too many open files ``` @@ -314,10 +314,10 @@ sudo systemctl restart ${SERVICE_NAME} ### 메모리 문제 -#### 문제: 메모리 부족(OOM) 종료 +#### 문제: 메모리 부족(OOM)으로 인한 강제 종료 **증상:** -``` +```text stabled.service: Main process exited, code=killed, status=9/KILL ``` @@ -353,7 +353,7 @@ sudo systemctl edit stabled #### 문제: 장치에 남은 공간 없음 **오류 메시지:** -``` +```text Error: write ~/.stabled/data/blockstore.db/001234.log: no space left on device ``` @@ -407,16 +407,16 @@ go tool pprof http://localhost:6060/debug/pprof/heap curl http://localhost:6060/debug/pprof/goroutine?debug=1 ``` -## 오류 메시지 참고 +## 오류 메시지 참조 | 오류 | 원인 | 해결책 | |-------|-------|----------| -| `wrong Block.Header.AppHash` | 상태 손상 | 스냅샷에서 재동기화 | +| `wrong Block.Header.AppHash` | 상태 손상 | 스냅샷에서 다시 동기화 | | `validator set is nil` | 제네시스 불일치 | 올바른 제네시스 다운로드 | -| `connection refused` | 서비스가 실행 중이 아님 | 서비스 시작 | -| `timeout waiting for tx to be included` | 네트워크 혼잡 | 가스 가격 인상 | -| `account sequence mismatch` | 논스 오류 | 현재 논스 조회 | -| `insufficient fees` | 가스 가격이 너무 낮음 | 가스 가격 인상 | +| `connection refused` | 서비스가 실행되고 있지 않음 | 서비스 시작 | +| `timeout waiting for tx to be included` | 네트워크 정체 | 가스 가격 증가 | +| `account sequence mismatch` | Nonce 오류 | 현재 Nonce 쿼리 | +| `insufficient fees` | 가스 가격이 너무 낮음 | 가스 가격 증가 | | `signature verification failed` | 키 불일치 | 키 구성 확인 | | `module account has not been set` | 초기화 오류 | 노드 재초기화 | @@ -463,5 +463,5 @@ echo "Share this file when requesting support" ## 다음 단계 -- 문제를 예방하려면 [모니터링 설정](/ko/how-to/monitor-node)을 검토하세요 -- 버전별 문제는 [업그레이드 가이드](/ko/how-to/upgrade-node)를 확인하세요 +- 문제 방지를 위해 [모니터링 설정](/ko/how-to/monitor-node) 검토 +- 버전별 문제를 위해 [업그레이드 가이드](/ko/how-to/upgrade-node) 확인 diff --git a/docs/pages/ko/how-to/use-system-modules.mdx b/docs/pages/ko/how-to/use-system-modules.mdx index 7da9ea2..06f3293 100644 --- a/docs/pages/ko/how-to/use-system-modules.mdx +++ b/docs/pages/ko/how-to/use-system-modules.mdx @@ -1,44 +1,44 @@ --- source_path: how-to/use-system-modules.mdx -source_sha: 20a3d686672800eb94c39601d0f332f12eff44cb -title: "시스템 모듈 사용하기" -description: "최소한의 ABI와 동작하는 예제로 Solidity 및 ethers.js에서 Stable의 Bank, Distribution, Staking 프리컴파일을 호출하세요." +source_sha: cfd6ec43ac3c766ae5fdb7d0007a1cb6671ad955 +title: "시스템 모듈 사용" +description: "최소한의 ABI와 작동 예시를 사용하여 Solidity 및 ethers.js에서 Stable의 Bank, Distribution 및 Staking 사전 컴파일을 호출합니다." diataxis: "how-to" --- -# 시스템 모듈 사용하기 +# 시스템 모듈 사용 -Stable은 고정된 주소의 **프리컴파일 컨트랙트(precompiled contracts)**를 통해 프로토콜 수준의 정산 로직을 노출합니다. 프리컴파일을 사용하면 EVM 코드가 Stable SDK 모듈(스테이킹, 보상 분배, STABLE 토큰 작업)을 다시 구현하지 않고 호출할 수 있습니다. 프로토콜 수준에서 실행되기 때문에 동등한 Solidity 구현보다 가스 효율이 훨씬 높습니다. +Stable은 고정 주소의 **사전 컴파일된 계약**을 통해 프로토콜 수준 결제 로직을 노출합니다. 사전 컴파일을 통해 EVM 코드는 Stable SDK 모듈(스테이킹, 보상 분배, STABLE 토큰 작업)을 다시 구현하지 않고도 호출할 수 있습니다. 프로토콜 수준에서 실행되므로 동등한 Solidity 구현보다 훨씬 더 가스 효율적입니다. -이 가이드는 Solidity와 ethers.js 양쪽에서 프리컴파일을 호출하는 방법과, 일반 컨트랙트 대신 언제 프리컴파일을 사용해야 하는지를 보여줍니다. +이 가이드에서는 Solidity 및 ethers.js에서 사전 컴파일을 호출하는 방법과 일반 계약 대신 사전 컴파일을 사용해야 하는 경우를 보여줍니다. :::note -**개념**: 시스템 모듈이 무엇을 하고 왜 프리컴파일인지에 대해서는 [시스템 모듈](/ko/explanation/system-modules-overview)을 참조하세요. 모듈별 메서드 시그니처와 이벤트는 [시스템 모듈 레퍼런스](/ko/reference/system-modules-api-overview)를 참조하세요. +**개념**: 시스템 모듈의 기능과 사전 컴파일인 이유에 대한 자세한 내용은 [시스템 모듈](/ko/explanation/system-modules-overview)을 참조하십시오. 모듈별 메서드 시그니처 및 이벤트에 대한 자세한 내용은 [시스템 모듈 참조](/ko/reference/system-modules-api-overview)를 참조하십시오. ::: -## 노출되는 항목 +## 노출되는 내용 -| **모듈** | **프리컴파일 주소** | **용도** | +| **모듈** | **사전 컴파일 주소** | **용도** | | :--- | :--- | :--- | | Bank | `0x0000000000000000000000000000000000001003` | STABLE 토큰 전송 및 잔액 작업 | -| Distribution | `0x0000000000000000000000000000000000000801` | 스테이킹 보상 청구, 보상 조회, 커미션 관리 | -| Staking | `0x0000000000000000000000000000000000000800` | 위임, 위임 해제, 재위임, 검증자 조회 | -| Gov | `0x0000000000000000000000000000000000000805` | 제안, 집계 결과, 온체인 투표 기록 | +| Distribution | `0x0000000000000000000000000000000000000801` | 스테이킹 보상 청구, 보상 쿼리, 수수료 관리 | +| Staking | `0x0000000000000000000000000000000000000800` | 위임, 위임 해제, 재위임, 검증자 쿼리 | +| Gov | `0x0000000000000000000000000000000000000805` | 제안, 집계 결과 및 온체인 투표 기록 | | Slashing | `0x0000000000000000000000000000000000000806` | 검증자 서명 정보 및 가동 시간 | -| StableSystem | `0x0000000000000000000000000000000000009999` | 시스템 트랜잭션(위임 해제 완료)을 위한 EVM 이벤트 발생 | +| StableSystem | `0x0000000000000000000000000000000000009999` | 시스템 트랜잭션(언본딩 완료)을 위한 EVM 이벤트 방출 | -이 모든 것은 EVM 컨트랙트나 오프체인 클라이언트에서 호출할 수 있습니다. 주소는 안정적이며 메인넷과 테스트넷에서 동일합니다. +이들 모두는 모든 EVM 계약 또는 오프체인 클라이언트에서 호출할 수 있습니다. 주소는 메인넷과 테스트넷에서 안정적이며 동일합니다. -## 프리컴파일 vs 일반 컨트랙트, 언제 호출할까 +## 사전 컴파일과 일반 계약을 호출하는 경우 -- **프리컴파일을 사용**: 작업이 Stable SDK 모듈에 매핑될 때 — 스테이킹, 보상 분배, STABLE 토큰 작업. 프리컴파일 호출은 더 저렴하면서도 프로토콜 수준 동작을 트리거하는 유일한 방법입니다. -- **일반 컨트랙트를 사용**: 작업이 애플리케이션 로직일 때 — 에스크로, 가격 책정, 접근 제어. 커스텀 권한 부여나 검증이 필요한 경우 프리컴파일 호출을 직접 만든 컨트랙트로 감싸세요. +- 작업이 Stable SDK 모듈(스테이킹, 보상 분배, STABLE 토큰 작업)에 매핑되는 경우 **사전 컴파일을 사용**합니다. 사전 컴파일을 호출하는 것이 더 저렴하고 프로토콜 수준 동작을 트리거하는 유일한 방법입니다. +- 작업이 애플리케이션 로직(에스크로, 가격 책정, 액세스 제어)인 경우 **일반 계약을 사용**합니다. 사용자 지정 권한 부여 또는 유효성 검사가 필요한 경우 사전 컴파일 호출을 사용자 지정 계약에 래핑하십시오. -프리컴파일은 애플리케이션 컨트랙트를 대체하지 않습니다. 기반 프로토콜로 향하는 안정적인 인터페이스입니다. +사전 컴파일은 애플리케이션 계약을 대체하는 것이 아닙니다. 기본 프로토콜에 대한 안정적인 인터페이스입니다. -## Solidity에서 호출하기 +## Solidity에서 호출 -필요한 메서드에 대한 인터페이스를 선언한 다음, 프리컴파일을 마치 배포된 컨트랙트처럼 호출하세요. +필요한 메서드에 대한 인터페이스를 선언한 다음, 마치 배포된 계약처럼 사전 컴파일을 호출합니다. ```solidity // SPDX-License-Identifier: MIT @@ -61,7 +61,7 @@ contract StakingHelper { address constant STAKING_PRECOMPILE = 0x0000000000000000000000000000000000000800; - /// @notice Delegate STABLE tokens to a validator from this contract. + /// @notice 이 계약에서 검증자에게 STABLE 토큰을 위임합니다. function delegateToValidator( string calldata validatorAddress, uint256 amount @@ -73,7 +73,7 @@ contract StakingHelper { ); } - /// @notice Read the current delegation of this contract to a validator. + /// @notice 이 계약의 검증자에 대한 현재 위임을 읽습니다. function myDelegation(string calldata validatorAddress) external view @@ -87,15 +87,15 @@ contract StakingHelper { } ``` -Foundry나 Hardhat으로 컴파일하고 배포하세요. 프리컴파일 주소는 상수 슬롯에서 컨트랙트에 고정되므로, 배포 후 연결할 것이 없습니다. +Foundry 또는 Hardhat으로 컴파일 및 배포합니다. 사전 컴파일 주소는 상수 슬롯에서 계약에 번인되므로 배포 후 연결할 것이 없습니다. ```solidity -// SAFE: precompile address is fixed on Stable and never changes. +// SAFE: 사전 컴파일 주소는 Stable에 고정되어 있으며 변경되지 않습니다. ``` -## ethers.js에서 호출하기 +## ethers.js에서 호출 -오프체인 클라이언트의 경우, 동일한 인터페이스를 최소 ABI로 선언하고 프리컴파일 주소를 가리키는 컨트랙트를 인스턴스화하세요. +오프체인 클라이언트의 경우, 최소한의 ABI와 동일한 인터페이스를 선언하고 사전 컴파일 주소를 가리키는 계약을 인스턴스화합니다. ```typescript // queryDelegation.ts @@ -115,7 +115,7 @@ const staking = new ethers.Contract( ); const delegator = "0xDelegatorAddress"; -const validator = "stablevaloper1..."; // bech32 validator operator address +const validator = "stablevaloper1..."; // bech32 검증자 운영자 주소 const [shares, balance] = await staking.delegation(delegator, validator); console.log("Delegation shares: ", shares.toString()); @@ -131,11 +131,11 @@ Delegation shares: 1000000000000000000000 Delegation balance: 1000.0 STABLE ``` -## 시스템 트랜잭션 이벤트 구독하기 +## 시스템 트랜잭션 이벤트 구독 -일부 Stable SDK 작업(예: 위임 해제 완료)은 자연스럽게 EVM 이벤트를 발생시키지 않습니다. Stable은 **시스템 트랜잭션**으로 이 간극을 메웁니다: 검증자가 생성한 트랜잭션이 `StableSystem` 프리컴파일을 호출하여 다음 블록 동안 표준 EVM 이벤트를 발생시킵니다. +일부 Stable SDK 작업(예: 언본딩 완료)은 자연적으로 EVM 이벤트를 방출하지 않습니다. Stable은 다음 블록에서 표준 EVM 이벤트를 방출하기 위해 `StableSystem` 사전 컴파일을 호출하는 검증자 생성 트랜잭션인 **시스템 트랜잭션**으로 이러한 격차를 해소합니다. -`UnbondingCompleted`를 감시하려면, 여느 ERC-20 `Transfer` 리스너처럼 프리컴파일 주소에서 구독하세요. +`UnbondingCompleted`를 보려면 모든 ERC-20 `Transfer` 리스너처럼 사전 컴파일 주소에서 구독하십시오. ```typescript // watchUnbonding.ts @@ -173,19 +173,19 @@ Amount: 100.0 STABLE Tx: 0x12ab... ``` -시스템 트랜잭션 메커니즘 전체와 사용자별 필터링 / 과거 조회 패턴은 [위임 해제 완료 추적하기](/ko/how-to/track-unbonding)를 참조하세요. +전체 시스템 트랜잭션 메커니즘 및 사용자 필터링/기록 쿼리 패턴에 대한 자세한 내용은 [언본딩 완료 추적](/ko/how-to/track-unbonding)을 참조하십시오. -## 모듈별 레퍼런스 +## 모듈별 참조 -각 프리컴파일의 전체 메서드 목록, 이벤트, 권한 부여 규칙은 해당 레퍼런스 페이지에 있습니다. +각 사전 컴파일의 전체 메서드 목록, 이벤트 및 권한 부여 규칙은 해당 참조 페이지에 있습니다. -- [Bank 프리컴파일](/ko/reference/bank-module-api): STABLE 토큰 전송 및 공급량 조회. -- [Distribution 프리컴파일](/ko/reference/distribution-module-api): 보상 청구 및 커미션. -- [Staking 프리컴파일](/ko/reference/staking-module-api): 위임, 위임 해제, 재위임, 검증자 조회. +- [Bank 사전 컴파일](/ko/reference/bank-module-api): STABLE 토큰 전송 및 공급 쿼리. +- [Distribution 사전 컴파일](/ko/reference/distribution-module-api): 보상 청구 및 수수료. +- [Staking 사전 컴파일](/ko/reference/staking-module-api): 위임, 위임 해제, 재위임, 검증자 쿼리. - [시스템 트랜잭션](/ko/reference/system-transactions-api): StableSystem 이벤트 형식 및 권한 부여. -## 다음 추천 +## 다음 권장 사항 -- [**위임 해제 완료 추적하기**](/ko/how-to/track-unbonding) — StableSystem 프리컴파일을 통해 발생하는 UnbondingCompleted 이벤트를 구독하세요. -- [**시스템 모듈 레퍼런스**](/ko/reference/system-modules-api-overview) — 모듈별 ABI, 메서드 시그니처, 이벤트 스키마로 바로 이동하세요. -- [**시스템 모듈 개념**](/ko/explanation/system-modules-overview) — Stable이 SDK 모듈을 프리컴파일을 통해 노출하는 이유를 이해하세요. +- [**언본딩 완료 추적**](/ko/how-to/track-unbonding): StableSystem 사전 컴파일을 통해 방출된 UnbondingCompleted 이벤트를 구독합니다. +- [**시스템 모듈 참조**](/ko/reference/system-modules-api-overview): 모듈별 ABI, 메서드 시그니처 및 이벤트 스키마로 이동합니다. +- [**시스템 모듈 개념**](/ko/explanation/system-modules-overview): Stable이 사전 컴파일을 통해 SDK 모듈을 노출하는 이유를 이해합니다. diff --git a/docs/pages/ko/how-to/verify-contract.mdx b/docs/pages/ko/how-to/verify-contract.mdx index 4c61024..4cb4337 100644 --- a/docs/pages/ko/how-to/verify-contract.mdx +++ b/docs/pages/ko/how-to/verify-contract.mdx @@ -1,24 +1,24 @@ --- source_path: how-to/verify-contract.mdx -source_sha: 830fdc192d492e9e07e95fd6c0cf3bde9df9d2cd -title: "스마트 컨트랙트 검증하기" -description: "forge verify-contract로 Stablescan에서 Stable 컨트랙트 소스를 검증하여 사용자가 읽고 상호작용할 수 있도록 하세요." +source_sha: 6cc73e10bb88685960bc61fa08f4942073bc61bc +title: "스마트 컨트랙트 검증" +description: "forge verify-contract를 사용하여 Stablescan에서 Stable 컨트랙트 소스를 검증하여 사용자가 코드를 읽고 상호작용할 수 있도록 합니다." diataxis: "how-to" --- -# 스마트 컨트랙트 검증하기 +# 스마트 컨트랙트 검증 -검증은 컨트랙트의 소스 코드를 블록 탐색기에 업로드하고 배포된 바이트코드로 컴파일됨을 증명합니다. 검증이 완료되면, 사용자는 코드를 재호스팅하지 않고도 Stablescan에서 상태를 읽고, 함수를 호출하고, 소스를 감사할 수 있습니다. 이 가이드는 Stable에서 Foundry로 배포된 컨트랙트를 검증하는 과정을 안내합니다. +검증은 컨트랙트의 소스 코드를 블록 탐색기에 업로드하고 배포된 바이트코드로 컴파일되었음을 증명합니다. 일단 검증되면, 사용자는 코드를 다시 호스팅할 필요 없이 Stablescan에서 상태를 읽고, 함수를 호출하고, 소스를 감사할 수 있습니다. 이 가이드는 Stable에 배포된 Foundry 컨트랙트를 검증하는 과정을 안내합니다. -## 사전 준비 +## 전제 조건 -- Stable 테스트넷 또는 메인넷에 이미 배포된 컨트랙트. 아직 배포하지 않았다면 [스마트 컨트랙트 배포하기](/ko/tutorial/smart-contract)를 참조하세요. -- Foundry 설치 (PATH에서 `forge` 사용 가능). +- Stable 테스트넷 또는 메인넷에 이미 배포된 컨트랙트. 아직 배포하지 않았다면, [스마트 컨트랙트 배포](/ko/tutorial/smart-contract)를 참조하세요. +- Foundry 설치 (`forge`가 PATH에 있어야 함). - `forge create` 출력에서 얻은 배포된 컨트랙트 주소. ## 1. 배포된 주소 확인 -이전 배포에서 얻은 `Deployed to` 주소가 있는지 확인하세요. [스마트 컨트랙트 배포하기](/ko/tutorial/smart-contract) 흐름에서는 `forge create` 이후에 출력된 값입니다. +이전 배포에서 얻은 `Deployed to` 주소를 확인하세요. [스마트 컨트랙트 배포](/ko/tutorial/smart-contract) 흐름에서 이는 `forge create` 이후에 출력된 값이었습니다. ```bash cast code 0xDeployedContractAddress --rpc-url https://rpc.testnet.stable.xyz | head -c 20 @@ -28,7 +28,7 @@ cast code 0xDeployedContractAddress --rpc-url https://rpc.testnet.stable.xyz | h 0x6080604052600436... ``` -비어 있지 않은 바이트코드는 해당 주소에 컨트랙트가 배포되었음을 확인해 줍니다. +비어 있지 않은 바이트코드는 해당 주소에 컨트랙트가 배포되었음을 확인합니다. ## 2. forge verify-contract 실행 @@ -45,23 +45,23 @@ forge verify-contract \ ``` ```text -Start verifying contract `0xDeployedContractAddress` deployed on 2201 +2201에 배포된 컨트랙트 `0xDeployedContractAddress` 검증 시작 -Submitting verification of contract: Counter -Submitted contract for verification: - Response: `OK` +컨트랙트 검증 제출: Counter +검증을 위해 제출된 컨트랙트: + 응답: `OK` GUID: `abc123...` URL: https://testnet.stablescan.xyz/address/0xDeployedContractAddress -Contract verification status: -Response: `OK` -Details: `Pass - Verified` -Contract successfully verified +컨트랙트 검증 상태: +응답: `OK` +세부 정보: `Pass - Verified` +컨트랙트가 성공적으로 검증되었습니다. ``` -`--watch`는 검증이 완료될 때까지 차단하므로 폴링할 필요가 없습니다. 메인넷에서는 chain ID를 `988`로, 검증기 URL을 `https://stablescan.xyz/api`로 바꾸세요. +`--watch`는 검증이 완료될 때까지 블록을 유지하므로 폴링할 필요가 없습니다. 메인넷에서는 체인 ID를 `988`로, 검증기 URL을 `https://stablescan.xyz/api`로 변경하세요. :::note -**생성자 인자**: 컨트랙트가 생성자 인자를 받는 경우, 명령어에 `--constructor-args $(cast abi-encode "constructor(uint256,address)" 42 0xSomeAddress)`를 추가하세요. 이 플래그가 없으면 비어 있지 않은 생성자를 가진 모든 컨트랙트의 검증이 실패합니다. +**생성자 인수**: 컨트랙트가 생성자 인수를 사용하는 경우, `--constructor-args $(cast abi-encode "constructor(uint256,address)" 42 0xSomeAddress)`를 명령에 추가하세요. 이 플래그가 없으면 비어 있지 않은 생성자를 가진 모든 컨트랙트에 대한 검증이 실패합니다. ::: ## 3. Stablescan에서 검증 확인 @@ -72,16 +72,16 @@ Contract successfully verified https://testnet.stablescan.xyz/address/0xDeployedContractAddress ``` -이제 **Contract** 탭에 소스 코드, 녹색 "Verified" 배지, 그리고 전체 ABI가 표시되어야 합니다. 사용자는 **Read Contract**에서 상태를 읽고 **Write Contract**에서 트랜잭션을 보낼 수 있습니다. +이제 **Contract** 탭에 소스 코드, 녹색 "Verified" 배지 및 전체 ABI가 표시되어야 합니다. 사용자는 **Read Contract**에서 상태를 읽고 **Write Contract**에서 트랜잭션을 보낼 수 있습니다. ## 문제 해결 -- **"Bytecode does not match"**: 소스가 배포된 것과 다른 바이트코드로 컴파일됩니다. 대부분 일치하지 않는 Solidity 버전이나 옵티마이저 설정으로 인해 발생합니다. `foundry.toml`과 일치하도록 `--compiler-version`과 `--optimizer-runs`를 명시적으로 전달하세요. -- **"GUID not found"**: 검증기가 아직 제출을 등록하지 않았습니다. `--watch`로 다시 실행하거나 응답에 출력된 URL을 수동으로 확인하세요. -- **컨트랙트가 라이브러리를 사용하는 경우**: 링크된 각 라이브러리에 대해 `--libraries src/Lib.sol:Lib:0xDeployedLibAddress`를 추가하세요. +- **"바이트코드가 일치하지 않습니다"**: 소스가 배포된 바이트코드와 다르게 컴파일됩니다. 가장 흔한 원인은 솔리디티 버전 또는 최적화 프로그램 설정 불일치입니다. `foundry.toml`과 일치하도록 `--compiler-version` 및 `--optimizer-runs`를 명시적으로 전달하세요. +- **"GUID를 찾을 수 없습니다"**: 검증기가 아직 제출을 등록하지 않았습니다. `--watch`로 다시 실행하거나 응답에 출력된 URL을 수동으로 확인하세요. +- **컨트랙트가 라이브러리를 사용합니다**: 연결된 각 라이브러리에 대해 `--libraries src/Lib.sol:Lib:0xDeployedLibAddress`를 추가하세요. -## 다음 추천 +## 다음 권장 사항 -- [**컨트랙트 이벤트 인덱싱**](/ko/how-to/index-contract) — ethers.js로 온체인 이벤트를 구독하고 실시간 이벤트 스트림을 구축하세요. -- [**스마트 컨트랙트 배포하기**](/ko/tutorial/smart-contract) — 새로운 Foundry 프로젝트를 구성하고 Stable 테스트넷에 배포하세요. -- [**JSON-RPC 레퍼런스**](/ko/reference/json-rpc-api) — Stable이 온체인 상호작용을 위해 지원하는 `eth_*` 메서드를 확인하세요. +- [**컨트랙트 이벤트 인덱싱**](/ko/how-to/index-contract): ethers.js로 온체인 이벤트를 구독하고 실시간 이벤트 스트림을 구축합니다. +- [**스마트 컨트랙트 배포**](/ko/tutorial/smart-contract): 새로운 Foundry 프로젝트를 스캐폴드하고 Stable 테스트넷에 배포합니다. +- [**JSON-RPC 참조**](/ko/reference/json-rpc-api): Stable이 온체인 상호 작용을 위해 지원하는 `eth_*` 메서드를 확인합니다. diff --git a/docs/pages/ko/how-to/work-with-usdt-gas.mdx b/docs/pages/ko/how-to/work-with-usdt-gas.mdx index 5d49247..302b8f7 100644 --- a/docs/pages/ko/how-to/work-with-usdt-gas.mdx +++ b/docs/pages/ko/how-to/work-with-usdt-gas.mdx @@ -1,34 +1,34 @@ --- source_path: how-to/work-with-usdt-gas.mdx -source_sha: 8b0a60e8fdc7a504803325125750cc39877974d5 -title: "USDT0를 가스로 사용하기" -description: "이더리움 트랜잭션 구성을 Stable로 이식하기: priority fee를 0으로 설정하고, baseFee를 USDT0로 읽고, value를 USDT0로 표기하기." +source_sha: ec41da713b012d64269926acdd594bc6255cd981 +title: "가스로 USDT0 사용하기" +description: "이더리움 트랜잭션 구성을 Stable로 포팅하기: 우선순위 수수료를 0으로 설정하고, baseFee를 USDT0으로 읽으며, 값을 USDT0으로 표시합니다." diataxis: "how-to" --- -# USDT0를 가스로 사용하기 +# 가스로 USDT0 사용하기 -Stable에서 USDT0는 체인의 네이티브 자산이자 ERC-20 토큰입니다. 가스 토큰은 별도의 네이티브 자산이 아닌 USDT0입니다. 표준 이더리움 가스 추정은 세 가지를 조정하면 그대로 작동합니다: `maxPriorityFeePerGas`는 항상 `0`이고, `baseFee`는 USDT0로 표기되며, 네이티브 전송에서 `value` 필드는 ETH가 아닌 USDT0를 담습니다. +Stable에서 USDT0은 체인의 네이티브 자산이면서 동시에 ERC-20 토큰입니다. 가스 토큰은 별도의 네이티브 자산이 아닌 USDT0입니다. 다음 세 가지 사항을 조정하면 표준 이더리움 가스 추정이 작동합니다: `maxPriorityFeePerGas`는 항상 `0`이어야 하고, `baseFee`는 USDT0으로 표시되며, 네이티브 전송의 `value` 필드는 USDT0(ETH가 아님)을 전달합니다. -이 가이드는 Stable에서 트랜잭션을 올바르게 구성하는 방법과 이더리움 코드를 이식할 때 무엇을 변경해야 하는지 보여줍니다. +이 가이드는 Stable에서 트랜잭션을 올바르게 구성하는 방법과 이더리움 코드를 포팅할 때 변경해야 할 사항을 보여줍니다. -## 이더리움과의 차이점 +## 이더리움과 비교하여 변경된 사항 | **필드** | **이더리움** | **Stable** | | :--- | :--- | :--- | | 가스 토큰 | ETH | USDT0 | -| `maxPriorityFeePerGas` | 순서 지정에 사용됨 | 무시됨 (`0`으로 설정) | -| `baseFeePerGas` | ETH로 표기 | USDT0로 표기 | +| `maxPriorityFeePerGas` | 순서 지정을 위해 사용 | 무시됨 (`0`으로 설정) | +| `baseFeePerGas` | ETH로 표시됨 | USDT0으로 표시됨 | | `value` (네이티브 전송) | ETH 전송 | USDT0 전송 | | EIP-1559 트랜잭션 형식 | 지원됨 | 지원됨 | | `eth_estimateGas`, `eth_gasPrice` | 지원됨 | 지원됨 | | `eth_maxPriorityFeePerGas` | 팁 반환 | `0` 반환 | -트랜잭션 형식이 변경되지 않으므로 기존 ethers.js, viem, Hardhat, Foundry 코드는 변경 없이 Stable에서 실행됩니다. 차이는 가스 필드를 *인코딩*하는 방식이 아니라 *계산*하는 방식에 있습니다. +트랜잭션 형식이 변경되지 않았으므로 기존 ethers.js, viem, Hardhat, Foundry 코드는 변경 없이 Stable에서 실행됩니다. 차이점은 가스 필드를 인코딩하는 방식이 아니라 *계산하는* 방식에 있습니다. -## 트랜잭션 구성하기 +## 트랜잭션 구성 -base fee를 가져오고, `maxPriorityFeePerGas`를 `0`으로 설정하고, 안전 마진으로 base fee를 두 배로 합니다. +기본 수수료를 가져오고, `maxPriorityFeePerGas`를 `0`으로 설정한 다음, 안전 마진으로 기본 수수료를 두 배로 늘립니다. ```typescript // sendNative.ts @@ -41,8 +41,8 @@ const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider); const block = await provider.getBlock("latest"); const baseFee = block!.baseFeePerGas!; -const maxPriorityFeePerGas = 0n; // always 0 on Stable -const maxFeePerGas = baseFee * 2n + maxPriorityFeePerGas; // 2x headroom +const maxPriorityFeePerGas = 0n; // Stable에서는 항상 0 +const maxFeePerGas = baseFee * 2n + maxPriorityFeePerGas; // 2배의 여유 공간 const tx = await wallet.sendTransaction({ to: "0xRecipientAddress", @@ -67,11 +67,11 @@ Gas used: 21000 Effective gas price: 1000000000 (USDT0 wei-equivalent) ``` -실효 가스 가격은 USDT0로 표기된 값입니다. `1 gwei`에서 21,000 가스 네이티브 전송은 약 `0.000021` USDT0의 비용이 듭니다. +유효 가스 가격은 USDT0으로 표시된 값입니다. `1 gwei`에서 21,000 가스 네이티브 전송은 약 `0.000021` USDT0이 소요됩니다. -## USDT0로 가스 비용 추정하기 +## USDT0으로 가스 비용 추정 -`eth_estimateGas`와 `eth_gasPrice`는 이더리움과 동일하게 동작합니다. 가스 토큰이 USDT0이므로 결과는 이미 USDT0 단위입니다. +`eth_estimateGas`와 `eth_gasPrice`는 이더리움과 동일하게 작동합니다. 결과는 가스 토큰이므로 이미 USDT0으로 표시됩니다. ```typescript // estimate.ts @@ -98,23 +98,23 @@ Estimated fee: 0.000021 USDT0 ``` :::warning -`eth_maxPriorityFeePerGas`는 Stable에서 항상 `0`을 반환합니다. 지갑이나 SDK가 RPC가 반환한 priority fee를 base fee 위에 추가하더라도 여전히 작동하지만, 별도의 팁을 표시하는 수수료 UI는 `0`을 표시하므로 숨겨야 합니다. +`eth_maxPriorityFeePerGas`는 Stable에서 항상 `0`을 반환합니다. 지갑이나 SDK가 RPC가 반환한 우선순위 수수료를 기본 수수료에 추가하더라도 작동하지만, 별도의 팁을 표시하는 수수료 UI는 `0`을 표시하므로 숨겨야 합니다. ::: -## 툴링 구성 +## 도구 구성 -- **Hardhat / Foundry**: 특별한 구성이 필요 없습니다. 표준 EVM 설정이 작동합니다. 구성에서 priority fee를 명시적으로 설정한다면 `0`으로 설정하세요. -- **지갑**: priority 팁 입력 필드를 숨기거나 비활성화하세요. 이 값은 순서 지정이나 포함에 영향을 미치지 않으므로 표시하는 것은 오해를 일으킵니다. -- **모니터링**: 수수료 분석 대시보드는 priority fee를 차트로 표시하지 않아야 합니다. Stable에서는 항상 0입니다. +- **Hardhat / Foundry**: 특별한 구성이 필요하지 않습니다. 표준 EVM 설정이 작동합니다. 구성에서 우선순위 수수료를 명시적으로 설정하는 경우 `0`으로 설정하십시오. +- **지갑**: 우선순위 팁 입력 필드를 숨기거나 비활성화하십시오. 이 값을 표시하면 값이 순서 지정이나 포함에 전혀 영향을 미치지 않으므로 오해의 소지가 있습니다. +- **모니터링**: 수수료 분석 대시보드는 우선순위 수수료를 차트로 만들어서는 안 됩니다. Stable에서는 항상 0입니다. -## 이더리움에서 이식할 때 흔한 실수 +## 이더리움에서 포팅할 때 흔히 발생하는 실수 -- **ETH로 표기된 팁 적용**: 이더리움에서 priority-fee 상수를 복사한다고 해서 더 빠른 포함이 이루어지지 않습니다. Stable은 base fee만으로 트랜잭션 순서를 정합니다. -- **`value`를 ETH로 취급**: 네이티브 전송의 `value`는 USDT0입니다. ETH/USD 가격으로 변환하지 마세요. -- **수수료 상한 하드코딩**: 고정 값 대신 실시간 `baseFeePerGas`로부터 `maxFeePerGas`를 설정하세요(예: `baseFee * 2`). 그래야 base fee가 상승할 때 트랜잭션이 멈추지 않습니다. +- **ETH로 표시된 팁 적용**: 이더리움에서 우선순위 수수료 상수를 복사한다고 해서 더 빠른 포함이 이루어지는 것은 아닙니다. Stable은 기본 수수료에 따라 트랜잭션을 정렬합니다. +- **`value`를 ETH로 취급**: 네이티브 전송의 `value`는 USDT0입니다. ETH/USD 가격으로 변환하지 마십시오. +- **수수료 상한을 하드코딩**: 고정된 값 대신 실시간 `baseFeePerGas`에서 `maxFeePerGas`를 설정하면(예: `baseFee * 2`) 기본 수수료가 상승할 때 트랜잭션이 중단되는 것을 방지합니다. -## 다음 추천 +## 다음 추천 항목 -- [**가스 가격 책정 레퍼런스**](/ko/reference/gas-pricing-api) — 전체 base-fee 모델, EIP-1559 형식, `eth_*` 메서드 동작. -- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions) — 애플리케이션이 Gas Waiver를 통해 가스를 부담하도록 하기. -- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior) — 잔액 조정 및 USDT0의 이중 역할을 고려한 컨트랙트 설계. +- [**가스 가격 책정 참조**](/ko/reference/gas-pricing-api): 전체 기본 수수료 모델, EIP-1559 형식 및 `eth_*` 메서드 동작. +- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions): 애플리케이션이 Gas Waiver를 통해 가스를 부담하도록 합니다. +- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior): USDT0의 이중 역할을 통한 잔액 조정 및 계약 설계. diff --git a/docs/pages/ko/how-to/zero-gas-transactions.mdx b/docs/pages/ko/how-to/zero-gas-transactions.mdx index 0d4210f..fce58dc 100644 --- a/docs/pages/ko/how-to/zero-gas-transactions.mdx +++ b/docs/pages/ko/how-to/zero-gas-transactions.mdx @@ -1,56 +1,56 @@ --- source_path: how-to/zero-gas-transactions.mdx -source_sha: 169da924be4764e0ff38c2b0af2e580ed4508070 -title: "가스리스 트랜잭션" -description: "Stable의 Gas Waiver를 사용하여 사용자에게 가스 비용이 들지 않는 USDT0 전송을 보내고, 영수증에 수수료가 0으로 표시되는지 확인합니다." +source_sha: e339e4b5be06cdca1384f6b51ea54df697194698 +title: "제로 가스 트랜잭션" +description: "Stable의 가스 면제(Gas Waiver)를 사용하여 사용자에게 가스가 전혀 들지 않는 USDT0 전송을 보내고, 영수증에 수수료가 0으로 표시되는지 확인합니다." diataxis: "how-to" --- -# 가스리스 트랜잭션 +# 제로 가스 트랜잭션 -Gas Waiver를 사용하면 애플리케이션이 사용자를 대신해 가스를 부담할 수 있습니다. 사용자는 `gasPrice = 0`으로 트랜잭션에 서명하고, 거버넌스에 등록된 waiver가 이를 감싸며, 검증자는 사용자에게 비용이 들지 않게 호출을 실행합니다. 이 가이드는 조건을 충족하는 전송 과정을 살펴보고, 가스가 면제되었는지 확인하는 방법을 보여주며, waiver가 무엇을 다루고 다루지 않는지 설명합니다. +가스 면제(Gas Waiver)를 사용하면 애플리케이션이 사용자를 대신하여 가스 요금을 지불할 수 있습니다. 사용자는 `gasPrice = 0`으로 트랜잭션에 서명하고, 거버넌스에 등록된 면제자가 이를 래핑하며, 검증자는 사용자에게 비용 없이 호출을 실행합니다. 이 가이드에서는 적격한 전송을 진행하고, 가스가 면제되었는지 확인하는 방법, 그리고 면제가 무엇을 다루고 무엇을 다루지 않는지 설명합니다. :::note -**개념**: 래퍼 트랜잭션 메커니즘, 권한 모델, 보안 보장에 대해서는 [Gas waiver](/ko/explanation/gas-waiver)와 [Gas waiver 프로토콜 레퍼런스](/ko/reference/gas-waiver-api)를 참조하세요. +**개념**: 래퍼 트랜잭션 메커니즘, 인증 모델 및 보안 보장에 대해서는 [가스 면제](/ko/explanation/gas-waiver) 및 [가스 면제 프로토콜 참조](/ko/reference/gas-waiver-api)를 참조하세요. ::: -## 무엇을 만들 것인가 +## 구축할 내용 -호스팅된 Waiver 서버를 통해 USDT0 전송을 제출하고, 영수증을 가져온 다음, `gasPrice = 0`을 확인하는 두 개의 스크립트 흐름입니다. +호스팅된 면제 서버를 통해 USDT0 전송을 제출하고, 영수증을 가져와서 `gasPrice = 0`을 확인하는 두 가지 스크립트 흐름입니다. ### 데모 ```text -step 1. Connect wallet, balance displayed as 0.01 USDT0 +1단계. 지갑 연결, 잔액이 0.01 USDT0으로 표시됩니다. -step 2. Send transaction via Gas Waiver → [Run] +2단계. 가스 면제를 통해 트랜잭션 전송 → [실행] -step 3. Result +3단계. 결과 tx: 0x8f3a...2d41 - Gas fee paid by you: 0.000000 USDT0 - Balance after: 0.01 USDT0 + 귀하가 지불한 가스 수수료: 0.000000 USDT0 + 이후 잔액: 0.01 USDT0 ``` -## waiver가 적용되는 경우 +## 면제가 적용되는 경우 -다음 조건이 모두 충족되면 트랜잭션이 자격을 갖춥니다: +모든 다음 조건이 충족될 때 트랜잭션이 적격하다고 간주됩니다. -- 사용자가 `gasPrice = 0`으로 내부 트랜잭션에 서명합니다. -- 제출자가 거버넌스에 등록된 waiver 주소입니다. -- 대상 `to` 주소와 메서드 셀렉터가 waiver의 `AllowedTarget` 정책에 있습니다. -- 래퍼가 `value = 0` 및 `gasPrice = 0`으로 마커 주소 `0x000000000000000000000000000000000000f333`에 전송됩니다. +- 사용자는 `gasPrice = 0`으로 내부 트랜잭션에 서명합니다. +- 제출자는 거버넌스에 등록된 면제 주소입니다. +- 대상 `to` 주소와 메서드 선택기가 면제자의 `AllowedTarget` 정책에 있습니다. +- 래퍼는 `value = 0` 및 `gasPrice = 0`으로 마커 주소 `0x000000000000000000000000000000000000f333`로 전송됩니다. -이 중 하나라도 실패하면, 검증자는 내부 호출을 실행하지 않고 래퍼를 거부합니다. `AllowedTarget`에 등록되지 않은 컨트랙트 호출은 다루지 않습니다. 임의의 셀프 서비스 waiver는 불가능하며, 모든 waiver는 검증자 거버넌스를 통해 등록되어야 합니다. +이 중 하나라도 실패하면 검증자는 내부 호출을 실행하지 않고 래퍼를 거부합니다. `AllowedTarget`에 나열되지 않은 계약 호출은 포함되지 않습니다. 임의의 셀프 서비스 면제는 불가능합니다. 모든 면제는 검증자 거버넌스를 통해 등록되어야 합니다. -## 사전 요구 사항 +## 전제 조건 -- Stable 팀이 발급한 Waiver 서버용 API 키. -- waiver의 `AllowedTarget` 정책에 등록된 대상 컨트랙트 주소와 메서드 셀렉터. -- 가스용 USDT0가 필요 없는 테스트넷의 사용자 지갑. +- Stable 팀에서 발행한 면제 서버용 API 키. +- 면제자의 `AllowedTarget` 정책에 등록된 대상 계약 주소 및 메서드 선택기. +- 가스에 필요한 USDT0가 없는 테스트넷 사용자의 지갑. -## 1단계: 자격을 갖춘 InnerTx 서명하기 +## 1단계: 적격 InnerTx 서명 -사용자는 `gasPrice = 0`으로 표준 트랜잭션에 서명합니다. 이 예제에서 호출은 USDT0 `transfer`이며, 이는 애플리케이션이 가스를 부담하는 흐름에서 흔히 사용되는 `AllowedTarget`입니다. +사용자는 `gasPrice = 0`으로 표준 트랜잭션에 서명합니다. 이 예제에서 호출은 USDT0 `transfer`이며, 이는 애플리케이션에서 처리하는 가스 흐름에 대한 일반적인 `AllowedTarget`입니다. ```typescript // config.ts @@ -113,12 +113,12 @@ Signed InnerTx: 0xf8a8...c1 ``` :::warning -`gasPrice`는 반드시 `0`이어야 합니다. 0이 아닌 값은 waiver 서버가 제출을 거부하고 검증자가 래퍼를 거부하게 만듭니다. +`gasPrice`는 반드시 `0`이어야 합니다. 0이 아닌 값은 면제 서버가 제출을 거부하고 검증자가 래퍼를 거부하도록 합니다. ::: -## 2단계: Waiver 서버를 통해 제출하기 +## 2단계: 면제 서버를 통해 제출 -Waiver 서버는 서명된 내부 트랜잭션을 감싸서 브로드캐스트합니다. 서버에서 발급한 API 키가 필요합니다. +면제 서버는 서명된 내부 트랜잭션을 래핑하고 브로드캐스트합니다. 서버에서 발행한 API 키가 필요합니다. ```typescript // submit.ts @@ -162,9 +162,9 @@ npx tsx submit.ts tx confirmed: 0x8f3a...2d41 ``` -## 3단계: 영수증에 가스가 0으로 표시되는지 확인하기 +## 3단계: 영수증에 가스 0이 표시되는지 확인 -영수증을 가져와 `effectiveGasPrice`가 0인지 확인합니다. 이것이 사용자가 가스를 지불하지 않았다는 암호학적 증거입니다. +영수증을 가져와 `effectiveGasPrice`가 0인지 확인합니다. 이는 사용자가 가스를 지불하지 않았음을 증명하는 암호화 증거입니다. ```typescript // verify.ts @@ -192,18 +192,18 @@ Effective gas price: 0 Gas fee paid: 0 USDT0 (wei-equivalent) ``` -`effectiveGasPrice`가 `0`이면 트랜잭션이 등록된 waiver 하에서 실행되었으며 사용자에게 요금이 부과되지 않았음을 확인할 수 있습니다. +`effectiveGasPrice`가 `0`이면 트랜잭션이 등록된 면제 하에 실행되었고 사용자에게 요금이 부과되지 않았음을 확인합니다. -## Gas Waiver가 다루지 않는 것 +## 가스 면제가 다루지 않는 것 -- **`AllowedTarget` 외부의 컨트랙트**: 임의의 컨트랙트 호출은 다루지 않습니다. 모든 대상은 거버넌스를 통해 waiver별로 범위가 지정됩니다. -- **사용자가 제출한 래퍼**: 사용자가 `0x...f333`에 직접 제출하면 실패합니다. 등록된 waiver 주소만 래핑할 수 있습니다. -- **수수료 추출**: 검증자는 내부 또는 래퍼 트랜잭션 어느 쪽에서도 0이 아닌 `gasPrice`를 허용하지 않습니다. +- **`AllowedTarget` 외부의 계약**: 임의의 계약 호출은 다루지 않습니다. 각 대상은 거버넌스를 통해 면제당 범위가 지정됩니다. +- **사용자가 제출한 래퍼**: 사용자가 직접 `0x...f333`에 제출하면 실패합니다. 등록된 면제 주소만 래핑할 수 있습니다. +- **수수료 추출**: 검증자는 내부 또는 래퍼 트랜잭션에서 0이 아닌 `gasPrice`를 허용하지 않습니다. -전체 정책 모델과 waiver별 범위 규칙은 [Gas waiver 프로토콜](/ko/reference/gas-waiver-api)을 참조하세요. +전체 정책 모델 및 면제별 범위 규칙은 [가스 면제 프로토콜](/ko/reference/gas-waiver-api)을 참조하세요. -## 다음 추천 사항 +## 다음 권장 사항 -- [**Waiver 서버 통합하기**](/ko/how-to/integrate-gas-waiver) — 전체 API 레퍼런스, 배치 제출, 오류 코드, NDJSON 스트리밍. -- [**셀프 호스팅 Gas Waiver**](/ko/how-to/self-hosted-gas-waiver) — 자체 waiver 주소를 등록하고 호스팅된 API 없이 래퍼를 브로드캐스트합니다. -- [**Gas waiver 프로토콜**](/ko/reference/gas-waiver-api) — 전체 명세를 읽어보세요: 마커 라우팅, 래퍼 형식, 거버넌스 제어. +- [**면제 서버 통합**](/ko/how-to/integrate-gas-waiver): 전체 API 참조, 배치 제출, 오류 코드 및 NDJSON 스트리밍. +- [**자체 호스팅 가스 면제**](/ko/how-to/self-hosted-gas-waiver): 자체 면제 주소를 등록하고 호스팅 API 없이 래퍼를 브로드캐스트합니다. +- [**가스 면제 프로토콜**](/ko/reference/gas-waiver-api): 전체 사양을 읽어보세요: 마커 라우팅, 래퍼 형식, 거버넌스 제어. diff --git a/docs/pages/ko/index.mdx b/docs/pages/ko/index.mdx index 960f2f8..1666740 100755 --- a/docs/pages/ko/index.mdx +++ b/docs/pages/ko/index.mdx @@ -1,34 +1,34 @@ --- source_path: index.mdx -source_sha: 4f3855b4d75c262f0f87dc286a2dce4c7b7ba36a -title: "Stable 통합하기" -description: "구축하려는 기능을 선택하세요. 모든 경로는 몇 분 안에 테스트넷에서 실행 가능한 가이드로 이어집니다." +source_sha: 1245c6893961ce66cd4dd228ab22312760d5f5b4 +title: "Stable 통합" +description: "구축하려는 기능을 선택하세요. 모든 경로는 몇 분 안에 테스트넷에서 실행 가능한 가이드로 연결됩니다." diataxis: "explanation" --- -# Stable 통합하기 +# Stable 통합 -Stable은 USDT0가 네이티브 가스 토큰이자 ERC-20인 레이어 1입니다. 단일 슬롯 완결성, 1초 미만의 블록 타임, 그리고 완전한 EVM 호환성을 갖추고 있습니다. 지갑, 시드 문구, USDT0만 준비하면 됩니다. +Stable은 USDT0가 네이티브 가스 토큰이자 ERC-20인 레이어 1입니다. 단일 슬롯 완결성, 1초 미만의 블록 시간, 완전한 EVM 호환성을 제공합니다. 지갑, 시드 문구, USDT0를 준비하기만 하면 됩니다. -구축하려는 기능을 선택하세요. 아래의 모든 경로는 몇 분 안에 테스트넷에서 실행 가능한 가이드로 이어집니다. +구축하려는 기능을 선택하세요. 아래의 모든 경로는 몇 분 안에 테스트넷에서 실행 가능한 가이드로 연결됩니다. ## 경로 선택 -- [**계정**](/ko/explanation/accounts-overview) — 지갑, EIP-7702 위임, 세션 키, 지출 한도. 사용자 및 에이전트 계정에 대한 최고 수준의 지원. -- [**결제**](/ko/explanation/payments-overview) — USDT0 전송, P2P 지갑 구축, 정기 구독, 인보이스 정산, 호출당 과금 API. -- [**컨트랙트**](/ko/explanation/contracts-overview) — 컨트랙트 배포, 검증, 인덱싱. Solidity에서 Bank, Distribution, Staking 프리컴파일 호출. -- [**AI / 에이전트**](/ko/explanation/agent-settlement) — MCP 서버와 에이전트 스킬을 AI 에디터에 연결. 자율 에이전트를 위한 요청당 API 과금. -- [**인프라**](/ko/explanation/integrate-overview) — 가스 면제 서비스, 생태계 제공자(브리지, 오라클, 램프), 네트워크 정보, 노드 운영. -- [**학습**](/ko/explanation/learn-overview) — 아키텍처, USDT0 동작, 사용 사례 시나리오, 그리고 Ethereum-to-Stable 레퍼런스. +- [**계정**](/ko/explanation/accounts-overview): 지갑, EIP-7702 위임, 세션 키, 지출 한도. 사용자 및 에이전트 계정에 대한 우선 지원. +- [**결제**](/ko/explanation/payments-overview): USDT0 전송, P2P 지갑 구축, 정기 구독, 송장 결제, API 호출당 요금 지불. +- [**컨트랙트**](/ko/explanation/contracts-overview): 컨트랙트 배포, 검증 및 인덱싱. Solidity에서 Bank, Distribution 및 Staking 프리컴파일 호출. +- [**AI / 에이전트**](/ko/explanation/agent-settlement): MCP 서버 및 에이전트 기술을 AI 편집기에 연결. 자율 에이전트의 요청당 API 가격 책정. +- [**인프라스트럭처**](/ko/explanation/integrate-overview): 가스 면제 서비스, 생태계 제공업체 (브릿지, 오라클, 램프), 네트워크 정보 및 노드 운영. +- [**학습**](/ko/explanation/learn-overview): 아키텍처, USDT0 동작, 사용 사례 내러티브 및 이더리움-Stable 참조. ## 5분 안에 시작하기 -- [**빠른 시작**](/ko/tutorial/quick-start) — 연결하고, 포셋에서 지갑에 자금을 충전하고, 0.001 USDT0를 네이티브로 전송하세요. -- [**Stable에 연결하기**](/ko/reference/connect) — 체인 ID, RPC 엔드포인트, 포셋, 블록 탐색기. -- [**Ethereum과의 차이점**](/ko/explanation/ethereum-comparison) — Ethereum에서 포팅할 때 동일하게 유지되는 것과 변경되는 것. +- [**빠른 시작**](/ko/tutorial/quick-start): 연결, Faucet에서 지갑에 자금 조달, 0.001 USDT0 기본 전송. +- [**Stable에 연결**](/ko/reference/connect): 체인 ID, RPC 엔드포인트, Faucet 및 블록 탐색기. +- [**이더리움과의 차이점**](/ko/explanation/ethereum-comparison): 이더리움에서 포팅할 때 유지되는 것과 변경되는 것. -## 그 외 모든 것 +## 기타 -- **네트워크 상태 및 버전**: [테스트넷](/ko/reference/testnet-information) · [메인넷](/ko/reference/mainnet-information) · [버전 기록](/ko/reference/testnet-version-history). -- **토크노믹스 및 로드맵**: [STABLE 토크노믹스](/ko/reference/tokenomics) · [기술 로드맵](/ko/explanation/technical-roadmap). +- **네트워크 상태 및 버전**: [testnet](/ko/reference/testnet-information) · [mainnet](/ko/reference/mainnet-information) · [버전 기록](/ko/reference/testnet-version-history). +- **토큰 경제학 및 로드맵**: [STABLE 토큰 경제학](/ko/reference/tokenomics) · [기술 로드맵](/ko/explanation/technical-roadmap). - **FAQ**: [개발자 FAQ](/ko/reference/faq) · [개발자 지원](/ko/reference/developer-assistance). diff --git a/docs/pages/ko/reference/connect.mdx b/docs/pages/ko/reference/connect.mdx index 47f4f26..d24aa4b 100644 --- a/docs/pages/ko/reference/connect.mdx +++ b/docs/pages/ko/reference/connect.mdx @@ -1,23 +1,21 @@ --- source_path: reference/connect.mdx -source_sha: ae01c8773f19829d94bf98e624e9fd6797ae283b +source_sha: 5499fbd8e32bd54d6d35e5b87182919c7eadd9a3 title: "연결" -description: "Stable의 메인넷 및 테스트넷 체인 ID, RPC 엔드포인트, 블록 탐색기, 포셋." +description: "Stable을 위한 메인넷 및 테스트넷 체인 ID, RPC 엔드포인트, 블록 탐색기, 그리고 Faucet." diataxis: "reference" --- -import { AddToMetaMask } from '../../../components/AddToMetaMask' - # 연결 -이 페이지는 Stable에 연결하는 데 필요한 네트워크 세부 정보를 정리합니다. +이 페이지는 Stable에 연결하는 데 필요한 네트워크 세부 정보를 통합합니다. ## 메인넷 | **필드** | **값** | | :--- | :--- | | 네트워크 이름 | Stable Mainnet | -| Chain ID | `988` | +| 체인 ID | `988` | | 통화 기호 | USDT0 | | EVM JSON-RPC | `https://rpc.stable.xyz` | | WebSocket | `wss://rpc.stable.xyz` | @@ -28,42 +26,36 @@ import { AddToMetaMask } from '../../../components/AddToMetaMask' | **필드** | **값** | | :--- | :--- | | 네트워크 이름 | Stable Testnet | -| Chain ID | `2201` | +| 체인 ID | `2201` | | 통화 기호 | USDT0 | | EVM JSON-RPC | `https://rpc.testnet.stable.xyz` | | WebSocket | `wss://rpc.testnet.stable.xyz` | | 블록 탐색기 | [https://testnet.stablescan.xyz](https://testnet.stablescan.xyz) | -서드파티 RPC 제공자에 대해서는 [RPC 제공자](/ko/reference/rpc-providers)를 참고하세요. 이러한 엔드포인트를 자동으로 연결해 주는 타입이 지정된 클라이언트는 [Stable SDK](/ko/explanation/sdk-overview)를 참고하세요. +타사 RPC 공급자에 대해서는 [RPC 공급자](/ko/reference/rpc-providers)를 참조하십시오. 이러한 엔드포인트를 자동으로 연결해주는 유형화된 클라이언트에 대해서는 [Stable SDK](/ko/explanation/sdk-overview)를 참조하십시오. ## 속도 제한 -공개 RPC 엔드포인트(`https://rpc.stable.xyz` 및 `https://rpc.testnet.stable.xyz`)는 **IP당 10초에 1,000 요청**으로 속도가 제한됩니다. 제한을 초과하는 요청은 `HTTP 429`를 반환합니다. +공개 RPC 엔드포인트(`https://rpc.stable.xyz` 및 `https://rpc.testnet.stable.xyz`)는 IP당 10초에 **1,000개 요청**으로 속도가 제한됩니다. 제한을 초과하는 요청은 `HTTP 429`를 반환합니다. -더 높은 처리량이 필요한 경우 [서드파티 RPC 제공자](/ko/reference/rpc-providers)를 사용하세요. +더 높은 처리량을 원하시면 [타사 RPC 공급자](/ko/reference/rpc-providers)를 이용하세요. :::note -USDT0는 네이티브 가스 토큰으로는 **18 소수 자릿수**를 사용하고(`address(x).balance`가 반환), ERC-20 토큰으로는 **6 소수 자릿수**를 사용합니다(`USDT0.balanceOf(x)`가 반환). 두 인터페이스 모두 동일한 기본 잔액에서 동작합니다. viem과 ethers.js 같은 라이브러리는 네이티브 가스 토큰을 읽기 때문에 18 소수 자릿수를 보고합니다. 정밀도 차이가 어떻게 조정되는지에 대한 자세한 내용은 [Stable에서의 USDT0 동작](/ko/explanation/usdt0-behavior)을 참고하세요. +USDT0는 네이티브 가스 토큰( `address(x).balance`에 의해 반환됨)으로 **18자리 소수점**을 사용하고, ERC-20 토큰(`USDT0.balanceOf(x)`에 의해 반환됨)으로 **6자리 소수점**을 사용합니다. 두 인터페이스는 동일한 기본 잔액에서 작동합니다. viem 및 ethers.js와 같은 라이브러리는 네이티브 가스 토큰을 읽기 때문에 18자리 소수점을 보고합니다. 정밀도 차이가 어떻게 조정되는지에 대한 자세한 내용은 [Stable에서의 USDT0 동작](/ko/explanation/usdt0-behavior)을 참조하십시오. ::: -## 지갑에 Stable 추가하기 - -MetaMask(또는 다른 주입형 EVM 지갑)를 사용한다면 한 번의 클릭으로 Stable을 추가하세요. 이 버튼은 `wallet_addEthereumChain`을 호출하므로, 지갑이 아래의 네트워크 세부 정보를 확인하도록 안내합니다. USDT0가 네이티브 가스 토큰이기 때문에 네트워크가 추가되면 별도의 토큰 가져오기 없이 잔액이 자동으로 표시됩니다. - - - -[Chainlist](https://chainlist.org/?search=Stable)에서도 Stable을 추가할 수 있습니다. "Stable"을 검색하고 지갑을 연결한 다음 **Add to MetaMask**를 클릭하세요. +## Stable을 지갑에 추가 -대신 Stable을 수동으로 추가하려면 지갑의 네트워크 설정을 열고 위 표의 값을 입력하세요. 필수 필드는 다음과 같습니다. +Stable을 수동으로 추가하려면 브라우저 지갑의 네트워크 설정을 열고 위 표의 값을 입력하십시오. 필수 필드는 다음과 같습니다. -- **네트워크 이름** -- **RPC URL** (EVM JSON-RPC 엔드포인트) -- **Chain ID** -- **통화 기호**: `USDT0` +- **네트워크 이름** +- **RPC URL** (EVM JSON-RPC 엔드포인트) +- **체인 ID** +- **통화 기호**: `USDT0` ## 연결 확인 -체인 ID를 쿼리하여 RPC 엔드포인트에 접근 가능한지 확인하세요: +체인 ID를 쿼리하여 RPC 엔드포인트에 연결할 수 있는지 확인합니다. ```bash cast chain-id --rpc-url https://rpc.stable.xyz @@ -87,8 +79,8 @@ cast chain-id --rpc-url https://rpc.testnet.stable.xyz 2201 ``` -## 다음 추천 +## 다음 권장 사항 -- [**빠른 시작**](/ko/tutorial/quick-start): 5분 안에 첫 테스트넷 트랜잭션을 보내세요. -- [**테스트넷 USDT0 받기**](/ko/how-to/use-faucet): 포셋에서 지갑에 자금을 충전하거나 Sepolia에서 브리지하세요. -- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior): 잔액을 다루는 코드를 작성하기 전에 18/6 소수 자릿수 이중 역할을 이해하세요. +- [**빠른 시작**](/ko/tutorial/quick-start): 5분 만에 첫 번째 테스트넷 트랜잭션을 전송하세요. +- [**테스트넷 USDT0 받기**](/ko/how-to/use-faucet): Faucet에서 지갑에 자금을 채우거나 Sepolia에서 브리지를 사용하세요. +- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior): 잔액에 대해 코드를 작성하기 전에 18/6 소수점 이중 역할을 이해하세요. diff --git a/docs/pages/ko/reference/developer-assistance.mdx b/docs/pages/ko/reference/developer-assistance.mdx index ec69888..f1c7eb6 100755 --- a/docs/pages/ko/reference/developer-assistance.mdx +++ b/docs/pages/ko/reference/developer-assistance.mdx @@ -1,42 +1,49 @@ --- source_path: reference/developer-assistance.mdx -source_sha: 740d84fb64ee73630cea7e1fc648dfa8ceea5b19 +source_sha: 2e55049566daa5a3f782c7ca3acee94096762402 title: 개발자 지원 -description: FAQ, 공식 커뮤니케이션 채널 및 주요 참조 위치입니다. +description: Stable에서 구축하기 위한 도움말, 공식 커뮤니케이션 채널 및 주요 참조 위치에 대한 빠른 액세스. +diataxis: "reference" --- # 개발자 지원 ## FAQ -다음과 같은 주제를 다루는 개발자 중심 질문 모음집입니다: +다음과 같은 주제를 다루는 개발자 중심 질문 모음이 계속 추가되고 있습니다. - Stable 네트워크에 어떻게 연결하나요? - - 일반적인 EVM 도구와 호환되는 표준 JSON-RPC 요청을 사용하여 네트워크와 상호작용할 수 있습니다. -- 트랜잭션 수수료에는 어떤 통화가 사용되나요? - - 트랜잭션 수수료는 USDT0로 지불됩니다. 표준 기본 가스 가격 외에 추가적인 수수료 매개변수는 필요하지 않습니다. -- 업데이트는 어디서 추적할 수 있나요? - - 모든 프로토콜 및 개발자 대상 변경사항은 릴리스 & 변경 로그에서 전달됩니다. + - 일반적인 EVM 툴링과 호환되는 표준 JSON-RPC 요청을 사용하여 네트워크와 상호 작용할 수 있습니다. +- 거래 수수료에 어떤 통화가 사용되나요? + - 거래 수수료는 USDT0으로 지불합니다. 표준 기본 가스 가격 외에 추가 수수료 매개변수는 필요하지 않습니다. +- 업데이트는 어디에서 확인할 수 있나요? + - 릴리스 및 변경 로그는 모든 프로토콜 및 개발자 관련 변경 사항을 전달합니다. - Stable은 계정 추상화를 지원하나요? - - 네. EIP-7702는 EOA가 일시적으로 스마트 계정 동작으로 작동할 수 있게 합니다. - - 자세한 내용은 [여기](ko/architecture/usdt-specific-features/eip-7702-and-aa)에서 읽을 수 있습니다. -- 트랜잭션 결과는 어디서 볼 수 있나요? - - 블록에 포함되면 다음을 통해 결과를 볼 수 있습니다: - - 잔액 읽기 - - 컨트랙트 상태 조회 - - 로그 및 방출된 이벤트 -- Stable용 스마트 컨트랙트는 어떻게 빌드하나요? - - 다음과 같은 표준 EVM 개발자 워크플로를 사용할 수 있습니다: - - Solidity 기반 컨트랙트 - - 네트워크와 상호작용하기 위한 JSON-RPC 라이브러리 - -이 페이지는 공개 테스트넷 사용 중 일반적인 질문이 발생하면서 확장될 것입니다. + - 네. EIP-7702를 통해 EOA는 스마트 계정 동작으로 일시적으로 작동할 수 있습니다. + - [EIP-7702 참조](/ko/reference/eip-7702-api) 및 [계정 추상화 방법](/ko/how-to/account-abstraction)을 참조하세요. +- 거래 결과를 어디에서 볼 수 있나요? + - 블록에 포함되면 결과는 다음을 통해 볼 수 있습니다. + - 잔고 읽기 + - 계약 상태 쿼리 + - 로그 및 발생된 이벤트 +- Stable용 스마트 계약을 어떻게 구축하나요? + - 다음과 같은 표준 EVM 개발자 워크플로를 사용할 수 있습니다. + - Solidity 기반 계약 + - 네트워크와 상호 작용하기 위한 JSON-RPC 라이브러리 + +이 페이지는 공개 테스트넷 사용 중에 일반적인 질문이 발생하면 확장될 것입니다. ## 지원 채널 -개발자는 기술 지원을 위해 Stable 팀과 직접 소통할 수 있습니다. +기술 지원을 위해 Stable 팀과 직접 소통할 수 있습니다. -- **Discord**: https://discord.gg/stablexyz 개발자 채널에 참여하세요. -- **이슈 보고**: 공개 깃헙 레포가 열리면 지침이 제공될 예정입니다. +- **Discord**: https://discord.gg/stablexyz 에서 개발자 채널에 참여하세요. +- **문제 보고**: 공개 리포지토리가 열리면 지침이 제공됩니다. -커뮤니티 플랫폼이 사용 가능해지면 지원 연락처가 업데이트될 예정입니다. +커뮤니티 플랫폼을 이용할 수 있게 되면 지원 연락처가 업데이트됩니다. + +## 다음 권장 사항 + +- [**빠른 시작**](/ko/tutorial/quick-start): 5분 안에 첫 번째 테스트넷 거래를 실행하세요. +- [**프로덕션 준비**](/ko/how-to/production-readiness): 메인넷에 배포하기 전에 통합을 검증하세요. +- [**FAQ**](/ko/reference/faq): 체인 ID, 엔드포인트 및 온보딩에 대한 일반적인 답변. diff --git a/docs/pages/ko/reference/eip-7702-api.mdx b/docs/pages/ko/reference/eip-7702-api.mdx index 80c1574..b055a9d 100644 --- a/docs/pages/ko/reference/eip-7702-api.mdx +++ b/docs/pages/ko/reference/eip-7702-api.mdx @@ -1,22 +1,22 @@ --- source_path: reference/eip-7702-api.mdx -source_sha: ed9c7f3d8305826eb401d45116a49d3adf2cd3f6 +source_sha: e14a186b9b5e856dc39965a4b8358d407e18dcbd title: "EIP-7702" -description: "Stable의 EIP-7702 지원. EOA는 자신의 계정 코드를 기존 스마트 컨트랙트로 설정하여 일괄 결제, 지출 한도, 세션 키 등을 사용할 수 있습니다." +description: "Stable에서 EIP-7702를 지원합니다. EOA는 자신의 계정 코드를 기존 스마트 계약으로 설정하여 일괄 결제, 지출 한도 및 세션 키를 사용할 수 있습니다." diataxis: "reference" --- # EIP-7702 -Stable은 **EIP-7702**를 지원하며, 이를 통해 EOA가 자신의 계정 코드를 기존 스마트 컨트랙트로 설정할 수 있습니다. EOA는 원래의 주소와 프라이빗 키를 유지하면서 위임 대상의 로직을 실행합니다. +Stable은 EOA가 계정 코드를 기존 스마트 계약으로 설정할 수 있도록 하는 **EIP-7702**를 지원합니다. EOA는 위임자의 로직을 실행하는 동안 원래 주소와 개인 키를 유지합니다. :::note -**개념:** EIP-7702가 Stable에서 가능하게 하는 것, 위임 모델, 보안 고려사항에 대해서는 [EIP-7702](/ko/explanation/eip-7702)를 참조하세요. 전체 명세는 [EIP-7702 spec](https://eips.ethereum.org/EIPS/eip-7702)을 참조하세요. +**개념:** EIP-7702가 Stable에서 지원하는 기능, 위임 모델 및 보안 고려 사항에 대해서는 [EIP-7702](/ko/explanation/eip-7702)를 참조하십시오. 전체 사양은 [EIP-7702 사양](https://eips.ethereum.org/EIPS/eip-7702)을 참조하십시오. ::: ## 트랜잭션 형식 -EIP-7702는 `authorizationList` 필드를 포함하는 트랜잭션 타입 `0x04`를 사용합니다. 각 authorization은 해당 트랜잭션에서 EOA가 실행할 코드를 가진 위임 컨트랙트를 지정합니다. +EIP-7702는 `authorizationList` 필드가 있는 트랜잭션 유형 `0x04`를 사용합니다. 각 권한 부여는 해당 트랜잭션에 대해 EOA가 코드를 실행하는 위임 계약을 지정합니다. ```typescript { @@ -29,21 +29,21 @@ EIP-7702는 `authorizationList` 필드를 포함하는 트랜잭션 타입 `0x04 } ``` -authorization이 담는 정보: +권한 부여는 다음을 포함합니다. - `chainId`: 대상 체인과 일치해야 합니다. -- `address`: 위임 컨트랙트 주소입니다. -- `nonce`: authorization nonce(트랜잭션 nonce와 별개)입니다. +- `address`: 위임 계약 주소. +- `nonce`: 권한 부여 논스(트랜잭션 논스와는 별개). -EIP-7702를 지원하는 지갑과 라이브러리는 authorization 형식을 자동으로 처리합니다. +EIP-7702를 지원하는 지갑 및 라이브러리는 권한 부여 형식을 자동으로 처리합니다. -## 도구 +## 툴링 -- **ethers.js**: `wallet.signAuthorization({ chainId, address, nonce })`는 `authorizationList`에 포함할 서명된 authorization을 생성합니다. -- **viem**: walletClient와 함께 `signAuthorization`을 사용한 다음, 그 결과를 `sendTransaction`에 전달합니다. -- **Hardhat / Foundry**: 도구 체인 버전이 Pectra 하드포크를 지원하면 표준 EIP-7702 트랜잭션 형식이 동작합니다. +- **ethers.js**: `wallet.signAuthorization({ chainId, address, nonce })`는 `authorizationList`에 포함될 서명된 권한 부여를 생성합니다. +- **viem**: `signAuthorization`을 walletClient와 함께 사용한 다음, 결과를 `sendTransaction`에 전달합니다. +- **Hardhat / Foundry**: 도구 체인 버전이 Pectra 하드포크를 지원하는 경우 표준 EIP-7702 트랜잭션 형식이 작동합니다. ## 다음 권장 사항 -- [**EIP-7702 개념**](/ko/explanation/eip-7702) — 위임 모델과 사용 시점을 이해하세요. -- [**계정 추상화 (EIP-7702)**](/ko/reference/eip-7702-api) — 일괄 결제, 지출 한도, 세션 키를 단계별로 구현하세요. +- [**EIP-7702 개념**](/ko/explanation/eip-7702): 위임 모델과 사용 시기를 이해합니다. +- [**계정 추상화 (EIP-7702)**](/ko/reference/eip-7702-api): 일괄 결제, 지출 한도 및 세션 키를 단계별로 구현합니다. diff --git a/docs/pages/ko/reference/faq.mdx b/docs/pages/ko/reference/faq.mdx index ba50f7c..b2ebc67 100755 --- a/docs/pages/ko/reference/faq.mdx +++ b/docs/pages/ko/reference/faq.mdx @@ -1,50 +1,75 @@ --- source_path: reference/faq.mdx -source_sha: 8bc0e6b7823c072b4f7c5dd26e280584966f7493 +source_sha: 348b72ccef22f764866c7d7b5395ae60c4e9f159 title: "FAQ" -description: "Stable의 설계, USDT 통합, 확장성 접근 방식 및 기술적 특성에 대한 자주 묻는 질문." +description: "Stable이란 무엇인지, 어떻게 시작하고, 이더리움과 다른 점은 무엇이며, 더 심층적인 문서는 어디에서 찾을 수 있는지와 같은 일반적인 온보딩 질문에 대한 빠른 답변을 얻으세요." +diataxis: "reference" --- # FAQ -## 일반 정보 +## 시작하기 **Stable이란 무엇인가요?** -Stable은 USDT를 위한 전용 네트워크로 설계된 **고성능 블록체인**으로, USDT의 글로벌 전송 방식을 혁신하는 것을 목표로 합니다. +USDT0가 네이티브 가스 토큰이자 결제 자산인 레이어 1입니다. 표준 EVM 도구는 변경 없이 작동합니다. -**Stable은 다른 블록체인과 무엇이 다른가요?** +**Stable은 누구를 위한 것인가요?** -Stable은 USDT에 최적화된 고성능 네트워크입니다. USDT를 기본 가스 토큰으로 사용하고, 보장된 블록스페이스, USDT0 전송 집계 기능 등을 제공하며, 모두 높은 확장성의 아키텍처를 기반으로 구축되어 있습니다. +세 가지 빌더 프로필: USDT0를 이동하는 결제 및 월렛 팀, EVM에 배포하는 스마트 컨트랙트 개발자, 노드 또는 RPC를 실행하는 인프라 팀. [학습 개요](/ko/explanation/learn-overview)에는 각 경로에 대한 카드가 있습니다. -## 기술 특징 +**어디서부터 시작해야 할까요: 결제, 계약, AI/에이전트 또는 인프라?** -**Stable은 확장성을 어떻게 향상시키나요?** +- USDT0를 이동하거나 결제 흐름을 구축하는 경우 → [결제](/ko/explanation/payments-overview). +- 계약을 배포하는 경우 → [계약](/ko/explanation/contracts-overview). +- AI 편집기를 연결하거나 에이전트 결제 서비스를 구축하는 경우 → [에이전트 결제](/ko/explanation/agent-settlement). +- 노드를 실행하거나 사용자를 위한 가스를 충당하는 경우 → [인프라](/ko/explanation/integrate-overview). -Stable은 트랜잭션 라이프사이클 내 모든 단계 - State DB, 실행 엔진, 합의, USDT 전용 최적화 - 를 업그레이드하는 풀스택 접근 방식을 사용합니다. +아직 테스트넷에 연결하지 않았다면, [빠른 시작](/ko/tutorial/quick-start)부터 시작하세요. -**Stable이 향후 DAG 기반 합의로 업그레이드될 수 있나요?** +## 기술 -네. StableBFT와 호환되지 않는 Narwhal 및 Tusk와 달리, Autobahn은 DAG 기반 PBFT 아키텍처를 제공하며, Stable의 합의 계층과 자연스럽게 통합될 수 있습니다. +**Stable은 EVM 호환입니까?** -**Stable은 EVM 호환되나요? 기존 dApp을 이식할 수 있나요?** +예. Solidity, Vyper, Foundry, Hardhat, ethers, viem과 `eth_*` JSON-RPC 메서드는 모두 변경 없이 작동합니다. 네 가지 동작은 이더리움과 다릅니다. [이더리움과의 차이점](/ko/explanation/ethereum-comparison)을 참조하세요. -네. Stable은 완전한 EVM 호환성을 가지며, 사용자 및 개발자는 기존 Ethereum 스마트 컨트랙트, 툴, 지갑 등을 그대로 사용할 수 있습니다. +**USDT0가 가스 토큰인 이유는 무엇인가요?** -## USDT 관련 기능 +이미 거래하고 있는 자산으로 수수료를 지불할 수 있도록 하기 위함입니다. 다른 토큰에 자금을 조달할 필요가 없으며, 수수료는 스테이블 코인으로 표시됩니다. 또한 프로토콜은 보장된 블록 공간과 전송 집계를 통해 USDT0 관련 워크로드를 최적화합니다. [핵심 개념](/ko/explanation/core-concepts)을 참조하세요. -**Stable에서 USDT0를 어떻게 받을 수 있나요?** +**USDT0는 어떻게 얻나요?** -USDT0는 OFT 표준을 따르기 때문에, LayerZero 브릿지를 통해 다른 네트워크에서 쉽게 Stable로 USDT0를 옮길 수 있습니다. +- **테스트넷:** [faucet.stable.xyz](https://faucet.stable.xyz)에서 파우셋을 사용하거나, 이더리움 세폴리아에서 테스트 USDT를 브릿지합니다. [테스트넷 USDT0 얻기](/ko/how-to/use-faucet)에서 상세한 과정을 확인하세요. +- **메인넷:** LayerZero를 통해 다른 체인에서 USDT0를 브릿지하거나, 거래소나 관리인을 통해 얻습니다. -**Stable의 기타 USDT 전용 기능은 무엇이 있나요?** +**이더리움에서 계약을 포팅할 때 무엇이 변경되나요?** -다음과 같은 기능들이 추가될 예정입니다. +대부분의 계약은 변경 없이 배포됩니다. 해당되는 경우 수정해야 할 세 가지 사항: -- 보장된 블록스페이스: 기관 사용자가 네트워크 혼잡 여부와 무관하게 예측 가능한 레이턴시와 비용으로 블록 공간을 확보할 수 있도록 합니다 -- USDT 전송 집계: 여러 개의 USDT0 전송을 묶어서 처리하여, 처리량을 향상하고 오버헤드를 감소시킵니다. -- 기밀 전송: 거래 금액에 대한 프라이버시를 보호하면서도 규제를 준수할 수 있습니다. +- 내부 변수에 네이티브 잔액을 미러링하지 마세요. `transferFrom`은 계약 호출 없이 네이티브를 소진할 수 있습니다. +- `address(0)`으로 전송하지 마세요. 네이티브 및 ERC-20 모두 0으로의 전송은 되돌려집니다. +- `EXTCODEHASH`에 주소 재사용 감지를 의존하지 마세요. Permit 기반 승인은 nonce 증가 없이 네이티브 잔액을 변경합니다. -**Stable Pay이란 무엇인가요?** +전체 체크리스트: [Stable에서의 USDT0 동작](/ko/explanation/usdt0-behavior). -Stable Pay은 초보자와 고급 사용자 모두를 위한 간단하고 직관적인 탈중앙화 지갑입니다. 소셜 로그인 등으로 쉽게 온보딩할 수 있으며, 기존 지갑도 별도 마이그레이션 없이 연결 가능합니다. 웹과 모바일 모두에서 제공되어, 언제 어디서나 안전한 자산 접근이 가능합니다. \ No newline at end of file +## 자료 + +**토큰 경제, 로드맵, 아키텍처는 어디에서 찾을 수 있나요?** + +- [토큰 경제](/ko/reference/tokenomics): STABLE 공급, 할당, 베스팅. +- [기술 로드맵](/ko/explanation/technical-roadmap): 단계별 최적화 계획. +- [기술 개요](/ko/explanation/tech-overview): StableBFT, Stable EVM, StableDB, RPC 디자인. +- [USDT 특정 기능](/ko/explanation/usdt-features-overview): 가스, 블록 공간, 집계, 기밀 전송에 대한 세부 정보. + +**도움이 필요하면 어디로 가야 하나요?** + +- [개발자 지원](/ko/reference/developer-assistance): FAQ 및 참조 포인터. +- [Discord](https://discord.gg/stablexyz): 커뮤니티 지원 및 프로토콜 업데이트. +- `bizdev@stable.xyz`: 파트너십 및 통합 대화. + +## 다음 권장 사항 + +- [**빠른 시작**](/ko/tutorial/quick-start): 테스트넷에서 첫 번째 트랜잭션을 전송하세요. +- [**핵심 개념**](/ko/explanation/core-concepts): 개발을 시작하기 전에 필요한 네 가지 핵심 개념을 학습하세요. +- [**학습 개요**](/ko/explanation/learn-overview): 개발하려는 항목에 맞는 문서 경로를 선택하세요. +- [**프로덕션 준비성**](/ko/how-to/production-readiness): 메인넷에 출시하기 전에 통합을 검증하세요. diff --git a/docs/pages/ko/reference/gas-pricing-api.mdx b/docs/pages/ko/reference/gas-pricing-api.mdx index fec7d3f..b94a588 100644 --- a/docs/pages/ko/reference/gas-pricing-api.mdx +++ b/docs/pages/ko/reference/gas-pricing-api.mdx @@ -1,30 +1,30 @@ --- source_path: reference/gas-pricing-api.mdx -source_sha: 9355a785da7466f7714460ce6e1ea80e95c4f55c +source_sha: 54bf228a3df7b32d8dc92f632372ba1adbd7bcce title: "가스 가격 책정 참조" -description: "Stable의 단일 구성 요소 수수료 모델에 맞춰 트랜잭션을 구성하고, 가스를 추정하고, 도구를 설정하세요." +description: "Stable의 단일 구성 요소 수수료 모델에 대해 트랜잭션을 구성하고, 가스를 추정하며, 툴링을 구성합니다." diataxis: "reference" --- # 가스 가격 책정 참조 -Stable에서의 트랜잭션 구성, 가스 추정, 도구 설정. +Stable을 위한 트랜잭션 구성, 가스 추정 및 툴링 구성. :::note -**개념:** Stable이 단일 구성 요소 수수료 모델을 사용하는 이유와 이더리움과의 비교에 대해서는 [가스 가격 책정](/ko/explanation/gas-pricing)을 참조하세요. +**개념**: Stable이 단일 구성 요소 수수료 모델을 사용하는 이유와 이더리움과 비교하는 방법은 [가스 가격 책정](/ko/explanation/gas-pricing)을 참조하세요. ::: ## 트랜잭션 구성 -Stable에서 트랜잭션을 구성할 때 `maxPriorityFeePerGas`를 `0`으로 설정하세요. 클라이언트는 가장 최근 블록에서 최신 기본 수수료(base fee)를 가져와야 하며, `maxFeePerGas`를 계산할 때 안전 마진을 포함해야 합니다. +Stable에서 트랜잭션을 구성할 때 `maxPriorityFeePerGas`를 `0`으로 설정하세요. 클라이언트는 가장 최근 블록에서 최신 기준 수수료를 가져와 `maxFeePerGas`를 계산할 때 안전 마진을 포함해야 합니다. ```javascript // ethers.js v6 const block = await provider.getBlock("latest"); const baseFee = block.baseFeePerGas; -const maxPriorityFeePerGas = 0n; // always 0 on Stable -const maxFeePerGas = baseFee * 2n + maxPriorityFeePerGas; // double the base fee as safety margin +const maxPriorityFeePerGas = 0n; // Stable에서는 항상 0 +const maxFeePerGas = baseFee * 2n + maxPriorityFeePerGas; // 안전 마진으로 기준 수수료의 두 배 const tx = await wallet.sendTransaction({ to: "0xRecipientAddress", @@ -35,12 +35,12 @@ const tx = await wallet.sendTransaction({ ``` ```text -Native USDT0 transfer confirmed. Fee ≈ 0.0000021 USDT0 at baseFee = 1 gwei. +기본 USDT0 전송 확인됨. 기준 수수료 = 1 gwei일 때 수수료 ≈ 0.0000021 USDT0. ``` ## 가스 추정 -이더리움에서와 마찬가지로 `eth_estimateGas`와 `eth_gasPrice`를 사용하세요. 주요 차이점은 `eth_maxPriorityFeePerGas`가 항상 `0`을 반환한다는 것입니다. +이더리움에서처럼 `eth_estimateGas` 및 `eth_gasPrice`를 사용하세요. 주요 차이점은 `eth_maxPriorityFeePerGas`가 항상 `0`을 반환한다는 것입니다. ```javascript const gasPrice = await provider.send("eth_gasPrice", []); @@ -52,14 +52,14 @@ const gasEstimate = await provider.estimateGas({ const estimatedFeeInUSDT0 = gasPrice * gasEstimate; ``` -## 도구 설정 +## 툴링 구성 -- **Hardhat / Foundry**: 특별한 설정이 필요 없습니다. 표준 EVM 설정으로 작동합니다. 설정에서 우선순위 수수료를 명시적으로 지정하는 경우 `0`으로 설정하세요. -- **지갑**: 우선순위 팁 입력 필드를 숨기거나 비활성화하세요. 이 값은 효과가 없으므로 표시하면 사용자에게 혼란을 줄 수 있습니다. -- **모니터링**: 수수료 분석 대시보드는 우선순위 수수료를 추적하지 않아야 합니다. 항상 0이 됩니다. +- **Hardhat / Foundry**: 특별한 구성이 필요하지 않으며, 표준 EVM 설정이 작동합니다. 구성에서 우선순위 수수료를 명시적으로 설정하는 경우 `0`으로 설정하세요. +- **월렛**: 우선순위 팁 입력 필드를 숨기거나 비활성화하세요. 값을 표시하면 해당 값이 효과가 없으므로 사용자가 혼란스러워할 수 있습니다. +- **모니터링**: 수수료 분석 대시보드는 우선순위 수수료를 추적해서는 안 됩니다. 항상 0이 됩니다. -## 다음 추천 +## 다음 권장 사항 -- [**가스 가격 책정 개념**](/ko/explanation/gas-pricing) — Stable이 단일 구성 요소 수수료 모델을 사용하는 이유를 이해하세요. -- [**이더리움 비교**](/ko/explanation/ethereum-comparison) — 이더리움에서 포팅할 때 마주치게 될 모든 동작 차이를 검토하세요. -- [**JSON-RPC API**](/ko/reference/json-rpc-api) — Stable이 노출하는 `eth_*` 메서드를 참조하세요. +- [**가스 가격 책정 개념**](/ko/explanation/gas-pricing): Stable이 단일 구성 요소 수수료 모델을 사용하는 이유를 이해하세요. +- [**이더리움 비교**](/ko/explanation/ethereum-comparison): 이더리움에서 포팅할 때 발생할 수 있는 모든 동작 차이점을 검토하세요. +- [**JSON-RPC API**](/ko/reference/json-rpc-api): Stable이 노출하는 `eth_*` 메서드를 참조하세요. diff --git a/docs/pages/ko/reference/gas-waiver-api.mdx b/docs/pages/ko/reference/gas-waiver-api.mdx index 01d217e..09d6d3a 100644 --- a/docs/pages/ko/reference/gas-waiver-api.mdx +++ b/docs/pages/ko/reference/gas-waiver-api.mdx @@ -1,103 +1,103 @@ --- source_path: reference/gas-waiver-api.mdx -source_sha: 92a2fff1dc4c0731b7b98573203aa468600dd6d8 +source_sha: 73af0a88040bca94925046ff388ccc018e9be11b title: "가스 면제 프로토콜" -description: "가스 면제에 대한 프로토콜 수준 사양: 트랜잭션 형식, 마커 라우팅, 거버넌스 제어, 그리고 Waiver Server API." +description: "가스 면제를 위한 프로토콜 수준 사양: 트랜잭션 형식, 마커 라우팅, 거버넌스 제어 및 면제 서버 API." diataxis: "reference" --- # 가스 면제 프로토콜 -이 문서는 가스 면제 메커니즘을 설명합니다: 트랜잭션 형식, 마커 라우팅, 거버넌스 제어, 그리고 Waiver Server API. +이 문서는 가스 면제 메커니즘을 지정합니다: 트랜잭션 형식, 마커 라우팅, 거버넌스 제어 및 면제 서버 API. :::note -**개념:** 가스 면제가 무엇이며 왜 존재하는지에 대해서는 [가스 면제](/ko/explanation/gas-waiver)를 참조하세요. 호스팅된 Waiver Server를 대상으로 한 통합 방법 가이드는 [가스 무료 트랜잭션 활성화](/ko/how-to/integrate-gas-waiver)를 참조하세요. +**개념:** 가스 면제가 무엇이며 왜 존재하는지에 대해서는 [가스 면제](/ko/explanation/gas-waiver)를 참조하십시오. 호스팅된 면제 서버에 대한 통합 가이드를 보려면 [가스 없는 트랜잭션 활성화](/ko/how-to/integrate-gas-waiver)를 참조하십시오. ::: ## 개요 -가스 면제는 거버넌스에서 승인된 소수의 주소 집합("waivers")이 `gasPrice = 0`으로 트랜잭션을 제출할 수 있도록 허용하여 Stable에서 가스 없는 최종 사용자 트랜잭션을 가능하게 합니다. Stable은 현재 프로토콜별 래퍼 로직을 구현하지 않고도 가스 없는 UX를 제공하기 위해 통합할 수 있는 waiver 서비스("Waiver Server")를 운영합니다. +가스 면제는 소수의 거버넌스 승인 주소("면제자")가 `gasPrice = 0`으로 트랜잭션을 제출하도록 허용함으로써 Stable에서 가스 없는 최종 사용자 트랜잭션을 가능하게 합니다. Stable은 현재 면제 서비스("면제 서버")를 운영하고 있으며, 프로토콜별 래퍼 로직을 구현하지 않고도 가스 없는 UX를 제공하기 위해 통합할 수 있습니다. ## 범위 -이 사양은 다음을 다룹니다: +이 사양은 다음을 다룹니다. -- 가스가 면제된 트랜잭션에 대한 프로토콜 수준 규칙 -- 래퍼 트랜잭션 메커니즘과 마커 주소 -- 거버넌스가 제어하는 권한 부여 및 허용된 대상 -- 서명된 사용자 트랜잭션을 제출하기 위한 Waiver Server 인터페이스 +- 가스 면제 트랜잭션에 대한 프로토콜 수준 규칙 +- 래퍼 트랜잭션 메커니즘 및 마커 주소 +- 거버넌스 제어 권한 부여 및 허용된 대상 +- 서명된 사용자 트랜잭션을 제출하기 위한 면제 서버 인터페이스 ## 정의 -- **Waiver**: 가스가 면제된 트랜잭션을 제출할 수 있도록 검증자 거버넌스를 통해 온체인에 등록된 이더리움 주소입니다. -- **InnerTx**: `gasPrice = 0`으로 최종 사용자가 서명한 트랜잭션입니다. -- **WrapperTx**: 사용자의 `InnerTx`를 체인으로 전송하고 실행을 승인하기 위해 waiver가 서명한 트랜잭션입니다. -- **마커 주소**: waiver 래퍼 트랜잭션을 식별하는 데 사용되는 센티넬 주소입니다: `0x000000000000000000000000000000000000f333`. -- **AllowedTarget**: waiver를 특정 컨트랙트 주소와 메서드 선택자로 제한하는 정책입니다. +- **면제자**: 검증자 거버넌스를 통해 온체인에 등록되어 가스 면제 트랜잭션을 제출할 권한이 부여된 이더리움 주소. +- **내부Tx**: 최종 사용자의 서명된 트랜잭션(`gasPrice = 0`). +- **래퍼Tx**: 면제자가 서명한 트랜잭션으로, 사용자의 `내부Tx`를 체인으로 전송하고 실행을 승인합니다. +- **마커 주소**: 면제 래퍼 트랜잭션을 식별하는 데 사용되는 센티넬 주소: `0x000000000000000000000000000000000000f333`. +- **AllowedTarget**: 면제자를 특정 계약 주소 및 메서드 선택기로 제한하는 정책. -## 살펴보기 +## 개요 -가스 면제는 래퍼 트랜잭션 패턴을 사용합니다: +가스 면제는 래퍼 트랜잭션 패턴을 사용합니다. -1. 사용자가 `gasPrice = 0`으로 `InnerTx`에 서명합니다. -2. waiver가 `InnerTx`를 `WrapperTx`로 감싸서 브로드캐스트합니다. -3. 검증자가 마커 트랜잭션을 감지하고, waiver 권한 부여 및 정책 제약 조건을 확인한 다음, 내장된 `InnerTx`를 실행합니다. +1. 사용자는 `gasPrice = 0`으로 `내부Tx`에 서명합니다. +2. 면제자는 `내부Tx`를 `래퍼Tx`로 래핑하고 브로드캐스트합니다. +3. 검증자는 마커 트랜잭션을 감지하고, 면제자 승인 및 정책 제약 조건을 확인한 다음, 내장된 `내부Tx`를 실행합니다. -Stable은 승인된 waiver로 온체인에 등록된 waiver 서비스(Waiver Server)를 운영합니다. 서명된 `InnerTx` 페이로드를 제출하기 위해 Waiver Server API와 통합합니다. +Stable은 승인된 면제자로 온체인에 등록된 면제 서비스(면제 서버)를 운영합니다. 서명된 `내부Tx` 페이로드를 제출하기 위해 면제 서버 API와 통합합니다. ## 프로토콜 사양 ### 마커 주소 라우팅 -트랜잭션은 다음의 경우에만 waiver 래퍼 트랜잭션으로 취급됩니다: +트랜잭션은 다음의 경우에만 가스 면제 래퍼 트랜잭션으로 처리됩니다. - `to == 0x000000000000000000000000000000000000f333`. -프로토콜은 트랜잭션 `data` 필드를 인코딩된 내부 트랜잭션 페이로드로 해석하고 아래의 waiver 검증 규칙을 사용하여 처리합니다. +프로토콜은 트랜잭션 `data` 필드를 인코딩된 내부 트랜잭션 페이로드로 해석하고 아래의 면제 검증 규칙을 사용하여 처리합니다. -### 권한 부여 및 정책 검사 +### 권한 부여 및 정책 확인 -각 후보 래퍼 트랜잭션에 대해 검증자는 다음을 적용해야 합니다: +각 후보 래퍼 트랜잭션에 대해 검증자는 다음 사항을 적용해야 합니다. -1. **Waiver 권한 부여** - - `WrapperTx.from`은 거버넌스를 통해 온체인에 등록된 waiver 주소여야 합니다. +1. **면제자 권한 부여** + - `WrapperTx.from`은 거버넌스를 통해 온체인에 등록된 면제자 주소여야 합니다. 2. **가스 면제** - - `WrapperTx.gasPrice`는 `0`이어야 합니다. - - `InnerTx.gasPrice`는 `0`이어야 합니다. + - `WrapperTx.gasPrice`는 `0`과 같아야 합니다. + - `InnerTx.gasPrice`는 `0`과 같아야 합니다. 3. **대상 허용 목록** - - `InnerTx.to`와 `InnerTx.data`에서 추출한 메서드 선택자는 waiver의 `AllowedTarget` 정책에 의해 허용되어야 합니다. + - `InnerTx.to`와 `InnerTx.data`에서 추출된 메서드 선택기는 면제자의 `AllowedTarget` 정책에 의해 허용되어야 합니다. 4. **값 제한** - - `WrapperTx.value`는 `0`이어야 합니다. + - `WrapperTx.value`는 `0`과 같아야 합니다. -검사 중 하나라도 실패하면 검증자는 래퍼 트랜잭션을 거부하고 내부 트랜잭션을 실행하지 않습니다. +어떠한 확인이라도 실패하면 검증자는 래퍼 트랜잭션을 거부하고 내부 트랜잭션을 실행하지 않습니다. -### 실행 의미론 +### 실행 시맨틱스 -모든 검사를 통과하면: +모든 확인이 통과하면: -1. 프로토콜은 사용자의 `from`, `nonce`, 호출 의미론을 보존하면서 `InnerTx`를 사용자로서 실행합니다. -2. 가스 정산은 waiver 메커니즘에 의해 처리됩니다: 사용자는 가스를 지불하지 않으며, waiver 트랜잭션은 이 기능의 정의에 따라 `gasPrice = 0`을 사용합니다. -3. 래퍼 트랜잭션은 `InnerTx`의 실행(언래핑 및 검증에 대한 오버헤드 포함)을 처리하기에 충분한 `gasLimit`을 제공해야 합니다. +1. 프로토콜은 사용자의 `from`, `nonce` 및 호출 시맨틱스를 보존하면서 사용자로 `InnerTx`를 실행합니다. +2. 가스 회계는 면제 메커니즘으로 처리됩니다: 사용자는 가스를 지불하지 않으며, 면제 트랜잭션은 기능 정의에 따라 `gasPrice = 0`을 사용합니다. +3. 래퍼 트랜잭션은 `InnerTx` 실행(언랩 및 검증을 위한 오버헤드 포함)을 충당하기에 충분한 `gasLimit`을 제공해야 합니다. ## 트랜잭션 형식 -### WrapperTx +### 래퍼Tx -래퍼 트랜잭션은 waiver가 서명하여 마커 주소로 전송됩니다. +래퍼 트랜잭션은 면제자가 서명하고 마커 주소로 전송됩니다. ```javascript WrapperTx { from: waiver_address, to: 0x000000000000000000000000000000000000f333, - value: 0, // must be zero - data: RLP(InnerTx), // RLP-encoded inner transaction - gasPrice: 0, // must be zero - gasLimit: sufficient_for_inner, // must cover inner execution + overhead + value: 0, // 0이어야 합니다. + data: RLP(InnerTx), // RLP 인코딩된 내부 트랜잭션 + gasPrice: 0, // 0이어야 합니다. + gasLimit: sufficient_for_inner, // 내부 실행 + 오버헤드를 포함해야 합니다. nonce: waiver_nonce } ``` -### InnerTx +### 내부Tx 내부 트랜잭션은 최종 사용자가 서명합니다. @@ -107,49 +107,49 @@ InnerTx { to: target_contract, value: value, data: call_data, - gasPrice: 0, // must be zero + gasPrice: 0, // 0이어야 합니다. gasLimit: execution_gas, nonce: user_nonce } ``` -## 거버넌스가 제어하는 접근 +## 거버넌스 제어 액세스 -waiver 권한 부여는 검증자 거버넌스에 의해 온체인에서 관리됩니다. +면제자 권한 부여는 검증자 거버넌스에 의해 온체인에서 제어됩니다. -거버넌스 제어는 다음을 제공합니다: +거버넌스 제어는 다음을 제공합니다. -- waiver 주소의 검토 가능한 권한 부여 -- waiver 등록 및 업데이트의 온체인 투명성 +- 면제자 주소의 검토 가능한 권한 부여 +- 면제자 등록 및 업데이트의 온체인 투명성 - 취소 기능 -- `AllowedTarget`을 통한 waiver별 범위 지정 +- `AllowedTarget`을 통한 면제별 범위 지정 ## 보안 모델 ### 최종 사용자 서명 무결성 -사용자는 `InnerTx`에 서명합니다. waiver는 서명을 무효화하지 않고는 내부 트랜잭션 페이로드를 수정할 수 없습니다. 사용자가 의도한 트랜잭션 페이로드에만 서명하도록 여전히 보장해야 합니다. +사용자가 `InnerTx`에 서명합니다. 면제자는 서명을 무효화하지 않고는 내부 트랜잭션 페이로드를 수정할 수 없습니다. 사용자가 의도한 트랜잭션 페이로드에만 서명하도록 여전히 확인해야 합니다. -### 신뢰 경계 +### 트러스트 경계 -가스 면제는 파트너가 Waiver Server를 통해 제출을 라우팅하는 경우 서비스 의존성을 도입합니다: +가스 면제는 파트너가 면제 서버를 통해 제출물을 라우팅하는 경우 서비스 종속성을 도입합니다. - 서비스의 가용성은 가스 없는 트랜잭션을 제출하는 능력에 영향을 미칩니다. -- 권한 부여는 온체인에 남아 있습니다. 등록된 waiver 주소만 유효한 래퍼 제출을 생성할 수 있습니다. +- 권한 부여는 온체인에 남아 있습니다. 등록된 면제자 주소만 유효한 래퍼 제출물을 생성할 수 있습니다. ## 통합 -다음과 같이 통합합니다: +다음과 같이 통합합니다. -1. 사용자로부터 서명된 `InnerTx`(`gasPrice = 0`)를 수집합니다. -2. 서명된 내부 트랜잭션을 Waiver Server API에 제출합니다. -3. 스트리밍된 결과를 처리하고 최종 사용자에게 트랜잭션 해시를 표시합니다. +1. 사용자로부터 서명된 `InnerTx`를 수집합니다 (`gasPrice = 0`). +2. 서명된 내부 트랜잭션을 면제 서버 API에 제출합니다. +3. 스트리밍된 결과를 처리하고 최종 사용자에게 트랜잭션 해시를 노출합니다. -## Waiver server +## 면제 서버 -### 살펴보기 +### 개요 -Waiver Server는 서명된 사용자 `InnerTx` 페이로드를 waiver가 승인한 래퍼 트랜잭션으로 감싸서 브로드캐스트합니다. 래퍼 트랜잭션을 구성하거나 waiver 주소를 운영할 필요가 없습니다. +면제 서버는 서명된 사용자 `InnerTx` 페이로드를 면제자 승인 래퍼 트랜잭션으로 래핑하고 브로드캐스트합니다. 래퍼 트랜잭션을 구성하거나 면제자 주소를 운영할 필요가 없습니다. ### 엔드포인트 및 기본 URL @@ -160,9 +160,9 @@ Waiver Server는 서명된 사용자 `InnerTx` 페이로드를 waiver가 승인 ### 인증 -health를 제외한 모든 엔드포인트는 베어러 토큰 인증이 필요합니다: +health를 제외한 모든 엔드포인트에는 베어러 토큰 인증이 필요합니다. -``` +```text Authorization: Bearer ``` @@ -170,7 +170,7 @@ Authorization: Bearer #### GET `/v1/health` -상태 확인 엔드포인트. +상태 확인 엔드포인트입니다. 인증: 없음. @@ -188,7 +188,7 @@ Authorization: Bearer } ``` -응답은 NDJSON(줄바꿈으로 구분된 JSON)으로 스트리밍됩니다. 각 줄은 제출된 트랜잭션 인덱스에 해당합니다. +응답은 NDJSON(줄 바꿈으로 구분된 JSON)으로 스트리밍됩니다. 각 줄은 제출된 트랜잭션 인덱스에 해당합니다. 예시: @@ -199,7 +199,7 @@ Authorization: Bearer #### GET `/v1/submit` -스트리밍 제출을 위한 WebSocket 인터페이스. +스트리밍 제출을 위한 WebSocket 인터페이스입니다. 인증: 필수 (`Bearer`). @@ -238,7 +238,7 @@ async function submitGaslessTransaction(signedInnerTxHex, apiKey) { ### 사용자 InnerTx 생성 -`gasPrice = 0`으로 `InnerTx`를 구성한 다음 사용자 서명을 수집할 책임이 있습니다. +`gasPrice = 0`으로 `InnerTx`를 구성한 다음 사용자 서명을 수집하는 것은 사용자의 책임입니다. 예시: @@ -250,10 +250,10 @@ async function createInnerTx(userWallet, contractAddress, callData, nonce) { to: contractAddress, data: callData, value: value, - gasPrice: 0, // must be 0 for waiver + gasPrice: 0, // 면제자의 경우 0이어야 합니다. gasLimit: 100000, nonce: nonce, - chainId: 2201, // 988 for mainnet, 2201 for testnet + chainId: 2201, // 메인넷은 988, 테스트넷은 2201 }; return await userWallet.signTransaction(innerTx); @@ -262,17 +262,17 @@ async function createInnerTx(userWallet, contractAddress, callData, nonce) { ### 오류 코드 -- `PARSE_ERROR`: 트랜잭션 파싱 실패 -- `INVALID_REQUEST`: 잘못된 형식의 요청 본문 -- `BATCH_SIZE_EXCEEDED`: 배치 크기가 허용된 최대값 초과 -- `VALIDATION_FAILED`: 트랜잭션 검증 실패 -- `BROADCAST_FAILED`: 체인으로 브로드캐스트 실패 -- `RATE_LIMITED`: 속도 제한 초과 -- `QUEUE_FULL`: 서버 큐가 용량에 도달 +- `PARSE_ERROR`: 트랜잭션을 구문 분석하지 못했습니다. +- `INVALID_REQUEST`: 잘못된 요청 본문 +- `BATCH_SIZE_EXCEEDED`: 배치 크기가 허용된 최대값을 초과합니다. +- `VALIDATION_FAILED`: 트랜잭션 유효성 검사 실패 +- `BROADCAST_FAILED`: 체인에 브로드캐스트하지 못했습니다. +- `RATE_LIMITED`: 비율 제한 초과 +- `QUEUE_FULL`: 서버 큐 용량 초과 - `TIMEOUT`: 요청 시간 초과 ## 다음 권장 사항 -- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions) — 가스 수수료가 0임을 보여주는 영수증과 함께하는 데모 중심 안내. -- [**가스 무료 트랜잭션 활성화**](/ko/how-to/integrate-gas-waiver) — 배치 제출 및 오류 처리를 포함한 전체 호스팅 API 통합 가이드. -- [**자체 호스팅 가스 면제**](/ko/how-to/self-hosted-gas-waiver) — 호스팅 API 없이 자체 waiver 인프라를 실행합니다. +- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions): 제로 가스 수수료를 보여주는 영수증과 함께 데모 중심의 설명. +- [**가스 없는 트랜잭션 활성화**](/ko/how-to/integrate-gas-waiver): 배치 제출 및 오류 처리가 포함된 전체 호스팅 API 통합 가이드. +- [**자체 호스팅 가스 면제**](/ko/how-to/self-hosted-gas-waiver): 호스팅 API 없이 자체 면제 인프라 실행. diff --git a/docs/pages/ko/reference/invoices.mdx b/docs/pages/ko/reference/invoices.mdx index eb7b12b..0651d20 100644 --- a/docs/pages/ko/reference/invoices.mdx +++ b/docs/pages/ko/reference/invoices.mdx @@ -1,52 +1,52 @@ --- source_path: reference/invoices.mdx -source_sha: 7e3a42da7db359e387c7b973b03c1248dde7baa2 -title: "인보이스 정산" -description: "인보이스 메타데이터에서 파생된 결정론적 nonce와 ERC-3009를 사용하여 Stable에서 인보이스를 정산하고 자동 대사(reconciliation)를 수행합니다." +source_sha: 39c34da4d80dcbcd49a25e21d22d8039202a418e +title: "송장 결제" +description: "송장 메타데이터에서 파생된 결정론적 논스를 사용하여 ERC-3009를 통해 Stable에서 송장을 결제하여 자동 조정을 수행합니다." diataxis: "reference" --- -# 인보이스 정산 +# 송장 결제 -각 인보이스는 인보이스 메타데이터(인보이스 번호, 당사자, 금액, 만기일)에서 파생된 고유하고 결정론적인 nonce에 매핑됩니다. 이 nonce는 [ERC-3009](/ko/explanation/erc-3009)를 통해 정산을 구동하며, 기존 회계 시스템과 대사할 수 있는 변경 불가능한 영수증을 생성합니다. +각 송장은 송장 번호, 당사자, 금액, 만기일과 같은 송장 메타데이터에서 파생된 고유하고 결정론적인 논스에 매핑됩니다. 이 논스는 [ERC-3009](/ko/explanation/erc-3009)를 통한 결제를 촉진하고 기존 회계 시스템과 조정될 수 있는 변경 불가능한 영수증을 생성합니다. ## 작동 방식 -구매자와 공급업체는 동일한 인보이스 메타데이터로부터 동일한 nonce를 각자 독립적으로 계산합니다. 결제를 조율하기 위한 외부 레지스트리가 필요하지 않습니다. +구매자와 판매자는 동일한 송장 메타데이터에서 독립적으로 동일한 논스를 계산합니다. 지불을 조정하기 위해 외부 레지스트리가 필요하지 않습니다. -nonce는 결정론적으로 파생됩니다: +논스는 결정론적으로 파생됩니다. -``` +```text nonce = keccak256(invoiceNumber, vendor, buyer, amount, dueDate) ``` -구매자가 이 nonce를 사용하여 ERC-3009 권한을 서명하면, 온체인 정산 이벤트가 위변조 방지 결제 영수증 역할을 합니다. +구매자가 이 논스를 사용하여 ERC-3009 승인에 서명하면 온체인 결제 이벤트는 변조 방지 지불 영수증 역할을 합니다. -### 정산 흐름 +### 결제 흐름 -1. **인보이스 발행**: 공급업체가 고유 번호, 금액, 만기일이 포함된 인보이스를 생성합니다. -2. **nonce 계산**: 양 당사자가 인보이스 메타데이터로부터 동일한 nonce를 각자 독립적으로 파생합니다. -3. **구매자 서명**: 구매자가 결정론적 nonce를 사용하여 ERC-3009 권한을 오프체인에서 서명합니다. `validBefore` 필드는 만기일에 유예 기간을 더한 값으로 설정할 수 있습니다. -4. **정산**: 구매자 또는 공급업체가 온체인에서 `transferWithAuthorization`을 제출합니다. 정산은 1초 미만으로 확정됩니다. -5. **대사**: 발생한 `AuthorizationUsed` 이벤트에는 nonce가 포함되어 있어 온체인 정산을 정확한 인보이스와 연결합니다. 동일한 트랜잭션의 `Transfer` 이벤트는 발신자, 수신자, 금액을 검증합니다. +1. **송장 발행**: 판매자가 고유 번호, 금액, 만기일이 포함된 송장을 생성합니다. +2. **논스 계산**: 양 당사자가 송장 메타데이터에서 독립적으로 동일한 논스를 파생합니다. +3. **구매자 서명**: 구매자는 결정론적 논스를 사용하여 오프체인으로 ERC-3009 승인에 서명합니다. `validBefore` 필드는 만기일과 유예 기간을 더한 값으로 설정할 수 있습니다. +4. **결제**: 구매자 또는 판매자가 온체인에서 `transferWithAuthorization`을 제출합니다. 결제는 1초 이내에 확인됩니다. +5. **조정**: 발행된 `AuthorizationUsed` 이벤트에는 논스가 포함되어 온체인 결제를 정확한 송장과 연결합니다. 동일한 트랜잭션의 `Transfer` 이벤트는 송신자, 수신자 및 금액을 확인합니다. -### 이중 결제 방지 +### 이중 지불 방지 -nonce는 결제 시 온체인에서 소비됩니다. 동일한 인보이스를 두 번 정산할 수 없으며, 이미 사용된 nonce로 권한을 재제출하면 되돌려집니다(revert). +논스는 지불 시 온체인에서 사용됩니다. 동일한 송장은 두 번 정산될 수 없습니다. 이미 사용된 논스로 승인을 다시 제출하면 취소됩니다. -## 차별점 +## 차이점 -전통적인 B2B 인보이스 발행은 은행 송금(영업일 기준 1~5일), 수동 대사, 그리고 인보이스 자체에 연결된 암호학적 결제 증명이 없는 과정을 수반합니다. 결정론적 nonce를 사용하면 온체인 결제가 자체 문서화됩니다. nonce는 정산을 정확한 인보이스와 연결하고, 블록체인 이벤트 로그는 변경 불가능한 감사 추적을 제공합니다. +기존 B2B 송장은 전신 송금(1~5영업일), 수동 조정, 송장 자체에 연결된 암호화된 지불 증명이 포함되지 않습니다. 결정론적 논스를 사용하면 온체인 지불은 자체적으로 문서화됩니다. 즉, 논스는 결제를 정확한 송장에 연결하고 블록체인 이벤트 로그는 변경 불가능한 감사 추적을 제공합니다. -| **측면** | **전통적 방식(은행 송금)** | **Stable (ERC-3009)** | +| **측면** | **전통적 (전신 송금)** | **Stable (ERC-3009)** | | :--- | :--- | :--- | -| 정산 | 영업일 기준 1~5일 | 1초 미만 | -| 대사 | 은행 명세서와 수동 대조 | `AuthorizationUsed` 이벤트가 결제를 인보이스 nonce에 연결 | -| 결제 증명 | 은행 확인서 | 인보이스에 암호학적으로 연결된 온체인 트랜잭션 | +| 결제 | 1~5영업일 | 1초 미만 | +| 조정 | 은행 명세서에 대한 수동 일치 | `AuthorizationUsed` 이벤트는 지불을 송장 논스에 연결합니다 | +| 지불 증명 | 은행 확인서 | 온체인 트랜잭션, 암호화 방식으로 송장에 연결됨 | | 중개자 | 코레스폰던트 은행 | 없음 | -| 수수료 | 송금 수수료($15~45) + 환전 스프레드 | 약 0.00021 USDT0 (또는 Gas Waiver 적용 시 0) | +| 수수료 | 송금 수수료 (15~45달러) + FX 스프레드 | ~0.00021 USDT0 (또는 Gas Waiver로 0) | **참고 항목:** -- [ERC-3009 (Transfer With Authorization)](/ko/explanation/erc-3009) -- [Gas Waiver](/ko/how-to/integrate-gas-waiver) +- [ERC-3009 (Transfer With Authorization)](/ko/explanation/erc-3009) +- [Gas Waiver](/ko/how-to/integrate-gas-waiver) diff --git a/docs/pages/ko/reference/json-rpc-api.mdx b/docs/pages/ko/reference/json-rpc-api.mdx index 14835e9..dd0f4d7 100755 --- a/docs/pages/ko/reference/json-rpc-api.mdx +++ b/docs/pages/ko/reference/json-rpc-api.mdx @@ -1,15 +1,16 @@ --- source_path: reference/json-rpc-api.mdx -source_sha: 1b6ce25dd5d0c90be028f78f97179a32c2c70a39 +source_sha: 838e9e92455c9c3acac3d94e4afcf7d7d907ef25 title: JSON-RPC API -description: "Stable에서 지원하는 eth, net, web3, debug 네임스페이스의 JSON-RPC API 메서드 목록." +description: "Stable에서 eth, net, web3, debug 네임스페이스에 걸쳐 지원되는 JSON-RPC API 메서드." +diataxis: "reference" --- # JSON-RPC API ## eth_namespace -| API | support | +| API | 지원 | |--------------------------------------------|---------| | eth_syncing | ✅ | | eth_gasPrice | ✅ | @@ -66,7 +67,7 @@ description: "Stable에서 지원하는 eth, net, web3, debug 네임스페이스 | eth_getLogs | ✅ | ## debug_namespace -| API | support | +| API | 지원 | |-----------------------------------|---------| | debug_accountRange | ❌ | | debug_backtraceAt | ❌ | @@ -121,3 +122,9 @@ description: "Stable에서 지원하는 eth, net, web3, debug 네임스페이스 | debug_writeBlockProfile | ✅ | | debug_writeMemProfile | ✅ | | debug_writeMutexProfile | ✅ | + +## 다음 권장 사항 + +- [**가스 가격 책정 참조**](/ko/reference/gas-pricing-api): Stable의 base-fee-only 모델에 대해 EIP-1559 트랜잭션을 구성합니다. +- [**EIP-7702 참조**](/ko/reference/eip-7702-api): `authorizationList` 필드를 사용하여 유형-4 트랜잭션을 구축합니다. +- [**시스템 모듈 참조**](/ko/reference/system-modules-api-overview): Bank, Distribution, Staking을 고정된 프리컴파일 주소에서 호출합니다. diff --git a/docs/pages/ko/reference/sdk.mdx b/docs/pages/ko/reference/sdk.mdx index be36c11..1b9bcd6 100644 --- a/docs/pages/ko/reference/sdk.mdx +++ b/docs/pages/ko/reference/sdk.mdx @@ -1,14 +1,14 @@ --- source_path: reference/sdk.mdx -source_sha: 77de6350f7056346c43e1b5ca5da572df7f4b7ae +source_sha: 64d437cfd1ea8f5c39da592e6dfad6bb6ab8b3bf title: "SDK 레퍼런스" -description: "@stablechain/sdk에 대한 완전한 레퍼런스: createStable, StableClient 메서드, 열거형, 체인 설정, 오류 클래스." +description: "@stablechain/sdk에 대한 완전한 레퍼런스: createStable, StableClient 메서드, 열거형, 체인 구성, 오류 클래스." diataxis: "reference" --- # SDK 레퍼런스 -`@stablechain/sdk`의 전체 표면. 단계별 안내는 [SDK 빠른 시작](/ko/tutorial/sdk-quickstart)을 참조하세요. +`@stablechain/sdk`의 전체 표면. 자세한 내용은 [SDK 퀵스타트](/ko/tutorial/sdk-quickstart)를 참조하십시오. ## 설치 @@ -20,11 +20,11 @@ npm install @stablechain/sdk viem added 2 packages, audited 3 packages in 2s ``` -`viem >= 2.0.0`은 피어 의존성입니다. +`viem >= 2.0.0`은 피어 종속성입니다. ## `createStable(config)` -`StableClient`를 생성합니다. [`StableClient`](#stableclient)에 나열된 메서드를 가진 객체를 반환합니다. +`StableClient`를 구성합니다. [`StableClient`](#stableclient) 아래에 나열된 메서드를 포함하는 객체를 반환합니다. ```ts import { createStable, Network } from "@stablechain/sdk"; @@ -38,21 +38,21 @@ StableClient { transfer, quoteBridge, bridge, quoteSwap, swap } ### `StableConfig` -| **필드** | **타입** | **기본값** | **설명** | +| **필드** | **유형** | **기본값** | **설명** | | :--- | :--- | :--- | :--- | | `network` | `Network` | `Network.Mainnet` | 대상 네트워크. | | `rpc` | `string` | `network`의 공개 RPC | RPC 재정의. | -| `account` | `viem.Account` | | 서버 측 서명자 (예: `privateKeyToAccount`). | -| `transport` | `viem.Transport` | | 브라우저 지갑 트랜스포트 (예: `custom(window.ethereum)`). | -| `walletClient` | `viem.WalletClient` | | 사전 구축된 지갑 클라이언트. `account` 및 `transport`보다 우선합니다. | +| `account` | `viem.Account` | | 서버 측 서명자(예: `privateKeyToAccount`). | +| `transport` | `viem.Transport` | | 브라우저-지갑 전송(예: `custom(window.ethereum)`). | +| `walletClient` | `viem.WalletClient` | | 미리 빌드된 지갑 클라이언트. `account` 및 `transport`보다 우선합니다. | -`account`, `transport`, `walletClient` 중 하나를 제공하세요. +`account`, `transport` 또는 `walletClient` 중 하나를 제공하십시오. ## `StableClient` ### `transfer(params)` -Stable에서 네이티브 USDT0 또는 임의의 ERC-20을 전송합니다. 지갑을 Stable 체인으로 전환하고, 누락된 경우 온체인에서 토큰 소수 자릿수를 가져오며, 영수증을 기다립니다. +기본 USDT0 또는 Stable의 ERC-20을 보냅니다. 지갑을 Stable 체인으로 전환하고, 누락된 경우 온체인에서 토큰 소수 자릿수를 가져오고, 영수증을 기다립니다. ```ts const { txHash } = await stable.transfer({ @@ -66,19 +66,19 @@ const { txHash } = await stable.transfer({ { txHash: "0x8f3a...2d41" } ``` -| **파라미터** | **타입** | **설명** | +| **매개변수** | **유형** | **설명** | | :--- | :--- | :--- | | `from` | `string` | 발신자 주소. | | `to` | `string` | 수신자 주소. | -| `amount` | `number` | 사람이 읽을 수 있는 금액. | -| `token` | `string?` | ERC-20 컨트랙트 주소. 네이티브 USDT0의 경우 생략. | +| `amount` | `number` | 읽기 쉬운 양. | +| `token` | `string?` | ERC-20 컨트랙트 주소. 기본 USDT0의 경우 생략합니다. | | `tokenDecimals` | `number?` | 소수 자릿수. 생략 시 온체인에서 가져옵니다. | `OperationResult` (`{ txHash, toAmount? }`)를 반환합니다. ### `quoteBridge(params)` -브리지를 미리 봅니다. 읽기 전용 — 서명도, 가스도 없습니다. +브릿지를 미리 봅니다. 읽기 전용. 서명, 가스 없음. ```ts const quote = await stable.quoteBridge({ @@ -98,7 +98,7 @@ const quote = await stable.quoteBridge({ ### `bridge(params)` -토큰을 크로스체인으로 브리지합니다. SDK가 경로를 선택합니다: USDT0 → USDT0에는 LayerZero, 그 외 모든 경우에는 LI.FI를 사용합니다. 내부 견적 호출을 건너뛰려면 사전에 가져온 `quote`를 전달하세요. +토큰을 크로스체인으로 브릿지합니다. SDK는 경로를 선택합니다: USDT0 → USDT0의 경우 LayerZero, 나머지 모든 것의 경우 LI.FI. 내부 인용 호출을 건너뛰려면 미리 가져온 `quote`를 전달하십시오. ```ts const { txHash } = await stable.bridge({ ...bridgeParams, quote }); @@ -108,20 +108,20 @@ const { txHash } = await stable.bridge({ ...bridgeParams, quote }); { txHash: "0xabcd...7890" } ``` -| **파라미터** | **타입** | **설명** | +| **매개변수** | **유형** | **설명** | | :--- | :--- | :--- | | `fromChain` | `Chain` | 소스 체인. | | `toChain` | `Chain` | 대상 체인. | | `fromToken` | `string` | 소스 토큰 컨트랙트 주소. | | `toToken` | `string` | 대상 토큰 컨트랙트 주소. | -| `amount` | `number` | 사람이 읽을 수 있는 금액. | -| `fromDecimals` | `number?` | 소스 토큰 소수 자릿수. 기본값은 `6`. | -| `recipient` | `string?` | 대상 주소. 기본값은 서명자. | -| `quote` | `BridgeQuote?` | 사전에 가져온 견적. 내부 견적 호출을 건너뜁니다. | +| `amount` | `number` | 읽기 쉬운 양. | +| `fromDecimals` | `number?` | 소스 토큰 소수 자릿수. 기본값은 `6`입니다. | +| `recipient` | `string?` | 대상 주소. 기본값은 서명자입니다. | +| `quote` | `BridgeQuote?` | 미리 가져온 인용. 내부 인용 호출을 건너뜁니다. | ### `quoteSwap(params)` -Stable에서 LI.FI 스왑 견적을 가져옵니다. 사전 구축된 트랜잭션 요청과 승인 주소를 반환합니다. +Stable에서 LI.FI 스왑 인용을 가져옵니다. 미리 빌드된 트랜잭션 요청 및 승인 주소를 반환합니다. ```ts const quote = await stable.quoteSwap({ @@ -138,7 +138,7 @@ const quote = await stable.quoteSwap({ ### `swap(params)` -LI.FI를 통해 Stable에서 토큰을 스왑합니다. ERC-20 승인을 자동으로 처리하고 필요한 경우 지갑의 체인을 전환합니다. +LI.FI를 통해 Stable에서 토큰을 스왑합니다. 필요한 경우 ERC-20 승인을 자동으로 처리하고 지갑의 체인을 전환합니다. ```ts const { txHash, toAmount } = await stable.swap({ ...swapParams, quote }); @@ -148,14 +148,14 @@ const { txHash, toAmount } = await stable.swap({ ...swapParams, quote }); { txHash: "0xabcd...", toAmount: 99.81 } ``` -| **파라미터** | **타입** | **기본값** | **설명** | +| **매개변수** | **유형** | **기본값** | **설명** | | :--- | :--- | :--- | :--- | -| `fromToken` | `string` | | 소스 토큰 주소. | -| `toToken` | `string` | | 대상 토큰 주소. | -| `amount` | `number` | | 사람이 읽을 수 있는 금액. | +| `fromToken` | `string` | | 소스 토큰 주소. | +| `toToken` | `string` | | 대상 토큰 주소. | +| `amount` | `number` | | 읽기 쉬운 양. | | `fromDecimals` | `number?` | `6` | 소스 토큰 소수 자릿수. | -| `toAddress` | `string?` | 서명자 | 수신자 주소. | -| `quote` | `SwapQuote?` | | 사전에 가져온 견적. LI.FI 호출을 건너뜁니다. | +| `toAddress` | `string?` | signer | 수신자 주소. | +| `quote` | `SwapQuote?` | | 미리 가져온 인용. LI.FI 호출을 건너뜁니다. | ## 열거형 @@ -168,7 +168,7 @@ const { txHash, toAmount } = await stable.swap({ ...swapParams, quote }); ### `Chain` -`quoteBridge`와 `bridge`에서 사용됩니다. 각 항목에는 해당하는 `CHAIN_CONFIGS` 항목이 있습니다. +`quoteBridge` 및 `bridge`에서 사용됩니다. 각 항목에는 해당 `CHAIN_CONFIGS` 항목이 있습니다. | **열거형** | **네트워크** | **체인 ID** | | :--- | :--- | :--- | @@ -186,7 +186,7 @@ const { txHash, toAmount } = await stable.swap({ ...swapParams, quote }); ## `CHAIN_CONFIGS` -`Chain` 열거형을 키로 하는 `Partial>`입니다. 각 항목은 `id`, `rpc`, `usdt`, `decimals`를 노출합니다. 지원되는 체인의 정식 USDT 주소를 하드코딩하지 않고 필요할 때 사용하세요. +`Chain` 열거형으로 키가 지정된 `Partial>`. 각 항목은 `id`, `rpc`, `usdt` 및 `decimals`를 노출합니다. 하드코딩하지 않고 지원되는 체인에서 표준 USDT 주소가 필요할 때 사용하십시오. ```ts import { CHAIN_CONFIGS, Chain } from "@stablechain/sdk"; @@ -200,14 +200,14 @@ console.log(CHAIN_CONFIGS[Chain.Stable]); ## 오류 -모든 SDK 오류는 viem의 `BaseError`를 확장하는 `StableError`를 확장합니다. 오류는 구조화된 메타데이터를 포함하므로 `error.name` 또는 `instanceof`로 분기할 수 있습니다. +모든 SDK 오류는 viem의 `BaseError`를 확장하는 `StableError`를 확장합니다. 오류는 구조화된 메타데이터를 전달하므로 `error.name` 또는 `instanceof`를 기준으로 분기할 수 있습니다. | **클래스** | **발생 시점** | **유용한 필드** | | :--- | :--- | :--- | -| `StableValidationError` | 파라미터가 검증에 실패할 때 (잘못된 주소, 유한하지 않은 금액, 지원되지 않는 체인). | `field`, `value` | -| `StableQuoteError` | LI.FI에 대한 견적 요청이 실패할 때. | `provider`, `httpStatus`, `providerCode`, `body` | -| `StableTransactionError` | 온체인 단계가 실패할 때: 체인 전환, 승인, 전송 또는 되돌리기. | `phase`, `txHash`, `chainId`, `revertReason` | -| `StableNetworkError` | 기본 HTTP/RPC 호출이 실패할 때. | `url` | +| `StableValidationError` | 매개변수가 유효성 검사에 실패함(잘못된 주소, 유한하지 않은 금액, 지원되지 않는 체인). | `field`, `value` | +| `StableQuoteError` | LI.FI에 대한 견적 요청이 실패함. | `provider`, `httpStatus`, `providerCode`, `body` | +| `StableTransactionError` | 온체인 단계가 실패함: 체인 전환, 승인, 전송 또는 되돌리기. | `phase`, `txHash`, `chainId`, `revertReason` | +| `StableNetworkError` | 기본 HTTP/RPC 호출이 실패함. | `url` | ```ts import { StableTransactionError } from "@stablechain/sdk"; @@ -216,7 +216,7 @@ try { await stable.transfer({ from, to, amount: 1 }); } catch (err) { if (err instanceof StableTransactionError && err.phase === "switch_chain") { - // user rejected the chain switch + // 사용자가 체인 전환을 거부했습니다. } throw err; } @@ -228,8 +228,8 @@ StableTransactionError: transfer: wallet rejected or failed to switch to chain 9 Chain ID: 988 ``` -## 다음 추천 항목 +## 다음 권장 사항 -- [**SDK 빠른 시작**](/ko/tutorial/sdk-quickstart) — SDK를 설치하고 테스트넷에서 첫 전송을 실행합니다. -- [**viem과 함께 사용하기**](/ko/how-to/sdk-with-viem) — 개인 키, 브라우저 지갑, 사전 구축된 서명자 간 전환. -- [**wagmi와 함께 사용하기**](/ko/how-to/sdk-with-wagmi) — 훅을 사용하여 React 앱에 SDK를 연결합니다. +- [**SDK 퀵스타트**](/ko/tutorial/sdk-quickstart): SDK를 설치하고 테스트넷에서 첫 번째 전송을 실행합니다. +- [**viem과 함께 사용**](/ko/how-to/sdk-with-viem): 개인 키, 브라우저 지갑 및 미리 빌드된 서명자 간에 전환합니다. +- [**wagmi와 함께 사용**](/ko/how-to/sdk-with-wagmi): 훅을 사용하여 SDK를 React 앱에 연결합니다. diff --git a/docs/pages/ko/resources/brand-kit.mdx b/docs/pages/ko/resources/brand-kit.mdx index 57255c0..8d25031 100755 --- a/docs/pages/ko/resources/brand-kit.mdx +++ b/docs/pages/ko/resources/brand-kit.mdx @@ -1,12 +1,13 @@ --- source_path: resources/brand-kit.mdx -source_sha: df4ff065c6969109cea93c5217b43a2f1ee1e573 -title: "Brand Kit" -description: "프로젝트 및 커뮤니케이션에서 일관된 사용을 위한 Stable 브랜드 킷 (로고, 색상 팔레트)." +source_sha: 668023711259b32b450e229eaa7f0f808795f146 +title: "브랜드 키트" +description: "프로젝트 및 커뮤니케이션에서 일관된 사용을 위한 로고 및 색상 팔레트가 포함된 Stable의 브랜드 키트." +diataxis: "reference" --- -# Brand Kit +# 브랜드 키트 -아래에서 Stable 브랜드 키트를 확인하실 수 있습니다. 이 키트에는 다양한 형식의 로고와 컬러 팔레트가 포함되어 있으며, 프로젝트나 커뮤니케이션에서 Stable의 브랜딩을 일관되게 유지할 수 있도록 설계되었습니다. +Stable 브랜드 키트에는 다양한 형식의 로고와 공식 색상 팔레트가 포함되어 있습니다. 프로젝트 및 커뮤니케이션 전반에 걸쳐 Stable의 브랜딩을 일관되게 유지하는 데 사용하십시오. -[Stable Brand Kit 확인하기](https://www.stable.xyz/brand-kit) \ No newline at end of file +[Stable 브랜드 키트 열기](https://www.stable.xyz/brand-kit) diff --git a/docs/pages/ko/tutorial/bridge-usdt0.mdx b/docs/pages/ko/tutorial/bridge-usdt0.mdx index 62f23fb..00d3b9e 100644 --- a/docs/pages/ko/tutorial/bridge-usdt0.mdx +++ b/docs/pages/ko/tutorial/bridge-usdt0.mdx @@ -1,28 +1,28 @@ --- source_path: tutorial/bridge-usdt0.mdx -source_sha: 401984b7572b9f0b7ee12064bf18768f17849e60 -title: "USDT0을 Stable로 브릿지하기" -description: "LayerZero의 OFT 프로토콜을 사용하여 Ethereum Sepolia에서 Stable Testnet으로 USDT0를 브릿지하는 단계별 튜토리얼입니다." +source_sha: 975772bc0a56943603358f10eeb56b45d01a2d24 +title: "USDT0를 Stable로 브리지" +description: "LayerZero의 OFT 프로토콜을 사용하여 이더리움 Sepolia에서 Stable 테스트넷으로 USDT0를 브리지하는 단계별 튜토리얼입니다." type: "tutorial" diataxis: "tutorial" --- -# USDT0을 Stable로 브릿지하기 +# USDT0를 Stable로 브리지 -이 튜토리얼에서는 TypeScript와 ethers v6를 사용하여 Ethereum Sepolia에서 Stable Testnet으로 USDT0를 프로그래밍 방식으로 브릿지합니다. 단계마다 함수를 하나씩 추가하면서 스크립트를 점진적으로 구축합니다. +이 튜토리얼에서는 TypeScript와 ethers v6를 사용하여 이더리움 Sepolia에서 Stable 테스트넷으로 USDT0를 프로그래밍 방식으로 브리지합니다. 스크립트를 점진적으로 빌드하며, 단계별로 하나의 함수를 추가합니다. -이 튜토리얼은 OFT Mesh 경로를 사용합니다. Sepolia의 OFT Adapter가 토큰을 잠그고, LayerZero의 이중 DVN 검증이 메시지를 확인하며, Stable에서 USDT0가 발행됩니다. 작동 방식에 대한 전체 설명은 [Stable로 브릿지하기](/ko/explanation/usdt0-bridging)를 참조하세요. +이 튜토리얼은 OFT Mesh 경로를 사용합니다. Sepolia의 OFT Adapter는 토큰을 잠그고, LayerZero의 이중 DVN 검증이 메시지를 확인하며, USDT0는 Stable에 발행됩니다. 이 작동 방식에 대한 자세한 설명은 [Stable로 브리지](/ko/explanation/usdt0-bridging)를 참조하세요. :::note -더 적은 코드 줄을 원하시나요? [Stable SDK](/ko/explanation/sdk-overview)는 `quoteBridge`와 `bridge`를 제공하며 경로(LayerZero 또는 LI.FI)를 자동으로 선택합니다. +코드 라인을 줄이고 싶으신가요? [Stable SDK](/ko/explanation/sdk-overview)는 `quoteBridge` 및 `bridge`를 노출하고 경로(LayerZero 또는 LI.FI)를 자동으로 선택합니다. ::: -## 사전 준비 사항 +## 전제 조건 - Node.js 18.0.0 이상 (`node --version`으로 확인) -- 직접 제어할 수 있는 개인 키가 있는 Sepolia 지갑 (실제 자금을 보유한 키는 절대 사용하지 마세요) -- 가스용 SepoliaETH ([sepoliafaucet.com](https://sepoliafaucet.com) 또는 [faucets.chain.link/sepolia](https://faucets.chain.link/sepolia)에서 받으세요) -- 터미널에서 스크립트를 실행하는 기본적인 지식 +- 제어하는 프라이빗 키가 있는 Sepolia 지갑 (실제 자금이 있는 키는 절대 사용하지 마세요) +- 가스비를 위한 SepoliaETH ( [sepoliafaucet.com](https://sepoliafaucet.com) 또는 [faucets.chain.link/sepolia](https://faucets.chain.link/sepolia)에서 얻을 수 있습니다.) +- 터미널에서 스크립트 실행에 대한 기본적인 지식 --- @@ -35,7 +35,7 @@ npm install ethers@6 @layerzerolabs/lz-v2-utilities npm install -D tsx ``` -`package.json`에는 다음 내용이 포함되어야 합니다: +`package.json`에는 다음이 포함되어야 합니다. ```json { @@ -56,21 +56,21 @@ npm install -D tsx ## 2. 환경 구성 -자격 증명이 담긴 `.env` 파일을 생성하세요: +자격 증명이 포함된 `.env` 파일을 생성합니다. ```bash PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE SEPOLIA_RPC_URL=https://rpc.sepolia.org ``` -`SEPOLIA_RPC_URL`의 경우, 다음 중 어느 것이든 작동합니다: -- 퍼블릭: `https://rpc.sepolia.org` 또는 `https://ethereum-sepolia-rpc.publicnode.com` +`SEPOLIA_RPC_URL`의 경우 다음 중 하나를 사용할 수 있습니다. +- 공개: `https://rpc.sepolia.org` 또는 `https://ethereum-sepolia-rpc.publicnode.com` - Alchemy: `https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY` - Infura: `https://sepolia.infura.io/v3/YOUR_KEY` -## 3. 스크립트 골격 작성 +## 3. 스크립트 스캐폴드 -임포트, 구성, 그리고 `main` 함수를 포함하는 `bridge.ts`를 생성하세요. 다음 단계에서 이 파일에 함수를 추가하고 `main`에서 호출하게 됩니다. +가져오기, 구성 및 `main` 함수가 포함된 `bridge.ts`를 생성합니다. 다음 단계에서 이 파일에 함수를 추가하고 `main`에서 호출할 것입니다. ```ts import { ethers, Contract, Wallet, JsonRpcProvider } from "ethers"; @@ -124,29 +124,29 @@ main().catch((err) => { }); ``` -## 4. Sepolia에서 테스트 USDT0 발행하기 +## 4. Sepolia에서 테스트 USDT0 발행 -Sepolia의 테스트 USDT0 컨트랙트는 퍼블릭 `mint` 함수를 노출합니다. `bridge.ts`의 `main` 위에 다음 함수를 추가하세요: +Sepolia의 테스트 USDT0 계약은 공개 `mint` 함수를 노출합니다. `main` 위에 다음 함수를 `bridge.ts`에 추가합니다. ```ts async function mint(usdt0: Contract, receiver: string, amount: bigint) { - console.log(`Minting ${ethers.formatEther(amount)} USDT0 on Sepolia...`); + console.log(`Sepolia에서 ${ethers.formatEther(amount)} USDT0 발행 중...`); const tx = await usdt0.mint(receiver, amount); await tx.wait(); - console.log(`Mint tx: ${tx.hash} confirmed`); + console.log(`발행 트랜잭션: ${tx.hash} 확인됨`); const balance = await usdt0.balanceOf(receiver); - console.log(`USDT0 balance: ${ethers.formatEther(balance)}`); + console.log(`USDT0 잔액: ${ethers.formatEther(balance)}`); } ``` -그런 다음 `main`에서 호출하세요: +그 다음 `main`에서 호출합니다: ```ts await mint(usdt0, wallet.address, amount); ``` -스크립트를 실행하세요: +스크립트를 실행합니다: ```bash npx tsx --env-file=.env bridge.ts @@ -154,44 +154,44 @@ npx tsx --env-file=.env bridge.ts --- -**체크포인트:** 발행이 확인된 후 0이 아닌 USDT0 잔액이 로그에 표시되어야 합니다. +**체크포인트:** 발행 확인 후 0이 아닌 USDT0 잔액이 기록된 것을 확인해야 합니다. --- -## 5. OFT Adapter 승인하기 +## 5. OFT 어댑터 승인 -OFT Adapter가 토큰을 이동시키려면 ERC-20 allowance가 필요합니다. `main` 위에 이 함수를 추가하세요: +OFT 어댑터가 토큰을 이동할 수 있으려면 ERC-20 허용이 필요합니다. 이 함수를 `main` 위에 추가합니다: ```ts async function approve(usdt0: Contract, spender: string, owner: string, amount: bigint) { - console.log("Approving OFT Adapter..."); + console.log("OFT 어댑터 승인 중..."); const tx = await usdt0.approve(spender, amount); await tx.wait(); - console.log(`Approve tx: ${tx.hash} confirmed`); + console.log(`승인 트랜잭션: ${tx.hash} 확인됨`); const allowance = await usdt0.allowance(owner, spender); - console.log(`Allowance: ${ethers.formatEther(allowance)}`); + console.log(`허용량: ${ethers.formatEther(allowance)}`); } ``` -`main`에서 `mint` 다음에 호출을 추가하세요: +`mint` 후에 `main`에 호출을 추가합니다: ```ts // await mint(usdt0, wallet.address, amount); await approve(usdt0, SEPOLIA_OFT_ADAPTER, wallet.address, amount); ``` -스크립트를 실행하세요. 이전 실행에서 이미 토큰이 있다면 `await mint(...)` 호출을 주석 처리할 수 있습니다. +스크립트를 실행합니다. 이전 실행에서 이미 토큰이 있는 경우 `await mint(...)` 호출을 주석 처리할 수 있습니다. --- -**체크포인트:** 승인이 확인된 후 스크립트가 0이 아닌 allowance를 로그에 표시해야 합니다. +**체크포인트:** 승인 확인 후 스크립트는 0이 아닌 허용량을 기록해야 합니다. --- -## 6. 수수료 견적 및 브릿지 트랜잭션 전송 +## 6. 수수료를 인용하고 브리지 트랜잭션 전송 -`quoteSend` 호출은 LayerZero 메시징 수수료를 SepoliaETH로 반환하며, 이를 `send`에 `msg.value`로 전달합니다. `main` 위에 이 함수를 추가하세요: +`quoteSend` 호출은 LayerZero 메시징 수수료를 SepoliaETH로 반환하며, 이를 `msg.value`로 `send`에 전달합니다. 이 함수를 `main` 위에 추가합니다: ```ts async function send(oftAdapter: Contract, receiver: string, amount: bigint) { @@ -207,23 +207,23 @@ async function send(oftAdapter: Contract, receiver: string, amount: bigint) { oftCmd: "0x", }; - console.log("Quoting bridge fee..."); + console.log("브리지 수수료 인용 중..."); const feeResult = await oftAdapter.quoteSend(sendParams, false); const fee = { nativeFee: feeResult.nativeFee, lzTokenFee: feeResult.lzTokenFee }; - console.log(`Bridge fee: ${ethers.formatEther(fee.nativeFee)} ETH`); + console.log(`브리지 수수료: ${ethers.formatEther(fee.nativeFee)} ETH`); - console.log("Sending bridge transaction..."); + console.log("브리지 트랜잭션 전송 중..."); const tx = await oftAdapter.send(sendParams, fee, receiver, { value: fee.nativeFee, }); await tx.wait(); - console.log(`Bridge tx: ${tx.hash} confirmed`); + console.log(`브리지 트랜잭션: ${tx.hash} 확인됨`); console.log(`Sepolia Etherscan: https://sepolia.etherscan.io/tx/${tx.hash}`); console.log(`LayerZero Scan: https://testnet.layerzeroscan.com/tx/${tx.hash}`); } ``` -`main`에서 `approve` 다음에 호출을 추가하세요: +`approve` 후에 `main`에 호출을 추가합니다: ```ts // await mint(usdt0, wallet.address, amount); @@ -231,13 +231,13 @@ async function send(oftAdapter: Contract, receiver: string, amount: bigint) { await send(oftAdapter, wallet.address, amount); ``` -## 7. Stable Testnet에서 도착 확인하기 +## 7. Stable 테스트넷 도착 확인 -전송 후, 스크립트는 토큰이 도착할 때까지 Stable Testnet RPC를 폴링할 수 있습니다. `main` 위에 이 함수를 추가하세요: +전송 후 스크립트는 토큰이 도착할 때까지 Stable 테스트넷 RPC를 폴링할 수 있습니다. 이 함수를 `main` 위에 추가합니다: ```ts async function verify(receiver: string) { - console.log("Waiting for DVN verification (~2 minutes)..."); + console.log("DVN 검증 대기 중 (~2분)..."); const stableProvider = new JsonRpcProvider("https://rpc.testnet.stable.xyz"); const stableUsdt0 = new Contract(STABLE_USDT0, ["function balanceOf(address) view returns (uint256)"], stableProvider); @@ -247,18 +247,18 @@ async function verify(receiver: string) { await new Promise((r) => setTimeout(r, 5000)); const current: bigint = await stableUsdt0.balanceOf(receiver); if (current > before) { - console.log(`\nUSDT0 on Stable: ${ethers.formatEther(current)}`); - console.log(`Explorer: https://testnet.stablescan.xyz/address/${receiver}`); + console.log(`\nStable에 있는 USDT0: ${ethers.formatEther(current)}`); + console.log(`탐색기: https://testnet.stablescan.xyz/address/${receiver}`); return; } process.stdout.write("."); } - console.log("\nTokens have not arrived yet. Check manually:"); - console.log(`Explorer: https://testnet.stablescan.xyz/address/${receiver}`); + console.log("\n아직 토큰이 도착하지 않았습니다. 수동으로 확인하십시오:"); + console.log(`탐색기: https://testnet.stablescan.xyz/address/${receiver}`); } ``` -`main`에서 `send` 다음에 호출을 추가하세요: +`send` 후에 `main`에 호출을 추가합니다: ```ts // await mint(usdt0, wallet.address, amount); @@ -267,9 +267,9 @@ async function verify(receiver: string) { await verify(wallet.address); ``` -## 8. 전체 브릿지 실행하기 +## 8. 전체 브리지 실행 -이제 `main` 함수는 다음과 같아야 합니다: +`main` 함수는 이제 다음과 같아야 합니다. ```ts async function main() { @@ -288,7 +288,7 @@ async function main() { } ``` -실행하세요: +실행합니다: ```bash npx tsx --env-file=.env bridge.ts @@ -296,9 +296,9 @@ npx tsx --env-file=.env bridge.ts --- -**체크포인트:** 다음과 같은 출력이 표시되어야 합니다: +**체크포인트:** 다음과 같은 출력이 보여야 합니다. -``` +```text Minting 1.0 USDT0 on Sepolia... Mint tx: 0x3a1f...c9d2 confirmed USDT0 balance: 1.0 @@ -316,23 +316,23 @@ Waiting for DVN verification (~2 minutes)... USDT0 on Stable: 1.0 ``` -[Stable Testnet 익스플로러](https://testnet.stablescan.xyz)에서 지갑 주소를 검색하여 발행 이벤트를 확인할 수도 있습니다. +[Stable Testnet 탐색기](https://testnet.stablescan.xyz)에서 지갑 주소를 검색하여 발행 이벤트를 확인할 수도 있습니다. --- -## 구축한 내용 +## 빌드한 내용 -Ethereum Sepolia에서 Stable Testnet으로 USDT0를 브릿지했습니다. 이제 다음을 알게 되었습니다: +이더리움 Sepolia에서 Stable 테스트넷으로 USDT0를 브리지했습니다. 이제 다음 방법을 알 수 있습니다. -- 컨트랙트의 퍼블릭 `mint` 함수를 사용하여 Sepolia에서 테스트 USDT0 발행하기 -- OFT Adapter가 사용자를 대신해 ERC-20 토큰을 사용하도록 승인하기 -- 32바이트 주소 인코딩과 executor 옵션으로 LayerZero `sendParams` 구성하기 -- 자금을 투입하기 전에 `quoteSend`로 크로스체인 메시징 수수료 견적 받기 -- `send`로 크로스체인 토큰 전송을 실행하고 목적지 체인에서 전달 확인하기 -- Stable의 RPC(`https://rpc.testnet.stable.xyz`, 체인 ID `2201`)와 Stablescan을 사용하여 온체인 상태 확인하기 +- 계약의 공개 `mint` 함수를 사용하여 Sepolia에서 테스트 USDT0 발행 +- OFT Adapter가 사용자를 대신하여 ERC-20 토큰을 지출하도록 승인 +- 32바이트 주소 인코딩 및 Executor 옵션을 사용하여 LayerZero `sendParams` 구성 +- 자금을 커밋하기 전에 `quoteSend`로 교차 체인 메시징 수수료 인용 +- `send`를 사용하여 교차 체인 토큰 전송 실행 및 대상 체인에서 전달 확인 +- Stable의 RPC(`https://rpc.testnet.stable.xyz`, 체인 ID `2201`) 및 Stablescan을 사용하여 온체인 상태 확인 -## 다음 추천 +## 다음 권장 사항 -- [**첫 USDT0 전송하기**](/ko/tutorial/send-usdt0) — 브릿지된 USDT0를 네이티브 및 ERC-20 전송에 사용하세요. -- [**Stable로 브릿지하기**](/ko/explanation/usdt0-bridging) — OFT Mesh와 Legacy Mesh 메커니즘에 대한 심층 분석. -- [**테스트넷 정보**](/ko/reference/testnet-information) — 전체 네트워크 파라미터, RPC 엔드포인트, 그리고 faucet 세부 정보. +- [**첫 번째 USDT0 전송**](/ko/tutorial/send-usdt0): 브리징된 USDT0를 네이티브 및 ERC-20 전송과 함께 사용합니다. +- [**Stable로 브리징**](/ko/explanation/usdt0-bridging): OFT Mesh 대 Legacy Mesh 메커니즘에 대한 심층 분석. +- [**테스트넷 정보**](/ko/reference/testnet-information): 전체 네트워크 매개변수, RPC 엔드포인트 및 Faucet 세부 정보. diff --git a/docs/pages/ko/tutorial/quick-start.mdx b/docs/pages/ko/tutorial/quick-start.mdx index 3be19c5..43863bf 100755 --- a/docs/pages/ko/tutorial/quick-start.mdx +++ b/docs/pages/ko/tutorial/quick-start.mdx @@ -1,27 +1,27 @@ --- source_path: tutorial/quick-start.mdx -source_sha: ac60005c171579369156d04b03a48434c2e6bbba +source_sha: f3a60f028fff5319841801dd9508ebb86d37069f title: "빠른 시작" -description: "Stable 테스트넷에 연결하고, 포셋에서 지갑에 자금을 충전하고, 첫 USDT0 트랜잭션을 전송하세요" +description: "Stable 테스트넷에 연결하고, faucet에서 지갑에 자금을 지원한 다음 첫 번째 USDT0 트랜잭션을 보냅니다." diataxis: "tutorial" --- # 빠른 시작 -필요한 도구는 Node.js, 포셋에서 받은 USDT0, 그리고 개인 키뿐입니다. Stable은 USDT0를 가스 토큰으로 사용하므로, 트랜잭션을 처리하는 데 USDT0만 있으면 됩니다. 별도로 충전해야 할 가스 자산은 없습니다. +필요한 도구는 Node.js, faucet의 USDT0 일부, 비공개 키뿐입니다. Stable은 USDT0를 가스 토큰으로 사용하므로 트랜잭션을 위해서는 USDT0만 있으면 됩니다. 별도의 가스 자산에 자금을 지원할 필요가 없습니다. :::note -타입이 지정된 클라이언트를 선호하시나요? [Stable SDK](/ko/explanation/sdk-overview)는 `transfer`, `bridge`, `swap` 메서드로 viem을 감싸므로 수동 ABI 및 소수점 작업을 건너뛸 수 있습니다. +타입이 지정된 클라이언트를 선호하시나요? [Stable SDK](/ko/explanation/sdk-overview)는 `transfer`, `bridge`, `swap` 메서드를 사용하여 viem을 래핑하므로 수동 ABI 및 소수점 작업을 건너뛸 수 있습니다. ::: -## 사전 준비 +## 전제 조건 - Node.js 20 이상 -- 직접 관리하는 개인 키 (새로운 테스트 키도 괜찮습니다) +- 본인이 관리하는 비공개 키 (새 테스트 키도 괜찮습니다) ## 1. 설치 및 구성 -프로젝트를 생성하고, `ethers`를 설치한 후, 테스트넷 구성을 저장하세요. +프로젝트를 만들고, `ethers`를 설치하고, 테스트넷 구성을 저장합니다. ```bash mkdir stable-quickstart && cd stable-quickstart @@ -32,13 +32,13 @@ npm init -y && npm install ethers added 1 package, audited 2 packages in 1s ``` -개인 키를 `.env`에 저장하세요: +비공개 키를 `.env`에 저장합니다. ```bash echo "PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE" > .env ``` -`config.ts`를 생성하세요: +`config.ts`를 생성합니다. ```typescript // config.ts @@ -52,9 +52,9 @@ export const provider = new ethers.JsonRpcProvider(STABLE_TESTNET_RPC); export const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider); ``` -## 2. 지갑에 자금 충전 +## 2. 지갑에 자금 지원 -주소를 출력한 다음, 포셋에서 테스트넷 USDT0를 요청하세요. +주소를 출력한 다음 faucet에서 테스트넷 USDT0를 요청합니다. ```typescript // address.ts @@ -71,11 +71,11 @@ npx tsx address.ts Wallet address: 0x1234...abcd ``` -[https://faucet.stable.xyz](https://faucet.stable.xyz)로 이동하여 주소를 붙여넣고, 버튼을 선택하여 테스트넷 USDT0를 받으세요. 포셋은 1 USDT0를 전송하며, 이는 수천 건의 네이티브 전송에 충분합니다. +[https://faucet.stable.xyz](https://faucet.stable.xyz)로 이동하여 주소를 붙여넣고 버튼을 선택하여 테스트넷 USDT0를 받습니다. faucet은 1 USDT0를 보내며, 이는 수천 개의 기본 전송에 충분합니다. -## 3. 첫 트랜잭션 전송 +## 3. 첫 번째 트랜잭션 보내기 -0.001 USDT0를 네이티브로 전송하세요. Stable에서 USDT0는 네이티브 자산이므로, 간단한 값 전송이 가장 저렴한 경로입니다(21,000 가스). +0.001 USDT0를 기본적으로 보냅니다. Stable에서는 USDT0가 기본 자산이므로 간단한 값 전송이 가장 저렴한 경로입니다 (21,000 가스). ```typescript // send.ts @@ -109,14 +109,14 @@ Tx: 0x8f3a...2d41 Explorer: https://testnet.stablescan.xyz/tx/0x8f3a...2d41 ``` -익스플로러 링크를 열어 트랜잭션을 확인하세요. 블록 생성 시간은 약 0.7초이므로, 이미 최종 확정되었을 것입니다. +탐색기 링크를 열어 트랜잭션을 확인하십시오. 블록 시간은 약 0.7초이므로 이미 최종적이어야 합니다. :::warning -`maxPriorityFeePerGas`는 Stable에서 무시되며 반드시 `0`으로 설정해야 합니다. base-fee-only 모델이 트랜잭션 구성을 어떻게 변경하는지는 [가스 가격 책정](/ko/reference/gas-pricing-api)을 참조하세요. +`maxPriorityFeePerGas`는 Stable에서 무시되며 `0`으로 설정해야 합니다. 기본 요금 전용 모델이 트랜잭션 구성을 변경하는 방법에 대해서는 [가스 가격 책정](/ko/reference/gas-pricing-api)을 참조하십시오. ::: ## 다음 단계 -- [**스마트 컨트랙트 배포**](/ko/tutorial/smart-contract) — Foundry 프로젝트를 스캐폴딩하고 Stable 테스트넷에 배포하세요. -- [**결제 앱 구축**](/ko/how-to/build-p2p-payments) — 지갑 생성, 전송, 수신, 결제 내역 조회를 만들어보세요. -- [**AI로 개발하기**](/ko/how-to/develop-with-ai) — MCP 서버와 에이전트 스킬을 AI 에디터에 연결하세요. +- [**스마트 계약 배포**](/ko/tutorial/smart-contract): Foundry 프로젝트를 스캐폴드하고 Stable 테스트넷에 배포합니다. +- [**결제 앱 구축**](/ko/how-to/build-p2p-payments): 지갑을 생성하고, 결제 내역을 보내고, 받고, 쿼리합니다. +- [**AI로 개발**](/ko/how-to/develop-with-ai): MCP 서버와 에이전트 기술을 AI 편집기에 연결합니다. diff --git a/docs/pages/ko/tutorial/sdk-quickstart.mdx b/docs/pages/ko/tutorial/sdk-quickstart.mdx index ed9fd6a..a2927e5 100644 --- a/docs/pages/ko/tutorial/sdk-quickstart.mdx +++ b/docs/pages/ko/tutorial/sdk-quickstart.mdx @@ -1,23 +1,23 @@ --- source_path: tutorial/sdk-quickstart.mdx -source_sha: 7f6797e29245d890cb46a01da0c772ffc797b252 -title: "SDK 빠른 시작" -description: "Stable SDK를 설치하고, 테스트넷에서 첫 USDT0 전송을 보내고, 브리지 및 스왑 견적을 미리 확인합니다." +source_sha: 24bdfc4340389e06e1cb06ee6a7f3e1939940c97 +title: "SDK 퀵스타트" +description: "Stable SDK를 설치하고, 테스트넷에서 첫 USDT0 전송을 보내고, 브릿지 및 스왑 견적을 미리 봅니다." diataxis: "tutorial" --- -# SDK 빠른 시작 +# SDK 퀵스타트 -`@stablechain/sdk`를 설치하고, 개인 키로 서명하는 클라이언트를 만들고, Stable Testnet에서 USDT0 전송을 보내고, 브리지 및 스왑 견적을 가져옵니다. 총 소요 시간: 약 5분. +`@stablechain/sdk`를 설치하고, 프라이빗 키로 서명된 클라이언트를 생성하고, Stable 테스트넷에서 USDT0 전송을 보내고, 브릿지 및 스왑 견적을 가져옵니다. 총 소요 시간: 약 5분. :::note -Stable은 USDT0를 가스 토큰으로 사용합니다. 거래하려면 테스트넷 USDT0만 있으면 됩니다 — 별도로 충전해야 할 네이티브 자산이 없습니다. +Stable은 가스 토큰으로 USDT0을 사용합니다. 거래를 위해서는 테스트넷 USDT0만 있으면 됩니다. 자금을 조달할 별도의 기본 자산은 없습니다. ::: -## 사전 준비 사항 +## 전제 조건 - Node.js 20 이상 -- 테스트넷 USDT0가 있는 테스트 개인 키. [테스트넷 지갑에 자금 충전하기](/ko/how-to/use-faucet)를 참고하세요. +- 테스트넷 USDT0이 있는 테스트 프라이빗 키. [테스트넷 지갑에 자금 조달](/ko/how-to/use-faucet) 참조. ## 1. 설치 @@ -30,7 +30,7 @@ npm init -y && npm install @stablechain/sdk viem added 2 packages, audited 3 packages in 2s ``` -테스트 키를 저장합니다: +테스트 키를 저장합니다. ```bash echo "PRIVATE_KEY=0xYOUR_TEST_KEY" > .env @@ -38,7 +38,7 @@ echo "PRIVATE_KEY=0xYOUR_TEST_KEY" > .env ## 2. 클라이언트 생성 -`index.ts`를 생성합니다: +`index.ts` 생성: ```ts import "dotenv/config"; @@ -59,11 +59,11 @@ console.log("Signer:", account.address); Signer: 0xYourAddress ``` -`createStable`은 세 가지 서명 모드를 허용합니다: `account`(서버 측, 위에 표시됨), `transport`(`custom(window.ethereum)`를 통한 브라우저 지갑), 또는 `walletClient`(미리 빌드된 viem `WalletClient`). 세 가지 모두에 대해서는 [viem과 함께 SDK 사용하기](/ko/how-to/sdk-with-viem)를 참고하세요. +`createStable`은 세 가지 서명 모드를 허용합니다: `account` (서버 측, 위 참조), `transport` (`custom(window.ethereum)`을 통한 브라우저 지갑), 또는 `walletClient` (사전 구축된 viem `WalletClient`). 세 가지 모두에 대해서는 [viem과 함께 SDK 사용](/ko/how-to/sdk-with-viem)을 참조하세요. ## 3. USDT0 전송 보내기 -`index.ts`에 추가합니다: +`index.ts`에 추가: ```ts const { txHash } = await stable.transfer({ @@ -75,7 +75,7 @@ const { txHash } = await stable.transfer({ console.log("Transfer:", txHash); ``` -실행합니다: +실행: ```bash npx tsx index.ts @@ -86,11 +86,11 @@ Signer: 0xYourAddress Transfer: 0x8f3a...2d41 ``` -[테스트넷 익스플로러](https://testnet.stablescan.xyz)에서 해시를 열어 확인하세요. +[테스트넷 탐색기](https://testnet.stablescan.xyz)에서 해시를 열어 확인합니다. -## 4. 브리지 견적 +## 4. 브릿지 견적 -USDT0를 Ethereum Sepolia에서 Stable Testnet으로 브리지합니다. `quoteBridge`는 읽기 전용 호출입니다 — 서명도, 가스도 필요 없습니다: +이더리움 Sepolia에서 Stable 테스트넷으로 USDT0을 브릿지합니다. `quoteBridge`는 서명도 가스도 없는 읽기 전용 호출입니다. ```ts import { Chain } from "@stablechain/sdk"; @@ -110,11 +110,11 @@ console.log("Bridge quote:", bridgeQuote); Bridge quote: { toAmount: 0.999812 } ``` -견적을 `stable.bridge({ ...params, quote })`에 전달하여 실행합니다. SDK는 USDT0 → USDT0 경로에는 LayerZero를, 그 외 모든 경우에는 LI.FI를 선택합니다. +견적을 `stable.bridge({ ...params, quote })`에 전달하여 실행합니다. SDK는 USDT0 → USDT0 경로에 LayerZero를, 그 외 모든 것에 LI.FI를 사용합니다. ## 5. 스왑 견적 -스왑은 LI.FI를 통해 Stable에서 실행됩니다. 견적은 예상 출력값과 미리 빌드된 트랜잭션을 반환합니다: +스왑은 LI.FI를 통해 Stable에서 실행됩니다. 견적은 예상 출력과 미리 구축된 트랜잭션을 반환합니다. ```ts const swapQuote = await stable.quoteSwap({ @@ -133,8 +133,8 @@ You'll receive: 0.998 USDT0 `stable.swap({ ...params, quote: swapQuote })`를 호출하여 실행합니다. ERC-20 소스에 대한 승인은 내부적으로 처리됩니다. -## 다음 추천 +## 다음 권장 사항 -- [**SDK 레퍼런스**](/ko/reference/sdk) — 모든 매개변수, 반환 타입, 오류 클래스. -- [**viem과 함께 사용하기**](/ko/how-to/sdk-with-viem) — 개인 키, 브라우저 지갑, 미리 빌드된 `WalletClient` 서명 간 전환. -- [**wagmi와 함께 사용하기**](/ko/how-to/sdk-with-wagmi) — wagmi 훅을 사용하여 React 앱에 SDK 연결하기. +- [**SDK 참조**](/ko/reference/sdk): 모든 매개변수, 반환 유형 및 오류 클래스. +- [**viem과 함께 사용**](/ko/how-to/sdk-with-viem): 프라이빗 키, 브라우저 지갑 및 미리 구축된 `WalletClient` 서명 간에 전환. +- [**wagmi와 함께 사용**](/ko/how-to/sdk-with-wagmi): wagmi 훅을 사용하여 SDK를 React 앱에 연결. diff --git a/docs/pages/ko/tutorial/send-usdt0.mdx b/docs/pages/ko/tutorial/send-usdt0.mdx index d7062e2..df164ea 100644 --- a/docs/pages/ko/tutorial/send-usdt0.mdx +++ b/docs/pages/ko/tutorial/send-usdt0.mdx @@ -1,48 +1,48 @@ --- source_path: tutorial/send-usdt0.mdx -source_sha: 1fff06b2bb41a34bd51591c23054ad451815f05e -title: "첫 USDT0 보내기" -description: "Stable에서 USDT0를 네이티브 전송과 ERC-20 전송 두 방식으로 보내고, 두 방식이 동일한 잔액에서 작동하는지 확인합니다." +source_sha: d631d3ab8138addcd0cd58e30ac907fe503a5d04 +title: "첫 USDT0 전송" +description: "Stable에서 USDT0를 네이티브 전송과 ERC-20 전송으로 모두 전송하고, 두 전송 모두 동일한 잔액으로 작동하는지 확인합니다." diataxis: "tutorial" --- -# 첫 USDT0 보내기 +# 첫 USDT0 전송 -Stable에서 USDT0는 체인의 네이티브 자산이자 ERC-20 토큰입니다. 이는 표준 가치 전송과 함께 `approve`, `transferFrom`, `permit`가 완전히 사용 가능하며, 두 경로 모두 동일한 기본 잔액에서 자금을 이동시킨다는 것을 의미합니다. +Stable에서 USDT0는 체인의 기본 자산이자 ERC-20 토큰입니다. 이는 `approve`, `transferFrom`, `permit`이 표준 가치 전송과 함께 완벽하게 사용 가능하며, 두 경로 모두 동일한 기본 잔액에서 자금을 이동한다는 것을 의미합니다. -이 페이지에서는 두 경로를 통해 USDT0를 보내고 두 방식이 하나의 잔액에서 인출됨을 확인하는 과정을 안내합니다. +이 페이지에서는 두 경로를 통해 USDT0를 전송하고 단일 잔액에서 인출되는 것을 확인하는 방법을 안내합니다. :::note -타입이 지정된 클라이언트를 선호하시나요? [Stable SDK](/ko/explanation/sdk-overview)는 두 경로를 모두 다루고, 온체인에서 소수점을 처리하며, 지갑의 체인을 자동으로 전환해주는 단일 `transfer({ to, amount, token? })`를 제공합니다. +타입 클라이언트를 선호하십니까? [Stable SDK](/ko/explanation/sdk-overview)는 두 경로를 모두 다루고, 온체인에서 소수 자릿수를 처리하며, 지갑의 체인을 자동으로 전환하는 단일 `transfer({ to, amount, token? })`를 노출합니다. ::: :::note -**18 소수점 vs 6 소수점**: 네이티브 USDT0는 18 소수점(표준 EVM 정밀도)을 사용하는 반면, ERC-20 인터페이스는 6 소수점(표준 USDT 정밀도)을 보고합니다. 둘 다 동일한 잔액을 반영하므로, `address(x).balance`와 `USDT0.balanceOf(x)`는 소수점 조정으로 인해 최대 0.000001 USDT0까지 차이가 날 수 있습니다. [Stable에서의 USDT0 동작](/ko/explanation/usdt0-behavior)을 참조하세요. +**18 vs 6 소수 자릿수**: 네이티브 USDT0는 18 소수 자릿수(표준 EVM 정밀도)를 사용하고, ERC-20 인터페이스는 6 소수 자릿수(표준 USDT 정밀도)를 보고합니다. 둘 다 동일한 잔액을 반영하므로 `address(x).balance`와 `USDT0.balanceOf(x)`는 소수점 조정으로 인해 최대 0.000001 USDT0까지 다를 수 있습니다. [Stable에서의 USDT0 동작](/ko/explanation/usdt0-behavior)을 참조하십시오. ::: -## 무엇을 만들 것인가 +## 무엇을 만들 것인가요? -0.001 USDT0를 네이티브 전송으로 보내고, 0.001 USDT0를 ERC-20 전송으로 보낸 다음, 두 잔액을 모두 출력하는 2개의 스크립트 흐름입니다. +0.001 USDT0를 네이티브 전송으로 보내고, 0.001 USDT0를 ERC-20 전송으로 보내고, 두 잔액을 모두 출력하는 두 스크립트 플로우입니다. ### 데모 ```text -step 1. Connect wallet → balance displayed +1단계. 지갑 연결 → 잔액 표시 0.01 USDT0 -step 2. Send 0.001 USDT0 (choose native or ERC-20 transfer) +2단계. 0.001 USDT0 전송 (네이티브 또는 ERC-20 전송 선택) -step 3. Result - Sent: 0.001 USDT0 - Gas fee: 0.000021 USDT0 - Native balance: 0.008979 USDT0 - ERC-20 balance: 0.008979 USDT0 +3단계. 결과 + 전송됨: 0.001 USDT0 + 가스 요금: 0.000021 USDT0 + 네이티브 잔액: 0.008979 USDT0 + ERC-20 잔액: 0.008979 USDT0 ``` -## 사전 준비물 +## 전제 조건 - Node.js 20 이상 -- 테스트넷 USDT0가 있는 프라이빗 키. 지갑에 자금을 충전하려면 [빠른 시작](/ko/tutorial/quick-start)을 참조하세요. +- testnet USDT0가 있는 프라이빗 키. 지갑에 자금을 지원하려면 [빠른 시작](/ko/tutorial/quick-start)을 참조하십시오. **USDT0 컨트랙트 주소** @@ -64,9 +64,9 @@ export const provider = new ethers.JsonRpcProvider(STABLE_TESTNET_RPC); export const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider); ``` -## 옵션 1 (권장): 네이티브 전송으로 보내기 +## 옵션 1 (권장): 네이티브 전송으로 전송 -네이티브 전송은 Ethereum에서 ETH를 보내는 것과 동일하게 작동합니다. `value` 필드가 USDT0 금액을 담습니다. 네이티브 전송은 21,000 가스만 소모하며, USDT0를 보내는 가장 저렴한 방법입니다. +네이티브 전송은 이더리움에서 ETH를 보내는 것과 동일하게 작동합니다. `value` 필드는 USDT0 금액을 전달합니다. 네이티브 전송은 21,000 가스만 소모하며, USDT0를 보내는 가장 저렴한 방법입니다. ```typescript // sendNative.ts @@ -74,7 +74,7 @@ import { ethers } from "ethers"; import { provider, wallet } from "./config"; const recipient = "0xRecipientAddress"; -const amount = ethers.parseUnits("0.001", 18); // 18 decimals for native +const amount = ethers.parseUnits("0.001", 18); // 네이티브의 경우 18 소수 자릿수 const block = await provider.getBlock("latest"); const baseFee = block!.baseFeePerGas!; @@ -83,11 +83,11 @@ const tx = await wallet.sendTransaction({ to: recipient, value: amount, maxFeePerGas: baseFee * 2n, - maxPriorityFeePerGas: 0n, // always 0 on Stable + maxPriorityFeePerGas: 0n, // Stable에서는 항상 0 }); const receipt = await tx.wait(1); -console.log("Native transfer tx:", receipt!.hash); +console.log("네이티브 전송 tx:", receipt!.hash); ``` ```bash @@ -95,12 +95,12 @@ npx tsx sendNative.ts ``` ```text -Native transfer tx: 0x8f3a...2d41 +네이티브 전송 tx: 0x8f3a...2d41 ``` -## 옵션 2: ERC-20 전송으로 보내기 +## 옵션 2: ERC-20 전송으로 전송 -USDT0는 ERC-20 전송으로도 보낼 수 있습니다. 이는 동일한 잔액에서 차감되지만, 6 소수점 정밀도를 가진 ERC-20 인터페이스를 사용합니다. +USDT0는 ERC-20 전송으로도 보낼 수 있습니다. 이는 동일한 잔액에서 차감되지만, 6자리 소수점 정밀도를 가진 ERC-20 인터페이스를 사용합니다. ```typescript // sendERC20.ts @@ -108,7 +108,7 @@ import { ethers } from "ethers"; import { wallet, USDT0_ADDRESS } from "./config"; const recipient = "0xRecipientAddress"; -const amount = ethers.parseUnits("0.001", 6); // 6 decimals for ERC-20 +const amount = ethers.parseUnits("0.001", 6); // ERC-20의 경우 6 소수 자릿수 const usdt0 = new ethers.Contract(USDT0_ADDRESS, [ "function transfer(address to, uint256 amount) returns (bool)" @@ -116,7 +116,7 @@ const usdt0 = new ethers.Contract(USDT0_ADDRESS, [ const tx = await usdt0.transfer(recipient, amount); const receipt = await tx.wait(1); -console.log("ERC-20 transfer tx:", receipt!.hash); +console.log("ERC-20 전송 tx:", receipt!.hash); ``` ```bash @@ -124,12 +124,12 @@ npx tsx sendERC20.ts ``` ```text -ERC-20 transfer tx: 0xa2b1...77c0 +ERC-20 전송 tx: 0xa2b1...77c0 ``` ## 통합 잔액 확인 -두 전송 중 어느 것이든 후에, 두 잔액을 조회하여 동일한 출처에서 인출되는지 확인하세요. +어떤 전송 후에도 두 잔액을 쿼리하여 동일한 소스에서 가져왔는지 확인합니다. ```typescript // balances.ts @@ -137,13 +137,13 @@ import { ethers } from "ethers"; import { provider, wallet, USDT0_ADDRESS } from "./config"; const nativeBalance = await provider.getBalance(wallet.address); -console.log("Native balance:", ethers.formatEther(nativeBalance), "USDT0"); +console.log("네이티브 잔액:", ethers.formatEther(nativeBalance), "USDT0"); const usdt0 = new ethers.Contract(USDT0_ADDRESS, [ "function balanceOf(address) view returns (uint256)" ], provider); const erc20Balance = await usdt0.balanceOf(wallet.address); -console.log("ERC-20 balance:", ethers.formatUnits(erc20Balance, 6), "USDT0"); +console.log("ERC-20 잔액:", ethers.formatUnits(erc20Balance, 6), "USDT0"); ``` ```bash @@ -151,14 +151,14 @@ npx tsx balances.ts ``` ```text -Native balance: 0.008979 USDT0 -ERC-20 balance: 0.008979 USDT0 +네이티브 잔액: 0.008979 USDT0 +ERC-20 잔액: 0.008979 USDT0 ``` -두 값은 동일한 잔액을 나타냅니다. [소수점 잔액 조정](/ko/explanation/usdt0-behavior#balance-reconciliation)으로 인해 최대 0.000001 USDT0까지 차이가 날 수 있습니다. +두 값 모두 동일한 잔액을 나타냅니다. [소수점 잔액 조정](/ko/explanation/usdt0-behavior#balance-reconciliation)으로 인해 최대 0.000001 USDT0까지 다를 수 있습니다. ## 다음 권장 사항 -- [**가스 제로 트랜잭션**](/ko/how-to/zero-gas-transactions) — 가스 비용을 면제 서비스가 지불하는 방식으로 USDT0를 보냅니다. -- [**P2P 결제 앱 만들기**](/ko/how-to/build-p2p-payments) — 지갑 생성, 전송, 수신 및 결제 내역 조회를 구현합니다. -- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior) — 이중 역할 잔액 조정과 컨트랙트 설계를 이해합니다. +- [**제로 가스 트랜잭션**](/ko/how-to/zero-gas-transactions): 웨이버 서비스가 가스 요금을 지불하는 USDT0를 보냅니다. +- [**P2P 결제 앱 구축**](/ko/how-to/build-p2p-payments): 지갑 생성, 송금, 수신 및 결제 내역 쿼리. +- [**Stable에서의 USDT0 동작**](/ko/explanation/usdt0-behavior): 이중 역할 잔액 조정 및 컨트랙트 설계 이해. diff --git a/docs/pages/ko/tutorial/smart-contract.mdx b/docs/pages/ko/tutorial/smart-contract.mdx index 2f9bc7d..150bf61 100644 --- a/docs/pages/ko/tutorial/smart-contract.mdx +++ b/docs/pages/ko/tutorial/smart-contract.mdx @@ -1,62 +1,62 @@ --- source_path: tutorial/smart-contract.mdx -source_sha: 55828da2370736b531a7427f6a8d2aeac3e6fe48 -title: "스마트 컨트랙트 배포하기" -description: "Foundry 프로젝트를 스캐폴딩하고, 지갑에 USDT0를 충전하고, Stable 테스트넷에 컨트랙트를 배포한 후 온체인에서 검증합니다." +source_sha: c0e4ec8dbb55d2a0f3067fe66608accef1c88fa6 +title: "스마트 계약 배포" +description: "Foundry 프로젝트를 스캐폴드하고, USDT0으로 지갑에 자금을 지원하고, Stable 테스트넷에 계약을 배포하고, 온체인에서 확인합니다." diataxis: "tutorial" --- -# 스마트 컨트랙트 배포하기 +# 스마트 계약 배포 -이 튜토리얼에서는 간단한 스마트 컨트랙트를 Stable 테스트넷에 배포하고 체인에서 해당 상태를 읽어옵니다. 그 과정에서 Stable 네트워크가 어떻게 구성되어 있는지, USDT0가 가스 토큰으로 어떻게 작동하는지, 그리고 표준 EVM 도구를 Stable로 가리키는 방법을 배우게 됩니다. +이 튜토리얼에서는 간단한 스마트 계약을 Stable Testnet에 배포하고 체인에서 상태를 읽는 방법을 다룹니다. 이 과정에서 Stable 네트워크가 어떻게 구성되어 있는지, USDT0이 가스 토큰으로 어떻게 작동하는지, 그리고 표준 EVM 툴링을 Stable에 어떻게 연결하는지 배우게 될 것입니다. -이 튜토리얼은 Solidity와 Unix 계열 터미널에 대한 기본적인 이해를 전제로 합니다. Stable에 대한 사전 경험은 필요하지 않습니다. +이 튜토리얼은 Solidity 및 Unix와 유사한 터미널에 대한 기본적인 지식을 전제로 합니다. Stable에 대한 사전 경험은 필요하지 않습니다. -## 무엇을 만들게 되나요 +## 만들게 될 것 -샘플 `Counter` 컨트랙트가 포함된 새로운 Foundry 프로젝트를 Stable 테스트넷에 배포하고, 상태를 변경하는 호출 한 번과 읽기 호출 한 번을 수행합니다. +새로운 Foundry 프로젝트에 샘플 `Counter` 계약을 Stable 테스트넷에 배포하고, 하나의 상태 변경 호출과 하나의 읽기 호출을 수행합니다. ### 데모 ```text -step 1. Scaffold Foundry project → stable-hello/ +1단계. Foundry 프로젝트 스캐폴드 → stable-hello/ -step 2. Configure testnet +2단계. 테스트넷 구성 RPC: https://rpc.testnet.stable.xyz - Chain ID: 2201 + 체인 ID: 2201 -step 3. Fund wallet from faucet (1 USDT0) +3단계. Faucet에서 지갑에 자금 지원 (1 USDT0) -step 4. forge create Counter - Deployed to: 0xContract... +4단계. forge create Counter + 배포 위치: 0xContract... -step 5. cast send Counter.setNumber(42) +5단계. cast send Counter.setNumber(42) -step 6. cast call Counter.number() +6단계. cast call Counter.number() → 42 ``` -## 사전 준비 +## 전제 조건 -- [Foundry](https://book.getfoundry.sh/getting-started/installation) 설치 (`forge`, `cast`, `anvil`이 PATH에서 사용 가능) -- 본인이 제어하는 개인 키가 있는 지갑 (새로운 테스트 키를 사용해도 됩니다. 테스트넷에서는 실제 자금이 있는 키를 절대 사용하지 마세요) -- 테스트넷 RPC와 faucet에 접근하기 위한 인터넷 연결 +- [Foundry](https://book.getfoundry.sh/getting-started/installation) 설치 (`forge`, `cast`, `anvil`이 PATH에 사용 가능해야 합니다) +- 제어할 수 있는 프라이빗 키가 있는 지갑 (새로운 테스트 키도 괜찮습니다; 실제 자금이 있는 키는 테스트넷에서 절대 사용하지 마십시오) +- 테스트넷 RPC 및 Faucet에 연결하기 위한 인터넷 연결 --- -## 1. 새 Foundry 프로젝트 생성하기 +## 1. 새 Foundry 프로젝트 생성 -다음 명령을 실행하여 새 프로젝트를 스캐폴딩합니다: +다음 명령을 실행하여 새 프로젝트를 스캐폴드합니다. ```bash forge init stable-hello && cd stable-hello ``` -Foundry는 샘플 `Counter.sol` 컨트랙트와 그에 맞는 테스트 파일이 있는 `src/` 디렉터리를 생성합니다. 이 컨트랙트를 있는 그대로 배포할 것입니다. 목표는 새로운 Solidity를 작성하는 것이 아니라 실제로 무언가를 온체인에 올리는 것입니다. +Foundry는 `src/` 디렉토리를 샘플 `Counter.sol` 계약 및 일치하는 테스트 파일과 함께 생성합니다. 이 계약을 그대로 배포할 것입니다. 목표는 새로운 Solidity를 작성하는 것이 아니라 체인에 실제 무언가를 올리는 것입니다. -## 2. 배포할 컨트랙트 살펴보기 +## 2. 배포할 계약 검토 -`src/Counter.sol`을 엽니다. 두 개의 함수가 들어 있습니다: +`src/Counter.sol`을 엽니다. 이 파일에는 두 가지 함수가 포함되어 있습니다. ```solidity // SPDX-License-Identifier: UNLICENSED @@ -75,34 +75,34 @@ contract Counter { } ``` -`number`는 온체인에 저장되는 public 상태 변수입니다. `increment()`와 `setNumber()`는 이를 변경하는 두 가지 방법입니다. `number`를 읽는 데는 가스가 들지 않습니다. 이는 무료 `eth_call`입니다. +`number`는 온체인에 저장된 공개 상태 변수입니다. `increment()` 및 `setNumber()`는 이를 변경하는 두 가지 방법입니다. `number`를 읽는 데는 가스가 들지 않습니다. 이는 무료 `eth_call`입니다. -## 3. Stable 테스트넷 구성하기 +## 3. Stable 테스트넷 구성 -프로젝트 루트에 `.env`라는 파일을 생성하여 네트워크 자격 증명을 저장합니다: +프로젝트 루트에 `.env`라는 파일을 만들어 네트워크 자격 증명을 저장합니다. ```bash touch .env ``` -다음 내용을 추가하고, 플레이스홀더를 실제 개인 키로 교체하세요: +다음 내용을 추가하고, 자리 표시자를 실제 프라이빗 키로 대체합니다. ```bash PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE ``` -다음으로, `foundry.toml`을 열고 Stable 테스트넷을 이름이 지정된 네트워크 프로필로 추가합니다. 기존 `[profile.default]` 섹션 아래에 이 블록을 추가하세요: +다음으로 `foundry.toml`을 열고 Stable 테스트넷을 명명된 네트워크 프로필로 추가합니다. 기존 `[profile.default]` 섹션 아래에 이 블록을 추가합니다. ```toml [rpc_endpoints] stable_testnet = "https://rpc.testnet.stable.xyz" ``` -이렇게 하면 `stable_testnet`을 대상으로 할 때 Foundry가 트랜잭션을 어디로 보낼지 알게 됩니다. Stable은 EVM 호환이므로 다른 구성은 필요하지 않습니다. +이것은 `stable_testnet`을 대상으로 할 때 Foundry가 트랜잭션을 보낼 위치를 알려줍니다. Stable은 EVM 호환이므로 다른 구성은 필요하지 않습니다. --- -**체크포인트:** RPC 엔드포인트에 접근할 수 있는지 확인하세요: +**체크포인트:** RPC 엔드포인트에 연결할 수 있는지 확인합니다. ```bash cast chain-id --rpc-url https://rpc.testnet.stable.xyz @@ -110,52 +110,52 @@ cast chain-id --rpc-url https://rpc.testnet.stable.xyz 예상 출력: -``` +```text 2201 ``` -체인 ID `2201`은 Stable 테스트넷입니다. 이 숫자가 보이면 사용 중인 컴퓨터가 네트워크에 접근할 수 있는 것입니다. +체인 ID `2201`은 Stable 테스트넷입니다. 이 숫자가 보이면 머신이 네트워크에 연결할 수 있습니다. --- ## 4. 지갑 주소 가져오기 -어떤 계정에 자금을 충전할지 알 수 있도록 개인 키에서 배포자 주소를 도출합니다: +프라이빗 키에서 배포자 주소를 가져와 어떤 계정에 자금을 조달해야 하는지 확인합니다. ```bash source .env cast wallet address $PRIVATE_KEY ``` -출력된 주소를 복사하세요. 다음 단계에서 필요합니다. +출력된 주소를 복사합니다. 다음 단계에서 필요합니다. -## 5. 지갑에 USDT0 충전하기 +## 5. USDT0으로 지갑에 자금 지원 -Stable은 가스 토큰으로 **USDT0**를 사용합니다. 상품과 서비스 비용을 지불하는 데 사용하는 것과 동일한 자산이 연산 비용을 지불하는 데 직접 사용됩니다. 별도의 네이티브 토큰은 없습니다. +Stable은 **USDT0**을 가스 토큰으로 사용합니다. 상품 및 서비스 비용을 지불하는 데 사용하는 자산과 동일한 자산을 직접 계산 비용을 지불하는 데 사용합니다. 보조 네이티브 토큰은 없습니다. -테스트넷 faucet에 방문하여 자금을 요청하세요: +테스트넷 Faucet에 방문하여 자금을 요청합니다. -``` +```text https://faucet.stable.xyz ``` -이전 단계의 주소를 붙여넣으세요. faucet은 지갑으로 1 USDT0를 보내며, 이는 여러 컨트랙트를 배포하고 상호작용하기에 충분합니다. +이전 단계에서 복사한 주소를 붙여넣습니다. Faucet은 지갑에 1 USDT0을 보냅니다. 이 금액은 여러 컨트랙트를 배포하고 상호 작용하기에 충분합니다. --- -**체크포인트:** 잔액이 도착했는지 확인하세요: +**체크포인트:** 잔액이 도착했는지 확인합니다. ```bash cast balance $PRIVATE_KEY --rpc-url https://rpc.testnet.stable.xyz ``` -0이 아닌 값이 보여야 합니다. 잔액이 여전히 `0`이면 몇 초 기다린 후 다시 실행하세요. Stable은 약 0.7초마다 새 블록을 생성하므로 자금은 빠르게 정산됩니다. +0이 아닌 값이 보여야 합니다. 잔액이 여전히 `0`이면 몇 초 기다렸다가 다시 실행하십시오. Stable은 약 0.7초마다 새 블록을 생성하므로 자금이 빠르게 정산됩니다. --- -## 6. 컨트랙트 배포하기 +## 6. 계약 배포 -`forge create`로 배포를 실행합니다: +`forge create`를 사용하여 배포를 실행합니다. ```bash source .env @@ -165,27 +165,27 @@ forge create src/Counter.sol:Counter \ --broadcast ``` -Foundry는 컨트랙트를 컴파일하고, 배포 트랜잭션을 브로드캐스트한 후 영수증을 기다립니다. 블록 시간이 약 0.7초이므로 잠깐이면 완료됩니다. +Foundry는 계약을 컴파일하고, 배포 트랜잭션을 브로드캐스트하며, 영수증을 기다립니다. 블록 시간이 ~0.7초이므로 이 작업은 잠시만 걸립니다. --- -**체크포인트:** 출력은 다음과 같아야 합니다: +**체크포인트:** 출력은 다음과 같아야 합니다. -``` -[⠒] Compiling... -No files changed, compilation skipped -Deployer: 0xYourAddress -Deployed to: 0xSomeContractAddress -Transaction hash: 0xSomeTxHash +```text +[⠒] 컴파일 중... +변경된 파일이 없어 컴파일을 건너뜁니다. +배포자: 0xYourAddress +배포 위치: 0xSomeContractAddress +트랜잭션 해시: 0xSomeTxHash ``` -`Deployed to` 주소를 복사하세요. 다음 두 단계에서 필요합니다. +`Deployed to` 주소를 복사합니다. 다음 두 단계에서 필요합니다. --- -## 7. 쓰기 함수 호출하기 +## 7. 쓰기 함수 호출 -이제 `setNumber()`를 호출하여 값을 온체인에 저장합니다: +이제 `setNumber()`를 호출하여 온체인에 값을 저장합니다. ```bash cast send 0xSomeContractAddress "setNumber(uint256)" 42 \ @@ -193,11 +193,11 @@ cast send 0xSomeContractAddress "setNumber(uint256)" 42 \ --private-key $PRIVATE_KEY ``` -이는 트랜잭션을 전송합니다. 상태 변경에 대해 소액의 USDT0 수수료를 지불하는 것입니다. 이제 값 `42`가 Stable 테스트넷의 `number` 변수에 저장됩니다. +이는 트랜잭션을 보냅니다. 당신은 상태 변경에 대해 작은 USDT0 수수료를 지불합니다. 값 `42`는 이제 Stable 테스트넷의 `number` 변수에 저장됩니다. ## 8. 체인에서 상태 읽기 -`number()`를 호출하여 값을 다시 읽어옵니다. 이는 트랜잭션과 가스가 없는 무료 읽기입니다: +`number()`를 호출하여 값을 다시 읽습니다. 이는 무료 읽기이며, 트랜잭션이나 가스가 필요 없습니다. ```bash cast call 0xSomeContractAddress "number()(uint256)" \ @@ -206,35 +206,35 @@ cast call 0xSomeContractAddress "number()(uint256)" \ 예상 출력: -``` +```text 42 ``` -방금 Stable 테스트넷에 쓰고 읽었습니다. 배포, 쓰기, 읽기의 왕복 과정은 EVM 개발의 핵심 루프이며, 다른 EVM 체인과 동일하게 여기서도 작동합니다. +방금 Stable 테스트넷에 쓰고 읽었습니다. 왕복 (배포, 쓰기, 읽기)은 EVM 개발의 핵심 루프이며, 다른 모든 EVM 체인과 동일하게 여기에서도 작동합니다. -## 9. Stablescan에서 배포 검사하기 +## 9. Stablescan에서 배포 검사 -Stable 테스트넷 블록 탐색기를 열고 컨트랙트 주소를 붙여넣으세요: +Stable 테스트넷 블록 탐색기를 열고 계약 주소를 붙여넣습니다. -``` +```text https://testnet.stablescan.xyz ``` -배포 트랜잭션과 방금 수행한 `setNumber` 호출을 볼 수 있습니다. Stablescan은 온체인 상태를 검사하고, 컨트랙트 소스 코드를 검증하고, Stable의 트랜잭션 기록을 읽는 표준 도구입니다. +배포 트랜잭션과 수행한 `setNumber` 호출을 볼 수 있습니다. Stablescan은 온체인 상태를 검사하고, 계약 소스 코드를 확인하고, Stable의 트랜잭션 기록을 읽는 데 사용되는 정식 도구입니다. --- -## 무엇을 만들었나요 +## 구축한 것 -컨트랙트를 배포하고, 상태를 변경하는 트랜잭션을 보내고, 온체인 상태를 읽었습니다. 모두 Stable 테스트넷에서 수행했습니다. 이제 다음을 할 수 있습니다: +Stable 테스트넷에 계약을 배포하고, 상태를 변경하는 트랜잭션을 보내고, 온체인 상태를 읽었습니다. 이제 다음 방법을 알게 되었습니다. -- 표준 RPC 엔드포인트를 사용하여 Foundry(또는 모든 EVM 도구 체인)를 Stable을 대상으로 구성하기 -- USDT0 faucet을 사용하여 지갑 충전하기 -- 가스 토큰인 USDT0로 트랜잭션 비용 지불하기 -- Stablescan에서 작업 검사하기 +- 표준 RPC Endpoint를 사용하여 Stable을 대상으로 Foundry(또는 모든 EVM 툴체인)를 구성하는 방법 +- USDT0 Faucet을 사용하여 지갑에 자금을 지원하는 방법 +- USDT0을 가스 토큰으로 사용하여 트랜잭션 비용을 지불하는 방법 +- Stablescan에서 작업을 검사하는 방법 -## 다음 권장 사항 +## 다음으로 추천하는 사항 -- [**컨트랙트 검증하기**](/ko/how-to/verify-contract) — 사용자가 읽고 상호작용할 수 있도록 소스를 Stablescan에 업로드하세요. -- [**컨트랙트 이벤트 인덱싱하기**](/ko/how-to/index-contract) — ethers.js로 이벤트를 구독하고 과거 로그를 백필하세요. -- [**가스 가격 책정 참조**](/ko/reference/gas-pricing-api) — USDT0 단위 수수료가 어떻게 계산되는지 이해하세요. +- [**계약 확인**](/ko/how-to/verify-contract): 사용자가 소스를 읽고 상호 작용할 수 있도록 Stablescan에 소스를 업로드합니다. +- [**계약 이벤트 인덱싱**](/ko/how-to/index-contract): ethers.js로 이벤트 구독 및 이전 로그를 백필하는 방법. +- [**가스 요금 참조**](/ko/reference/gas-pricing-api): USDT0으로 표시된 수수료가 어떻게 계산되는지 이해합니다. diff --git a/package.json b/package.json index 082fc77..007f17a 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,10 @@ "docs:dev": "vocs dev", "docs:build": "NODE_OPTIONS=--max-old-space-size=6144 vocs build", "docs:preview": "vocs preview", - "i18n:check": "node docs/lib/verify-i18n.mjs" + "i18n:check": "node docs/lib/verify-i18n.mjs", + "style:check": "node docs/lib/verify-style.mjs" }, "dependencies": { - "@anthropic-ai/sdk": "^0.104.2", "lucide-react": "^0.468.0", "react": "^19.0.0", "react-dom": "^19.0.0",