Merge pull request #91 from Xahau/i18n

This commit is contained in:
Ekiserrepé
2026-04-15 09:21:04 +02:00
committed by GitHub
263 changed files with 20870 additions and 749 deletions

View File

@@ -16,6 +16,12 @@ export default defineConfig({
starlight({
title: 'Xahau Docs',
description: 'Documentation for the Xahau blockchain',
defaultLocale: 'root',
locales: {
root: { label: 'English', lang: 'en' },
es: { label: 'Español', lang: 'es' },
ja: { label: '日本語', lang: 'ja' },
},
tableOfContents: {
minHeadingLevel: 1,
maxHeadingLevel: 3,
@@ -69,30 +75,48 @@ export default defineConfig({
sidebar: [
{
label: 'Get started',
translations: { es: 'Primeros pasos', ja: 'はじめる' },
items: ['docs', 'docs/what-is-different'],
},
{
label: 'Features',
translations: { es: 'Características', ja: '機能' },
items: [
'docs/features/public-nodes-rpc',
'docs/features/amendments',
{
label: 'Transaction Signing',
translations: {
es: 'Firma de Transacciones',
ja: 'トランザクション署名',
},
autogenerate: { directory: 'docs/features/transaction-signing' },
collapsed: true,
},
{
label: 'Developer Tooling',
translations: {
es: 'Herramientas para Desarrolladores',
ja: '開発者ツール',
},
autogenerate: { directory: 'docs/features/developer-tooling' },
collapsed: true,
},
{
label: 'HTTP / WebSocket APIs',
translations: {
es: 'APIs HTTP / WebSocket',
ja: 'HTTP / WebSocket API',
},
autogenerate: { directory: 'docs/features/http-websocket-apis' },
collapsed: true,
},
{
label: 'Network Features',
translations: {
es: 'Funcionalidades de Red',
ja: 'ネットワーク機能',
},
autogenerate: { directory: 'docs/features/network-features' },
collapsed: true,
},
@@ -105,14 +129,23 @@ export default defineConfig({
},
{
label: 'Protocol Reference',
translations: {
es: 'Referencia del Protocolo',
ja: 'プロトコルリファレンス',
},
items: [
{
label: 'Transactions',
translations: { es: 'Transacciones', ja: 'トランザクション' },
collapsed: true,
items: [
'docs/protocol-reference/transactions',
{
label: 'Transaction Types',
translations: {
es: 'Tipos de Transacción',
ja: 'トランザクションタイプ',
},
autogenerate: {
directory:
'docs/protocol-reference/transactions/transaction-types',
@@ -121,6 +154,10 @@ export default defineConfig({
},
{
label: 'Pseudo Transaction Types',
translations: {
es: 'Tipos de Pseudotransacción',
ja: '擬似トランザクションタイプ',
},
autogenerate: {
directory:
'docs/protocol-reference/transactions/pseudo-transaction-types',
@@ -129,6 +166,10 @@ export default defineConfig({
},
{
label: 'Transaction Results',
translations: {
es: 'Resultados de Transacción',
ja: 'トランザクション結果',
},
autogenerate: {
directory:
'docs/protocol-reference/transactions/transaction-results',
@@ -141,11 +182,16 @@ export default defineConfig({
},
{
label: 'Ledger Data',
translations: { es: 'Datos del Ledger', ja: 'レジャーデータ' },
collapsed: true,
items: [
'docs/protocol-reference/ledger-data',
{
label: 'Ledger Objects Types',
translations: {
es: 'Tipos de Objetos del Ledger',
ja: 'レジャーオブジェクトタイプ',
},
autogenerate: {
directory:
'docs/protocol-reference/ledger-data/ledger-objects-types',
@@ -158,6 +204,7 @@ export default defineConfig({
},
{
label: 'Data Types',
translations: { es: 'Tipos de Datos', ja: 'データ型' },
collapsed: true,
items: [
'docs/protocol-reference/data-types',
@@ -174,6 +221,7 @@ export default defineConfig({
'docs/hooks',
{
label: 'Concepts',
translations: { es: 'Conceptos', ja: 'コンセプト' },
collapsed: true,
items: [
'docs/hooks/concepts/introduction',
@@ -201,15 +249,21 @@ export default defineConfig({
},
{
label: 'Functions',
translations: { es: 'Funciones', ja: '関数' },
collapsed: true,
items: [
{
label: 'Overview',
translations: { es: 'Descripción General', ja: '概要' },
collapsed: true,
autogenerate: { directory: 'docs/hooks/functions/overview' },
},
{
label: 'Developer Defined',
translations: {
es: 'Definidas por el Desarrollador',
ja: '開発者定義',
},
collapsed: true,
autogenerate: {
directory: 'docs/hooks/functions/developer-defined',
@@ -222,11 +276,16 @@ export default defineConfig({
},
{
label: 'Utilities',
translations: { es: 'Utilidades', ja: 'ユーティリティ' },
collapsed: true,
autogenerate: { directory: 'docs/hooks/functions/utilities' },
},
{
label: 'Serialization',
translations: {
es: 'Serialización',
ja: 'シリアライゼーション',
},
collapsed: true,
autogenerate: {
directory: 'docs/hooks/functions/serialization',
@@ -234,6 +293,10 @@ export default defineConfig({
},
{
label: 'Emitted Transaction',
translations: {
es: 'Transacción Emitida',
ja: '発行トランザクション',
},
collapsed: true,
autogenerate: {
directory: 'docs/hooks/functions/emitted-transaction',
@@ -251,6 +314,10 @@ export default defineConfig({
},
{
label: 'Hook Context',
translations: {
es: 'Contexto del Hook',
ja: 'フックコンテキスト',
},
collapsed: true,
autogenerate: {
directory: 'docs/hooks/functions/hook-context',
@@ -263,11 +330,16 @@ export default defineConfig({
},
{
label: 'State',
translations: { es: 'Estado', ja: '状態' },
collapsed: true,
autogenerate: { directory: 'docs/hooks/functions/state' },
},
{
label: 'Trace (Debug)',
translations: {
es: 'Traza (Debug)',
ja: 'トレース(デバッグ)',
},
collapsed: true,
autogenerate: {
directory: 'docs/hooks/functions/trace-debug',
@@ -275,6 +347,10 @@ export default defineConfig({
},
{
label: 'Originating Transaction',
translations: {
es: 'Transacción de Origen',
ja: '発信トランザクション',
},
collapsed: true,
autogenerate: {
directory: 'docs/hooks/functions/originating-transaction',
@@ -297,6 +373,7 @@ export default defineConfig({
},
{
label: 'Compliance',
translations: { es: 'Cumplimiento', ja: 'コンプライアンス' },
items: [
'docs/compliance/security-audit',
'docs/compliance/responsible-disclosure',
@@ -304,6 +381,7 @@ export default defineConfig({
},
{
label: 'Infrastructure',
translations: { es: 'Infraestructura', ja: 'インフラストラクチャ' },
items: [
'docs/infrastructure/system-requirements',
'docs/infrastructure/installing-xahaud',
@@ -314,6 +392,10 @@ export default defineConfig({
'docs/infrastructure/advanced-configuration',
{
label: 'Build xahaud (Advanced)',
translations: {
es: 'Compilar xahaud (Avanzado)',
ja: 'xahaudをビルド上級',
},
collapsed: true,
items: [
'docs/infrastructure/build-xahaud',
@@ -325,10 +407,12 @@ export default defineConfig({
},
{
label: 'Resources',
translations: { es: 'Recursos', ja: 'リソース' },
items: ['docs/resources/whitepaper', 'docs/resources/media-kit'],
},
{
label: 'Support',
translations: { es: 'Soporte', ja: 'サポート' },
autogenerate: { directory: 'docs/support' },
},
],

View File

@@ -1,79 +1,77 @@
import { getRelativeLocaleUrl } from 'astro:i18n'
import type { CookieConsentConfig } from 'vanilla-cookieconsent'
export const config: CookieConsentConfig = {
guiOptions: {
consentModal: {
layout: 'box',
position: 'bottom left',
equalWeightButtons: true,
flipButtons: false,
export function createCookieConsentConfig(locale: string): CookieConsentConfig {
const privacyPolicyHref = getRelativeLocaleUrl(locale, '/privacy-policy')
return {
guiOptions: {
consentModal: {
layout: 'box',
position: 'bottom left',
equalWeightButtons: true,
flipButtons: false,
},
},
preferencesModal: {
layout: 'box',
position: 'right',
equalWeightButtons: true,
flipButtons: false,
categories: {
necessary: {
readOnly: true,
},
functionality: {
enabled: true,
},
analytics: {
enabled: true,
},
},
},
categories: {
necessary: {
readOnly: true,
},
functionality: {
enabled: true,
},
analytics: {
enabled: true,
},
},
language: {
default: 'en',
translations: {
en: {
consentModal: {
title: 'Select your cookie preferences',
description:
'We use cookies to ensure you get the best experience on our website.',
acceptAllBtn: 'Accept all',
acceptNecessaryBtn: 'Reject all',
showPreferencesBtn: 'Manage preferences',
footer: '<a href="/privacy-policy">Privacy Policy</a>',
},
preferencesModal: {
title: 'Consent Preferences Center',
acceptAllBtn: 'Accept all',
acceptNecessaryBtn: 'Reject all',
savePreferencesBtn: 'Save preferences',
closeIconLabel: 'Close modal',
serviceCounterLabel: 'Service|Services',
sections: [
{
title:
'Strictly Necessary Cookies <span class="pm__badge">Always Enabled</span>',
description:
'Some cookies are essential in order to use the website and use some of its features.',
linkedCategory: 'necessary',
},
{
title: 'Functionality Cookies',
description:
'These cookies are used to enhance the performance and functionality of the website but are non-essential to their use. However, without these cookies, certain functionality (like videos) may become unavailable.',
linkedCategory: 'functionality',
},
{
title: 'Analytics Cookies',
description:
'We use analytics cookies to understand how you use our website so we can improve it.',
linkedCategory: 'analytics',
},
{
title: 'More information',
description:
'For any query in relation to the policy on cookies and your choices, please refer to the <a class="cc__link" href="/privacy-policy">Privacy Policy</a>.',
},
],
language: {
default: 'en',
translations: {
en: {
consentModal: {
title: 'Select your cookie preferences',
description:
'We use cookies to ensure you get the best experience on our website.',
acceptAllBtn: 'Accept all',
acceptNecessaryBtn: 'Reject all',
showPreferencesBtn: 'Manage preferences',
footer: `<a href="${privacyPolicyHref}">Privacy Policy</a>`,
},
preferencesModal: {
title: 'Consent Preferences Center',
acceptAllBtn: 'Accept all',
acceptNecessaryBtn: 'Reject all',
savePreferencesBtn: 'Save preferences',
closeIconLabel: 'Close modal',
serviceCounterLabel: 'Service|Services',
sections: [
{
title:
'Strictly Necessary Cookies <span class="pm__badge">Always Enabled</span>',
description:
'Some cookies are essential in order to use the website and use some of its features.',
linkedCategory: 'necessary',
},
{
title: 'Functionality Cookies',
description:
'These cookies are used to enhance the performance and functionality of the website but are non-essential to their use. However, without these cookies, certain functionality (like videos) may become unavailable.',
linkedCategory: 'functionality',
},
{
title: 'Analytics Cookies',
description:
'We use analytics cookies to understand how you use our website so we can improve it.',
linkedCategory: 'analytics',
},
{
title: 'More information',
description: `For any query in relation to the policy on cookies and your choices, please refer to the <a class="cc__link" href="${privacyPolicyHref}">Privacy Policy</a>.`,
},
],
},
},
},
},
},
}
}

View File

@@ -1,11 +1,14 @@
---
import 'vanilla-cookieconsent/dist/cookieconsent.css'
---
<script>
import { run } from 'vanilla-cookieconsent'
import { config } from '../CookieConsentConfig'
import { createCookieConsentConfig } from '../CookieConsentConfig'
run(config)
const locale = (Astro.currentLocale ?? 'en') as 'en' | 'es' | 'ja'
const cookieConsentConfig = createCookieConsentConfig(locale)
---
<script define:vars={{ cookieConsentConfig }}>
import { run } from 'vanilla-cookieconsent'
run(cookieConsentConfig)
document.body.classList.add('cc--darkmode')
</script>

View File

@@ -1,6 +1,73 @@
---
import { Image } from 'astro:assets'
import { getRelativeLocaleUrl } from 'astro:i18n'
import logo from '../assets/xahau-logo.svg'
const locale = Astro.currentLocale ?? 'en'
const translations = {
en: {
tagline: 'This website is open source and open for contributions',
on: 'on',
about: 'About',
features: 'Features',
ecosystem: 'Ecosystem',
roadmap: 'Roadmap',
break: 'Break Xahau',
fraud: 'Report Fraud',
media: 'Media kit',
privacy: 'Privacy Policy',
docs: 'Documentation',
getstarted: 'Get started',
protocol: 'Protocol Reference',
infra: 'Infrastructure',
connect: 'Connect',
events: 'Events',
discord: 'Community Discord',
},
es: {
tagline:
'Este sitio web es de código abierto y está abierto a contribuciones',
on: 'en',
about: 'Acerca de',
features: 'Características',
ecosystem: 'Ecosistema',
roadmap: 'Hoja de ruta',
break: 'Break Xahau',
fraud: 'Reportar Fraude',
media: 'Kit de Prensa',
privacy: 'Política de Privacidad',
docs: 'Documentación',
getstarted: 'Primeros pasos',
protocol: 'Referencia de Protocolo',
infra: 'Infraestructura',
connect: 'Conectar',
events: 'Eventos',
discord: 'Discord de la Comunidad',
},
ja: {
tagline:
'このウェブサイトはオープンソースで、コントリビューションを受け付けています',
on: 'にて',
about: 'Xahauについて',
features: '機能',
ecosystem: 'エコシステム',
roadmap: 'ロードマップ',
break: 'Break Xahau',
fraud: '不正を報告',
media: 'メディアキット',
privacy: 'プライバシーポリシー',
docs: 'ドキュメント',
getstarted: 'はじめる',
protocol: 'プロトコルリファレンス',
infra: 'インフラストラクチャ',
connect: 'コネクト',
events: 'イベント',
discord: 'コミュニティDiscord',
},
}
const t = translations[locale as 'en' | 'es' | 'ja'] || translations.en
---
<footer
class="bg-white text-base font-regular text-black **:text-black **:no-underline"
@@ -9,13 +76,13 @@
class="flex-none container mx-auto py-12 max-w-7xl p-6 grid grid-cols-1 md:grid-cols-10 gap-4"
>
<div class="col-span-1 md:col-span-3 flex flex-col gap-3">
<a href="/">
<a href={getRelativeLocaleUrl(locale, '/')}>
<Image src={logo} class="w-1/2" alt="Xahau"/>
</a>
<p>
This website is open source and open for contributions
{t.tagline}
<a href="https://github.com/Xahau/xahau-web" target="_blank"
>on GitHub</a
>{t.on}GitHub</a
>
</p>
</div>
@@ -23,36 +90,52 @@
<p>
<strong>Xahau</strong>
</p>
<a href="/about">About</a>
<a href="/features">Features</a>
<a href="/ecosystem">Ecosystem</a>
<a href="/roadmap">Roadmap</a>
<a href="/docs/compliance/responsible-disclosure">Break Xahau</a>
<a href="/fraud-report">Report Fraud</a>
<a href="/docs/resources/media-kit">Media kit</a>
<a href="/privacy-policy">Privacy Policy</a>
<a href={getRelativeLocaleUrl(locale, '/about')}>{t.about}</a>
<a href={getRelativeLocaleUrl(locale, '/features')}>{t.features}</a>
<a href={getRelativeLocaleUrl(locale, '/ecosystem')}>{t.ecosystem}</a>
<a href={getRelativeLocaleUrl(locale, '/roadmap')}>{t.roadmap}</a>
<a
href={getRelativeLocaleUrl(locale, '/docs/compliance/responsible-disclosure')}
>
{t.break}
</a>
<a href={getRelativeLocaleUrl(locale, '/fraud-report')}>{t.fraud}</a>
<a href={getRelativeLocaleUrl(locale, '/docs/resources/media-kit')}>
{t.media}
</a>
<a href={getRelativeLocaleUrl(locale, '/privacy-policy')}>{t.privacy}</a>
</div>
<div class="col-span-1 md:col-span-2 flex flex-col gap-3">
<p>
<strong>Documentation</strong>
<strong>{t.docs}</strong>
</p>
<a href="/docs">Get started</a>
<a href="/docs/protocol-reference/transactions">Protocol Reference</a>
<a href="/docs/hooks">Hooks</a>
<a href="/docs/data-apis">Data APIs</a>
<a href="/docs/infrastructure/system-requirements">Infrastructure</a>
<a href="/docs/resources/whitepaper">Whitepaper</a>
<a href={getRelativeLocaleUrl(locale, '/docs')}>{t.getstarted}</a>
<a
href={getRelativeLocaleUrl(locale, '/docs/protocol-reference/transactions')}
>
{t.protocol}
</a>
<a href={getRelativeLocaleUrl(locale, '/docs/hooks')}>Hooks</a>
<a href={getRelativeLocaleUrl(locale, '/docs/data-apis')}>Data APIs</a>
<a
href={getRelativeLocaleUrl(locale, '/docs/infrastructure/system-requirements')}
>
{t.infra}
</a>
<a href={getRelativeLocaleUrl(locale, '/docs/resources/whitepaper')}>
Whitepaper
</a>
</div>
<div class="col-span-1 md:col-span-2 flex flex-col gap-3">
<p>
<strong>Connect</strong>
<strong>{t.connect}</strong>
</p>
<a href="/connect">Events</a>
<a href="/contest">Dev Contest</a>
<a href={getRelativeLocaleUrl(locale, '/connect')}>{t.events}</a>
<a href={getRelativeLocaleUrl(locale, '/contest')}>Dev Contest</a>
<a href="https://x.com/XahauNetwork" target="_blank">X</a>
<a href="https://github.com/Xahau" target="_blank">GitHub</a>
<a href="https://discord.com/invite/UzU58haAn4" target="_blank">
Community Discord
{t.discord}
</a>
</div>
</div>

View File

@@ -0,0 +1,413 @@
---
import '../styles/main.css'
import type { FraudReportTranslations } from '../i18n/fraudReportTranslations'
import PageLayout from '../layouts/PageLayout.astro'
import PageSection from './PageSection.astro'
const { t } = Astro.props as { t: FraudReportTranslations }
---
<PageLayout frontmatter={t.frontmatter} wide="true">
<PageSection align="center">
<p>{t.intro.body}</p>
<div class="p-4 bg-green-50 border border-green-200 rounded-lg my-4">
<strong>{t.intro.warning}</strong>
</div>
<p>{t.intro.lead}</p>
<ul class="list-disc list-outside">
{t.intro.bullets.map((bullet) => <li>{bullet}</li>)}
</ul>
{
t.intro.steps.map((step) => (
<>
<h3 class="mt-4">{step.title}</h3>
<p>{step.body}</p>
</>
))
}
<h2 class="mt-4">{t.intro.expectationTitle}</h2>
<ul class="list-disc list-outside">
{t.intro.expectations.map((expectation) => <li>{expectation}</li>)}
</ul>
<div class="p-4 bg-green-50 border border-green-200 rounded-lg my-4">
<strong>{t.intro.expectationWarning}</strong>
</div>
</PageSection>
<main class="page-content flex-1 container mx-auto max-w-4xl p-6">
<div class="bg-white rounded-lg shadow-lg p-8">
<div
id="success-message"
class="mb-6 p-6 bg-green-50 border-2 border-green-500 text-green-800 rounded-lg hidden shadow-md"
>
<div class="flex items-center mb-2">
<svg
class="w-6 h-6 mr-2 text-green-500"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clip-rule="evenodd"
/>
</svg>
<p class="font-bold text-lg">{t.form.successTitle}</p>
</div>
<p class="mb-2">{t.form.successBody}</p>
<p class="text-sm mt-3 font-semibold">
{t.form.reportIdLabel}
<code
id="report-id"
class="bg-green-200 px-3 py-1 rounded text-green-900"
/>
</p>
</div>
<div
id="error-message"
class="mb-6 p-6 bg-red-50 border-2 border-red-500 text-red-800 rounded-lg hidden shadow-md"
>
<div class="flex items-center mb-2">
<svg
class="w-6 h-6 mr-2 text-red-500"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
clip-rule="evenodd"
/>
</svg>
<p class="font-bold text-lg">{t.form.errorTitle}</p>
</div>
<p id="error-text" class="whitespace-pre-wrap"></p>
</div>
<div id="form-container">
<form id="fraud-report-form" class="space-y-6">
<div>
<label
for="address"
class="block text-sm font-semibold text-gray-700 mb-2"
>
{t.form.addressLabel}
<span class="text-red-500">*</span>
</label>
<input
type="text"
id="address"
name="address"
required
placeholder={t.form.addressPlaceholder}
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-xahau-green focus:border-transparent transition-all"
>
<p class="text-sm text-gray-500 mt-1">{t.form.addressHint}</p>
</div>
<div>
<label
for="description"
class="block text-sm font-semibold text-gray-700 mb-2"
>
{t.form.descriptionLabel}
<span class="text-red-500">*</span>
</label>
<textarea
id="description"
name="description"
required
rows="6"
placeholder={t.form.descriptionPlaceholder}
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-xahau-green focus:border-transparent transition-all"
></textarea>
<p class="text-sm text-gray-500 mt-1">{t.form.descriptionHint}</p>
</div>
<div>
<label
for="url"
class="block text-sm font-semibold text-gray-700 mb-2"
>
{t.form.urlLabel}
<span class="text-gray-400 text-xs">({t.form.optional})</span>
</label>
<input
type="url"
id="url"
name="url"
placeholder={t.form.urlPlaceholder}
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-xahau-green focus:border-transparent transition-all"
>
<p class="text-sm text-gray-500 mt-1">{t.form.urlHint}</p>
</div>
<div>
<label
for="category_suggested"
class="block text-sm font-semibold text-gray-700 mb-2"
>
{t.form.categoryLabel}
<span class="text-gray-400 text-xs">({t.form.optional})</span>
</label>
<select
id="category_suggested"
name="category_suggested"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-xahau-green focus:border-transparent transition-all bg-white"
>
<option value="">{t.form.categoryPlaceholder}</option>
{
t.form.categoryOptions.map((option) => (
<option value={option.value}>{option.label}</option>
))
}
</select>
<p class="text-sm text-gray-500 mt-1">{t.form.categoryHint}</p>
</div>
<div>
<label
for="reporter_contact"
class="block text-sm font-semibold text-gray-700 mb-2"
>
{t.form.contactLabel}
<span class="text-gray-400 text-xs">({t.form.optional})</span>
</label>
<input
type="text"
id="reporter_contact"
name="reporter_contact"
placeholder={t.form.contactPlaceholder}
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-xahau-green focus:border-transparent transition-all"
>
<p class="text-sm text-gray-500 mt-1">{t.form.contactHint}</p>
</div>
<div class="bg-gray-50 p-4 rounded-lg border border-gray-200">
<altcha-widget
name="altcha"
challengeurl="https://api.analytics.xahau.network/captcha/challenge"
hidefooter="false"
hidelogo="false"
></altcha-widget>
</div>
<div class="flex items-center justify-between pt-4">
<p class="text-sm text-gray-600">
<span class="text-red-500">*</span>
{t.form.requiredFields}
</p>
<button
type="submit"
class="px-8 py-3 bg-xahau-green-dark text-white font-semibold rounded-lg hover:bg-xahau-green transition-all transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-xahau-green focus:ring-offset-2"
>
{t.form.submitLabel}
</button>
</div>
</form>
<div id="another-report-btn" class="mt-6 hidden">
<button
onclick="location.reload()"
class="inline-block px-6 py-3 bg-xahau-green-dark text-white font-semibold rounded-lg hover:bg-xahau-green transition-all no-underline"
>
{t.form.submitAnotherLabel}
</button>
</div>
</div>
</div>
<div class="mt-8 bg-blue-50 border border-blue-200 rounded-lg p-6 pt-0">
<h3 class="text-lg font-semibold text-blue-900 mb-3">
{t.privacy.title}
</h3>
<ul class="space-y-2 text-sm text-blue-800">
{
t.privacy.bullets.map((bullet) => (
<li class="flex items-start">
<svg
class="w-5 h-5 mr-2 mt-0.5 flex-shrink-0"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clip-rule="evenodd"
/>
</svg>
<span>{bullet}</span>
</li>
))
}
</ul>
</div>
<div class="mt-6 text-center text-sm text-gray-600">
<p>
{t.attribution.prefix}
<a
href="https://inftf.org"
class="text-xahau-green-dark underline hover:text-black"
>
{t.attribution.label}
</a>
{t.attribution.suffix}
</p>
</div>
</main>
<script
define:vars={{
messages: {
...t.messages,
reportIdFallback: t.form.reportIdFallback,
},
}}
is:inline
type="module"
>
import 'https://cdn.jsdelivr.net/npm/altcha/dist/altcha.min.js'
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('fraud-report-form')
const altchaWidget = document.querySelector('altcha-widget')
const successMessage = document.getElementById('success-message')
const errorMessage = document.getElementById('error-message')
const errorText = document.getElementById('error-text')
const reportIdEl = document.getElementById('report-id')
const formContainer = document.getElementById('form-container')
const anotherReportBtn = document.getElementById('another-report-btn')
if (!form || !altchaWidget) {
return
}
const scrollCardIntoView = () => {
const card = document.querySelector('.bg-white.rounded-lg.shadow-lg')
if (card) {
card.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
}
let isVerified = false
altchaWidget.addEventListener('statechange', (event) => {
isVerified = event.detail.state === 'verified'
})
form.addEventListener('submit', async (e) => {
e.preventDefault()
errorMessage.classList.add('hidden')
successMessage.classList.add('hidden')
if (!isVerified) {
errorText.textContent = messages.captchaIncomplete
errorMessage.classList.remove('hidden')
scrollCardIntoView()
return
}
let altchaSolution = null
const formData = new FormData(form)
altchaSolution = formData.get('altcha')
if (!altchaSolution) {
const hiddenInput = form.querySelector('input[name="altcha"]')
if (hiddenInput) {
altchaSolution = hiddenInput.value
}
}
if (!altchaSolution) {
altchaSolution = altchaWidget.dataset.payload
}
if (!altchaSolution) {
errorText.textContent = messages.captchaFailed
errorMessage.classList.remove('hidden')
scrollCardIntoView()
return
}
const requestBody = {
address: formData.get('address'),
description: formData.get('description'),
altcha_solution: altchaSolution,
}
if (formData.get('url')) requestBody.url = formData.get('url')
if (formData.get('category_suggested')) {
requestBody.category_suggested = formData.get('category_suggested')
}
if (formData.get('reporter_contact')) {
requestBody.reporter_contact = formData.get('reporter_contact')
}
const submitBtn = form.querySelector('button[type="submit"]')
const originalText = submitBtn.textContent
submitBtn.disabled = true
submitBtn.innerHTML = `<span class="flex items-center justify-center"><svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>${messages.submitting}</span>`
try {
const response = await fetch(
'https://api.analytics.xahau.network/ufr',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
},
)
const result = await response.json()
if (response.ok) {
reportIdEl.textContent =
result.reportId || messages.reportIdFallback
successMessage.classList.remove('hidden')
errorMessage.classList.add('hidden')
formContainer.style.display = 'none'
anotherReportBtn.classList.remove('hidden')
scrollCardIntoView()
} else {
const errorMsg = Array.isArray(result.message)
? result.message.join(', ')
: result.message || messages.submitFailed
errorText.textContent = errorMsg
errorMessage.classList.remove('hidden')
successMessage.classList.add('hidden')
submitBtn.disabled = false
submitBtn.innerHTML = originalText
scrollCardIntoView()
}
} catch (_error) {
errorText.textContent = messages.networkError
errorMessage.classList.remove('hidden')
successMessage.classList.add('hidden')
submitBtn.disabled = false
submitBtn.innerHTML = originalText
scrollCardIntoView()
}
})
})
</script>
<style>
altcha-widget {
--altcha-primary-color: #007b3d;
--altcha-background-color: #ffffff;
--altcha-border-color: #e1e5e9;
--altcha-text-color: #333333;
--altcha-border-radius: 8px;
--altcha-font-family:
'Onest', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
sans-serif;
}
</style>
</PageLayout>

View File

@@ -1,5 +1,6 @@
'use client'
import { getRelativeLocaleUrl } from 'astro:i18n'
import {
Dialog,
DialogPanel,
@@ -14,49 +15,66 @@ import {
import {
Bars3Icon,
ChevronDownIcon,
GlobeAltIcon,
XMarkIcon,
} from '@heroicons/react/20/solid'
import { useState } from 'react'
const socials = [
{ name: 'Events', href: '/connect' },
{ name: 'Dev Contest', href: '/contest' },
{ name: 'X', href: 'https://x.com/XahauNetwork' },
{ name: 'GitHub', href: 'https://github.com/Xahau' },
{ name: 'Community Discord', href: 'https://discord.com/invite/UzU58haAn4' },
]
const docs = [
{ name: 'Get started', href: '/docs' },
{ name: 'Protocol Reference', href: '/docs/protocol-reference/transactions' },
{ name: 'Hooks', href: '/docs/hooks' },
{ name: 'Data APIs', href: '/docs/data-apis' },
{ name: 'Infrastructure', href: '/docs/infrastructure/system-requirements' },
{ name: 'Whitepaper', href: '/docs/resources/whitepaper' },
]
const explorers = [
{ name: 'XAHSCAN', href: 'https://xahscan.com/' },
{ name: 'Bithomp Xahau Explorer', href: 'https://xahauexplorer.com/en' },
{ name: 'XRPLWin Xahau Explorer', href: 'https://xahau.xrplwin.com/' },
{ name: 'Technical Explorer', href: 'https://explorer.xahau.network/' },
]
// Navigation items definition shared between desktop and mobile
const navItems = [
{ name: 'About', href: '/about', urlPattern: 'about' },
{ name: 'Features', href: '/features', urlPattern: 'features' },
{ name: 'Ecosystem', href: '/ecosystem', urlPattern: 'ecosystem' },
{ name: 'Roadmap', href: '/roadmap', urlPattern: 'roadmap' },
{ name: 'Documentation', children: docs, urlPattern: 'docs' },
{ name: 'Connect', children: socials },
{ name: 'Explorers', children: explorers },
]
import logo from '../assets/xahau-logo.svg'
import { getAlternateLocaleHref } from '../utils/localizedHref'
const XahauLogo = () => (
<a href="/" className="-m-1.5 p-1.5">
const languages = [
{ code: 'en', label: 'English' },
{ code: 'es', label: 'Español' },
// { code: 'ja', label: '日本語' },
]
const nav = {
en: {
about: 'About',
features: 'Features',
ecosystem: 'Ecosystem',
roadmap: 'Roadmap',
docs: 'Documentation',
connect: 'Connect',
explorers: 'Explorers',
events: 'Events',
getstarted: 'Get started',
protocol: 'Protocol Reference',
infra: 'Infrastructure',
discord: 'Community Discord',
},
es: {
about: 'Acerca de',
features: 'Características',
ecosystem: 'Ecosistema',
roadmap: 'Hoja de ruta',
docs: 'Documentación',
connect: 'Conectar',
explorers: 'Exploradores',
events: 'Eventos',
getstarted: 'Primeros pasos',
protocol: 'Referencia de Protocolo',
infra: 'Infraestructura',
discord: 'Discord de la Comunidad',
},
ja: {
about: 'Xahauについて',
features: '機能',
ecosystem: 'エコシステム',
roadmap: 'ロードマップ',
docs: 'ドキュメント',
connect: 'コネクト',
explorers: 'エクスプローラー',
events: 'イベント',
getstarted: 'はじめる',
protocol: 'プロトコルリファレンス',
infra: 'インフラストラクチャ',
discord: 'コミュニティDiscord',
},
}
const XahauLogo = ({ href }) => (
<a href={href} className="-m-1.5 p-1.5">
<span className="sr-only">Xahau</span>
<img src={logo.src} width="222" height="40" alt="Xahau Logo" />
</a>
@@ -65,6 +83,92 @@ const XahauLogo = () => (
export default function Header(props) {
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
const pathname = props.url.pathname
const currentLocale = props.locale || 'en'
const t = nav[currentLocale] || nav.en
function langUrl(code) {
return getAlternateLocaleHref(pathname, code)
}
const socials = [
{ name: t.events, href: getRelativeLocaleUrl(currentLocale, '/connect') },
{
name: 'Dev Contest',
href: getRelativeLocaleUrl(currentLocale, '/contest'),
},
{ name: 'X', href: 'https://x.com/XahauNetwork' },
{ name: 'GitHub', href: 'https://github.com/Xahau' },
{ name: t.discord, href: 'https://discord.com/invite/UzU58haAn4' },
]
const docs = [
{ name: t.getstarted, href: getRelativeLocaleUrl(currentLocale, '/docs') },
{
name: t.protocol,
href: getRelativeLocaleUrl(
currentLocale,
'/docs/protocol-reference/transactions',
),
},
{ name: 'Hooks', href: getRelativeLocaleUrl(currentLocale, '/docs/hooks') },
{
name: 'Data APIs',
href: getRelativeLocaleUrl(currentLocale, '/docs/data-apis'),
},
{
name: t.infra,
href: getRelativeLocaleUrl(
currentLocale,
'/docs/infrastructure/system-requirements',
),
},
{
name: 'Whitepaper',
href: getRelativeLocaleUrl(currentLocale, '/docs/resources/whitepaper'),
},
]
const explorers = [
{ name: 'XAHSCAN', href: 'https://xahscan.com/' },
{ name: 'Bithomp Xahau Explorer', href: 'https://xahauexplorer.com/en' },
{ name: 'XRPLWin Xahau Explorer', href: 'https://xahau.xrplwin.com/' },
{ name: 'Technical Explorer', href: 'https://explorer.xahau.network/' },
]
const navItems = [
{
name: t.about,
href: getRelativeLocaleUrl(currentLocale, '/about'),
urlPattern: 'about',
},
{
name: t.features,
href: getRelativeLocaleUrl(currentLocale, '/features'),
urlPattern: 'features',
},
{
name: t.ecosystem,
href: getRelativeLocaleUrl(currentLocale, '/ecosystem'),
urlPattern: 'ecosystem',
},
{
name: t.roadmap,
href: getRelativeLocaleUrl(currentLocale, '/roadmap'),
urlPattern: 'roadmap',
},
{ name: t.docs, children: docs, urlPattern: 'docs' },
{ name: t.connect, children: socials },
{ name: t.explorers, children: explorers },
]
const pathSegments = pathname.slice(1).split('/')
const activeSegment =
currentLocale !== 'en' ? pathSegments[1] : pathSegments[0]
const dropdownItemClass =
'group relative flex items-center gap-x-6 p-2 text-sm/6'
return (
<header className="header bg-xahau-background z-20">
<nav
@@ -72,7 +176,7 @@ export default function Header(props) {
className="mx-auto flex max-w-7xl items-center justify-between p-6"
>
<div className="flex lg:flex-1">
<XahauLogo />
<XahauLogo href={getRelativeLocaleUrl(currentLocale, '/')} />
</div>
<div className="flex lg:hidden">
<button
@@ -84,13 +188,12 @@ export default function Header(props) {
<Bars3Icon aria-hidden="true" className="size-6" />
</button>
</div>
{/* Desktop navigation */}
<PopoverGroup className="hidden lg:flex lg:gap-x-12">
<PopoverGroup className="hidden lg:flex lg:gap-x-12 lg:items-center">
{navItems.map((navItem) => {
const isActive =
navItem.urlPattern &&
props.url.pathname.slice(1).split('/')[0] === navItem.urlPattern
// Single link item
navItem.urlPattern && activeSegment === navItem.urlPattern
if (navItem.href) {
return (
<a
@@ -102,7 +205,6 @@ export default function Header(props) {
</a>
)
}
// Dropdown item
return (
<Popover key={navItem.name} className="relative">
<PopoverButton
@@ -128,9 +230,7 @@ export default function Header(props) {
}
className="no-underline block font-regular text-white"
>
<div className="group relative flex items-center gap-x-6 p-2 text-sm/6">
{item.name}
</div>
<div className={dropdownItemClass}>{item.name}</div>
</a>
))}
</div>
@@ -138,8 +238,43 @@ export default function Header(props) {
</Popover>
)
})}
{/* Language switcher */}
<Popover className="relative">
<PopoverButton
className="no-underline p-0 border-none text-black flex items-center gap-x-1 bg-transparent hover:cursor-pointer"
aria-label="Select language"
>
<GlobeAltIcon className="size-5 text-black" />
<ChevronDownIcon
aria-hidden="true"
className="size-4 flex-none text-black"
/>
</PopoverButton>
<PopoverPanel
transition
className="absolute right-0 z-10 mt-3 w-40 overflow-hidden bg-xahau-gray shadow-lg ring-1 ring-gray-900/5 transition data-closed:translate-y-1 data-closed:opacity-0 data-enter:duration-200 data-enter:ease-out data-leave:duration-150 data-leave:ease-in"
>
<div className="p-2">
{languages.map((lang) => (
<a
key={lang.code}
href={langUrl(lang.code)}
className={`no-underline flex items-center gap-x-2 px-3 py-2 text-sm text-white hover:bg-white/10 ${currentLocale === lang.code ? 'font-bold' : 'font-regular'}`}
>
<span>{lang.label}</span>
{currentLocale === lang.code && (
<span className="ml-auto"></span>
)}
</a>
))}
</div>
</PopoverPanel>
</Popover>
</PopoverGroup>
</nav>
{/* Mobile menu */}
<Dialog
open={mobileMenuOpen}
onClose={setMobileMenuOpen}
@@ -148,7 +283,7 @@ export default function Header(props) {
<div className="fixed inset-0 z-50" />
<DialogPanel className="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-white p-6 sm:max-w-sm sm:ring-1 sm:ring-gray-900/10">
<div className="flex items-center justify-between">
<XahauLogo />
<XahauLogo href={getRelativeLocaleUrl(currentLocale, '/')} />
<button
type="button"
onClick={() => setMobileMenuOpen(false)}
@@ -163,10 +298,7 @@ export default function Header(props) {
<div className="space-y-2 py-6">
{navItems.map((navItem) => {
const isActive =
navItem.urlPattern &&
props.url.pathname.slice(1).split('/')[0] ===
navItem.urlPattern
// Single link item
navItem.urlPattern && activeSegment === navItem.urlPattern
if (navItem.href) {
return (
<a
@@ -178,7 +310,6 @@ export default function Header(props) {
</a>
)
}
// Dropdown item
return (
<Disclosure key={navItem.name} as="div" className="-mx-3">
<DisclosureButton
@@ -211,6 +342,36 @@ export default function Header(props) {
)
})}
</div>
{/* Mobile language selector */}
<div className="py-6">
<Disclosure as="div" className="-mx-3">
<DisclosureButton className="border-none rounded-lg py-2 text-base/7 hover:bg-gray-50 text-black bg-transparent group flex w-full items-center justify-between pr-3.5 pl-3 font-regular no-underline">
<span className="flex items-center gap-x-2">
<GlobeAltIcon className="size-5 text-black" />
{languages.find((l) => l.code === currentLocale)?.label}
</span>
<ChevronDownIcon
aria-hidden="true"
className="size-5 flex-none group-data-open:rotate-180"
/>
</DisclosureButton>
<DisclosurePanel className="mt-2 space-y-1">
{languages.map((lang) => (
<a
key={lang.code}
href={langUrl(lang.code)}
className={`no-underline flex items-center gap-x-2 rounded-lg py-2 pr-3 pl-6 text-sm/7 text-black hover:bg-gray-50 ${currentLocale === lang.code ? 'font-bold' : 'font-regular'}`}
>
<span>{lang.label}</span>
{currentLocale === lang.code && (
<span className="ml-auto text-xs"></span>
)}
</a>
))}
</DisclosurePanel>
</Disclosure>
</div>
</div>
</div>
</DialogPanel>

View File

@@ -0,0 +1,69 @@
---
title: Divulgación Responsable
description: >-
Nuestra Política de Divulgación Responsable proporciona directrices claras para enviar
informes a través de nuestro portal de soporte, garantizando la confidencialidad.
---
import { Aside } from '@astrojs/starlight/components';
### Política de Divulgación Responsable
En Xahau, creemos que la seguridad de nuestros sistemas es extremadamente importante.
A pesar de nuestra preocupación por la seguridad de nuestros sistemas durante el desarrollo y mantenimiento de productos, siempre existe la posibilidad de que alguien encuentre algo que necesitemos mejorar/actualizar/cambiar/arreglar /...
Agradecemos que nos notifiques si has encontrado un punto débil en alguno de nuestros sistemas lo antes posible para que podamos tomar medidas inmediatamente para proteger a nuestros clientes y sus datos.
### Cómo reportar
Si crees que has encontrado un problema de seguridad en uno de nuestros sistemas, notifícanos lo antes posible publicando una **descripción general de alto nivel de tu hallazgo y tu información de contacto (para que alguien pueda comunicarse contigo) en Github:** [**https://github.com/Xahau/xahaud/issues**](https://github.com/Xahau/xahaud/issues)
### Reglas
Esta política de divulgación responsable no es una invitación abierta a escanear activamente nuestra red y aplicaciones en busca de vulnerabilidades. Nuestro monitoreo continuo probablemente detectará tus escaneos, y estos serán investigados.
#### Te pedimos que:
* No compartas información sobre el problema de seguridad con otros hasta que el problema esté resuelto, y que elimines inmediatamente cualquier dato confidencial obtenido
* No abuses del problema, por ejemplo, descargando más datos de los necesarios para demostrar la filtración o para ver, eliminar o modificar datos de terceros
* Proporciones información detallada para que podamos reproducir, validar y resolver el problema lo antes posible. Incluye tus datos de prueba, marcas de tiempo y URL(s) de los sistemas involucrados
* Dejes tus datos de contacto (dirección de correo electrónico y/o número de teléfono) para que podamos contactarte sobre el progreso de la solución. Aceptamos informes anónimos
* No utilices ataques a la seguridad física, ingeniería social, denegación de servicio distribuida, spam o aplicaciones de terceros
### Procedimiento(s) de divulgación responsable
#### Cuando reportes un problema de seguridad, actuaremos de la siguiente manera:
* Recibirás una confirmación de recepción dentro de los 4 días laborables posteriores al envío del informe
* Recibirás una respuesta con la evaluación del problema de seguridad y una fecha estimada de resolución dentro de los 4 días laborables posteriores a la confirmación de recepción
* No tomaremos acciones legales contra ti en relación con el informe si has cumplido las condiciones establecidas anteriormente
* Trataremos tu informe de manera confidencial y no compartiremos tus datos con terceros sin tu permiso, salvo que sea necesario para cumplir con una obligación legal
#### Este esquema de divulgación responsable no está destinado a:
* Quejas
* Informes de sitios web no disponibles
* Informes de phishing
* Informes de fraude
Para estas quejas o informes, publica una **descripción general de alto nivel de tu problema y tu información de contacto (para que alguien pueda comunicarse contigo) en Github:** [**https://github.com/Xahau/xahaud/issues**](https://github.com/Xahau/xahaud/issues)
### Programa de recompensas (bug bounty)
Xahau fomenta el reporte de problemas de seguridad o vulnerabilidades. Podemos ofrecer una recompensa adecuada por la divulgación confidencial de cualquier problema de diseño o implementación que pueda ser utilizado para comprometer la confidencialidad o integridad de los datos de nuestros usuarios y que aún no conocíamos. Decidimos si el informe es elegible y la cantidad de la recompensa.
### Exclusiones
#### Se excluyen los siguientes tipos de problemas de seguridad:
* Ataques (D)DOS
* Mensajes o páginas de error sin datos sensibles
* Pruebas y datos de ejemplo disponibles públicamente en nuestros repositorios de Github
* Problemas comunes como advertencias de cabeceras del navegador o configuración DNS, identificados por escáneres de vulnerabilidades
* Informes de escaneos de vulnerabilidades para software que usamos públicamente
* Problemas de seguridad relacionados con sistemas operativos, navegadores o plugins desactualizados
* Informes de problemas de seguridad de los que ya hemos sido notificados previamente
Ten en cuenta: Los informes que carezcan de pruebas (como capturas de pantalla u otros datos), información detallada o detalles sobre cómo reproducir resultados inesperados serán investigados, pero no serán elegibles para ninguna recompensa.
Esta política se basa en las Directrices de Divulgación Responsable del Centro Nacional de Ciberseguridad y en un [ejemplo de Floor Terra](https://responsibledisclosure.nl/).

View File

@@ -0,0 +1,24 @@
---
title: Auditorías de Seguridad
---
import { Aside } from '@astrojs/starlight/components';
La enmienda Hooks, parte integral de la infraestructura de contratos inteligentes de XRPL, ha superado una auditoría de seguridad detallada realizada por FYEO. La auditoría examinó la implementación del framework de Hooks, incluyendo la API de Hooks, funciones auxiliares y el entorno de ejecución.
Sin detectarse problemas de seguridad graves y con todos los problemas menores resueltos, esta auditoría sirve como testimonio de nuestro compromiso con la seguridad y la solidez de Hooks.
Al permitir lógica de transacciones inteligentes directamente en la Capa 1 de XRPL, Hooks aporta una mayor flexibilidad para adaptar las aplicaciones a sus necesidades específicas, inspirando una mayor innovación dentro del ecosistema XRPL.
Los desarrolladores ahora cuentan con herramientas robustas para crear y desplegar lógica personalizada, accesibles en nuestra testnet.
### **Garantía de Seguridad Continua**
La finalización exitosa de la auditoría no es solo un hito, sino una base fundamental para la seguridad y sostenibilidad continuas de la red Hooks.
Con todas las vulnerabilidades identificadas resueltas, la enmienda Hooks está preparada para impulsar la innovación de forma segura en Xahau.
<Aside type="note">
La auditoría de seguridad completa puede encontrarse [**aquí**](https://xrpl-labs.com/static/misc/Security%20Assessment%20of%20the%20XRP%20Labs%20Hooks%20Amendment%20v1.0.pdf).
</Aside>
¡Hacia un futuro más brillante e innovador con Xahau!

View File

@@ -0,0 +1,5 @@
---
title: "APIs de Datos"
---
La API principal de datos se encuentra en https://data.xahau.network/

View File

@@ -0,0 +1,184 @@
---
title: Enmiendas
---
Las enmiendas representan nuevas características u otros cambios en el procesamiento de transacciones.
El sistema de enmiendas utiliza el proceso de consenso para aprobar cualquier cambio que afecte al procesamiento de transacciones en Xahau. Los cambios en el procesamiento de transacciones, completamente funcionales, se introducen como enmiendas; los validadores luego votan sobre estos cambios. Si una enmienda recibe más del 80% de apoyo durante cinco días, la enmienda se aprueba y el cambio se aplica permanentemente a todas las versiones posteriores del ledger. Deshabilitar una enmienda aprobada requiere una nueva enmienda para hacerlo.
**Nota:** Las correcciones de errores que cambian los procesos de transacciones también requieren enmiendas.
### Proceso de Enmienda
El tema Contribuir Código a Xahau describe el flujo de trabajo para desarrollar una enmienda desde una idea hasta su activación en Xahau.
Una vez que el código para una enmienda se incluye en una versión del software, el proceso para habilitarla ocurre dentro de la red Xahau, que verifica el estado de las enmiendas en cada ledger _flag_ (típicamente cada 15 minutos aproximadamente).
Cada 256 ledgers se denomina ledger **flag**. El ledger flag no tiene contenidos especiales, pero el proceso de enmienda ocurre alrededor de él.
1. **Flag Ledger -1:** Cuando los validadores `xahaud` envían mensajes de validación, también envían sus votos de enmienda.
2. **Flag Ledger:** Los servidores interpretan los votos de los validadores de confianza.
3. **Flag Ledger +1:** Los servidores insertan una pseudo-transacción `EnableAmendment` y establecen una bandera según lo que creen que ocurrió:
* La bandera `tfGotMajority` significa que la enmienda tiene más del 80% de apoyo.
* La bandera `tfLostMajority` significa que el apoyo a la enmienda ha caído al 80% o menos.
* Sin bandera significa que la enmienda está habilitada.
**Nota:** Es posible que una enmienda pierda el 80% de apoyo en el mismo ledger en que alcanza el período requerido de cinco días para ser habilitada. En estos casos, se añade una pseudo-transacción `EnableAmendment` para ambos escenarios, pero la enmienda finalmente se habilita.
4. **Flag Ledger +2:** Las enmiendas habilitadas se aplican a las transacciones de este ledger en adelante.
### Votación de Enmiendas
Cada versión de `xahaud` se compila con una lista de enmiendas conocidas y el código para implementarlas. Los operadores de validadores `xahaud` configuran sus servidores para votar sobre cada enmienda y pueden cambiarlo en cualquier momento. Si el operador no elige un voto, el servidor usa un voto predeterminado definido por el código fuente.
**Nota:** El voto predeterminado puede cambiar entre versiones del software. \[Actualizado en: rippled 1.8.1]\[]
Las enmiendas deben mantener cinco días de apoyo de más del 80% de los validadores de confianza para ser habilitadas. Si el apoyo cae por debajo del 80%, la enmienda se rechaza temporalmente y el período de dos semanas se reinicia. Las enmiendas pueden ganar y perder mayoría cualquier número de veces antes de quedar habilitadas permanentemente.
Las enmiendas cuyo código fuente ha sido eliminado sin haber sido habilitadas se consideran **Vetadas** por la red.
### Servidores Bloqueados por Enmienda
El bloqueo por enmienda es una función de seguridad para proteger la precisión de los datos de Xahau. Cuando se habilita una enmienda, los servidores que ejecutan versiones anteriores de `xahaud` sin el código fuente de la enmienda ya no comprenden las reglas de la red. En lugar de adivinar e interpretar incorrectamente los datos del ledger, estos servidores quedan **bloqueados por enmienda** y no pueden:
* Determinar la validez de un ledger.
* Enviar o procesar transacciones.
* Participar en el proceso de consenso.
* Votar sobre futuras enmiendas.
La configuración de votación de un servidor `xahaud` no tiene impacto en si queda bloqueado por enmienda. Un servidor `xahaud` siempre sigue las enmiendas habilitadas por el resto de la red, por lo que los bloqueos se basan únicamente en tener el código para entender los cambios de reglas. Esto significa que también puede quedar bloqueado por enmienda si conecta su servidor a una red paralela con diferentes enmiendas habilitadas. Por ejemplo, la Testnet de Xahau típicamente tiene enmiendas experimentales habilitadas. Si usa la última versión de producción, es probable que su servidor no tenga el código para esas enmiendas experimentales.
Puede desbloquear servidores bloqueados por enmienda actualizando a la versión más reciente de `xahaud`.
### Retirar Enmiendas
Cuando las enmiendas se habilitan, el código fuente de los comportamientos previos a la enmienda permanece en `xahaud`. Si bien hay casos de uso para mantener el código antiguo, como reconstruir resultados de ledger para verificación, el seguimiento de enmiendas y el código heredado añade complejidad con el tiempo.
El [XRP Ledger Standard 11d](https://github.com/XRPLF/XRPL-Standards/discussions/19) define un proceso para retirar enmiendas antiguas y el código previo a la enmienda asociado. Después de que una enmienda haya estado habilitada en Mainnet durante dos años, puede retirarse. Retirar una enmienda la convierte en parte del protocolo central de forma incondicional; ya no se rastrea ni se trata como una enmienda, y todo el código previo a la enmienda se elimina.
### Enmiendas Conocidas
Las siguientes enmiendas han sido implementadas o están en proceso de habilitarse en Xahau:
#### Enmiendas de Características
##### XahauGenesis
Habilita la cuenta génesis para acuñar XAH y distribuirlo mediante [transacciones GenesisMint](/es/docs/protocol-reference/transactions/transaction-types/genesismint-emitted-txn).
##### MultiSign
Habilita la funcionalidad de firma múltiple, permitiendo a las cuentas requerir múltiples firmas para las transacciones. Esta enmienda introduce [transacciones SignerListSet](/es/docs/protocol-reference/transactions/transaction-types/signerlistset) y [objetos de ledger SignerList](/es/docs/protocol-reference/ledger-data/ledger-objects-types/signers-list) para soportar la firma múltiple.
##### DepositAuth
Habilita la funcionalidad de autorización de depósito, permitiendo a las cuentas requerir preautorización antes de recibir pagos. Esta enmienda introduce [transacciones DepositPreauth](/es/docs/protocol-reference/transactions/transaction-types/depositpreauth) y [objetos de ledger DepositPreauth](/es/docs/protocol-reference/ledger-data/ledger-objects-types/deposit-pre-auth) para gestionar las preautorizaciones.
##### Hooks
Enmienda principal que habilita la funcionalidad de contratos inteligentes Hook en Xahau. _(Añadida por la [enmienda Hooks][].)_
##### HooksUpdate1
Actualizaciones y mejoras al sistema de Hooks.
##### Remit
Implementa [XLS-55](https://github.com/XRPLF/XRPL-Standards/discussions/156). Un nuevo tipo de transacción de pago push simple pero potente de lo-que-ves-es-lo-que-obtienes. Habilita [transacciones Remit](/es/docs/protocol-reference/transactions/transaction-types/remit) que permiten pagar múltiples monedas y URITokens en la misma transacción al mismo destino. La transacción paga automáticamente para crear líneas de confianza faltantes, paga automáticamente las reservas en tokens transferidos y paga automáticamente para crear la cuenta de destino si no existe. Puede acuñar un recibo o URIToken de bonificación inline dentro de la transacción. Opcionalmente, informar a un Hook de terceros sobre la transacción. Sin pagos parciales ni rutas.
##### ZeroB2M
Deshabilita la ruta burn-to-mint para XRP a XAH. El comportamiento normal de la transacción Import permanece, pero el XRP quemado no se acredita. B2M sigue disponible para sincronización de claves o para activar una cuenta, pero no puede usarse para acuñar nuevos activos.
##### Remarks
La enmienda Remarks permite almacenar pares clave-valor (similares al estado de hooks) por los propietarios de objetos en esos objetos. Esto es análogo a dar vuelta un documento y escribir una nota a mano en él. Los Remarks pueden ser cualquier cosa y significar cosas diferentes para distintas partes. Los Remarks también pueden establecerse como inmutables. Los Remarks siguen a un objeto a través de cambios de propiedad y pueden usarse para lograr casos de uso novedosos como NFTs dinámicos y simplificar algunas operaciones de estado de hooks que de otro modo serían muy complicadas. Habilita [transacciones SetRemarks](/es/docs/protocol-reference/transactions/transaction-types/setremarks).
##### Touch
Esta enmienda garantiza que todas las cuentas involucradas en una transacción (todas las partes interesadas transaccionales) se vean forzadas a aparecer en sus metadatos incrementando un "contador de toque" incluso si nada más en la cuenta cambió. Lleva el nombre de la utilidad de archivos unix touch. Esto proporciona mejor consistencia de auditoría y facilidad de programación de herramientas automatizadas.
##### HookCanEmit
Esta enmienda añade un nuevo campo a los objetos HookSet: `HookCanEmit` es sintácticamente idéntico al campo `HookOn`, excepto que controla qué tipos de transacciones el Hook tiene permitido emitir en lugar de qué tipos de transacciones activan el hook. Tenga en cuenta que usa la misma semántica activo-bajo que `HookOn` con `SetHook` siendo activo-alto. Sin embargo, si el campo está ausente, se toma como que el Hook puede emitir cualquier transacción incluyendo `SetHook`. Añade el campo `HookCanEmit` a los objetos [HookDefinition](/es/docs/protocol-reference/ledger-data/ledger-objects-types/hook-definition).
##### Clawback
Habilita [transacciones Clawback](/es/docs/protocol-reference/transactions/transaction-types/clawback) que permiten a los emisores revocar tokens que fueron previamente emitidos por su cuenta. Esta es una característica portada desde XRPL. _(Introducida en 2025.7.9-release+1951)_
##### DeepFreeze
Habilita la funcionalidad de congelamiento profundo para líneas de confianza y activos. Esta es una característica portada desde XRPL. _(Introducida en 2025.7.9-release+1951)_
##### IOUIssuerWeakTSH
Convierte a los emisores de IOU en partes interesadas transaccionales (TSH) débiles en ciertos tipos de transacciones. Garantiza que los Emisores de Moneda tengan sus hooks ejecutados en transacciones de terceros que toquen o mencionen su moneda, si han optado por la ejecución débil. Consulte [Débil y Fuerte](/es/docs/hooks/concepts/weak-and-strong) para más detalles. _(Introducida en 2025.7.9-release+1951)_
##### Cron
Habilita la ejecución programada de Hooks mediante [transacciones CronSet](/es/docs/protocol-reference/transactions/transaction-types/cronset) y [objetos de ledger Cron](/es/docs/protocol-reference/ledger-data/ledger-objects-types/cron). Esta característica permite a los Hooks programar una serie de auto-invocaciones futuras (similar a un cronjob en sistemas Linux) que puede ayudar a los desarrolladores de Hooks a escribir estructuras de gobernanza complejas, juegos y más. El número máximo de repeticiones es 256, sin embargo emitir una transacción `CronSet` adicional puede extender esto una vez que el número de repeticiones cruce un umbral mínimo deseado. _(Introducida en 2025.10.27-release+2405)_
##### ExtendedHookState
Extiende las capacidades de gestión del estado de Hooks, incluyendo el campo `HookStateScale` para objetos [AccountRoot](/es/docs/protocol-reference/ledger-data/ledger-objects-types/accountroot) para controlar cuándo las entradas de estado de Hook quedan obsoletas. Esta característica expande la cantidad de datos que los Hooks pueden almacenar en su estado (sistema clave-valor para Hooks) para permitir a los Hooks un almacenamiento de datos más rico cuando lo necesiten. La escala (hasta 16) afecta tanto al tamaño máximo del valor que puede almacenar en un único estado de hook, como al número de unidades de reserva que ese par k-v consume. Una escala de 1 (predeterminada) significa que paga 1 reserva por hasta 256 bytes almacenados por estado de Hook. Una escala de 4 significa que paga 4 unidades de reserva por hasta 1024 bytes por estado de Hook. Es importante tener en cuenta que paga esta tasa (la tasa de escala) incluso si todos sus estados de Hook contienen solo un byte. Es posible aumentar la escala después de que su Hook ya tenga estado almacenado, pero no disminuirla. Disminuir la escala requiere que primero se eliminen todos los HookState. _(Introducida en 2025.10.27-release+2405)_
#### Enmiendas de Corrección de Errores
##### fixXahauV1
Aplica un límite de 256 espacios de nombres por cuenta. Varias correcciones de errores con la lógica de URIToken. Garantiza que los STAmounts predeterminados (0) se registren en los metadatos. Garantiza que OfferID pueda usarse en lugar de OfferSequence al cancelar una oferta. Corrige un error donde ciertos hooks no pueden eliminarse. Corrige un error donde el quórum requerido para un `ttIMPORT` es accidentalmente demasiado alto. Permite que las cuentas aparezcan más de una vez en una transacción GenesisMint. Cambia el Emisor de un URIToken de TSH fuerte a débil cuando se está quemando un URIToken. Garantiza que los TSH en escrows creados por transacciones emitidas se activen correctamente. Añade la tarifa de tamaño de parámetros de hook a todas las txns (1 drop por byte). _(Introducida en 2024.9.11-release+985)_
##### fixXahauV2
Limpia la lógica TSH y elimina la tabla antigua redundante. Añade banderas informativas a cada miembro de `sfHookExecutions`, describiendo la ejecución débil, fuerte, etc. Añade `sfEmitNonce` a cada miembro de `sfHookEmissions`, para desambiguar mejor las txns emitidas. Verificaciones de cordura adicionales en las txns emitidas para garantizar que se coloquen en el ledger correcto.
##### fixXahauV3
Correcciones adicionales para los problemas de implementación del protocolo Xahau. Esta enmienda garantiza consistencia y resultados sensatos para varios casos extremos. Esta enmienda está configurada para votar: _sí_ por defecto. Si los validadores desean votar en contra de esta enmienda, deben cambiar manualmente su voto a no. _(Introducida en 2025.2.6-release+1299)_
##### fixNSDelete
Corrige el comportamiento de la eliminación del espacio de nombres de estado de Hook para garantizar la consistencia del ledger. Introduce un nuevo código tes: `tesPARTIAL`. `tesPARTIAL` se devuelve si la transacción fue exitosa pero debe ser reenviada por el usuario con un nuevo número de secuencia para completar el trabajo amortizado hasta que se devuelva `tesSUCCESS`.
##### fix240819
Enmienda de corrección de errores del 19 de agosto de 2024.
##### fixPageCap
Corrige problemas relacionados con los límites de capacidad de página.
##### fix240911
Enmienda de corrección de errores del 11 de septiembre de 2024.
##### fixFloatDivide
Corrige problemas con las operaciones de división de punto flotante en Hooks. Esta enmienda garantiza el manejo adecuado de la división por cero y los casos extremos en la función `float_divide`. Cambia el comportamiento de la API de hook `float_divide` para corregir un pequeño error. Esta enmienda está configurada para votar: _sí_ por defecto. Consulte [float_divide](/es/docs/hooks/functions/float/float_divide) para más detalles. _(Introducida en 2024.11.18-release+1141)_
##### fixReduceImport
Corrige problemas relacionados con el procesamiento de transacciones Import. Esta enmienda garantiza consistencia y resultados sensatos para varios casos extremos. Esta enmienda está configurada para votar: _sí_ por defecto. Si los validadores desean votar en contra de esta enmienda, deben cambiar manualmente su voto a no. _(Introducida en 2025.2.6-release+1299)_
##### fix20250131
Enmienda de corrección de errores del 31 de enero de 2025. Esta enmienda garantiza consistencia y resultados sensatos para varios casos extremos. Esta enmienda está configurada para votar: _sí_ por defecto. Si los validadores desean votar en contra de esta enmienda, deben cambiar manualmente su voto a no. _(Introducida en 2025.2.6-release+1299)_
##### fixRewardClaimFlags
Corrige problemas con las banderas de las transacciones de reclamación de recompensas.
##### fixProvisionalDoubleThreading
Corrige problemas con el doble enhebrado provisional en el procesamiento de transacciones. Garantiza que el PreviousTxnID correcto y los metadatos de la transacción se mantengan en escenarios de doble enhebrado. _(Introducida en 2025.7.9-release+1951)_
##### fixInvalidTxFlags
Corrige un error que actualmente permite proporcionar banderas no válidas a algunas transacciones. Si bien estas banderas no válidas actualmente no hacen nada, deberían producir un error de formato incorrecto. Después de que se aplique esta corrección, las banderas no válidas producirán un error de formato incorrecto como se esperaba. _(Introducida en 2025.10.27-release+2405)_
##### fixCronStacking
Corrige problemas con el comportamiento de apilamiento de transacciones Cron.
### Estado de las Enmiendas
Para conocer el estado más actual de las enmiendas (habilitadas, en votación o vetadas), consulte el [repositorio xahaud](https://github.com/Xahau/xahaud) o consulte a un servidor `xahaud` en ejecución usando el comando `feature`.

View File

@@ -0,0 +1,68 @@
---
title: Ajustes de Balance
description: Cómo reclamar un Ajuste de Balance en Xahau
---
### Opt-in + Reclamar
Optar por los Ajustes de Balance es la misma transacción que reclamar un ajuste. Debe hacerlo primero para iniciar la capacidad de reclamar más adelante.
```json
{
"Account": "<rAddr...>",
"TransactionType": "ClaimReward",
"Issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"NetworkID": 21337
}
```
### Opt-out
Para excluirse de los Ajustes de Balance, omita el campo Issuer y establezca Flags en 1. Al hacerlo se eliminarán sus estadísticas de balance promedio. Estas no serán restauradas. Si vuelve a optar, se restablecerán a una posición inicial.
```json
{
"Account": "<rAddr...>",
"TransactionType": "ClaimReward",
"NetworkID": 21337,
"Flags": 1
}
```
### Detalles Técnicos
Los Ajustes de Balance se implementan como una combinación de dos piezas de código:
1. Enmienda BalanceRewards (código nativo)
2. Hook de Recompensa de la Cuenta Génesis (código de hook).
BalanceRewards recopila estadísticas de balance promedio sobre las cuentas en las que están activados. Estas estadísticas luego se pasan a un Hook objetivo cuando el usuario desea reclamar.
Todas las interacciones con esta enmienda son mediante la transacción ClaimReward:
```json
{
"Account": "<rAddr...>",
"TransactionType": "ClaimReward",
"Issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"NetworkID": 21337
}
```
Cuando una transacción ClaimReward se envía exitosamente con un código de error **tesSUCCESS**, las estadísticas de balance promedio de la cuenta se restablecen. Lo único adicional que hace la enmienda es invocar los Hooks en la cuenta del Emisor especificado.
El campo _Issuer_ es la cuenta responsable de cumplir con el reclamo. Dependiendo de lo que esté instalado en la cuenta del Emisor, pueden ocurrir varias cosas:
* Si no hay ningún Hook instalado en la cuenta del Emisor, entonces no se hace nada y las estadísticas de BalanceRewards simplemente se restablecen.
* Si hay un Hook instalado en la cuenta del Emisor y el Hook realiza un rollback, entonces la transacción falla y las estadísticas _no_ se restablecen.
* Si hay un Hook instalado en la cuenta del Emisor y el Hook realiza accept, entonces la transacción tiene éxito y las estadísticas se restablecen. En este caso, el Hook también debería emitir una transacción de vuelta a la cuenta del usuario que contenga su recompensa.
En la práctica, en Xahau, el Emisor probablemente siempre será la cuenta génesis **rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh**.
A menos que:
* La Gobernanza de la Red resulte en que se use una cuenta diferente para BalanceAdjustments.
* Una parte no relacionada con la Gobernanza ejecute su propio sorteo de BalanceRewards en el que el usuario quiera participar. Tenga en cuenta que los reclamos exitosos resultan en el restablecimiento de las estadísticas de balance promedio, por lo que solo se puede reclamar un tipo de recompensa por restablecimiento.
Las estadísticas de balance promedio existen como una colección de tres nuevos campos en el objeto AccountRoot. Estos son:
<table><thead><tr><th width="240">Campo</th><th width="95.33333333333331">Tipo</th><th>Explicación</th></tr></thead><tbody><tr><td><code>sfRewardAccumulator</code></td><td>UINT64</td><td>El área bajo la gráfica balance-tiempo de su cuenta desde la última transacción ClaimReward.</td></tr><tr><td><code>sfRewardLgrFirst</code></td><td>UINT32</td><td>El número de ledger de la última transacción ClaimReward.</td></tr><tr><td><code>sfRewardLgrLast</code></td><td>UINT32</td><td>El número de secuencia del ledger de la última transacción entrante o saliente de su cuenta.</td></tr><tr><td><code>sfRewardTime</code></td><td>UINT32</td><td>El tiempo del ledger en que se reclamó la última recompensa.</td></tr></tbody></table>

View File

@@ -0,0 +1,291 @@
---
title: Burn 2 Mint (B2M)
description: >-
Burn2Mint es una primitiva de intercadena de bajo nivel y está pensada para usuarios
empresariales que necesitan autoabastecer su propia liquidez según sus propios propósitos.
---
import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';
<Aside type="caution">
Dado que la enmienda ZeroB2M ha sido aprobada en Xahau, Burn 2 Mint (B2M) ya no está disponible para acuñar nuevos activos. B2M sigue disponible, pero solo para **sincronización de claves** o para activar una cuenta (para lo cual la información y los procedimientos a continuación siguen siendo relevantes)
[https://xahscan.com/amendment/7CA0426E7F411D39BB014E57CD9E08F61DE1750F0D41FCD428D9FB80BB7596B0](https://xahscan.com/amendment/7CA0426E7F411D39BB014E57CD9E08F61DE1750F0D41FCD428D9FB80BB7596B0)
</Aside>
## Manual Técnico de Burn2Mint (Xahau Testnet)
<Aside type="caution">
**Este proceso es deliberadamente no trivial y no está diseñado para usuarios finales.** Los errores resultan en que una quema no pueda convertirse en una acuñación.
Esta es una advertencia que aparecerá en la versión de producción de este documento. Puede ignorarla porque está quemando XRP de testnet gratuito en este caso.
</Aside>
Burn2Mint es una primitiva de intercadena de bajo nivel pensada para usuarios empresariales que necesitan autoabastecer su liquidez según sus propósitos. Ejecutar sus propios nodos y realizar esta operación usted mismo en sus nodos significa que usted y solo usted asume la responsabilidad del resultado del procedimiento.
La generación y recopilación de XPOPs depende fundamentalmente de recopilar mensajes de validación en la red overlay, que son efímeros por naturaleza. Si sus nodos no están conectados de forma confiable, o si su hardware, conexión de red o sistema operativo falla en el momento equivocado, entonces el XPOP para una Transacción de Quema podría no generarse o podría no generarse correctamente. Esto puede llevar a la pérdida de fondos ya que el XPOP de la Transacción de Quema no fue capturado a tiempo, y es posible que los mensajes de validación se pierdan para siempre, haciendo imposible una Transacción de Acuñación a pesar de una Transacción de Quema exitosa.
Si no se siente cómodo asumiendo estos riesgos técnicos o no comprende lo que está haciendo, o no es un usuario empresarial, por favor obtenga su liquidez a través de otras alternativas amigables.
### Configuración
Para realizar B2M, el usuario debe operar _dos_ nodos del protocolo XRPL:
1. **Obtener xPOP de la quema**
<Tabs>
<TabItem label="xPOP Collector & Server (más fácil)">
Ejecute esto (por ejemplo, usando Docker Compose; vea la documentación del repositorio)\
[**https://github.com/Xahau/Validation-Ledger-Tx-Store-to-xPOP**](https://github.com/Xahau/Validation-Ledger-Tx-Store-to-xPOP)
* El servicio escucha los mensajes de validación de XRPL, los ledgers cerrados y las transacciones.
* Almacena estos datos en un sistema de archivos organizado.
* Es esencial para generar xPOPs, ya que los mensajes de validación de XRPL son efímeros; sin almacenarlos, una quema de transacción no puede convertirse en una acuñación.
* **Cómo funciona**:
* Un observador se conecta a múltiples nodos XRPL y escucha datos específicos.
* Los datos capturados luego se guardan, organizan y usan para generar xPOPs
Simplemente obtenga el xPOP ahora desde:\
`http[s]://{su-host}:{su-puerto}/xpop/{tx-hash}`
Puede obtener/crear fácilmente xPOPs desde un nodo usando el repositorio anterior con este paquete NPM:
[**https://www.npmjs.com/package/xpop**](https://www.npmjs.com/package/xpop)
</TabItem>
<TabItem label='o: "Nodo de Quema" dedicado'>
**Nodo de Quema**, que comprende:
* Una instancia de Rippled modificada (modificada para registrar XPOPs)
* Binario universal de linux aquí: [https://tvntezq.dlvr.cloud/rippled_with_xpop](https://tvntezq.dlvr.cloud/rippled_with_xpop)
* [https://github.com/RichardAH/rippled/tree/proof-of-burn](https://github.com/RichardAH/rippled/tree/proof-of-burn)
* Ejecutándose con un rippled.cfg que tiene:
* una estrofa **\[xpop_dir]** que especifica un directorio de salida para los XPOPs generados.
* una estrofa **\[network_id]** que especifica network_id: 1
* (en producción esto sería la red 0)
* un `validators.txt` que contiene:\\
```
[validator_list_sites]
https://vl.altnet.rippletest.net
[validator_list_keys]
ED264807102805220DA0F312E71FC2C69E1552C9C5790F6C25E3729DEB573D5860
```
</TabItem>
</Tabs>
2. **Acuñar**
* En este escenario de prueba, se conectará directamente a Xahau. No necesita ejecutar su propio nodo. En el escenario de producción, necesitará ejecutar un nodo de Acuñación, que es simplemente un nodo estándar para la red de destino. Esto se debe a que los nodos públicos probablemente optarán por no aceptar transacciones Import debido al riesgo legal.
* Conéctese a **wss://xahau-test.net**
* O descargue/ejecute: [**https://github.com/Xahau/Xahau-Testnet-Docker**](https://github.com/Xahau/Xahau-Testnet-Docker)
## Ejemplo (nodejs)
Este ejemplo crea una cuenta de testnet, quema 10 XRP y luego los importa en Xahau Testnet, usando el xPOP obtenido con las herramientas mencionadas anteriormente.
```js
import { derive, utils, signAndSubmit } from 'xrpl-accountlib'
import { TxData } from 'xrpl-txdata'
import { XrplClient } from 'xrpl-client'
import { xpop, setEndpoints as xpopEndpoints } from 'xpop'
import fetch from 'node-fetch'
// Lo anterior requiere:
// npm install xrpl-accountlib xrpl-txdata xrpl-client xpop node-fetch
console.log('Obteniendo cuenta de XRPL Testnet (faucet)')
const faucet = await (await fetch('https://faucet.altnet.rippletest.net/accounts', { method: 'POST' })).json()
console.log(' -->', faucet.account.address)
const account = derive.familySeed(faucet.account.secret)
xpopEndpoints((await (await fetch('https://xrpl.ws-stats.com/xpop/list?json=true')).json()).bestguess)
const nodes = {
testnet: [
new XrplClient('wss://s.altnet.rippletest.net:51233'),
new XrplClient('wss://testnet.xrpl-labs.com'),
],
xahau: [
new XrplClient('wss://xahau-test.net'),
]
}
console.log('Esperando que las conexiones de red estén listas')
await Promise.all(Object.keys(nodes).map(k => Promise.race(nodes[k].map(n => n.ready()))))
console.log('Esperando financiación de la cuenta faucet y obteniendo valores de red...')
await new Promise(resolve => setTimeout(resolve, 4000)) // Esperar hasta que el ledger cierre
const [
testnetParams,
xahauParams,
] = await Promise.all([
Promise.race(nodes.testnet.map(n => utils.accountAndLedgerSequence(n, account))),
Promise.race(nodes.xahau.map(n => utils.accountAndLedgerSequence(n, account))),
])
const testnetTx = {
...testnetParams.txValues,
TransactionType: 'AccountSet',
Fee: String(10_000_000),
OperationLimit: xahauParams.txValues.NetworkID,
NetworkID: undefined, // Testnet tiene un NetworkID < 1024, por lo que no se debe proporcionar ninguno
}
console.log('Enviando quema...', testnetTx)
const testnetSubmitted = await Promise.race(nodes.testnet.map(n => signAndSubmit(testnetTx, n, account)))
console.log('Quema enviada a testnet')
console.log(' -->', 'https://testnet.xrpl.org/transactions/' + testnetSubmitted.tx_id)
console.log('Obteniendo datos de la tx de quema...')
const txdata = new TxData(nodes.testnet.map(n => n.getState().server.uri), {
AllowNoFullHistory: true,
EndpointTimeoutMs: 2_000,
OverallTimeoutMs: 10_000,
})
const appliedtx = await txdata.getOne(testnetSubmitted.tx_id)
console.log(' -->', 'Quema validada en el ledger', appliedtx?.result?.ledger_index)
console.log('Esperando el cierre del ledger antes de obtener el xPOP...')
await new Promise(resolve => setTimeout(resolve, 4000)) // Esperar hasta que el ledger cierre
console.log('Obteniendo xPOP...')
const Blob = await xpop(testnetSubmitted.tx_id, appliedtx?.result?.ledger_index, 1)
console.log(' -->', 'xPOP obtenido, longitud hex:', Blob.length)
const hooksTx = {
...xahauParams.txValues,
TransactionType: 'Import',
Fee: '0',
Blob,
}
console.log('Enviando para acuñar el xPOP...')
const b2mSubmitted = await Promise.race(nodes.xahau.map(n => signAndSubmit(hooksTx, n, account)))
console.log(' -->', '¡B2M enviado! TX en Xahau Testnet:')
console.log(' -->', 'https://test.xahauexplorer.com/explorer/' + b2mSubmitted?.tx_id)
console.log(' -->', b2mSubmitted.response.engine_result, b2mSubmitted.response.engine_result_message)
// Cerrando conexiones
Object.keys(nodes).map(k => nodes[k].map(n => n.close()))
```
[Fuente](https://gist.github.com/WietseWind/cd8a7a8c88f218fe7b768f59a665685d)
## Resumen Técnico del procedimiento B2M
#### Nuevo Tipo de Transacción: `Import`
Xahau Testnet (_network_id=21338_) introduce un nuevo tipo de transacción llamado _**Import**_, que acepta un XPOP de la cadena de testnet de Ripple (_network_id=1_) y proporciona una transferencia de valor unidireccional "burn-to-mint" y sincronización de claves/cuentas.
### Transacción de Quema
Una _**Transacción de Quema**_ es una transacción que quema XRP en una cadena XRPL fuente, la cual se usaría como prueba (XPOP) para acuñar en una cadena XRPL de destino.
Los siguientes tipos de transacciones son compatibles:
* AccountSet
* SetRegularKey
* SignerListSet.
<Aside type="caution">
Los Tickets _**no son aceptados**_ en **ninguna** Transacción de Quema y llevarían a que una Transacción de Quema sea inválida para acuñar. Para protegerse contra el spam, las transacciones deben validarse con un número de secuencia real y natural.
</Aside>
Tenga en cuenta que otros tipos de transacciones no son actualmente compatibles y no pueden usarse para acuñar en Xahau Testnet. (Sin embargo, esto puede cambiar).
Los tres tipos de transacciones pueden usarse para acuñar. Esto significa que la _**Tarifa**_ quemada por la Transacción de Quema se acuña posteriormente en Xahau Testnet después de un `Import` exitoso.
Si se usa `SetRegularKey` o `SignerListSet`, entonces la sincronización de claves ocurre de acuerdo con las reglas estándar del tipo de transacción. Si se usa `AccountSet`, entonces no se produce sincronización de claves en la cadena XRPL de destino (Xahau Testnet).
Un campo llamado _**OperationLimit**_ debe estar presente en la Transacción de Quema para ser el ID de red de la cadena de destino. Este campo es para prevenir ataques de repetición en otras cadenas integradas con B2M.
La Transacción de Quema puede usarse para Acuñar si tiene un código de transacción **tesSUCCESS** o _cualquiera_ de los códigos de transacción **tec**. Esto significa que _si_ se quemó la tarifa, entonces la transacción puede usarse para acuñar. Sin embargo, la sincronización de claves _solo_ ocurre cuando el resultado de la Transacción de Quema fue tesSUCCESS.
Ejemplo de Transacción de Quema:
```json
{
"TransactionType": "AccountSet",
"Fee": 10000000,
"OperationLimit": 21338
}
```
### Recopilación de XPOP
Antes de enviar la Transacción de Quema, asegúrese de que su Nodo de Quema esté sincronizado con la cadena de testnet (ID de red: `1`).
Después de verificar el estado de su Nodo de Quema, envíe la Transacción de Quema firmada al Nodo de Quema.
El Nodo de Quema monitorea los ledgers cerrados en busca de transacciones que contengan el campo **OperationLimit** y usa los mensajes de validación recopilados para generar un XPOP (Prueba de Quema). Estos se escriben en un archivo bajo el directorio especificado en la estrofa **\[xpop_dir]** en el `rippled.cfg` del Nodo de Quema.
Espere a que el ledger cierre, luego busque en el xpop_dir el XPOP de la Transacción de Quema según su TXID. El archivo contiene un documento JSON, que es el XPOP que retransmitirá a la cadena XRPL de destino (HooksV3).
Tome el contenido bruto de este archivo y codifíquelo como HEX. Esto se convertirá en el contenido del campo _Blob_ en la transacción `Import`.
### Transacción de Acuñación
Su codec binario estará al que le falten los campos necesarios para construir la transacción `Import` (Acuñación). Si está usando ripple-binary-codec, puede actualizar su archivo `definitions.json` de la siguiente manera:
1. Cambie de directorio a `node_modules`
2. Ejecute `find . | grep 'dist/enums/definitions.json'` para localizar el archivo relevante a actualizar
3. Conéctese a **wss://hooks-testnet-v3.xrpl-labs.com**
4. Solicitud: `{"command":"server_definitions"}`
5. Vuelque el contenido de la clave `"result"` en `definitions.json` del paso 2.
El tipo de transacción `Import` toma solo un campo no común _**Blob.**_. Este debe contener el XPOP codificado en HEX de la fase de Recopilación de XPOP.
* Puede hacer esto con `cat xpopjsonfile | xxd -p | tr -d '\n'`
El campo `Account` y el campo `SigningPubKey` (o el array Signers) deben coincidir exactamente entre la Transacción de Quema y la Transacción de Acuñación. Los usuarios solo pueden acuñar en la misma cuenta desde la que quemaron.
Si el campo `Account` especifica una cuenta que aún no existe en Xahau Testnet, será creada. En este caso, use 0 para el campo `Sequence` en la Transacción de Acuñación. Si la cuenta ya existe en Xahau Testnet, use el siguiente número de Sequence disponible en la cuenta en Xahau Testnet.
Ejemplo de Import:
```json
{
"Account": "<igual que en la Transacción de Quema>",
"TransactionType": "Import",
"Blob": "<XPOP codificado en HEX (mayúsculas)>",
"Sequence": 0
}
```
IMPORTANTE: **¡La Transacción de Acuñación debe firmarse exactamente de la misma manera y por la misma cuenta que la Transacción de Quema!**
Codifique y firme la transacción apropiadamente, produciendo un blob de transacción firmado (hex).
Si no está ejecutando su propio nodo de Acuñación:
* Conéctese a **wss://xahau-testn.et**
* Envíe la transacción al nodo:
```json
{
"command": "submit",
"tx_blob": "<TRANSACCIÓN IMPORT CODIFICADA EN HEX>"
}
```
O, si está ejecutando su propio nodo de Acuñación:
* Asegúrese de que el Nodo de Acuñación esté ejecutándose y sincronizado con el ID de red 21338.
* Use la llamada RPC `submit` para enviar la Transacción de Acuñación.
* Puede hacer esto desde la línea de comandos usando `./hooksv3d submit <hex aquí>`
### Consideraciones
Si la Cuenta debe crearse en Xahau Testnet pero el manejo de claves para la cuenta no está claro en el contexto de la Transacción de Quema, entonces la Cuenta se crea en modo blackholed. Puede ser reconfigurada posteriormente usando cualquier tipo de transacción de manejo de claves.
Si la Transacción de Quema es un `SignerListSet` o un `SetRegularKey`, y tuvo un resultado de transacción tesSUCCESS en la cadena XRPL fuente (testnet), esa misma operación de manejo de claves se aplica ahora a esa misma cuenta en la cadena XRPL de destino (Xahau Testnet).
Durante las pruebas, las Cuentas en Xahau Testnet _pueden_ eliminarse; sin embargo, en la cadena de producción con Hooks habilitados, no podrán eliminarse.
Las Cuentas en Xahau Testnet tienen un campo opcional _**ImportSequence**_ en el AccountRoot. Si **Import** se ha usado alguna vez en esa cuenta en Xahau Testnet, este campo está presente y se rellena con el número de Sequence de la Transacción de Quema importada más recientemente. Esto es para prevenir ataques de repetición, pero también significa que nunca debe enviar sus Burn2Mints fuera de secuencia, de lo contrario las transacciones omitidas nunca serán aceptadas para Acuñar.

View File

@@ -0,0 +1,10 @@
---
title: Bibliotecas de Cliente
---
Estas bibliotecas de cliente simplifican parte del trabajo habitual de acceso y procesamiento de datos del XAH Ledger y los presentan en una forma que se adapta a las convenciones nativas de sus respectivos lenguajes de programación.
Para otros lenguajes de programación, puede acceder al XAH Ledger a través de las APIs HTTP.
<table><thead><tr><th width="172">Lenguaje</th><th width="172">Nombre de la Biblioteca</th><th>Comenzar</th><th>Protocolo</th><th>Código Fuente</th></tr></thead><tbody><tr><td><strong>Python</strong></td><td><code>xahau-py</code></td><td><a href="https://github.com/Xahau/xahau-py">Comenzar</a></td><td>XAH / XRP</td><td><a href="https://github.com/Xahau/xahau-py">Repositorio</a></td></tr><tr><td><strong>JavaScript</strong> / <strong>TypeScript</strong></td><td><code>xahau.js</code></td><td><a href="https://github.com/Xahau/xahau.js">Comenzar</a></td><td>XAH / XRP</td><td><a href="https://github.com/Xahau/xahau.js">Repositorio</a></td></tr><tr><td><strong>JavaScript</strong> / <strong>TypeScript</strong></td><td><a href="https://www.npmjs.com/package/xrpl-accountlib"><code>xrpl-accountlib</code></a></td><td><a href="https://www.npmjs.com/package/xrpl-accountlib">Comenzar</a><br /><a href="https://github.com/WietseWind/xrpl-accountlib/blob/master/samples/prefill-sign-and-submit.mjs">Ejemplo</a></td><td>XAH / XRP</td><td><a href="https://github.com/WietseWind/xrpl-accountlib">Repositorio</a></td></tr></tbody></table>
**Consejo:** ¡Para añadir una biblioteca de cliente que no esté listada aquí, sugiera cambios en esta página!

View File

@@ -0,0 +1,16 @@
---
title: Herramientas Seleccionadas
---
Estas herramientas simplifican parte del trabajo habitual de acceso y procesamiento de Hooks.
| Herramienta | Enlace de Referencia |
| ----------------------- | ---------------------------------------------------------------------- |
| **Hooks Builder** | [Enlace al Builder](https://builder.xahau.network/develop) |
| **Hooks Toolkit** | [Enlace al Toolkit](https://hooks-toolkit.com/) |
| **Xpop Toolkit** | [Enlace al Toolkit](https://github.com/Transia-RnD/xpop-toolkit) |
| **Hooks Blog** | [Enlace al Blog](https://dev.to/t/xrplhooks/top/infinity) |
| **XFL Tools** | [Enlace a la Herramienta](https://richardah.github.io/xfl-tools/) |
| **Binary Visualizer** | [Enlace a la Herramienta](https://richardah.github.io/xrpl-binary-visualizer/) |
| **Keylet Tools** | [Enlace a la Herramienta](https://richardah.github.io/xrpl-keylet-tools/) |
| **CTID Visualizer** | [Enlace a la Herramienta](https://transia-rnd.github.io/xrpl-ctid-visualizer/) |
| **C Hook Tx Builder** | [Enlace a la Herramienta](https://transia-rnd.github.io/xrpl-tt-visualizer/) |

View File

@@ -0,0 +1,29 @@
---
title: Trucos para Desarrolladores
---
## Firma Wildcard
Para probar y reproducir fácilmente, use `NetworkID` con el valor `65535` (configuración: `[network_id]`) para deshabilitar la verificación de firmas.
Añadido: [https://github.com/Xahau/xahaud/pull/201](https://github.com/Xahau/xahaud/pull/201)
## Definiciones del Servidor
Las definiciones del servidor pueden obtenerse fácilmente desde los nodos públicos. Estas definiciones incluyen información del codec binario y otros datos específicos de la red necesarios para la serialización y deserialización de transacciones.
### Mainnet
- [`https://xahau.network/server_definitions.json`](https://xahau.network/server_definitions.json)
### Testnet
- [`https://xahau-test.net/server_definitions.json`](https://xahau-test.net/server_definitions.json)
### JSHooks-Testnet
- [`https://jshooks.xahau-test.net/server_definitions.json`](https://jshooks.xahau-test.net/server_definitions.json)
Estas definiciones del servidor son esenciales para:
- Operaciones de codec binario
- Serialización de transacciones
- Definiciones de tipos de campos
- Constantes específicas de la red
Puede usar estas definiciones en sus aplicaciones para codificar y decodificar correctamente las transacciones para la red Xahau.

View File

@@ -0,0 +1,27 @@
---
title: Faucet y Exploradores
---
El Faucet y los Exploradores de Xahau se pueden encontrar aquí:
## Testnet
* **Faucet:** [**https://xahau-test.net**](https://xahau-test.net)
* Para automatizar la financiación de cuentas en testnet, realice un HTTP POST en:\
[https://xahau-test.net/accounts](https://xahau-test.net/accounts)\
Cuerpo vacío: nueva cuenta (prefundada)\
Cuerpo JSON con propiedad `destination`: financiar la cuenta `destination` mencionada.
* **Exploradores:**
* **Xahauexplorer:** [**https://test.xahauexplorer.com**](https://test.xahauexplorer.com)
* **InFTF:** [**https://explorer.xahau-test.net**](https://explorer.xahau-test.net)
* **XRPL.org:** [**https://xahau-testnet.xrpl.org**](https://xahau-testnet.xrpl.org)
* **XRPLWin:** [**https://xahau-testnet.xrplwin.com**](https://xahau-testnet.xrplwin.com/)
## Mainnet
* **Página principal:** [**https://xahau.network**](https://xahau.network/)
* **Exploradores:**
* **Xahauexplorer:** [**https://xahauexplorer.com**](https://xahauexplorer.com/)
* **Xahscan:** [**https://xahscan.com/**](https://xahscan.com/)
* **InFTF:** [**https://explorer.xahau.network**](https://explorer.xahau.network/)
* **XRPL.org:** [**https://xahau.xrpl.org**](https://xahau.xrpl.org)
* **XRPLWin:** [**https://xahau.xrplwin.com**](https://xahau.xrplwin.com/)

View File

@@ -0,0 +1,195 @@
---
title: Juego de Gobernanza
description: >-
El Juego de Gobernanza es un mecanismo de gobernanza innovador dentro del ecosistema
Xahau para garantizar un enfoque centrado en la comunidad en la toma de decisiones.
---
### Descripción General
El Juego de Gobernanza de Xahau permite a hasta 400 partes interesadas participar democráticamente en la gestión de la red Xahau a través del Hook de Gobernanza instalado en la Cuenta Génesis.
### Capa 1
El juego consiste en una mesa de "Capa 1" en la que hay 20 asientos. Una cuenta Xahau (dirección r) puede ocupar cada asiento, o puede estar vacío. Cuando un asiento está ocupado, se dice que un miembro de la mesa se sienta allí.
Para jugar el juego, los miembros de la mesa emiten votos. Los votos son sobre uno de tres tipos de temas:
* Temas de asientos
* Temas de hooks
* Temas de recompensas.
Los temas de asientos van de S00 a S19 y representan un voto sobre quién (si alguien) ocupa actualmente ese asiento. Un voto del 80% es suficiente para hacer un cambio. El proceso de votación es continuo, y el voto final que supera el umbral acciona el cambio.
Los temas de hooks van de H0 a H9 y representan qué Hooks, incluido el propio Hook de Gobernanza, están instalados en la cuenta de la mesa. Estos temas requieren el 100% de los miembros sentados en esa mesa para estar de acuerdo antes de que se pueda hacer un cambio. Esto permite que el Juego de Gobernanza sea actualizado y que se añadan más características a la cuenta génesis con el tiempo.
Los temas de recompensas son RR y RD, que significan Tasa de Recompensa y Retraso de Recompensa, respectivamente. Estos temas también requieren el 100% de los miembros en la mesa para estar de acuerdo para hacer un cambio. Estos parámetros afectan al sistema de BalanceAdjustments: cuánto puede reclamar cada usuario activo en la red y con qué frecuencia.
### Capa 2
Los miembros que ocupan asientos en la mesa de Capa 1 son cuentas Xahau (direcciones r). El juego de gobernanza está diseñado para ser estructuralmente recursivo, de modo que una de estas cuentas pueda ser en sí misma una mesa que consiste en otros 20 asientos. Esto se llama mesa de Capa 2, y los asientos son asientos de Capa 2.
Dentro de una mesa de Capa 2, existen los mismos temas de votación de asientos y hooks, con las mismas reglas de votación que la mesa de Capa 1. Esto permite a una mesa gobernar su propia membresía y los hooks que se ejecutan allí.
Además de estos temas, una mesa de Capa 2 también puede, mediante un voto del 51%, elevar un voto a la mesa de Capa 1. Este es un voto en nombre de la dirección r en la que existe la mesa de Capa 2 y cuenta como un único voto en la mesa de Capa 1.
El voto de la mesa de Capa 2 puede caer por debajo del 51%, en cuyo caso el voto originalmente elevado a la mesa de Capa 1 **no** se retira. Solo un nuevo voto (diferente) que alcance el 51% puede cambiar el voto de la mesa en Capa 1.
Las mesas de Capa 2 solo pueden votar sobre temas de Recompensas a través de un voto elevado a Capa 1.
En resumen, los miembros de Capa 2 pueden votar por:
* Asientos y Hooks para su propia mesa, y
* Asientos, Hooks y temas de Recompensas para la mesa L1 a través del asiento de Capa 1 en el que reside su mesa de Capa 2.
### Restricciones del Juego
* Cualquier mesa puede tener al menos 2 miembros y como máximo 20 miembros.
* Una sola dirección r solo puede ocupar un asiento en una mesa determinada, pero puede ocupar un asiento en cada una de muchas mesas diferentes.
* El Juego de Gobernanza no está diseñado para recurrir más allá de dos capas. No hay ninguna imposibilidad técnica para implementar una mesa de Capa 3, pero el Hook de Gobernanza actual no la soporta.
### Recompensas de Validadores
Las recompensas de validadores son un incentivo para ejecutar un validador en la red. Las recompensas son generadas por la red y otorgadas a la intersección de miembros de Capa 1 y validadores UNL activos. Para calificar para las recompensas de validador dentro de un bloque dado de 256 ledgers, lo siguiente debe ser verdad:
* El validador está en el UNL de Xahau.
* El validador valida exitosamente a los ojos de otros validadores UNL.
* Cuando la clave pública maestra del validador se convierte en una dirección r, esa cuenta se sienta en la Mesa L1.
Las recompensas son ad hoc y se basan en los Ajustes de Balance de los usuarios de Xahau. Cuando un usuario realiza un Ajuste de Balance, una cantidad igual a su ajuste dividida por 20 se envía a la dirección r de cada uno de los validadores activos que cumplen los criterios anteriores.
## Especificación Técnica
El Hook de Gobernanza se instala en la cuenta génesis por la enmienda XahauGenesis varios ledgers después del ledger 1 en una nueva red. Esta es la mesa L1. Para crear una mesa L2, instale el Hook en una cuenta diferente, luego siente esa cuenta en la mesa L1.
### Parámetros del Hook de Gobernanza
Cuando se instala el Hook de Gobernanza, se instala con un conjunto de HookParameters. Estos especifican la composición inicial de la mesa.
Cada HookParameter tiene un nombre de 3 bytes que consiste en 3 caracteres Ascii o 2 caracteres Ascii y un identificador como se indica a continuación. LE = Little Endian.
```
Parameter Name: {'I', 'R', 'R'}
Parameter Value: Initial Reward Rate <8 byte XFL fraction between 0 and 1, LE>
Parameter Name: {'I', 'R', 'D'}
Parameter Value: Initial Reward Delay <8 byte LE XFL seconds between rewards>
Parameter Name: {'I', 'M', 'C'}
Parameter Value: Initial Member Count <1 byte>
Parameter Name: {'I', 'S', 0x00}
Parameter Value: Initial seat #0's member's 20 byte Account ID.
Parameter Name: {'I', 'S', 0x01}
Parameter Value: Initial seat #1's member's 20 byte Account ID.
... etc ... up to at most Seat 19.
```
Para iniciar el juego, se debe enviar una transacción Invoke al Hook. Puede ser enviada por cualquier cuenta. No se requieren Blob ni HookParameters. Esta transacción Invoke activa el Hook por primera vez y le solicita que cree entradas de estado para cada asiento inicial, tasa de recompensa y retraso de recompensa.
### Estado del Hook de Gobernanza
El Estado del Hook del Hook de Gobernanza se almacena en el espacio de nombres cero: `0000000000000000000000000000000000000000000000000000000000000000.`
Hay varios tipos de entradas de estado. El primero son lo que se denominan claves de miembro directas e inversas. Estas mapean cada número de asiento al miembro que se sienta allí y cada miembro al asiento en el que se sienta.
```
Key: 0x0000000000000000000000000000000000000000000000000000000000000005
Val: <20 byte AccountID of the member at seat 5 or all 0's or absent.>
Key: <20 byte AccountID of the member at seat 3>
Val: 0x03
```
A continuación, hay algunas entradas de estado singleton. Conteo de Miembros, Tasa de Recompensa y Retraso de Recompensa, respectivamente:
```
Key in Ascii: MC
Key: 0x0000000000000000000000000000000000000000000000000000000000004D43
Val: <1 byte member count (how many seats are occupied)>
Key in Ascii: RR
Key: 0x0000000000000000000000000000000000000000000000000000000000005252
Val: <8 byte LE XFL reward rate (between 0 and 1 (1 being 100%))>
Key in Ascii: RD
Key: 0x0000000000000000000000000000000000000000000000000000000000005244
Val: <8 byte LE XFL reward delay in seconds>
```
Finalmente, los votos y contadores de votos también se almacenan en el estado del Hook. Cuando un voto es emitido por un asiento, se registra en el estado del Hook de la siguiente manera:
```
Vote key is 32 bytes comprising:
'V' (0x56) - vote
'H' (0x48) or 'R' (0x52) or 'S' (0x53) - topic type
'R' (0x52) or 'D' (0x44) or 0 (0x00) to 19 (0x13) - topic detail
1 (0x01) or 2 (0x02) - target layer for this vote
0x00 00 00 00 00 00 00 00 - 8 bytes of padding
20 byte Account ID - the voter
Vote data:
20 byte Account ID or 8 byte XFL
```
Cuando se emite un voto, incrementa una entrada de estado contador de votos. Este contador realiza un seguimiento de cuántos votos hay actualmente para este par tema-dato y permite al Hook accionar el voto cuando la votación supera el umbral requerido. El estado contador es el siguiente:
```
Counter key is 32 bytes comprising:
'C' (0x43) - count
'H' (0x48) or 'R' (0x52) or 'S' (0x53) - topic type
'R' (0x52) or 'D' (0x44) or 0 (0x00) to 19 (0x13) - topic detail
1 (0x01) or 2 (0x02) - target layer for this vote
0's for padding
vote data or left-truncated vote data
```
### Transacciones del Hook de Gobernanza
Los miembros interactúan con el Hook de Gobernanza usando transacciones ttINVOKE. Además de esto, el Hook también puede emitir sus propias transacciones ttINVOKE si es una mesa L2 elevando un voto a la mesa L1.
Una transacción de voto contiene un array HookParameters en el nivel superior de la transacción:
```
{
Account: <member's account>,
TransactionType: Invoke,
NetworkID: 21337,
Destination: <table's account>,
HookParameters:
[
{
HookParameter:
{
HookParameterName: "4C", // L - the target layer
HookParameterValue: "01", // 01 for L1 table, 02 for L2 table
// note: this is the table the vote is
// intended for, not the table you're at
// i.e. for a L2 table you can vote on
// your own membership or on L1's
}
},
{
HookParameter:
{
HookParameterName: "54", // T - topic type
HookParameterValue: "4801", // H [0x00-0x09] or
// S [0x00-0x13] or
// RR or RD
}
},
{
HookParameter:
{
HookParameterName: "56", // V - vote data
HookParameterValue: <32 or 20 or 8 bytes of vote data>
}
}
]
}
```
### Borrar un Voto
No hay forma de "eliminar un voto" como tal. Puede cambiar su voto para reflejar la posición actual en su lugar.
Por ejemplo, si nadie se sienta en el asiento 8 y usted ha votado por la cuenta A para sentarse allí, y luego cambia de opinión, puede hacer un voto para vaciar el asiento 8 (aunque ya esté vacante) alineando así su voto con el estado actual del asiento.
Para hacer esto, vota con todos ceros en los datos del voto, con la misma longitud que el tema del voto normalmente requiere. Por lo tanto, para un voto de asiento, esto son 20 bytes de ceros.

View File

@@ -0,0 +1,61 @@
---
title: Métodos de API de Administrador
---
Estos métodos están destinados exclusivamente al personal de confianza responsable del mantenimiento de las operaciones del servidor xahaud.
### Métodos de Generación de Claves
| Método | Descripción |
| ------------------ | -------------------------------------------------------------------------------------------------------------------- |
| validation_create | Genera un par de claves formateado para nodos xahaud. (Los validadores deben usar tokens en lugar de claves de este método.) |
| wallet_propose | Genera claves para una nueva cuenta. |
### Métodos de Registro y Gestión de Datos
| Método | Descripción |
| --------------- | ------------------------------------------------------------------------ |
| can_delete | Habilita la eliminación en línea de ledgers hasta un ledger especificado. |
| download_shard | Descarga un fragmento específico del historial del ledger. |
| ledger_cleaner | Configura el limpiador de ledger para detectar y resolver datos corruptos. |
| ledger_request | Consulta a un servidor par por una versión específica del ledger. |
| log_level | Ver o cambiar los niveles de verbosidad del registro. |
| logrotate | Reabre el archivo de registro. |
| node_to_shard | Transfiere datos del almacén del ledger al almacén de fragmentos. |
### Métodos de Control del Servidor
| Método | Descripción |
| -------------- | -------------------------------------------------------- |
| ledger_accept | Cierra y avanza el ledger en modo autónomo. |
| stop | Apaga el servidor xahaud. |
### Métodos de Firma
| Método | Descripción |
| --------- | -------------------------------------------- |
| sign | Firma criptográficamente una transacción. |
| sign_for | Contribuye a una firma múltiple. |
### Métodos de Gestión de Pares
| Método | Descripción |
| ------------------------ | ------------------------------------------------------ |
| connect | Fuerza al servidor a conectarse a un par específico. |
| peer_reservations_add | Añade o actualiza un espacio reservado para un par específico. |
| peer_reservations_del | Elimina un espacio reservado para un par específico. |
| peer_reservations_list | Ver todos los espacios de par reservados. |
| peers | Recupera información sobre los pares conectados. |
### Métodos de Estado/Depuración
| Método | Descripción |
| ---------------------- | ------------------------------------------------------------------ |
| consensus_info | Ver el estado actual del proceso de consenso. |
| feature | Recupera información sobre las enmiendas del protocolo. |
| fetch_info | Comprueba el estado de sincronización del servidor con la red. |
| get_counts | Ver estadísticas sobre los componentes internos y el uso de memoria del servidor. |
| manifest | Recupera detalles de clave pública para un validador conocido. |
| print | Accede a información sobre los subsistemas internos. |
| validator_info | Obtiene los detalles de configuración del validador del servidor. |
| validator_list_sites | Ver los sitios que publican listas de validadores. |
| validators | Recupera información sobre los validadores actuales. |

View File

@@ -0,0 +1,16 @@
---
title: Consideraciones
---
## Marcadores
Algunos métodos devuelven más datos de los que caben eficientemente en una sola respuesta. Cuando los resultados superan el límite de la respuesta, se incluye un campo `marker` en la respuesta. Este campo le permite recuperar páginas adicionales de datos mediante solicitudes posteriores. Para continuar obteniendo datos, incluya el valor `marker` de la respuesta anterior en su próxima solicitud. Si una respuesta no incluye un `marker`, significa que ha llegado al final del conjunto de datos.
El formato del campo `marker` no está especificado intencionalmente. Cada servidor puede definir el `marker` según sea necesario, lo que significa que podría ser una cadena, un objeto anidado u otro tipo. El formato del `marker` puede variar entre servidores e incluso entre métodos en el mismo servidor. Cada `marker` es temporal y puede volverse inválido después de aproximadamente 10 minutos.
## Límite de Velocidad
El servidor `xahaud` aplica límites de velocidad a los clientes de la API que usan APIs públicas para prevenir solicitudes excesivas. El límite de velocidad se aplica en función de la dirección IP del cliente, lo que significa que múltiples clientes que comparten una [traducción de direcciones de red (NAT)](https://es.wikipedia.org/wiki/Traducci%C3%B3n_de_direcciones_de_red) compartirán el mismo límite de velocidad asociado con su IP pública.
Cuando un cliente se está acercando al límite de velocidad, el servidor incluye un campo `"warning": "load"` en el nivel superior de una respuesta de la API. Esta advertencia no aparece en cada respuesta, pero puede enviarse varias veces antes de que el servidor desconecte al cliente. Los clientes conectados como administrador están exentos del límite de velocidad.
Si un cliente supera el límite de velocidad, el servidor desconecta al cliente y bloquea temporalmente otras solicitudes de esa dirección IP. Las APIs WebSocket y JSON-RPC manejan las desconexiones de manera diferente, como se describe a continuación.

View File

@@ -0,0 +1,77 @@
---
title: Métodos de API Pública
---
Interactúe directamente con un servidor xahaud usando los métodos de API pública. Estos métodos no están necesariamente destinados al uso público en general, pero son accesibles para cualquier cliente conectado al servidor.
### Métodos de Cuenta
| Método | Descripción |
| ------------------- | --------------------------------------------------------------------------- |
| account_channels | Lista los canales de pago donde la cuenta es la fuente del canal. |
| account_currencies | Lista las monedas que la cuenta puede enviar o recibir. |
| account_info | Recupera información básica sobre una cuenta. |
| account_lines | Accede a la información de líneas de confianza de una cuenta. |
| account_objects | Recupera todos los objetos del ledger propiedad de una cuenta. |
| account_offers | Ver las ofertas de intercambio de moneda de una cuenta. |
| account_tx | Recupera el historial de transacciones de una cuenta. |
| gateway_balances | Calcula los montos totales emitidos para una cuenta. |
| noripple_check | Sugiere cambios en la configuración de Default Ripple y No Ripple de una cuenta. |
### Métodos de Ledger
| Método | Descripción |
| --------------- | ------------------------------------------------------- |
| ledger | Obtiene información sobre una versión específica del ledger. |
| ledger_closed | Recupera la versión del ledger cerrada más recientemente. |
| ledger_current | Recupera la versión actual del ledger de trabajo. |
| ledger_data | Accede al contenido bruto del ledger. |
| ledger_entry | Recupera un elemento específico de una versión del ledger. |
### Métodos de Transacción
| Método | Descripción |
| ------------------- | ------------------------------------------------------------------ |
| submit | Envía una transacción a la red. |
| submit_multisigned | Envía una transacción con firma múltiple. |
| transaction_entry | Recupera detalles sobre una transacción en un ledger específico. |
| tx | Recupera información de transacciones en todos los ledgers. |
| sign | (Admin) Firma criptográficamente una transacción. |
| sign_for | (Admin) Contribuye a una firma múltiple. |
### Métodos de Libro de Órdenes
| Método | Descripción |
| ------------------- | ----------------------------------------------------------------- |
| book_offers | Ver ofertas para intercambiar dos monedas. |
| deposit_authorized | Comprueba si una cuenta puede enviar pagos directamente a otra. |
### Métodos de Canal de Pago
| Método | Descripción |
| ------------------ | ------------------------------------------------ |
| channel_authorize | Firma un reclamo para un canal de pago. |
| channel_verify | Verifica la firma de un reclamo de canal de pago. |
### Métodos de Suscripción
| Método | Descripción |
| ----------- | ---------------------------------------- |
| subscribe | Escuchar actualizaciones sobre un tema |
| unsubscribe | Dejar de recibir actualizaciones |
### Métodos de Información del Servidor
| Método | Descripción |
| ------------- | --------------------------------------------------------- |
| fee | Recupera información sobre los costos de transacción. |
| server_info | Obtiene el estado del servidor en formato legible. |
| server_state | Obtiene el estado del servidor en formato legible por máquina. |
| manifest | Recupera detalles de clave pública para un validador. |
### Métodos de Utilidad
| Método | Descripción |
| ------ | --------------------------------------------------------------------------------- |
| json | Proxy para ejecutar comandos con parámetros JSON. _(Solo línea de comandos.)_ |
| ping | Verifica la conectividad con el servidor. |
| random | Genera números aleatorios. |

View File

@@ -0,0 +1,63 @@
---
title: Guía de Formato de Solicitudes
---
### Servidores Públicos
* wss://xahau.network o https://xahau.network (Mainnet)
* wss://xahau-test.net o https://xahau-test.net (Testnet)
### Solicitudes de Ejemplo
Para enviar una solicitud de ejemplo a la API, use los siguientes comandos.
### Websocket
```
{
"id": 3,
"command": "account_info",
"account": "rhBDFMmr3jSjgsWMqBAYaATLy3PuXy395y",
"strict": true,
"ledger_index": "validated",
"api_version": 1
}
```
### Estructura de Solicitud WebSocket
Una vez que establezca una conexión WebSocket al servidor `xahaud`, puede enviar comandos como objetos JSON con estos campos:
<table><thead><tr><th>Campo</th><th width="220">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>command</td><td>String</td><td>El nombre del método de la API</td></tr><tr><td>id</td><td>(Múltiple)</td><td><em>(Opcional)</em> Identificador único para la solicitud.</td></tr><tr><td>api_version</td><td>Number</td><td><em>(Opcional)</em> Especifica la versión de la API.</td></tr></tbody></table>
### JSON-RPC
```
POST https://xahau.network/
Content-Type: application/json
{
"method": "account_info",
"params": [
{
"account": "rhBDFMmr3jSjgsWMqBAYaATLy3PuXy395y",
"strict": true,
"ledger_index": "validated",
"api_version": 1
}
]
}
```
### Estructura de Solicitud JSON-RPC
<table><thead><tr><th>Campo</th><th width="220">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>method</td><td>String</td><td>El nombre del método de la API</td></tr><tr><td>params</td><td>Array</td><td><em>(Opcional)</em> Un array de un elemento que contiene un objeto JSON con los parámetros del método.</td></tr></tbody></table>
### Línea de Comandos
```
xahaud account_info rhBDFMmr3jSjgsWMqBAYaATLy3PuXy395y validated strict
```
### Estructura de Solicitud por Línea de Comandos
<table><thead><tr><th>Campo</th><th width="220">Descripción</th></tr></thead><tbody><tr><td>xahaud</td><td>Comenzar a llamar al servicio xahaud</td></tr><tr><td>method</td><td>El nombre del método de la API</td></tr><tr><td>params</td><td>(Opcional)</td></tr></tbody></table>

View File

@@ -0,0 +1,27 @@
---
title: Guía de Formato de Respuestas
---
Las respuestas están estructuradas de manera diferente según si la solicitud se realiza a través de las interfaces WebSocket, JSON-RPC o Línea de Comandos. Las interfaces JSON-RPC y Línea de Comandos comparten el mismo formato, ya que la interfaz de Línea de Comandos usa internamente JSON-RPC.
### Campos
| Campo | Tipo | Descripción |
| ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | (Varía) | (Para WebSocket) El ID de la solicitud original. |
| status | String | (Para WebSocket) Indica `success` cuando la solicitud fue recibida y procesada correctamente. |
| result.status | String | (Para JSON-RPC y Línea de Comandos) Indica `success` cuando la solicitud fue procesada exitosamente. |
| type | String | (Para WebSocket) El valor `response` se usa para respuestas directas a solicitudes de la API. Las notificaciones asíncronas usan otros valores, como `ledgerClosed` o `transaction`. |
| result | Object | Contiene el resultado de la consulta, con contenido que varía según el comando. |
| warning | String | _(Opcional)_ Si está presente, el valor es `load`, indicando que el cliente se está acercando al umbral del límite de velocidad donde el servidor puede desconectarse. |
| warnings | Array | _(Opcional)_ Una lista de **Objetos de Advertencia** con advertencias importantes del servidor. Para más detalles, consulte Advertencias de la API. |
| forwarded | Boolean | _(Opcional)_ `true` indica que la solicitud fue reenviada desde un servidor en Modo de Reporte a un servidor P2P para cumplir con la solicitud. El valor predeterminado es `false`. |
Advertencias de la API
Cuando una respuesta contiene un array `warnings`, cada entrada representa una advertencia específica del servidor. Cada **Objeto de Advertencia** incluye los siguientes campos:
| Campo | Tipo | Descripción |
| ------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | Number | Un código numérico único que identifica este mensaje de advertencia. |
| message | String | Una explicación legible por humanos de la advertencia. Evite escribir código que dependa del contenido de este campo; use el `id` (y `details`, si está disponible) para interpretar la advertencia. |
| details | Object | _(Opcional)_ Contexto adicional sobre la advertencia. El contenido varía según el tipo de advertencia. |

View File

@@ -0,0 +1,44 @@
---
title: Gestión de Cuentas
---
import { LinkCard } from '@astrojs/starlight/components';
Las características de Gestión de Cuentas en la red Xahau son un componente crucial para que los usuarios gestionen sus cuentas de manera efectiva.
Esto incluye varios tipos de transacciones que permiten a los usuarios realizar diversas operaciones en sus cuentas.
### Tipos de Transacciones
#### AccountSet
El tipo de transacción `AccountSet` permite a los usuarios modificar las propiedades de sus cuentas. Esto incluye configuraciones como la tasa de transferencia, las banderas de cuenta y más.
<LinkCard title="AccountSet" href="/es/docs/protocol-reference/transactions/transaction-types/accountset" />
#### AccountDelete
El tipo de transacción `AccountDelete` permite a los usuarios eliminar sus cuentas de la red Xahau. Esta operación es irreversible y debe usarse con precaución.
<LinkCard title="AccountDelete" href="/es/docs/protocol-reference/transactions/transaction-types/accountdelete" />
#### SetRegularKey
El tipo de transacción `SetRegularKey` permite a los usuarios establecer un par de claves regular para su cuenta. Este par de claves puede usarse como alternativa al par de claves maestro para firmar transacciones.
<LinkCard title="SetRegularKey" href="/es/docs/protocol-reference/transactions/transaction-types/setregularkey" />
#### SignerListSet
El tipo de transacción `SignerListSet` permite a los usuarios establecer una lista de firmantes para su cuenta. Esto es particularmente útil para las cuentas de firma múltiple donde múltiples partes deben aprobar las transacciones.
<LinkCard title="SignerListSet" href="/es/docs/protocol-reference/transactions/transaction-types/signerlistset" />
#### Import
El tipo de transacción `Import` se usa para importar transacciones desde otras redes. Esta característica es especialmente útil para los emisores que necesitan importar transacciones para sus titulares de activos. Se recomienda configurar primero las claves de sus cuentas antes de intentar importar transacciones.
Tenga en cuenta que el proceso de importación para el emisor implica tipos de transacciones específicos y requiere una configuración cuidadosa. Siempre asegúrese de que los hooks estén correctamente configurados y de que las transacciones sean válidas para las operaciones previstas.
<LinkCard title="Import" href="/es/docs/protocol-reference/transactions/transaction-types/import" />
Estos tipos de transacciones proporcionan a los usuarios un conjunto completo de herramientas para gestionar sus cuentas en la red Xahau. Como con todas las operaciones, los usuarios deben asegurarse de comprender las implicaciones de cada tipo de transacción antes de usarlos.

View File

@@ -0,0 +1,20 @@
---
title: Recompensas de Balance
---
import { LinkCard } from '@astrojs/starlight/components';
La característica de Recompensas de Balance es un aspecto único de la red Xahau que permite a los usuarios acumular y reclamar recompensas basadas en el balance de su cuenta. Esta característica se implementa mediante una combinación de código nativo (Enmienda BalanceRewards) y código de hook (Hook de Recompensa de la Cuenta Génesis).
### Tipos de Transacciones
#### ClaimReward
Una transacción `ClaimReward` permite a una cuenta reclamar las recompensas que ha acumulado. Las recompensas pueden ser reclamadas por el propietario de la cuenta o por un emisor especificado. La cuenta también puede excluirse de las recompensas estableciendo el campo Flags en 1.
<LinkCard title="ClaimReward" href="/es/docs/protocol-reference/transactions/transaction-types/claimreward" />
#### GenesisMint
El tipo de transacción `GenesisMint` también está asociado con la característica de Recompensas de Balance. Esta es una transacción Emitida que se ejecuta a través del Hook de Recompensa cada vez que un usuario reclama sus recompensas de balance.
<LinkCard title="GenesisMint - (Txn Emitida)" href="/es/docs/protocol-reference/transactions/transaction-types/genesismint-emitted-txn" />

View File

@@ -0,0 +1,26 @@
---
title: Check
---
import { LinkCard } from '@astrojs/starlight/components';
La característica Check en la red Xahau es un sistema de pago diferido que permite la creación, cancelación y cobro de cheques dentro del ledger. Esta característica está diseñada para facilitar transacciones seguras y eficientes entre partes.
### Tipos de Transacciones
#### CheckCreate
La transacción `CheckCreate` se usa para crear un objeto Check en el ledger. Esto representa un pago diferido que puede ser cobrado por su destino previsto.
<LinkCard title="CheckCreate" href="/es/docs/protocol-reference/transactions/transaction-types/checkcreate" />
#### CheckCancel
La transacción `CheckCancel` se usa para cancelar un Check que ha sido creado pero aún no cobrado. Esto permite al remitente detener el procesamiento del pago si es necesario.
<LinkCard title="CheckCancel" href="/es/docs/protocol-reference/transactions/transaction-types/checkcancel" />
#### CheckCash
La transacción `CheckCash` se usa para cobrar un Check que ha sido creado. Esto permite al destinatario recibir los fondos que han sido diferidos.
<LinkCard title="CheckCash" href="/es/docs/protocol-reference/transactions/transaction-types/checkcash" />

View File

@@ -0,0 +1,28 @@
---
title: Escrow
---
import { LinkCard } from '@astrojs/starlight/components';
La característica de Escrow es una parte crucial de la red Xahau. Proporciona un método seguro y sin confianza para las transacciones entre partes. La característica de Escrow garantiza que los activos involucrados en una transacción se mantengan de forma segura hasta que se cumplan todas las condiciones de la transacción.
### Tipos de Transacciones
La característica de Escrow incluye tres tipos de transacciones:
#### EscrowCreate
La transacción `EscrowCreate` se usa para crear un nuevo acuerdo de escrow. Esta transacción especifica los términos del escrow, incluyendo las partes involucradas, los activos a mantener en escrow y las condiciones bajo las cuales se liberarán los activos.
<LinkCard title="EscrowCreate" href="/es/docs/protocol-reference/transactions/transaction-types/escrowcreate" />
#### EscrowFinish
La transacción `EscrowFinish` se usa para completar un acuerdo de escrow. Esta transacción se ejecuta cuando se cumplen todas las condiciones del escrow. Al ejecutarse, los activos mantenidos en escrow se liberan a la parte correspondiente.
<LinkCard title="EscrowFinish" href="/es/docs/protocol-reference/transactions/transaction-types/escrowfinish" />
#### EscrowCancel
La transacción `EscrowCancel` se usa para cancelar un acuerdo de escrow. Esta transacción puede ejecutarse si las condiciones del escrow no se cumplen dentro de un plazo especificado. Al cancelarse, los activos mantenidos en escrow se devuelven a la parte que inició el escrow.
<LinkCard title="EscrowCancel" href="/es/docs/protocol-reference/transactions/transaction-types/escrowcancel" />

View File

@@ -0,0 +1,22 @@
---
title: Hooks
---
import { LinkCard } from '@astrojs/starlight/components';
Los Hooks son una característica poderosa de la red XRPL, que proporciona una sólida funcionalidad de contratos inteligentes. Son módulos WebAssembly pequeños y eficientes diseñados específicamente para el XRPL, y pueden denominarse Contratos Inteligentes para el Protocolo XRP Ledger. Los Hooks pueden escribirse en cualquier lenguaje que sea compilable con WebAssembly, lo que permite implementar una amplia gama de lógica de negocio y conceptos de contratos inteligentes.
### Tipos de Transacciones
La característica Hooks incluye dos tipos de transacciones:
**SetHook**
Este tipo de transacción se usa para configurar un hook en una cuenta.
<LinkCard title="SetHook" href="/es/docs/protocol-reference/transactions/transaction-types/sethook" />
**Invoke**
Este tipo de transacción se usa para llamar o invocar la funcionalidad de un hook.
<LinkCard title="Invoke" href="/es/docs/protocol-reference/transactions/transaction-types/invoke" />

View File

@@ -0,0 +1,20 @@
---
title: Oferta
---
import { LinkCard } from '@astrojs/starlight/components';
La característica de Oferta en la red Xahau es un componente crucial del sistema de intercambio descentralizado. Permite a los usuarios crear y cancelar ofertas, facilitando un entorno de trading dinámico y responsivo.
### Tipos de Transacciones
#### OfferCreate
La transacción `OfferCreate` se usa para colocar una oferta en el intercambio descentralizado.
<LinkCard title="OfferCreate" href="/es/docs/protocol-reference/transactions/transaction-types/offercreate" />
#### OfferCancel
La transacción `OfferCancel` se usa para cancelar una oferta existente. La documentación para este tipo de transacción se referencia en la Documentación de Xahau pero no se proporciona en el contexto dado.
<LinkCard title="OfferCancel" href="/es/docs/protocol-reference/transactions/transaction-types/offercancel" />

View File

@@ -0,0 +1,46 @@
---
title: Pagos
---
import { LinkCard } from '@astrojs/starlight/components';
La característica de Pagos en la red Xahau es un componente crucial que permite la transferencia de activos y fondos dentro de la red. Esta característica está diseñada para facilitar transacciones fluidas, garantizando una operación eficiente de la red.
### Tipos de Transacciones
La característica de Pagos comprende varios tipos de transacciones, cada uno con un propósito único en la red. Aquí hay una breve descripción de cada tipo de transacción:
**DepositPreauth**
Este tipo de transacción permite a una cuenta preautorizar transacciones entrantes desde una fuente especificada. Es una forma de incluir en la lista blanca a las cuentas, garantizando que solo se procesen las transacciones autorizadas.
<LinkCard title="DepositPreauth" href="/es/docs/protocol-reference/transactions/transaction-types/depositpreauth" />
**TrustSet**
Este tipo de transacción permite a los usuarios crear una línea de confianza con otra cuenta. Es una forma de establecer confianza entre dos cuentas, permitiéndoles realizar transacciones entre sí.
<LinkCard title="TrustSet" href="/es/docs/protocol-reference/transactions/transaction-types/trustset" />
**Payment**
Este es el tipo de transacción básico que permite la transferencia de activos entre cuentas. Es el tipo de transacción fundamental para cualquier operación de pago en la red.
<LinkCard title="Payment" href="/es/docs/protocol-reference/transactions/transaction-types/payment" />
**PaymentChannelCreate**
Este tipo de transacción permite la creación de un canal de pago entre dos cuentas. Los canales de pago son soluciones de escalabilidad fuera del ledger que permiten transacciones de alta frecuencia y bajo costo entre dos partes.
<LinkCard title="PaymentChannelCreate" href="/es/docs/protocol-reference/transactions/transaction-types/paymentchannelcreate" />
**PaymentChannelFund**
Este tipo de transacción permite a una cuenta financiar un canal de pago existente. Es una forma de añadir más activos a un canal de pago, permitiendo que se realicen más transacciones.
<LinkCard title="PaymentChannelFund" href="/es/docs/protocol-reference/transactions/transaction-types/paymentchannelfund" />
**PaymentChannelClaim**
Este tipo de transacción permite a una cuenta reclamar los fondos de un canal de pago. Es una forma de cerrar un canal de pago y recuperar los activos restantes.
<LinkCard title="PaymentChannelClaim" href="/es/docs/protocol-reference/transactions/transaction-types/paymentchannelclaim" />

View File

@@ -0,0 +1,32 @@
---
title: URIToken
---
import { LinkCard } from '@astrojs/starlight/components';
Los URITokens son la implementación de Tokens No Fungibles (NFT) nativa de la red Xahau. Existen como objetos de primera clase en el ledger, identificados de forma única por el hash de su emisor y el Identificador Uniforme de Recursos (URI). Los URITokens pueden apuntar a cualquier contenido digital, y solo puede existir un objeto por URI por cuenta en el ledger.
El emisor tiene la capacidad de establecer una bandera para permitir la destrucción del objeto en el futuro. La reserva de cada propietario también queda bloqueada al poseer el URIToken.
### Tipos de Transacciones
#### URITokenMint
La transacción URITokenMint acuña un nuevo URIToken y asigna la propiedad a la cuenta especificada. El URIToken acuñado representa un activo digital único que puede usarse en diversas aplicaciones. El emisor puede optar por permitir que el URIToken acuñado sea destruido en el futuro.
<LinkCard title="URITokenMint" href="/es/docs/protocol-reference/transactions/transaction-types/uritokenmint" />
#### URITokenBurn
La transacción URITokenBurn se usa para quemar un URIToken en Xahau. Quemar un URIToken lo elimina permanentemente de la circulación. La transacción no tiene requisitos especiales de costo de transacción. Se requiere la cuenta que posee el URIToken a quemar para esta transacción.
<LinkCard title="URITokenBurn" href="/es/docs/protocol-reference/transactions/transaction-types/uritokenburn" />
#### URITokenBuy
La transacción URITokenBuy permite a un usuario comprar un URIToken del emisor. Esta transacción se usa para transferir la propiedad de un URIToken del emisor al comprador. Se requieren la cuenta del comprador, el identificador único del URIToken a comprar y la cantidad de moneda a pagar por el URIToken para esta transacción.
<LinkCard title="URITokenBuy" href="/es/docs/protocol-reference/transactions/transaction-types/uritokenbuy" />
<LinkCard title="URITokenCreateSellOffer" href="/es/docs/protocol-reference/transactions/transaction-types/uritokencreateselloffer" />
<LinkCard title="URITokenCancelSellOffer" href="/es/docs/protocol-reference/transactions/transaction-types/uritokencancelselloffer" />

View File

@@ -0,0 +1,33 @@
---
title: Nodos Públicos (RPC)
description: >-
Ejecutar su propio nodo: genial. ¿Quiere empezar rápido? Use los nodos RPC públicos de Xahau.
---
## Mainnet (red 21337)
* Websocket
* `wss://xahau.network`
* `wss://xahau.org` (alias, algunos bloqueadores de anuncios bloquean .network)
* HTTP POST RPC
* `https://xahau.network`
* `https://xahau.org` (alias, algunos bloqueadores de anuncios bloquean .network)
* Definiciones de Red (Binary Codec, ...)
* [`https://xahau.network/server_definitions.json`](https://xahau.network/server_definitions.json)
## Testnet (red 21338)
* Websocket
* `wss://xahau-test.net`
* HTTP POST RPC
* `https://xahau-test.net`
* Definiciones de Red (Binary Codec, ...)
* [`https://xahau-test.net/server_definitions.json`](https://xahau-test.net/server_definitions.json)
## JSHooks-Testnet (red 31338)
* Websocket
* `wss://jshooks.xahau-test.net`
* HTTP POST RPC
* `https://jshooks.xahau-test.net`
* Definiciones de Red (Binary Codec, ...)
* [`https://jshooks.xahau-test.net/server_definitions.json`](https://jshooks.xahau-test.net/server_definitions.json)

View File

@@ -0,0 +1,64 @@
---
title: Firma de Transacciones
description: >-
Las redes con Hooks habilitados requieren campos de transacción específicos y ofrecen más
tipos de transacciones, por lo que no todos los clientes funcionarán de inmediato. `xrpl-accountlib`
---
## Principales diferencias
1. Las redes con Hooks habilitados permiten obtener las definiciones de red de forma dinámica. Esto permite a los clientes adaptar los tipos de transacciones disponibles, los objetos del ledger, las propiedades y los tipos de valor. Cuando se implementa correctamente, las bibliotecas de firma y codificación no tienen que actualizarse cuando la red añade tipos/propiedades de transacciones/objetos. <mark style="color:blue;">**Las bibliotecas a continuación implementan esto y lo gestionarán por usted.**</mark>
2. Las redes con Hooks habilitados requieren un **NetworkID** con cada transacción para prevenir la repetición de transacciones en otra cadena. El **NetworkID** también será devuelto por un comando RPC `server_info` en el campo `network_id` (por ejemplo, **`21338`** para Hooks V3 testnet)
3. Las transacciones en una red con Hooks habilitados pueden necesitar tarifas más altas para entregar una transacción a otra cuenta, basándose en los Hooks que se ejecutarán al salir de la cuenta remitente y al recibir en la cuenta de destino. Una tarifa razonable para satisfacer la ejecución de Hooks puede obtenerse dinámicamente desde un nodo emitiendo el comando `fee` mientras se proporciona una transacción como `tx_blob`. <mark style="color:blue;">**Las bibliotecas a continuación implementan esto y lo gestionarán por usted.**</mark>
## JavaScript/Typescript
El [**paquete npm `xrpl-accountlib`**](https://www.npmjs.com/package/xrpl-accountlib) puede firmar transacciones para redes con Hooks habilitados, ya que ofrece soporte completo de características de red dinámico, obteniendo las definiciones de red en tiempo de ejecución.
El [**paquete npm `xrpl-client`**](https://www.npmjs.com/package/xrpl-client) se integra perfectamente con `xrpl-accountlib` (y viene como dependencia) para obtener dinámicamente las definiciones de red mencionadas y los valores de cuenta, ayudando a enviar la transacción.
### Ejemplo de Código
```javascript
import {
derive,
utils,
signAndSubmit,
} from "xrpl-accountlib"
const wss = 'wss://xahau-test.net'
const account = derive.familySeed("s...")
const networkInfo = await utils.txNetworkAndAccountValues(wss, account)
const tx = {
TransactionType: "SetHook",
Hooks: [ { Hook: {
CreateCode: "0061736D01000000011C0460057F7F7F7F7F017E60037F7F7E017E60027F7F017F60017F017E02230303656E76057472616365000003656E7606616363657074000103656E76025F670002030201030503010002062B077F0141B088040B7F004180080B7F0041A6080B7F004180080B7F0041B088040B7F0041000B7F0041010B07080104686F6F6B00030AC4800001C0800001017F230041106B220124002001200036020C41920841134180084112410010001A410022002000420010011A41012200200010021A200141106A240042000B0B2C01004180080B254163636570742E633A2043616C6C65642E00224163636570742E633A2043616C6C65642E22",
Flags: 1,
HookApiVersion: 0,
HookNamespace: "F".repeat(64),
HookOn: "F".repeat(58) + "BFFFFE",
}
}],
...networkInfo.txValues,
// ^^ Esto añade valores obtenidos automáticamente:
// Sequence, Account, LastLedgerSequence,
// Fee (Hooks habilitados: autodetección (desde el ledger))
}
/**
* Nota: el código anterior y `signAndSubmit` resultan en obtener
* y establecer automáticamente una tarifa para usted. Si desea comprobar la tarifa
* para min/max/..., obtenga su propia tarifa (string en drops) usando:
* utils.networkTxFee(wss, tx)
*
* por ejemplo:
* const Fee = await utils.networkTxFee(wss, tx)
* assert(Number(Fee) < 50_000, "Auto fee above 50k drops, abort")
* Object.assign(tx, { Fee, })
*/
const submitted = await signAndSubmit(tx, wss, account)
console.log(submitted)
```

View File

@@ -0,0 +1,56 @@
---
title: Tarifas de Transacción
description: >-
Los contratos inteligentes (Hooks) de Xahau requieren tarifas específicas para la transacción y el destino.
Puede obtener fácilmente la tarifa requerida del comando RPC `fee`.
---
import { Aside } from '@astrojs/starlight/components';
Aunque las bibliotecas pueden encargarse de la determinación de tarifas por usted, al construir sus propias integraciones con la Red Xahau, es posible que deba implementar la determinación dinámica de tarifas basada en la transacción, la cuenta de origen y la cuenta de destino.
Dado que el remitente de una transacción tendrá que pagar las tarifas requeridas para los Hooks invocados para el tipo de transacción específico, donde los Hooks pueden existir tanto en la cuenta de origen como en la de destino, puede enviar un TX Blob (firmado con una cuenta ficticia) al comando `fee`, después del cual Xahau devolverá las tarifas específicas requeridas para la transacción específica.
### Ayudante RPC de Tarifas
Las tarifas de transacción en un ledger con la enmienda Hooks habilitada se vuelven no triviales para calcular para usuarios finales y/o aplicaciones de cartera. Esto se debe a que los hooks fuertes deben ser pagados por el originador de una transacción, y puede haber hasta 4 hooks fuertes en la cuenta remitente y 4 en la cuenta receptora, así como cualquier otra parte interesada transaccional fuerte involucrada (como puede ser el caso con algunos tipos de transacciones exóticas). Además, si la transacción es un SetHook, el tamaño de los parámetros, el tamaño del código y si es una operación _create_ o _install_ determinan el tamaño de la tarifa.
Por lo tanto, se recomienda encarecidamente que **todas** las transacciones se ejecuten a través de la llamada RPC de tarifas actualizada antes de ser enviadas al ledger.
#### Para invocar la llamada RPC:
1. Abra una conexión WebSocket al nodo Hooks con el que trabajará.
2. Componga la transacción serializada de la que desea conocer la tarifa con lo siguiente:
* `Fee: 0`
* `SigningPubKey: ""` (Es decir: VL de 0 bytes de tipo 0x73. En hex:`0x7300`.)
* **No** firme la transacción.
3. Envíela como blob hex al RPC de la siguiente manera:
```json
{"command":"fee", "tx_blob":"<hex blob>"}
```
Para HTTP POST RPC, envíela de la siguiente manera:
```json
{"method":"fee", "params": [{"tx_blob":"<hex blob>"}] }
```
La respuesta debería tener un aspecto similar a:
```json
{
result: {
drops: {
base_fee: '130520',
},
//...
},
type: 'response'
}
```
Tome la tarifa base y establézcala como el campo `Fee` en la transacción. Ahora firme y envíela según el proceso normal de envío de transacciones.
Si hay un valor no válido para `tx_blob` o `tx_blob` está ausente, se devolverá un resultado JSON normal con una `base_fee` de 10.

View File

@@ -0,0 +1,63 @@
---
title: Proceso de Versionado
description: >-
Este documento describe nuestro flujo de trabajo de versionado en GitHub para agilizar
el desarrollo, pruebas y despliegue de nuevas características y correcciones.
---
import { Aside } from '@astrojs/starlight/components';
Este documento describe el proceso de versionado que usamos en nuestro repositorio de GitHub. Usamos un flujo de trabajo de tres ramas: `dev`, `candidate` y `release`. Este proceso garantiza que todas las nuevas características y correcciones sean probadas exhaustivamente antes del lanzamiento.
### Rama Dev
La rama dev es la rama principal para el desarrollo continuo. Todas las nuevas características, correcciones de errores y mejoras se fusionan en esta rama. Esta es la rama más activa, y es donde los desarrolladores deben basar su trabajo.
Para contribuir a la rama dev, siga estos pasos:
1. Haga un fork del repositorio en su propia cuenta de GitHub.
2. Clone el repositorio bifurcado en su máquina local.
3. Cree una nueva rama para su característica o corrección de errores.
4. Realice sus cambios y haga commit en su rama.
5. Haga push de su rama a su repositorio bifurcado en GitHub.
6. Cree un pull request desde su rama a la rama dev en el repositorio principal.
<Aside type="caution">
Todos los merges en la rama dev deben ser squashed
</Aside>
Los mantenedores de código revisarán su pull request y proporcionarán retroalimentación. Una vez que el código sea aprobado, se fusionará en la rama dev.
### Ramas Candidate
Una vez que las características en la rama `dev` están listas para pruebas, se fusionan en una rama `candidate`. Esta rama sirve como área de preparación para el código que está casi listo para su lanzamiento.
El código en la rama `candidate` se prueba exhaustivamente. Los errores o problemas encontrados se corrigen en la rama `dev` y luego se fusionan de vuelta en la rama `candidate`.
La rama `candidate` normalmente está en esta fase de pruebas durante aproximadamente 2 semanas. Sin embargo, este período puede ser más largo o más corto, dependiendo de la urgencia de las correcciones o del tamaño de las nuevas características.
1. Cree una nueva rama `candidate` desde `dev`.
2. Cree un PR desde la rama `candidate` a la rama `release` con un nombre como "Proposed."
3. Actualice la "Descripción General de Alto Nivel del Cambio" para incluir los Pull Requests de `candidate`. Actualice el "Contexto del Cambio" para incluir cualquier nota adicional sobre los PRs.
### Rama Release
Una vez que el código en la rama `candidate` ha sido probado exhaustivamente y todos los problemas han sido abordados, se fusiona en la rama `release`. Este es el paso final antes de que se lance el código.
La rama `release` contiene el código que está actualmente en producción o está a punto de ser lanzado. Solo el código completamente probado y estable debe estar en esta rama.
Una vez que el código está en la rama `release`, se etiqueta con un número de versión. Este número de versión se usa para rastrear el lanzamiento y también se usa al crear notas de versión.
En la rama `release`, se construye y publica un binario en https://build.xahau.tech/. Este binario es el producto final que se entrega a los usuarios finales.
Para lanzar el código, siga estos pasos:
1. Fusione el pull request `candidate` en la rama release.
2. Elimine la rama `candidate`.
<Aside type="caution">
Todos los merges en la rama release deben hacerse con \`git merge --ff-only candidate\`
</Aside>
### Resumen
Este flujo de trabajo de tres ramas garantiza que todo el código sea probado exhaustivamente antes del lanzamiento. Nos permite detectar y corregir problemas antes de que lleguen a producción, y proporciona un camino claro para mover el código desde el desarrollo hasta el lanzamiento. El uso de una LAN personalizada para pruebas y métricas de perfilado garantiza que nuestro código no solo sea funcional sino también eficiente y con buen rendimiento.

View File

@@ -0,0 +1,47 @@
---
title: Encadenamiento
description: Encadena múltiples hooks para realizar tareas más útiles
---
import { Aside } from '@astrojs/starlight/components';
<Aside type="tip" title="Filosofía de diseño de Hooks">
_Cada Hook debe hacer una sola cosa, y hacerla realmente bien._
</Aside>
### Historia
En los primeros días de los Hooks, solo era posible instalar un Hook por cuenta. Esto obligaba a los usuarios a crear Hooks monolíticos si querían hacer más de una cosa: por ejemplo, compensar carbono y actuar como firewall al mismo tiempo.
Esto iba en contra de la Filosofía de diseño de Hooks, por lo que se introdujo el Encadenamiento de Hooks.
### Encadenamiento
Una cadena de Hooks es una secuencia de hasta **10** Hooks instalados en una cuenta de Xahau.
* Una cadena de Hooks se ejecuta correctamente cuando cada Hook de la cadena ha sido ejecutado individualmente y posteriormente llama a [accept](/es/docs/hooks/functions/control/accept).
* La ejecución de cada cadena comienza en la posición 0 y termina en la posición 9. Si una posición está vacía (porque nunca fue ocupada o porque el Hook instalado allí ha sido eliminado), entonces esa posición se omite y se considera exitosa.
* Para que una transacción tenga éxito, ambos extremos de la transacción (lado emisor y lado receptor) deben haberse ejecutado correctamente. Esto significa que, si hay una cadena de Hooks instalada en ambos lados, ambas cadenas deben ejecutarse correctamente para que la transacción tenga éxito.
Los Hooks se instalan en la cadena utilizando la [transacción SetHook](/es/docs/hooks/concepts/sethook-transaction). Al instalarlos, quien los instala puede especificar [parámetros](/es/docs/hooks/concepts/parameters) en el momento de la instalación, los cuales pueden cambiar el comportamiento del Hook instalado.
<figure>
![Example: Execution flow for a transaction passing through two Hook Chains](/assets/spaces_m6f29os4wP16vCS4lHNh_uploads_0OucxySTRinbe13SITJT_5561b32-sethook-Page-3.png)
<figcaption>*Ejemplo: flujo de ejecución de una transacción que pasa por dos cadenas de Hooks*</figcaption>
</figure>
### Manipulación de la cadena
Además de las operaciones en el momento de la instalación especificadas en la [transacción SetHook](/es/docs/hooks/concepts/sethook-transaction), los Hooks tienen cierto control en tiempo de ejecución sobre la ejecución de la cadena:
* Un Hook puede determinar su propio `HookHash` llamando a [hook_hash](/es/docs/hooks/functions/hook-context/hook_hash).
* Un Hook puede determinar su posición en la cadena de Hooks utilizando [hook_pos](/es/docs/hooks/functions/hook-context/hook_pos).
* Un Hook puede omitir (o volver a habilitar) otro Hook más adelante en la cadena utilizando [hook_skip](/es/docs/hooks/functions/hook-context/hook_skip).
* Un Hook puede modificar los [parámetros](/es/docs/hooks/concepts/parameters) de otro Hook más adelante en la cadena utilizando [hook_param_set](/es/docs/hooks/functions/hook-context/hook_param_set).
### Ejecuciones débiles
Las cadenas de Hooks se ejecutan de forma [fuerte](/es/docs/hooks/concepts/weak-and-strong). Sin embargo, cualquier Hook en cualquier cadena puede indicar que requiere una segunda ejecución débil llamando a [hook_again](/es/docs/hooks/functions/hook-context/hook_again). Si todas las cadenas de Hooks se ejecutan correctamente, entonces la transacción original se aplica. Una vez aplicada la transacción original, pueden producirse ejecuciones débiles en el siguiente orden:
1. Ejecución `cbak` si se trata de una transacción emitida.
2. Participantes transaccionales débiles que hayan optado por permitir una [Collect Call](/es/docs/hooks/concepts/collect-call). El orden de ejecución es por orden de llegada según el evento que provocó que el participante fuera marcado (como el pathing).
3. Cualquier Hook marcado como _Again as Weak_ (AAW). El orden de ejecución para AAW es primero numérico según el ID de la cuenta y luego numérico según la posición del Hook.

View File

@@ -0,0 +1,27 @@
---
title: Collect Call
---
import { Card, Aside } from '@astrojs/starlight/components';
<Card title="Filosofía de diseño de Hooks">
_Cada parte afectada por una transacción debería tener la oportunidad de que sus hooks se ejecuten._
</Card>
Cuando los hooks no se ejecutan de forma fuerte (Strongly Executed), no es justo cargar el coste de su ejecución a la transacción original. Por ejemplo, un _OfferCreate_ que cruza 20 ofertas en el DEX no debería verse obligado a pagar por la ejecución de los Hooks de cada una de esas cuentas.
Por lo tanto, durante la ejecución débil típica, la tarifa de ejecución se cobra al propietario del Hook. Para habilitar esto:
* El propietario del Hook debe haber configurado `asfTshCollect` en su cuenta de Xahau utilizando la transacción AccountSet.
* El propietario del Hook debe haber configurado `hsfCollect` en el Hook específico que desea que sea llamado como un TSH débil.
### Tabla de responsabilidad de tarifas
| Tipo de ejecución débil | Tarifa |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><strong>Again As Weak</strong><br />- Ocurre cuando un Hook ejecutado de forma fuerte llama a <a href="/es/docs/hooks/functions/hook-context/hook_again">hook_again</a></p> | Gratis (ya pagado durante la ejecución fuerte). |
| <p><strong>Callback</strong><br />- Ocurre cuando una transacción emitida entra en un ledger o se marca como imposible de entrar en un ledger.</p> | Gratis (ya pagado durante la emisión). |
| <p><strong>Participante transaccional débil</strong><br />- Ocurre si una transacción afecta de alguna manera a tu cuenta.</p> | Pagado por tu cuenta (no por la transacción original) solo si tu cuenta tiene activada la bandera `asfTshCollect` y tu Hook tiene activada la bandera `hsfCollect`. |
<Aside type="caution">
Esta es una funcionalidad avanzada que probablemente la mayoría de desarrolladores de Hooks no utilizarán.
</Aside>

View File

@@ -0,0 +1,227 @@
---
title: Compilación de Hooks
---
import { Aside } from '@astrojs/starlight/components';
### Restricciones
Todos los Hooks se compilan en un único [módulo de WebAssembly](https://webassembly.github.io/spec/core/syntax/modules.html) antes de poder ser establecidos en una cuenta de Xahau.
Un Hook siempre implementa y exporta exactamente una o ambas de las siguientes funciones:
`int64_t hook(uint32_t ctx) { ... }` _obligatoria_
* Se ejecuta cuando una transacción entra o sale de la cuenta en la que está configurado el Hook (`ctx = 0`) o
* Se ejecuta cuando se ejecuta como un [Participante Transaccional Débil](/es/docs/hooks/concepts/weak-and-strong) (`ctx > 0`).
`int64_t cbak(uint32_t ctx) { ... }` _opcional_
* Se ejecuta cuando una transacción emitida es aceptada con éxito en un ledger (`ctx = 0`) o
* Se ejecuta cuando una transacción emitida no puede ser aceptada en ningún ledger (`ctx = 1`).
Los Hooks no pueden definir otras funciones. En su lugar, deben hacer un uso ingenioso de macros para realizar todos sus cálculos dentro de estas dos funciones. Esto forma parte de una restricción computacional diseñada para mantener predecible el tiempo de ejecución de los Hooks.
Además, los Hooks no disponen de memoria _heap_. Toda la memoria necesaria debe reservarse y utilizarse en la pila (_stack_).
### Ejemplo
Aquí tienes un ejemplo de un Hook escrito en C. El Hook imprime 0...3 en el log de trazas antes de aceptar la transacción original.
```c
#include <stdint.h>
#define GUARD(maxiter) _g(__LINE__, (maxiter)+1)
extern int32_t _g (uint32_t id, uint32_t maxiter);
extern int64_t accept (uint32_t read_ptr, uint32_t read_len, int64_t error_code);
extern int64_t trace_num (uint32_t read_ptr, uint32_t read_len, int64_t number);
int64_t hook(uint32_t ctx)
{
for (int i = 0; GUARD(3), i < 3; ++i)
{
trace_num("test", 4, i);
}
accept (0,0,0);
return 0;
}
````
<Aside type="tip">
Con fines educativos, el ejemplo anterior no incluye deliberadamente `hookapi.h` (que normalmente utilizarían los desarrolladores).
</Aside>
### Compilación
Una [variedad de compiladores](https://www.google.com/search?q=webassembly+compiler+C) puede generar WebAssembly válido a partir de un archivo fuente en C. Una vez compilado, un Hook existe como un archivo binario `.wasm`. Este contiene un módulo de WebAssembly. Utilizando `wasmcc` para compilar y la herramienta `wasm2wat` para convertirlo a una forma legible por humanos, este binario puede representarse en formato comprensible. A continuación se muestra el resultado de compilación del ejemplo anterior.
```
(module
(type (;0;) (func (param i32 i32) (result i32)))
(type (;1;) (func (param i32 i32 i64) (result i64)))
(type (;2;) (func))
(type (;3;) (func (param i32) (result i64)))
(import "env" "_g" (func $_g (type 0)))
(import "env" "trace_num" (func $trace_num (type 1)))
(import "env" "accept" (func $accept (type 1)))
(func $__wasm_call_ctors (type 2))
(func $cbak (type 3) (param i32) (result i64)
(local i32 i32 i32 i64)
global.get 0
local.set 1
i32.const 16
local.set 2
local.get 1
local.get 2
i32.sub
local.set 3
i64.const 0
local.set 4
local.get 3
local.get 0
i64.store offset=8
local.get 4
return)
(func $hook (type 3) (param i32) (result i64)
(local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i64 i32 i32 i32 i64 i32 i32 i32)
global.get 0
local.set 1
i32.const 16
local.set 2
local.get 1
local.get 2
i32.sub
local.set 3
local.get 3
global.set 0
i32.const 0
local.set 4
local.get 3
local.get 0
i64.store offset=8
local.get 3
local.get 4
i32.store offset=4
block ;; label = @1
loop ;; label = @2
i32.const 3
local.set 5
i32.const 14
local.set 6
i32.const 4
local.set 7
local.get 6
local.get 7
call $_g
drop
local.get 3
i32.load offset=4
local.set 8
local.get 8
local.set 9
local.get 5
local.set 10
local.get 9
local.get 10
i32.lt_s
local.set 11
i32.const 1
local.set 12
local.get 11
local.get 12
i32.and
local.set 13
local.get 13
i32.eqz
br_if 1 (;@1;)
i32.const 1024
local.set 14
i32.const 4
local.set 15
local.get 3
i32.load offset=4
local.set 16
local.get 16
local.set 17
local.get 17
i64.extend_i32_s
local.set 18
local.get 14
local.get 15
local.get 18
call $trace_num
drop
local.get 3
i32.load offset=4
local.set 19
i32.const 1
local.set 20
local.get 19
local.get 20
i32.add
local.set 21
local.get 3
local.get 21
i32.store offset=4
br 0 (;@2;)
end
end
i64.const 0
local.set 22
i32.const 0
local.set 23
local.get 23
local.get 23
local.get 22
call $accept
drop
i32.const 16
local.set 24
local.get 3
local.get 24
i32.add
local.set 25
local.get 25
global.set 0
local.get 22
return)
(table (;0;) 1 1 funcref)
(memory (;0;) 2)
(global (;0;) (mut i32) (i32.const 66576))
(global (;1;) i32 (i32.const 1029))
(global (;2;) i32 (i32.const 1024))
(global (;3;) i32 (i32.const 66576))
(global (;4;) i32 (i32.const 1024))
(export "memory" (memory 0))
(export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "__data_end" (global 1))
(export "__global_base" (global 2))
(export "__heap_base" (global 3))
(export "__dso_handle" (global 4))
(export "cbak" (func $cbak))
(export "hook" (func $hook))
(data (;0;) (i32.const 1024) "test\00"))
```
El desarrollador promedio de Hooks nunca necesitará examinar directamente WebAssembly. Sin embargo, es un ejercicio conceptual útil revisar el contenido del Hook de ejemplo.
Arriba podemos ver:
* Se importan tres funciones desde la API de Hooks (`_g`, `accept`, `trace_num`)
* El Hook define dos funciones (`cbak`, `hook`)
* El Hook exporta dos funciones (de nuevo: `cbak`, `hook`)
* Algunos datos estáticos (constantes) se registran en el Hook (ver `data` al final).
Es muy importante tener en cuenta que un Hook *solo debe* importar funciones disponibles desde la API de Hooks y *solo debe* exportar las funciones `cbak` y `hook`. Además, todos los Hooks deben importar `_g` desde la API de Hooks, que es la función `guard`.
<Aside type="tip">
WebAssembly es un lenguaje de `bytecode` de computación general independiente de la plataforma. Tiene una correspondencia directa con una versión legible por humanos. Ambos formatos se utilizan de forma intercambiable.
</Aside>
### Exportaciones no deseadas
La mayoría de los compiladores de WebAssembly (incluido el anterior) generan exportaciones adicionales para sus propios propósitos de enlace. En muchos casos, desactivar su generación es difícil o imposible.
Las exportaciones no deseadas provocarán que un Hook válido sea rechazado. Por lo tanto, tras la compilación, los desarrolladores deben usar la [Hook Cleaner Utility](https://github.com/XRPLF/hook-cleaner-c) para eliminarlas. No hacerlo provocará que tu Hook sea rechazado.
<Aside type="caution">
No olvides usar la [Hook Cleaner Utility](https://github.com/XRPLF/hook-cleaner-c) o tus Hooks serán rechazados.
</Aside>

View File

@@ -0,0 +1,71 @@
---
title: Depuración de Hooks
description: ¡Cómo imprimir "hello world" desde tu Hook!
---
import { Aside } from '@astrojs/starlight/components';
### ¿Cómo puedo depurar un Hook?
La API de Hooks proporciona un conjunto de funciones en el espacio de nombres `trace` que escriben salida en el archivo de logs de `xrpld` cuando este está configurado con el nivel de log _trace_. Estas funciones, en términos generales, te permiten ver el valor de variables, buffers y, en general, seguir la ejecución y el estado de un Hook en tiempo de ejecución.
<Aside type="tip">
En el momento de escribir esto no existe un depurador interactivo de Hooks. Debes utilizar las funciones de trace.
</Aside>
### APIs de Trace
Las siguientes funciones `trace` están disponibles en la API de Hooks:
| Hook API | Qué hace |
| ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| [trace](/es/docs/hooks/functions/trace-debug/trace) | Imprime un mensaje en utf-8, seguido de un buffer especificado por el usuario (este último opcionalmente en hexadecimal). |
| [trace_num](/es/docs/hooks/functions/trace-debug/trace_num) | Imprime un mensaje en utf-8, seguido de un entero. |
| [trace_float](/es/docs/hooks/functions/trace-debug/trace_float) | Imprime un mensaje en utf-8, seguido de un número de punto flotante XFL. |
### Ejemplo
El siguiente código imprimirá una única línea de traza y luego aceptará la Transacción Originaria.
```c
#include "../hookapi.h"
int64_t hook(int64_t reserved)
{
trace_num(SBUF("A number"), 10);
accept(0,0,0);
return 0;
}
````
Un ejemplo de la línea de log generada por `xahaud` cuando un pago entra o sale de la cuenta del Hook:
```
2021-Apr-13 13:59:11.083700726 UTC View:TRC
HookTrace[rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh-rE3SfnjwfzZFL3JK9cLVfJuy8Ar1XnCqPw]:
A number 10
```
Lo anterior aparece en el log en una sola línea, pero aquí se muestra dividido para mayor claridad.
<Aside type="tip" title="Usa testnet">
La [Xahau Testnet](https://xahau-test.net/) es el lugar perfecto para probar tus Hooks.
</Aside>
### Formato del log
A continuación se muestra un desglose del formato del log:
| Parte | Descripción | # |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | - |
| 2021-Apr-13 13:59:11.083700726 UTC View:TRC | Prefijo de `xahaud` en la línea de log | 1 |
| HookTrace | Indica que es una traza iniciada por el propio Hook y no otro tipo de información. Otros tipos incluyen `HookError`, `HookEmit` y `HookInfo`. | 2 |
| [rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh | La primera cuenta entre corchetes es la cuenta del Hook. | 3 |
| -rE3SfnjwfzZFL3JK9cLVfJuy8Ar1XnCqPw]: | La segunda cuenta entre corchetes es la cuenta que originó la transacción. | 4 |
| A number | Este es el mensaje que el Hook debía mostrar antes de la carga útil de la traza | 5 |
| 10 | Este es el valor de la traza | 6 |
<Aside type="tip">
`Xahaud` genera una gran cantidad de salida. Por ello, suele ser recomendable filtrar los logs para las cuentas que te interesan.
Por ejemplo: `tail -f log | grep HookTrace | grep <account>`
</Aside>

View File

@@ -0,0 +1,64 @@
---
title: Transacciones emitidas
description: ¡Tu Hook puede hacer mucho más que simplemente bloquear o permitir transacciones!
---
import { Aside } from '@astrojs/starlight/components';
### Contexto
**Todos** los cambios realizados en Xahau _deben_ ser el resultado de aplicar una transacción válida al ledger. Por lo tanto, si se realiza algún cambio _X_, entonces alguna transacción _Y_ es responsable.
Al diseñar la API de Hooks, necesitábamos una forma de que los Hooks pudieran realizar cambios en el ledger _más allá_ de simplemente aceptar o rechazar una transacción. Sin embargo, asociar estos cambios a la Transacción Originaria resultaba confuso y aumentaba significativamente la complejidad general del sistema.
Supongamos, por ejemplo, que un Hook necesita enviarte fondos... la operación de envío se aplicaría efectivamente en el ledger a través de la Transacción Originaria, que podría haber sido algo completamente distinto, como una transacción AccountSet. Además, esta operación de envío debería poder activar otro Hook en el lado receptor del pago.
La solución: **Transacciones emitidas**. Permitimos que la Transacción Originaria haga exactamente lo que indica su contenido. Si nuestro Hook necesita realizar un cambio adicional en el ledger, como enviar un pago, crea y luego _emite_ una nueva transacción.
### ¿Qué son las Transacciones emitidas?
Las Transacciones emitidas son transacciones _nuevas_ creadas por la ejecución de un Hook y que entran en consenso para ser procesadas en el siguiente ledger. La transacción puede ser de cualquier tipo, pero debe seguir reglas estrictas de emisión.
Para emitir una transacción, el Hook primero prepara la transacción serializada y luego llama a [emit](/es/docs/hooks/functions/emitted-transaction/emit-1).
Dado que las transacciones emitidas pueden activar Hooks en el siguiente ledger, que a su vez pueden emitir más transacciones, todas las transacciones emitidas incluyen un campo `burden` y un campo `generation` dentro de su bloque `EmitDetails`. El bloque `EmitDetails` reemplaza el campo de firma en una transacción tradicional.
Los campos `burden` y `generation` previenen conjuntamente ataques de tipo [Fork bomb](https://en.wikipedia.org/wiki/Fork_bomb) en el ledger al aumentar exponencialmente el coste de las transacciones emitidas que crecen de forma exponencial.
Es importante destacar que la API de Hooks sigue la regla estricta de _no reescritura_. Debes presentar una transacción emitida completa, válida y canónicamente formada a xahaud para su emisión, o será rechazada. No es responsabilidad de xahaud construir tu transacción por ti. El Hook debe hacerlo por sí mismo.
### Callbacks
Como se introdujo en [Introducción y Terminología](/es/docs/hooks/concepts/terminology), las transacciones emitidas activan callbacks cuando son aceptadas en un ledger. Debido a la naturaleza descentralizada del consenso, la aceptación en un ledger de una transacción emitida **no está garantizada**, aunque normalmente es muy probable.
Si una transacción emitida expira antes de poder ser aceptada en un ledger (por varias razones: los ledgers pueden estar llenos, la comisión puede ser demasiado alta o la transacción puede ser inválida), entonces se crea una _pseudo-transacción_ en el ledger para limpiar la transacción emitida. Esta pseudo-transacción también llama al callback de tu Hook, con `parameter = 1` para indicar que la transacción emitida ha fallado.
### Reglas de emisión
La API [emit](/es/docs/hooks/functions/emitted-transaction/emit-1) aplicará las siguientes reglas sobre una transacción propuesta (a emitir):
| # | Regla de emisión | Explicación |
| - | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | `sfSequence` = 0 | Las transacciones emitidas _no_ incrementan el número de secuencia de la cuenta del Hook. Siempre debe establecerse en cero. |
| 2 | `sfPubSigningKey` = 0 | Las transacciones emitidas no están firmadas, pero este campo es obligatorio para el procesamiento en xrpld. Debe establecerse en ceros. |
| 3 | `sfEmitDetails` presente y válido | Las transacciones emitidas requieren un bloque `sfEmitDetails` correctamente completado. Consulta la sección EmitDetails más abajo. |
| 4 | `sfSignature` ausente | Este campo debe estar ausente en la transacción emitida, ya que de lo contrario la transacción sería ambigua. |
| 5 | `LastLedgerSequence` válido y en el futuro | Todas las transacciones emitidas deben tener este campo definido para que el Hook pueda detectar fallos si no recibe callback. Actualmente se establece como máximo en 5 ledgers después del ledger actual. |
| 6 | `FirstLedgerSequence` válido y en el siguiente ledger | Todas las transacciones emitidas deben comenzar en el siguiente ledger (después del actual) para evitar ejecuciones recursivas dentro de un mismo ledger. |
| 7 | Fee correctamente calculada y establecida | La comisión depende del tamaño de la transacción emitida y de la carga en la red (por ejemplo, si proviene de otra transacción emitida). |
| 8 | Límite de generación no excedido | Una transacción emitida puede generar otras, formando una cadena. La longitud de esta cadena (`sfEmitGeneration`) está actualmente limitada a 10. |
### Bloque EmitDetails
Todas las transacciones emitidas deben contener un objeto `sfEmitDetails` correctamente rellenado con los campos siguientes:
| Campo | Valor requerido | Descripción |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| sfEmitGeneration | <p>Si la Transacción Originaria es una transacción emitida, entonces uno más que su <code>sfEmitGeneration</code>.<br /><br />Si no lo es, entonces <code>1</code>.<br /><br />Debe establecerse usando <a href="/es/docs/hooks/functions/emitted-transaction/etxn_generation">etxn_generation</a>.</p> | Este campo realiza el seguimiento de la cadena de transacciones emitidas que generan otras transacciones. |
| sfEmitBurden | <p>Si la Transacción Originaria es una transacción emitida, entonces su <code>burden</code> multiplicado por el número máximo de transacciones que el Hook ha declarado emitir mediante <a href="/es/docs/hooks/functions/emitted-transaction/etxn_reserve">etxn_reserve</a>.<br /><br />Si no lo es, entonces <code>1</code>.<br /><br />Debe establecerse usando <a href="/es/docs/hooks/functions/emitted-transaction/etxn_burden">etxn_burden</a>.</p> | Este campo sirve como heurística para detectar ataques tipo fork bomb. Las comisiones aumentan exponencialmente en cadenas de emisión para evitar la saturación de la red. |
| sfEmitParentTxnID| El ID de la Transacción Originaria | Conecta la ejecución del Hook con la transacción original, permitiendo trazar el comportamiento de forma eficiente. |
| sfEmitNonce | Un nonce determinista generado mediante [nonce](/es/docs/hooks/functions/emitted-transaction/etxn_nonce) | Evita que transacciones idénticas tengan el mismo hash. Todos los nodos deben coincidir en este valor, por lo que se usa una API determinista. |
| sfEmitCallback | El ID de cuenta del Hook (20 bytes) | Permite a xahaud saber a qué Hook y cuenta debe enviar el callback cuando la transacción emitida es aceptada en un ledger. |
<Aside type="tip" title="Revisa los ejemplos">
Los [Hooks de ejemplo](https://github.com/XRPL-Labs/xrpld-hooks/tree/hooks-ssvm/hook-api-examples), en particular Peggy, Carbon y Doubler, muestran cómo emitir tanto transacciones simples como más complejas.
</Aside>

View File

@@ -0,0 +1,18 @@
---
title: Metadatos de ejecución
description: Qué esperar cuando tu Hook se ejecuta.
---
Cuando los Hooks se ejecutan, dejan información sobre el estado de esa ejecución. Esta aparece en los metadatos de la Transacción Originaria como un bloque `sfHookExecutions`. Este bloque contiene los siguientes campos:
| Campo | Descripción |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| sfHookResult | <p>Los Hooks pueden terminar de tres maneras: <code>accept</code>, <code>rollback</code> y <code>error</code>.<br />¡Esto <em>no</em> es lo mismo que sfHookReturnCode!</p> |
| sfHookHash | El SHA512H del Hook en el momento en que fue ejecutado. |
| sfHookAccount | La cuenta en la que se ejecutó el Hook. |
| sfHookReturnCode | El entero devuelto como tercer parámetro de `accept` o `rollback`. |
| sfHookReturnString | La cadena devuelta en los dos primeros parámetros de `accept` o `rollback`, si existe. |
| sfHookInstructionCount | El número total de instrucciones de WebAssembly ejecutadas durante la ejecución del Hook. |
| sfHookEmitCount | El número total de [Transacciones emitidas](/es/docs/hooks/concepts/emitted-transactions) producidas por el Hook. |
| sfHookExecutionIndex | El orden en el que se ejecutó el Hook (en relación con otras ejecuciones de Hooks en la misma Transacción Originaria). |
| sfHookStateChangeCount | El número de cambios de [estado del Hook](/es/docs/hooks/concepts/state-management) realizados durante la ejecución. |

View File

@@ -0,0 +1,98 @@
---
title: Números de punto flotante (XFL)
description: Los cálculos de alta precisión son nativos en Hooks.
---
import { Aside } from '@astrojs/starlight/components';
### Contexto
Los [números de punto flotante](https://en.wikipedia.org/wiki/Floating-point_arithmetic) se utilizan ampliamente en informática para realizar cálculos de precisión finita pero escala arbitraria.
La mayoría de las CPUs modernas son capaces de realizar operaciones rápidas de punto flotante utilizando el [estándar IEEE de punto flotante binario](https://en.wikipedia.org/wiki/Double-precision_floating-point_format), sin embargo `xahaud` **no** utiliza este formato. En su lugar, Xahau utiliza un [estándar decimal de punto flotante personalizado](/es/docs/protocol-reference/binary-format).
Este formato personalizado tiene tres propiedades básicas:
1. El formato es inherentemente decimal, expresado como una `mantisa` decimal multiplicada por `10` elevado a un `exponente`.
2. Todos los valores expresados tienen 16 cifras significativas (decimales).
3. El rango de exponentes es de `-96` a `+80`.
Cuando se serializa, la mantisa ocupa 54 bits y el exponente 8 bits, con un bit adicional de signo que lleva el tamaño total a 63 bits.
### ¿Qué es XFL?
[XLS-17d](https://github.com/XRPLF/XRPL-Standards/discussions/39) es una propuesta de estándar XRPL que define una forma eficiente de empaquetar y almacenar números de punto flotante en xrpld (como se describió anteriormente).
Los XFL almacenan los bits del número de punto flotante dentro de un _número contenedor_. Este siempre es un `int64_t`. Los números contenedores negativos representan XFL inválidos (por ejemplo, como resultado de una división por cero).
<Aside type="tip">
Usa la herramienta XFL <a href="https://richardah.github.io/xfl-tools/" target="_blank" rel="noopener">aquí</a> para componer y descomponer XFLs en tu navegador.
</Aside>
Algunos ejemplos de XFL:
| Valor de punto flotante | Número contenedor | Representación |
| ------------------------ | ------------------- | ----------------------------- |
| -1 | 1478180677777522688 | -1000000000000000 \* 10^(-15) |
| 0 | 0 | 0 (_cero canónico_) |
| 1 | 6089866696204910592 | +1000000000000000 \* 10^(-15) |
| _PI_ | 6092008288858500385 | +3141592653589793 \* 10^(-15) |
| -_PI_ | 1480322270431112481 | -3141592653589793 \* 10^(-15) |
Este formato es muy conveniente para Hooks, ya que solo pueden intercambiar valores _enteros_ con xrpld. Al encapsular el número de punto flotante dentro de un entero de forma bien definida, es posible realizar cálculos complejos de punto flotante desde un Hook. Esto resulta útil, por ejemplo, para calcular tipos de cambio.
### Cero canónico
Los sistemas de punto flotante suelen tener múltiples formas de representar el cero, lo que puede causar problemas al comprobarlo. Por ejemplo, `0 x 10 ^ 1` es cero y `0 x 10 ^ 2` también es cero. Por esta razón, el estándar y la API de Hooks imponen un cero canónico. Este corresponde al número contenedor cero (`0`).
### API de Float en Hooks
Una vez que tienes un XFL, puedes usar la API de Float para realizar distintos cálculos. Cada función recibe uno o más números contenedores XFL y devuelve otro número contenedor XFL. Los valores negativos _siempre_ representan un error de cálculo (como división por cero). No existen números contenedores negativos válidos.
| Hook API | Qué hace |
| ----------------------------------------------------------------------- | ----------------------------------------------------------------- |
| [float_set](/es/docs/hooks/functions/float/float_set) | Crear un float a partir de un exponente y una mantisa |
| [float_multiply](/es/docs/hooks/functions/float/float_multiply) | Multiplicar dos números XFL |
| [float_mulratio](/es/docs/hooks/functions/float/float_mulratio) | Multiplicar un XFL por un numerador y denominador no-XFL |
| [float_negate](/es/docs/hooks/functions/float/float_negate) | Negar un número de punto flotante XFL |
| [float_compare](/es/docs/hooks/functions/float/float_compare) | Comparar dos números XFL |
| [float_sum](/es/docs/hooks/functions/float/float_sum) | Sumar dos números XFL |
| [float_sto](/es/docs/hooks/functions/float/float_sto) | Convertir un XFL en un objeto serializado |
| [float_sto_set](/es/docs/hooks/functions/float/float_sto_set) | Leer una cantidad serializada en un XFL |
| [float_invert](/es/docs/hooks/functions/float/float_invert) | Calcular el inverso de un XFL |
| [float_divide](/es/docs/hooks/functions/float/float_divide) | Dividir un XFL entre otro XFL |
| [float_one](/es/docs/hooks/functions/float/float_one) | Devolver el número 1 como XFL |
| [float_exponent](/es/docs/hooks/functions/float/float_exponent) | Obtener el exponente de un XFL |
| [float_mantissa](/es/docs/hooks/functions/float/float_mantissa) | Obtener la mantisa de un XFL |
| [float_sign](/es/docs/hooks/functions/float/float_sign) | Obtener el signo de un XFL |
| float_exponent_set | Establecer el exponente de un XFL |
| float_mantissa_set | Establecer la mantisa de un XFL |
| float_sign_set | Establecer el signo de un XFL |
| [float_int](/es/docs/hooks/functions/float/float_int) | Convertir un XFL a entero (redondeo hacia abajo) |
| [float_root](/es/docs/hooks/functions/float/float_root) | Calcular la raíz n-ésima de un XFL |
| [float_log](/es/docs/hooks/functions/float/float_log) | Calcular el logaritmo decimal de un XFL |
<Aside type="caution">
Nunca debes realizar cálculos directos o comparaciones sobre el _número contenedor_. Esto casi siempre dará resultados incorrectos.
La única excepción es comprobar el cero canónico.
</Aside>
### Ejemplo
En el siguiente ejemplo se realiza una conversión de tipo de cambio seguida de una multiplicación de fracciones de alta precisión:
```c
int64_t max_vault_pusd =
float_multiply(vault_xrp, exchange_rate);
max_vault_pusd =
float_mulratio(max_vault_pusd, 0,
NEW_COLLATERALIZATION_NUMERATOR, NEW_COLLATERALIZATION_DENOMINATOR);
````
<Aside type="tip">
Si una función de la API de float devuelve un valor negativo y no lo verificas, al pasar ese valor a otra función también producirá un resultado negativo. De este modo, los errores se propagan de forma similar a `NaN` (not a number).
Si obtienes un número contenedor negativo, significa que ocurrió un error en tus cálculos de punto flotante.
</Aside>

View File

@@ -0,0 +1,90 @@
---
title: Grants
description: Hook Grants
---
import { Aside } from '@astrojs/starlight/components';
<Aside type="caution">
La mayoría de los desarrolladores de Hooks rara vez necesitarán usar HookGrants, y deben extremar la precaución al otorgar permisos de modificación de estado a Hooks y cuentas externas.
Aunque un HookGrant no puede utilizarse directamente para robar fondos, la modificación externa intencionada del estado de un Hook puede hacer que este se comporte de forma inesperada, lo que en algunos casos podría derivar en un robo.
Si crees que necesitas usar un Grant, revisa primero tu diseño para asegurarte de que realmente es necesario antes de continuar.
</Aside>
### Grants
Los Grants proporcionan una forma para que quien instala un Hook asigne permisos de [gestión de estado](/es/docs/hooks/concepts/state-management) a un Hook _externo_ en otras cuentas de Xahau.
Una [transacción SetHook](/es/docs/hooks/concepts/sethook-transaction) puede especificar un array `HookGrants` dentro de cualquier objeto `Hook` en su array `Hooks`. El array `HookGrants` contiene uno o más objetos `HookGrant` (hasta un máximo de 8).
A diferencia de los [Parameters](/es/docs/hooks/concepts/parameters), el array `HookGrants` siempre se establece exactamente como se especifica en la [transacción SetHook](/es/docs/hooks/concepts/sethook-transaction). Por lo tanto, si deseas actualizar un `HookGrant` manteniendo otros previamente definidos, debes obtener primero el array existente, modificarlo y reenviar el array completo en una operación de [_Update_](/es/docs/hooks/concepts/sethook-transaction).
Para eliminar todos los Grants, envía un array `HookGrants` vacío.
<Aside type="caution">
A diferencia de los [Parameters](/es/docs/hooks/concepts/parameters), el array `HookGrants` siempre se establece exactamente como se especifica en la [transacción SetHook](/es/docs/hooks/concepts/sethook-transaction).
</Aside>
Un Grant permite que una cuenta XRPL externa o un Hook modifique el estado del Hook dentro del namespace del Hook específico para el que se define el Grant.
El HookGrant debe especificar al menos:
* `HookHash`\
Y también puede especificar una cuenta:
* `Authorize`
Solo el Hook especificado por `HookHash` puede modificar el estado del Hook dentro del namespace del Hook para el cual se define el Grant. Si se especifica `Authorize`, este permiso se restringe aún más al Hook con ese `HookHash` cuando está instalado en la cuenta indicada en `Authorize`.
<Aside type="tip">
Los Grants solo se aplican a Hooks externos y nunca limitan el funcionamiento de los Hooks respecto al estado en la cuenta donde están instalados.
</Aside>
### Ejemplo
```json
Account: "rALicebv3hMYNBWtu1VEEWkToArgYsYERs",
TransactionType: "SetHook",
Hooks:
[
{
Hook: {
...,
HookNamespace: "3963ADEB1B0E8934C0963680531202FD511FF1E16D5864402C2DA63861C420A8",
HookGrants:
[
{
HookGrant: // primer grant
{
HookHash: "78CAF69EEE950A6C55A450AC2A980DE434D624CD1B13148E007E28B7B6461CC8"
},
HookGrant: // segundo grant
{
Authorize: "rCLairev2ma2gNZdcHJeTk7fCQ1ki84vr9",
HookHash: "A5B8D62154DA1C329BE13582086B52612476720CEBD097EB85CEE1455E1C70A6"
}
},
]
}
}
],
...
````
El *primer grant* anterior permite:
* cualquier instancia del Hook cuyo código tenga el hash `78CAF69EEE950A6C55A450AC2A980DE434D624CD1B13148E007E28B7B6461CC8`
* ejecutándose en **cualquier cuenta**
* modificar el estado del Hook de la cuenta `rALicebv3hMYNBWtu1VEEWkToArgYsYERs`
* dentro del namespace `3963ADEB1B0E8934C0963680531202FD511FF1E16D5864402C2DA63861C420A8`
El *segundo grant* anterior permite:
* cualquier instancia del Hook cuyo código tenga el hash `A5B8D62154DA1C329BE13582086B52612476720CEBD097EB85CEE1455E1C70A6`
* pero solo cuando se ejecuta en la cuenta `rCLairev2ma2gNZdcHJeTk7fCQ1ki84vr9`
* modificar el estado del Hook de la cuenta `rALicebv3hMYNBWtu1VEEWkToArgYsYERs`
* dentro del namespace `3963ADEB1B0E8934C0963680531202FD511FF1E16D5864402C2DA63861C420A8`
### Uso del Grant
Para utilizar un grant, un Hook modifica objetos de estado en una cuenta externa llamando a [state_foreign_set](/es/docs/hooks/functions/state/state_foreign_set).

View File

@@ -0,0 +1,65 @@
---
title: Comisiones de Hooks
description: Qué esperar cuando tu Hook se ejecuta.
---
### Comisiones de creación de Hooks
Las transacciones SetHook se cobran por byte de WebAssembly creado. La tarifa es de 500 drops por byte. Por lo tanto, un Hook de 1 KiB costará 0.5 XAH crearlo.
### Comisiones de ejecución de Hooks
Cuando los Hooks se ejecutan de forma [fuerte](/es/docs/hooks/concepts/weak-and-strong), la transacción originaria debe pagar estas ejecuciones dentro de su propia comisión.
Las comisiones de ejecución de Hooks se cobran a razón de 1 drop por instrucción de WebAssembly en el peor caso de ejecución de la función `hook` (o `cbak` en el caso de un callback). Por lo tanto, un Hook pequeño con muchos bucles puede generar comisiones elevadas en tiempo de ejecución.
### Helper RPC de comisiones
Las comisiones de transacción en un ledger con la enmienda Hooks habilitada se vuelven complejas de calcular para usuarios finales y/o aplicaciones de cartera. Esto se debe a que los Hooks fuertes deben ser pagados por el originador de la transacción, y puede haber hasta 4 Hooks fuertes en la cuenta emisora y 4 en la cuenta receptora, además de otros posibles participantes transaccionales fuertes (como ocurre en algunos tipos de transacciones más complejos). Además, si la transacción es un SetHook, el tamaño de los parámetros, el tamaño del código y si se trata de una operación de _create_ o _install_ también afectan a la comisión.
Por lo tanto, se recomienda encarecidamente que **todas** las transacciones se pasen por la llamada RPC de comisiones actualizada antes de enviarlas al ledger.
Para invocar la llamada RPC:
1. Abre una conexión websocket con el nodo Hooks con el que vas a trabajar.
2. Construye la transacción serializada para la que quieres conocer la comisión con los siguientes campos:
* `Fee: "0"`
* `SigningPubKey: ""` (es decir: VL de 0 bytes de tipo 0x73. En hexadecimal: `0x7300`)
* **No firmes la transacción**
3. Envíala como un blob hexadecimal al RPC de la siguiente forma:
```json
{"command":"fee", "tx_blob":"<hex blob>"}
````
Para HTTP POST RPC:
```json
{"method":"fee", "params": [{"tx_blob":"<hex blob>"}] }
```
La respuesta tendrá un formato similar a:
```json
{
result: {
drops: {
base_fee: '130520',
},
//...
},
type: 'response'
}
```
Toma el valor de `base_fee` y establécelo como el campo `Fee` en la transacción. Después, fírmala y envíala siguiendo el proceso habitual.
Si `tx_blob` es inválido o falta, se devolverá un resultado JSON estándar con un `base_fee` de 10.
### Comisiones de emisión
Los Hooks tienen acceso al mismo cálculo que el *Fee RPC Helper*. Para usarlo, llama a [etxn_fee_base](/es/docs/hooks/functions/emitted-transaction/etxn_fee_base) pasando como argumento un buffer con la transacción serializada. Al igual que en la llamada RPC, debes asegurarte de que el campo `Fee` está presente en la transacción serializada (su valor es irrelevante).
Cuando `etxn_fee_base` devuelve la comisión recomendada, puedes usar [sto_emplace](/es/docs/hooks/functions/serialization/sto_emplace) para insertarla en la transacción serializada antes de emitirla. El campo correspondiente es `sfFee`.

View File

@@ -0,0 +1,44 @@
---
title: Campo HookOn
description: Especifica en qué tipos de transacción debe activarse un Hook
---
import { LinkCard } from '@astrojs/starlight/components';
### Comprendiendo el campo HookOn
Cada bit en este entero sin signo de 256 bits indica si el Hook debe ejecutarse para un tipo de transacción concreto. Todos los bits son _activo bajo_ **excepto** el bit 22, que es _activo alto_. Dado que el 22 corresponde a ttHOOK_SET, esto significa que el valor por defecto de todos los bits en 0 no activará el Hook en una transacción SetHook, pero sí en todos los demás tipos de transacción. Esta es una decisión de diseño intencionada para evitar que los usuarios bloqueen su cuenta de Xahau con un Hook defectuoso.
Los bits se numeran de derecha a izquierda:
* bit 0 - el más a la derecha, es decir, el bit menos significativo.
* bit 63 - el más a la izquierda, es decir, el bit más significativo.
Ejemplos (asumiendo un entero sin signo de 256 bits):
1. Si queremos desactivar completamente el Hook:
```c
~(1ULL << 22) /* todos los bits son 1 excepto el bit 22 que es 0 */
````
2. Si queremos desactivar el Hook en todo excepto ttPAYMENT:
```c
~(1ULL << 22) & ~(1ULL)
```
3. Si queremos activar el Hook en todo excepto ttHOOK_SET:
```c
0
```
4. Si queremos activar el Hook en ttHOOK_SET (peligroso) y en todos los demás tipos de transacción:
```c
(1ULL << 22)
```
### Calculadora HookOn
<LinkCard title="Calculadora HookOn" href="https://richardah.github.io/xrpl-hookon-calculator/" />

View File

@@ -0,0 +1,24 @@
---
title: Ejemplo de uso
---
Por favor, lee [la introducción de Hooks en este blog](https://coil.com/p/XUMM/XRPL-Labs-is-working-on-the-transaction-HOOKS-amendment-for-the-XRP-Ledger-Supporting-business-logic/kEmqhoqMW).
Mientras trabajábamos en Hooks, publicamos varios blogs sobre nuestro progreso, ideas y conceptos relacionados con Hooks. Puedes [leer todo sobre ello en nuestros blogs en Dev.to](https://dev.to/t/xrplhooks/top/infinity)
### Ejemplos (escenarios)
#### 1. El Hook receptor ejecuta lógica adicional
![senarios-1](/assets/hook-examples-senarios-1.png)
#### 2. El Hook receptor bloquea una transacción entrante
![senarios-2](/assets/hook-examples-senarios-2.png)
#### 3. El Hook emisor bloquea una transacción saliente
![senarios-3](/assets/hook-examples-senarios-3.png)
#### 4. El Hook controla una cuenta institucional
![senarios-4](/assets/hook-examples-senarios-4.png)

View File

@@ -0,0 +1,33 @@
---
title: Introducción
---
import { Aside } from '@astrojs/starlight/components';
Los Hooks añaden funcionalidad de smart contracts a Xahau: código personalizado de _capa uno_ para influir en el comportamiento y flujo de las transacciones. Los Hooks son pequeñas y eficientes piezas de código definidas en una cuenta de Xahau, que permiten ejecutar lógica antes y/o después de las transacciones en Xahau.
<Aside type="note">
Ten en cuenta: estás leyendo la **documentación técnica** de Hooks. Esta documentación es altamente técnica y asume conocimientos previos de programación y de la red Xahau. Si estás buscando ejemplos sobre qué son los Hooks, qué aportan a la red Xahau y qué pueden hacer, por favor [consulta esta página](/es/docs/hooks/concepts/introduction/example-usage).
</Aside>
Xahau es conocida y valorada por su alto rendimiento en transacciones, su velocidad y sus bajas comisiones. Combinado con tipos de transacciones avanzados disponibles como multifirma, escrows, canales de pago e incluso un exchange descentralizado (todo en el ledger, listo para usar, sin necesidad de smart contracts), Xahau ofrece mucho a empresas y desarrolladores creativos.
Los Hooks añaden funcionalidad de smart contracts a Xahau: código personalizado de _capa uno_ para influir en el comportamiento y flujo de las transacciones. Los Hooks son pequeñas y eficientes piezas de código definidas en una cuenta de Xahau, que permiten ejecutar lógica antes y/o después de las transacciones en Xahau. Estos Hooks pueden ser muy simples, como: “rechazar pagos < 10 XAH”, o “para todos los pagos salientes, enviar el 10% a mi cuenta de ahorros”, o más avanzados.
<figure>
![Hooks high level concept](/assets/spaces_m6f29os4wP16vCS4lHNh_uploads_sEBiInWuRskTqxB29Xgd_7359187-Hooks_High_Level2x_1.png)
<figcaption>*Concepto general de Hooks*</figcaption>
</figure>
Al permitir que los Hooks no solo ejecuten lógica eficiente, sino también almacenen pequeños objetos de datos simples, se podría definir un Hook como: “para transacciones de pago entrantes, comprobar si la cuenta emisora está en una lista mantenida por otro Hook y, si está presente: rechazar la transacción”.
Los Hooks no son deliberadamente Turing-completos. Aunque a menudo se presenta como el santo grial de los smart contracts, la completitud de Turing en realidad no es apropiada para los smart contracts. (Ver [Blog 2](https://dev.to/wietse/hooked-2-hooks-security-smart-contracts-on-the-xrp-ledger-83e).)
Actualmente, los Hooks están activos en una testnet pública. Es momento de probar, programar, experimentar y romper cosas, para que una futura enmienda que añada Hooks a la red principal de Xahau pueda proponerse con confianza.
### Recursos
* [Xahau Testnet](https://xahau-test.net/)
* [Xahau Testnet Explorer](https://explorer.xahau-test.net/)
* [Ejemplos (código fuente)](https://github.com/XRPL-Labs/xrpld-hooks/tree/hooks-ssvm/hook-api-examples)
* [Conceptos en blogs](https://dev.to/t/xrplhooks/top/infinity)

View File

@@ -0,0 +1,90 @@
---
title: Bucles y Guards
description: Los guards son necesarios para realizar bucles en un Hook.
---
import { Aside } from '@astrojs/starlight/components';
### ¿Qué son los guards?
Los Hooks no son deliberadamente [Turing completos](https://en.wikipedia.org/wiki/Turing_completeness). Esto significa que los bucles arbitrarios no están permitidos. En su lugar, debes _proteger_ tus bucles con un límite máximo de iteraciones.
Un guard es una marca que se coloca en tu código al inicio de cada bucle. Esta marca informa a Xahau cuál será el límite superior de iteraciones _en cualquier escenario posible_. Así, si tu bucle normalmente se ejecuta dos veces pero en ocasiones puede ejecutarse _500_ veces, entonces tu guard deberá indicar 500.
Los guards se utilizan para que Xahau determine el _tiempo de ejecución en el peor caso_ (en número de instrucciones) de tu Hook antes de ejecutarlo. Esto sirve de base para calcular la comisión que se cobra por la ejecución del Hook y hace que los tiempos de ejecución sean predecibles y controlables.
<Aside type="tip">
Los desarrolladores que provienen de otras plataformas de smart contracts pueden encontrar los guards molestos al principio, pero una vez te acostumbras, no son más difíciles de usar que un bucle for normal.
</Aside>
### La función guard
La función guard indica al ledger el **número máximo de iteraciones** que tendrá un bucle. Concretamente, la función recibe dos argumentos:
```c
int32_t _g (uint32_t id, uint32_t maxiter);
````
El primer argumento `id` es el identificador del guard. Es una constante única elegida por el desarrollador, normalmente se usa el número de línea del archivo fuente.
El segundo argumento `maxiter` es una promesa del desarrollador al ledger de que este guard no será ejecutado más de `maxiter` veces durante la ejecución del Hook. Si el guard se ejecuta más veces, el Hook hará automáticamente rollback con un error `GUARD_VIOLATION` ([códigos de retorno de la Hook API](/es/docs/hooks/functions/overview/return-codes)). Como el guard se ejecuta *antes* de comprobar la condición del bucle, es importante sumar uno al número total esperado de iteraciones. (Nota: la macro GUARD() ya suma uno).
<Aside type="caution">
Los guards deben definirse usando valores numéricos literales. No puedes usar variables ni valores calculados en tiempo de ejecución.
</Aside>
### Aplicación de los guards
Considera el siguiente bucle for en C:
```c
#define GUARD(maxiter) _g(__LINE__, (maxiter)+1)
for (int i = 0; GUARD(3), i < 3; ++i)
{
...
}
```
En C, el operador coma ejecuta cada expresión en una lista (por ejemplo `A, B, C`) y devuelve la última (`C`). Por lo tanto, la condición sigue siendo `i < 3`, pero el guard se ejecuta antes de evaluar la condición. Esta es la única forma de cumplir la *regla del guard* al usar un bucle for en C.
<Aside type="tip" title="La regla del Guard">
Una llamada a <code>_g</code> (la función guard) debe ser la primera instrucción de salto después de una instrucción de bucle.
</Aside>
A continuación se muestra la salida en WebAssembly al compilar el ejemplo anterior. Observa cómo la función guard se llama al inicio del bucle. Las únicas instrucciones permitidas antes de esta llamada son aquellas que no implican saltos (normalmente manipulación de constantes).
```
block ;; label = @1
loop ;; label = @2
i32.const 3
i32.const 14
=====> call $_g <=====
drop
...
```
### Bucles anidados
Cuando se utilizan bucles anidados, el argumento `maxiter` debe reflejar el número total de veces que el guard será ejecutado. Esto significa que debes multiplicar los bucles entre sí.
Considera el siguiente ejemplo:
```c
#define GUARD(maxiter) _g(__LINE__, (maxiter)+1)
for (int i = 0; GUARD(3), i < 3; ++i)
{
for (int j = 0; GUARD(15), j < 5; ++j)
{
...
}
}
```
Observa que el guard del bucle interno está configurado en **15**. Esto se debe a que debes multiplicar las iteraciones de ambos bucles para calcular el máximo número de ejecuciones del guard interno.
### Sin recursión
Las llamadas a funciones que no pertenecen a la Hook API no están permitidas en la enmienda Hooks. Todo el código del usuario debe estar contenido dentro de las dos funciones permitidas: `cbak` y `hook`.
<Aside type="caution">
No usar correctamente los guards provocará que una transacción <code>SetHook</code> sea rechazada.
</Aside>

View File

@@ -0,0 +1,42 @@
---
title: Namespaces
description: Evita sobrescrituras de estado utilizando el namespace correcto
---
### Namespaces
Para evitar que dos o más Hooks instalados en la misma cuenta sobrescriban accidentalmente el [estado del Hook](/es/docs/hooks/concepts/state-management) entre sí, se debe proporcionar un namespace de 32 bytes al crear o instalar cada Hook.
El namespace puede ser cualquier valor arbitrario de 32 bytes elegido por el desarrollador. Siempre que el namespace sea único dentro de la cadena de Hooks, no se producirá sobrescritura de estado.
Recomendamos encarecidamente usar `SHA256` sobre el nombre de trabajo del Hook definido por el desarrollador. SHA256 es uno de los dos algoritmos de hash utilizados en la generación de direcciones en Xahau (a partir de la clave maestra de una cuenta), por lo que suele estar fácilmente disponible para el desarrollador.
El campo `HookNamespace` se proporciona como un blob _hexadecimal_ de 32 bytes dentro de cada objeto `Hook` en el array `Hooks` al [ejecutar una transacción SetHook](/es/docs/hooks/concepts/sethook-transaction).
El namespace configurado bajo el que opera un Hook modifica los [Keylets](/es/docs/hooks/concepts/slots-and-keylets) bajo los que se almacena su [estado](/es/docs/hooks/concepts/state-management). Por lo tanto, dos Hooks bajo diferentes namespaces instalados en la misma cuenta de Xahau pueden usar la misma clave de estado para referirse a diferentes objetos de estado. Por el contrario, dos Hooks distintos que utilicen el mismo namespace en la misma cuenta pueden acceder y modificar los objetos de estado del otro utilizando las mismas claves.
### Ejemplo
En JavaScript, al importar `ripple-address-codec` se obtiene acceso a SHA256.\
(También es posible usar `crypto.subtle` en navegador o `crypto.createHash` en Node para acceder a este algoritmo de hash.)
```js
HookNamespace: addr.codec.sha256('carbon').toString('hex')
````
### Namespace por defecto
El primer usuario que [establece un Hook nuevo](/es/docs/hooks/concepts/sethook-transaction) define un `HookNamespace` que se convierte en el *namespace por defecto* para ese Hook. Esto significa que cualquier usuario posterior que [referencie la misma *HookDefinition*](/es/docs/hooks/concepts/reference-counted-hook-definitions) recibirá este namespace por defecto.
El usuario posterior puede especificar su propio namespace, sobrescribiendo el namespace por defecto solo para su instalación.
### APIs de Hook afectadas
La elección del HookNamespace afecta al comportamiento de las siguientes APIs de Hook:
* [state](/es/docs/hooks/functions/state/state)
* [state_set](/es/docs/hooks/functions/state/state_set)
### Helper de API para namespaces
Consulta [account_info](/es/docs/hooks/functions/websocket-apis/account_info) y [account_namespace](/es/docs/hooks/functions/websocket-apis/account_namespace) para obtener información sobre cómo consultar el ledger respecto a namespaces.

View File

@@ -0,0 +1,58 @@
---
title: Parámetros
description: Los parámetros en tiempo de instalación permiten que los Hooks sean genéricos y flexibles
---
### Parámetros
Los desarrolladores de Hooks pueden optar por utilizar parámetros en _tiempo de instalación_ (llamados Hook Parameters) en sus Hooks. Esto permite que quienes instalen posteriormente el Hook puedan modificar ciertos comportamientos definidos por el programador sin necesidad de recompilar o volver a subir el Hook (siempre que al menos una cuenta siga [referenciando](/es/docs/hooks/concepts/reference-counted-hook-definitions) la definición existente del Hook).
Los Hook Parameters son un conjunto de pares clave-valor establecidos durante la [transacción SetHook](/es/docs/hooks/concepts/sethook-transaction) y recuperables por el Hook en tiempo de ejecución. Tanto `ParameterName` como `ParameterValue` se definen como blobs _hexadecimales_, con un tamaño máximo de 32 bytes y 256 bytes respectivamente.
Una [transacción SetHook](/es/docs/hooks/concepts/sethook-transaction) puede definir hasta _16_ parámetros por cada Hook instalado.
### Establecer parámetros
El array `HookParameters` se define opcionalmente dentro de cada `Hook` en el array `Hooks`, como se muestra a continuación:
```json
TransactionType: "SetHook",
Hooks:
[
{
Hook: {
...,
HookParameters:
[
{
HookParameter:
{
HookParameterName: "ABCDEF12",
HookParameterValue: "12345678"
}
},
... // opcionalmente hasta 15 parámetros más
]
}
}
],
...
````
### Parámetros por defecto
El primer usuario que [establece un Hook nuevo](/es/docs/hooks/concepts/sethook-transaction) puede definir Hook Parameters que se convierten en los *parámetros por defecto* de ese Hook. Esto significa que cualquier usuario posterior que [referencie la misma *HookDefinition*](/es/docs/hooks/concepts/reference-counted-hook-definitions) recibirá estos parámetros por defecto.
El usuario posterior puede definir sus propios parámetros, sobrescribiendo los parámetros por defecto para su instalación.
Para eliminar un parámetro en una instalación posterior, especifica la clave `ParameterName` sin incluir la clave `ParameterValue`.
### Uso de parámetros en Hooks
Los parámetros pueden ser leídos por los Hooks utilizando [hook_param](/es/docs/hooks/functions/hook-context/hook_param).
Si hay más de un Hook instalado en una cadena de Hooks, entonces [hook_param_set](/es/docs/hooks/functions/hook-context/hook_param_set) puede utilizarse en ciertos casos para modificar los parámetros de un Hook situado más adelante en la cadena dentro de la misma cuenta.
### Parámetros en tiempo de ejecución
En Xahau y en la testnet de Xahau, los HookParameters también pueden incluirse en el nivel superior de cualquier tipo de transacción, respetando las mismas reglas y límites de tamaño. Estos parámetros pueden ser accedidos dentro de un Hook mediante la API [otxn_param](/es/docs/hooks/functions/originating-transaction/otxn_param).

View File

@@ -0,0 +1,15 @@
---
title: Definiciones de Hook con conteo de referencias
description: Evita volver a subir el mismo bytecode al ledger
---
Cuando el bytecode WebAssembly de un Hook nuevo se sube a Xahau, se impone una carga de almacenamiento significativa en la red. Esta carga se refleja en las [comisiones de Hooks](/es/docs/hooks/concepts/hook-fees) que cobra la red.
Para evitar esta carga (y las altas comisiones para los usuarios), se utiliza el conteo de referencias:
* La primera vez que se instala un Hook nuevo, la [transacción SetHook](/es/docs/hooks/concepts/sethook-transaction) debe pagar una comisión elevada.
* El bytecode WebAssembly del Hook se convierte en un objeto sin propietario y con conteo de referencias en el ledger (llamado `HookDefinition`).
* Las instalaciones posteriores, por el mismo u otros usuarios, de un Hook idéntico (es decir, con el mismo bytecode) incrementan el contador de referencias. Estas instalaciones apuntan al mismo objeto en el ledger. Estas transacciones se cobran de forma similar a la creación de una Trust Line, ya que la carga de almacenamiento ya fue cubierta por la primera transacción SetHook.
* Mientras el contador de referencias de la Hook Definition sea mayor que cero (es decir, una o más cuentas sigan teniendo el Hook instalado), el objeto permanecerá en el ledger.
![Reference Counted Hook Definitions](/assets/spaces_m6f29os4wP16vCS4lHNh_uploads_TlDL7tsVNYi1yU64EZQh_3ef0cee-sethook-Page-2.png)

View File

@@ -0,0 +1,55 @@
---
title: Objetos serializados
description: ¡Manipula objetos serializados de xahaud directamente!
---
### ¿Qué son los objetos serializados?
Xahau tiene formas [serializadas](/es/docs/protocol-reference/binary-format) canónicas de todos los objetos sujetos a consenso. Al escribir un Hook, es inevitable encontrarse con objetos serializados. Estos aparecen como buffers que pueden parecer blobs binarios opacos para el desarrollador. Sin embargo, pueden analizarse utilizando el [XRPL-Binary-Visualiser](https://richardah.github.io/xrpl-binary-visualizer/).
Por ejemplo, un campo `sfAmount` se serializa como una secuencia de bytes como `61D50F26109A32B7EC`.
### API de objetos serializados
Para ayudar a los desarrolladores de Hooks a trabajar con objetos serializados, se creó el espacio de nombres `sto` dentro de la API de Hooks. Estas funciones manipulan punteros dentro de un buffer proporcionado por el Hook. Consulta la siguiente tabla:
| Hook API | Qué hace |
| --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| [sto_subfield](/es/docs/hooks/functions/serialization/sto_subfield) | Indexa dentro de un objeto serializado de xrpld y devuelve la posición y longitud de un subcampo |
| [sto_subarray](/es/docs/hooks/functions/serialization/sto_subarray) | Indexa dentro de un array serializado de xrpld y devuelve la posición y longitud de un índice |
| [sto_emplace](/es/docs/hooks/functions/serialization/sto_emplace) | Inserta un campo en un STObject en su posición canónica |
| [sto_erase](/es/docs/hooks/functions/serialization/sto_erase) | Elimina un campo de un STObject |
| [sto_validate](/es/docs/hooks/functions/serialization/sto_validate) | Valida un STObject |
Cuando corresponde, estas APIs devuelven un _offset_ y una _longitud_ codificados en un único `int64_t`. Consulta la documentación específica para más detalles.
### Ejemplo
Un caso típico en el que usarías la API STO es al procesar memos en una Transacción Originaria. Dado que probablemente necesites acceder al memo completo, una forma eficiente de procesar un conjunto de memos es copiar todo el campo `sfMemos` a un buffer y luego indexar dentro de él. Aunque también es posible hacerlo con la API de slots, esto implicaría más código y más operaciones de copia.
```c
#define SUB_OFFSET(x) ((int32_t)(x >> 32))
#define SUB_LENGTH(x) ((int32_t)(x & 0xFFFFFFFFULL))
#define SBUF(str) (uint32_t)(str), sizeof(str)
uint8_t memos[2048];
int64_t memos_len = otxn_field(SBUF(memos), sfMemos);
for (int i = 0; GUARD(3), i < 3; ++i)
{
int64_t memo_lookup = sto_subarray(memos, memos_len, i);
if (memo_lookup < 0)
rollback(SBUF("Error al buscar memo"), 1);
uint8_t* memo_ptr = SUB_OFFSET(memo_lookup) + memos;
uint32_t memo_len = SUB_LENGTH(memo_lookup);
// lo anterior ahora apunta al memo ... haz algo aquí
}
````
### Solapamiento con slots
Puede que observes cierta superposición entre las APIs de slots y las APIs STO. La diferencia clave es quién *posee* los datos subyacentes:
* Si usas *slots*, entonces xrpld es quien posee el objeto con el que interactúas.
* Si usas la *API STO*, entonces el **Hook** es quien posee el buffer con el que interactúas.
Ambos conjuntos de funciones permiten indexar dentro de un objeto serializado sin realizar copias innecesarias.

View File

@@ -0,0 +1,155 @@
---
title: Transacción SetHook
---
### Transacción SetHook
El bytecode WebAssembly de un Hook se instala en una cuenta de Xahau utilizando la transacción `SetHook`.
Un ejemplo:
```js
{
Account: "r4GDFMLGJUKMjNhhycgt2d5LXCdXzCYPoc",
TransactionType: "SetHook",
Fee: "2000000",
Hooks:
[
{
Hook: {
CreateCode: fs.readFileSync('accept.wasm').toString('hex').toUpperCase(),
HookOn: '0000000000000000',
HookNamespace: addr.codec.sha256('accept').toString('hex').toUpperCase(),
HookApiVersion: 0
}
}
]
}
````
La transacción parece sencilla, pero oculta una complejidad significativa que se describe a continuación.
### Array Hooks
El cuerpo principal de la transacción SetHook es el array Hooks:
```js
{
Account: "r4GDFMLGJUKMjNhhycgt2d5LXCdXzCYPoc",
TransactionType: "SetHook",
Hooks: // Este es el array Hooks
[
{ Hook: { ... } }, // HookSet Object (posición 0)
{ Hook: { ... } },
{ Hook: { ... } },
{ Hook: { ... } }. // HookSet Object (posición 3)
]
}
```
Este array *refleja* la [cadena de Hooks](/es/docs/hooks/concepts/chaining) instalada en la cuenta:
* La posición 0 del array corresponde a la posición 0 en la cadena.
* La posición 3 corresponde a la posición 3 en la cadena, etc.
### HookSet Object y Hook correspondiente
Cada entrada del array Hooks se llama *HookSet Object*, y su Hook correspondiente en la cuenta se llama *Hook correspondiente*.
### HookDefinition
Cada Hook correspondiente contiene una referencia a un objeto `HookDefinition`.
Este objeto es un objeto del ledger sin propietario y con conteo de referencias que evita duplicar bytecode idéntico.
Consulta: [Reference Counting](/es/docs/hooks/concepts/reference-counted-hook-definitions)
### Valores por defecto del Hook
Cuando se crea un `HookDefinition`, contiene los [Parameters](/es/docs/hooks/concepts/parameters), [Namespace](/es/docs/hooks/concepts/namespaces) y [Grants](/es/docs/hooks/concepts/grants) iniciales. Estos se convierten en valores por defecto.
### Operaciones HookSet
Existen seis operaciones: No Operation, Create, Install, Update, Delete y Namespace Reset.
Se determinan según los campos incluidos u omitidos en el HookSet Object.
---
### No Operation
**Ocurre cuando**:
* El HookSet Object está vacío
**Comportamiento**:
* No se realiza ningún cambio
---
### Create Operation
**Ocurre cuando**:
* No existe Hook o se usa `FLAG_OVERRIDE`
* Se incluye `CreateCode`
* No existe aún ese bytecode en el ledger
**Comportamiento**:
* Se crea un `HookDefinition`
* Se crea el Hook en la cuenta
* El Hook apunta a ese HookDefinition
---
### Install Operation
**Ocurre cuando**:
* Existe HookDefinition previo (mismo bytecode o hash)
**Comportamiento**:
* Se incrementa el contador de referencias
* El Hook apunta al HookDefinition existente
---
### Update Operation
**Ocurre cuando**:
* El Hook ya existe
* Se modifican parámetros, namespace o grants
**Comportamiento**:
* Se actualizan los campos del Hook
---
### Delete Operation
**Ocurre cuando**:
* Se usa `CreateCode: ""` y `hsfOVERRIDE`
**Comportamiento**:
* Se elimina el Hook
* Se reduce el contador de referencias
---
### Namespace Reset
**Ocurre cuando**:
* Se usa `hsfNSDELETE`
* Se especifica namespace
**Comportamiento**:
* Se eliminan entradas de estado asociadas al namespace

View File

@@ -0,0 +1,62 @@
---
title: Slots y Keylets
description: Inspecciona y manipula objetos en el ledger.
---
import { Aside } from '@astrojs/starlight/components';
### Contexto
Xahau contiene numerosos tipos de objetos heterogéneos a los que un Hook tiene acceso de lectura. Por ejemplo: _transacciones_, _cuentas_, _ledgers_ y los subcomponentes de cada uno, entre otros.
Es muy fácil programar de forma descuidada un sistema que realice muchas operaciones de copia innecesarias, cuando un acceso disciplinado a los mismos datos subyacentes (por ejemplo, mediante una vista) sería suficiente. La evitación deliberada de copias en programación se conoce como [Zero copy](https://en.wikipedia.org/wiki/Zero-copy).
Con Hooks se aplica el mismo principio: queremos evitar copias siempre que sea posible. En particular, queremos evitar copiar objetos grandes como ledgers completos, así como serializarlos y deserializarlos innecesariamente.
### ¿Qué son los slots?
Los slots forman parte de la API de Hooks y proporcionan un sistema de acceso _heterogéneo_ sin copias a objetos y transacciones en el ledger.
* Cada Hook tiene acceso a 255 slots durante su ejecución.
* Cada slot puede estar vacío o contener un objeto _asignado_ (slotted).
* La API de slots permite navegar dentro de objetos internos y asignarlos también a otros slots.
* La API permite volcar objetos a buffers o leerlos directamente desde el Hook.
Las APIs disponibles son:
| Hook API | Qué hace |
| -------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| [slot](/es/docs/hooks/functions/slot/slot) | Serializa y devuelve un objeto asignado a un slot |
| [slot_clear](/es/docs/hooks/functions/slot/slot_clear) | Libera un slot ocupado |
| [slot_count](/es/docs/hooks/functions/slot/slot_count) | Cuenta los elementos de un array en un slot |
| slot_id | Calcula el hash canónico del objeto en el slot y lo devuelve |
| [slot_set](/es/docs/hooks/functions/slot/slot_set) | Localiza un objeto mediante su keylet y lo coloca en un slot |
| [slot_subarray](/es/docs/hooks/functions/slot/slot_subarray) | Indexa un array en un slot y asigna un subobjeto a otro slot |
| [slot_subfield](/es/docs/hooks/functions/slot/slot_subfield) | Indexa un objeto en un slot y asigna un subobjeto a otro slot |
| [slot_type](/es/docs/hooks/functions/slot/slot_type) | Obtiene el tipo de campo de un objeto en un slot y otra información opcional |
| [slot_float](/es/docs/hooks/functions/slot/slot_float) | Convierte un STI_AMOUNT en el slot a un número XFL |
| [slot_size](/es/docs/hooks/functions/slot/slot_size) | Calcula el tamaño serializado de un objeto en un slot |
### ¿Qué son los keylets?
Los keylets se utilizan para localizar (apuntar a) objetos en el ledger. Básicamente, son un _hash_ de la información identificativa del objeto, que actúa como identificador canónico.
Los Hooks utilizan un formato serializado de 34 bytes para keylets, que puede generarse con la función [util_keylet](/es/docs/hooks/functions/utilities/util_keylet). Sin esto, localizar y asignar objetos sería prácticamente imposible.
<Aside type="tip">
Las APIs de Hooks que aceptan keylets de 34 bytes también suelen aceptar hashes de transacción canónicos de 32 bytes.
</Aside>
### Ejemplo
En el siguiente ejemplo se genera un keylet de 34 bytes para un objeto `signers` y se asigna a un slot:
```c
uint8_t keylet[34];
if (util_keylet(SBUF(keylet), KEYLET_SIGNERS, SBUF(hook_accid), 0, 0, 0, 0) != 34)
rollback(SBUF("Notary: Error interno, no se pudo generar el keylet"), 10);
// solicitar a XRPLD que coloque ese keylet en un slot
int64_t slot_no = slot_set(SBUF(keylet), 0);
if (slot_no < 0)
rollback(SBUF("Notary: No se pudo asignar el keylet al slot"), 10);
````

View File

@@ -0,0 +1,65 @@
---
title: Gestión de estado
description: Los Hooks pueden leer y guardar pequeños fragmentos de datos en el ledger 🚀
---
import { Aside } from '@astrojs/starlight/components';
### ¿Qué es el estado de un Hook?
El [estado](https://en.wikipedia.org/wiki/State_\(computer_science\)) en informática describe la información que un sistema mantiene entre ejecuciones (a diferencia de entradas y salidas). Por ejemplo, tu navegador te mantiene conectado a un sitio web incluso después de cerrarlo y volver a abrirlo. La cookie de sesión se guarda en el _estado_ del navegador.
El **estado de un Hook** se refiere a un mapeo clave-valor que existe lógicamente para cada cuenta en Xahau, independientemente de si actualmente hay claves almacenadas o no. Las claves son siempre de 32 bytes (entero sin signo de 256 bits) y los valores tienen longitud variable, con un tamaño máximo determinado por votación de validadores (en el momento de escribir esto, 256 bytes).
La gestión de estado se realiza mediante:
* [state](/es/docs/hooks/functions/state/state)
* [state_set](/es/docs/hooks/functions/state/state_set)
* [state_foreign](/es/docs/hooks/functions/state/state_foreign)
### Almacenamiento y recuperación
El siguiente ejemplo utiliza la API [state_set](/es/docs/hooks/functions/state/state_set) para asignar el valor `0xC001CAFE` a la clave `0x0..000001` (uint256 = 1) en el estado del Hook de la cuenta:
```c
uint8_t key[32] = {
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x01U
};
uint8_t value[4] = { 0xC0U, 0x01U, 0xCAU, 0xFEU };
if (state_set(value, 4, key, 32) == 4)
{
// ... estado guardado correctamente
}
````
En una ejecución posterior del Hook, este valor puede recuperarse utilizando la misma clave:
```c
uint8_t value[4];
uint8_t key[32] = {
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x01U
};
if (state(value, 4, key, 32) < 0)
{
// ... error al recuperar el estado
}
```
Después de ejecutar este código, el buffer `value` contendrá el valor almacenado en esa clave.
<Aside type="tip">
El buffer en el que <code>state()</code> escribe (<code>writeptr</code>) debe ser lo suficientemente grande para almacenar el valor asociado a la clave. Si no lo es, la API devolverá un error <code>TOO_SMALL</code>.
</Aside>
### Estado externo (foreign state)
En ocasiones puede ser útil que un Hook que se ejecuta en una cuenta lea el estado de otro Hook en otra cuenta. La API [state_foreign](/es/docs/hooks/functions/state/state_foreign) permite hacer esto. Dado que el ledger es público, no hay expectativa real de privacidad. Por tanto, cualquier Hook puede *leer* (pero no escribir) el estado de otro Hook.
### Namespaces y consultas
Consulta [Namespaces](/es/docs/hooks/concepts/namespaces)

View File

@@ -0,0 +1,38 @@
---
title: Terminología
description: Bienvenido a Hooks 👋
---
### ¿Qué son los Hooks?
Los Hooks son pequeños y eficientes módulos de WebAssembly diseñados específicamente para Xahau. Pueden escribirse en cualquier lenguaje que compile a WebAssembly, y la mayoría de la lógica de negocio y conceptos de smart contracts pueden implementarse en un Hook. Normalmente, se escriben en C.
Los Hooks se instalan en una cuenta de Xahau mediante una transacción `SetHook`. Una vez instalados, un Hook puede:
1. Bloquear o permitir transacciones entrantes y salientes en la cuenta,
2. Modificar y mantener estado interno y lógica específica del Hook en esa cuenta, y
3. Emitir nuevas transacciones en nombre de la cuenta.
### Glosario
Esta documentación utiliza términos específicos que pueden resultar desconocidos. Consulta la siguiente tabla si necesitas orientación:
| Término | Explicación |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Hook | <p><em>Este término puede referirse a varias cosas según el contexto</em><br />1. Un binario WebAssembly que puede subirse a Xahau mediante una <a href="/es/docs/hooks/concepts/sethook-transaction">transacción SetHook</a>.<br />2. Un binario WebAssembly ya instalado o configurado en una cuenta.<br />3. El <a href="/es/docs/hooks/concepts/compiling-hooks">código fuente</a> de dicho binario.</p> |
| Transacción originaria | La transacción que dispara la ejecución del Hook. Puede ser una transacción enviada desde o hacia una cuenta con un Hook instalado. |
| Cuenta originaria | La cuenta que envió la transacción originaria. |
| Cuenta del Hook | La cuenta donde reside el Hook que se está ejecutando. Es la cuenta que lo instaló mediante la transacción SetHook y donde se almacena su estado. |
| Instalador | La cuenta que está instalando un Hook mediante la transacción SetHook. |
| Transacción emitida | Una nueva transacción creada por un Hook durante su ejecución (distinta de la originaria). Normalmente se usa para enviar fondos de vuelta. Ver: [Emitted Transactions](/es/docs/hooks/concepts/emitted-transactions). |
| Estado | Un mapa clave-valor por cuenta donde las claves son de 32 bytes y los valores datos arbitrarios. Todos los Hooks de una cuenta comparten este estado. Vive en la cuenta del Hook, no en la cuenta originaria. Ver: [State Management](/es/docs/hooks/concepts/state-management). |
| SetHook | Tipo de transacción introducido por Hooks que permite instalar un Hook en una cuenta. Ver: [SetHook Transaction](/es/docs/hooks/concepts/sethook-transaction). |
| Guards | Mecanismo de control obligatorio para usar bucles en Hooks. Ver: [Loops and Guarding](/es/docs/hooks/concepts/loops-and-guarding). |
| Grants | Permisos que un instalador puede otorgar a otros Hooks o cuentas para modificar su estado. |
| Namespace | Código único de 32 bytes que separa espacios de estado. Permite que distintos Hooks usen las mismas claves sin conflicto. |
| Parameters | Parámetros definidos en el momento de instalación de un Hook. |
| Reference Counting | Sistema donde un objeto del ledger se elimina cuando ya no es referenciado por ninguna cuenta. |
| XFL o coma flotante | Método para cálculos de alta precisión en Hooks (por ejemplo, tasas de cambio). Ver: [Floating Point Numbers (XFL)](/es/docs/hooks/concepts/floating-point-numbers-xfl). |
| Objetos serializados (STO) | Forma en que xahaud almacena y transmite objetos del ledger. Ver: [Serialized Objects](/es/docs/hooks/concepts/serialized-objects). |
| Slots y Keylets | Los slots contienen objetos del ledger y los keylets los identifican. Ver: [Slots and Keylets](/es/docs/hooks/concepts/slots-and-keylets). |
| Trace | Método para imprimir logs desde un Hook en la salida de xrpld. Ver: [Debugging Hooks](/es/docs/hooks/concepts/debugging-hooks). |

View File

@@ -0,0 +1,116 @@
---
title: Débil y Fuerte
description: ¿Qué Hooks pueden ejecutarse y cuándo?
---
import { Aside } from '@astrojs/starlight/components';
<Aside type="tip" title="Filosofía de diseño de Hooks">
Toda parte afectada por una transacción debería tener la oportunidad de ejecutar sus Hooks.
</Aside>
Los Transactional Stake Holders (TSH) son las partes que tienen algún tipo de interés o se ven afectadas por una transacción. Su relación puede ser _débil_ o _fuerte_. El grado de conexión determina si tienen derecho a ejecutar sus Hooks y quién paga por esa ejecución.
Por ejemplo:
* En una transacción **Payment** directa de XAH, los TSH son la _cuenta originaria_ y la _cuenta destino_.
* En una transacción **SetSignerList**, los TSH son la _cuenta originaria_ y cada cuenta incluida en la lista de firmantes.
* En una transacción **OfferCreate**, las cuentas cuyas ofertas son cruzadas son TSH débiles.
* Con la enmienda **IOUIssuerWeakTSH**, los emisores de moneda pueden ejecutar Hooks en transacciones de terceros si lo han activado.
Debido a la diversidad de transacciones en Xahau, los TSH pueden ser complejos y poco intuitivos.
### Débil y Fuerte
Cada TSH tiene una conexión débil o fuerte:
#### Conexión Fuerte
1. La transacción paga la ejecución del Hook.
2. Puede hacer rollback completo usando `rollback()`.
#### Conexión Débil
1. La transacción **no paga** la ejecución.
2. El TSH paga su ejecución mediante [Collect Call Hooks](/es/docs/hooks/concepts/collect-call).
3. Debe tener activado `asfTshCollect`.
4. **No puede hacer rollback**, pero sí modificar estado o emitir transacciones.
### Antes o Después
* Los Hooks **fuertes** se ejecutan **antes** de aplicar la transacción → pueden bloquearla.
* Los Hooks **débiles** se ejecutan **después** → no pueden bloquearla pero acceden al metadata.
<Aside type="tip">
Hooks fuertes pueden usar <code>hook_again</code> para ejecutarse después como débiles.
</Aside>
### Contexto de ejecución
El parámetro `uint32_t` indica el contexto:
#### En `hook`:
* 0 → ejecución fuerte
* 1 → ejecución débil
* 2 → débil tras `hook_again`
#### En `cbak`:
* 0 → transacción emitida aceptada
* 1 → transacción emitida fallida
### Tabla de referencia
Si una transacción no aparece, solo tiene como TSH a la cuenta originaria.
| Tipo de transacción | Tipo TSH | Quién es el TSH |
|--------------------|---------|----------------|
| AccountDelete | Fuerte | Cuenta destino |
| AccountSet | Ninguno | N/A |
| CheckCancel | Débil | Cuenta destino |
| CheckCreate | Fuerte | Cuenta destino |
| ClaimReward | Fuerte | Emisor |
| DepositPreauth | Fuerte | Cuenta autorizada |
| EscrowCreate | Fuerte | Cuenta destino |
| OfferCreate | Débil | Cuentas cruzadas |
| Payment | Fuerte + Débil | Destino (fuerte), intermediarios (débil) |
| SetHook | Ninguno | N/A |
| TrustSet | Débil | Emisor |
### Tablas detalladas
**AccountSet**
| OTXN | TSH | AccountSet |
| ------- | ------- | ---------- |
| Account | Account | Fuerte |
**AccountDelete**
| OTXN | TSH | AccountDelete |
| ------- | ----------- | ------------- |
| Account | Account | Ninguno |
| Account | Beneficiario| Fuerte |
**Payment**
| OTXN | TSH | Payment |
| ------- | ----------- | ------- |
| Account | Account | Fuerte |
| Account | Destino | Fuerte |
| Account | Cruzado | Débil |
**TrustSet**
| OTXN | TSH | TrustSet |
| ------- | ------- | -------- |
| Account | Account | Fuerte |
| Account | Emisor | Débil |
**URIToken**
| OTXN | Burnable | TSH | Mint | Burn | Buy | Sell | Cancel |
| ------ | -------- | ------ | ------ | ------ | ------ | ------ | ------ |
| Owner | False | Owner | Ninguno| Fuerte | Fuerte | Fuerte | Fuerte |
| Owner | False | Issuer | Ninguno| Débil | Débil | Débil | Ninguno|
| Owner | True | Issuer | Ninguno| Débil | Fuerte | Fuerte | Ninguno|

View File

@@ -0,0 +1,95 @@
---
title: accept
description: Acepta la transacción originaria y confirma los cambios realizados por el hook.
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/introduction">Introducción</LinkButton>
<LinkButton href="/es/docs/hooks/concepts/execution-metadata">Metadatos de ejecución</LinkButton>
### Comportamiento
Finaliza la ejecución del hook con estado: éxito.
* Registra una cadena de retorno y un código de retorno en los metadatos de la transacción.
* Confirma todos los cambios de estado.
* Envía todas las transacciones `emit()`.
* Permite que la transacción originaria continúe.
<Aside type="caution">
Si la transacción originaria se detiene por otra razón, este accept se convierte en un rollback. Ver: orden de ejecución.
</Aside>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t accept (
uint32_t read_ptr,
uint32_t read_len,
uint64_t error_code
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function accept(msg: string, code: number): number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
accept("Éxito", 7, 100);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
accept('Éxito', 100)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ----------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| read_ptr | uint32_t | <p>Puntero a una cadena de retorno que se almacenará en los metadatos de ejecución.<br />Puede ser cualquier texto definido por el desarrollador. <em>Puede ser nulo.</em></p> |
| read_len | uint32_t | Longitud de la cadena de retorno. Máximo 32. <em>Puede ser nulo.</em> |
| error_code | uint64_t | <p>Código de retorno específico del hook que se almacenará en los metadatos.<br /><br />Similar al código de salida de una aplicación en sistemas *nix. Por convención, éxito es 0.</p> |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| msg | string | <p>Cadena que se almacenará en los metadatos de ejecución.<br />Puede ser cualquier texto definido por el desarrollador. <em>Puede ser nulo.</em></p> |
| code | number | <p>Código de retorno específico del hook que se almacenará en los metadatos.<br /><br />Similar al código de salida en sistemas *nix. Por convención, éxito es 0.</p> |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | Accept finaliza el hook, por lo que no devuelve valor al llamador. Por convención todas las APIs devuelven `int64_t`, pero aquí no se retorna nada. |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| number | Accept finaliza el hook, por lo que no devuelve valor al llamador. Por convención las APIs devuelven un número, pero aquí no se retorna nada. |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,81 @@
---
title: rollback
---
import { Aside, Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/introduction">Introducción</LinkButton>
<LinkButton href="/es/docs/hooks/concepts/execution-metadata">Metadatos de ejecución</LinkButton>
### Comportamiento
Finaliza la ejecución del hook con estado: rechazo.
* Registra una cadena de retorno y un código de retorno en los metadatos de la transacción.
* Descarta todos los cambios de estado.
* Descarta todas las transacciones `emit()`.
* Impide que la transacción originaria continúe.
<Aside type="caution">
La transacción originaria fallará con <code>tecHOOK_REJECTED</code> y se cobrará una comisión. Ver: orden de ejecución.
</Aside>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t rollback (
uint32_t read_ptr,
uint32_t read_len,
uint64_t error_code
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function rollback(error_msg: string, error_code: number): number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
rollback("¡Rechazado!", 9, 100);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
rollback('¡Rechazado!', 100)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
<table><thead><tr><th>Nombre</th><th>Tipo</th><th width="202">Descripción</th></tr></thead><tbody><tr><td>read_ptr</td><td>uint32_t</td><td>Puntero a una cadena de retorno que se almacenará en los metadatos de ejecución.<br />Puede ser cualquier texto definido por el desarrollador. <em>Puede ser nulo.</em></td></tr><tr><td>read_len</td><td>uint32_t</td><td>Longitud de la cadena de retorno. Máximo 32. <em>Puede ser nulo.</em></td></tr><tr><td>error_code</td><td>uint64_t</td><td>Código de retorno específico del hook que se almacenará en los metadatos.<br /><br />Similar al código de salida de una aplicación en sistemas *nix. Por convención, los errores son valores distintos de cero.</td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th>Nombre</th><th>Tipo</th><th width="202">Descripción</th></tr></thead><tbody><tr><td>error_msg</td><td>string</td><td>Cadena que se almacenará en los metadatos de ejecución.<br />Puede ser cualquier texto definido por el desarrollador. <em>Puede ser nulo.</em></td></tr><tr><td>error_code</td><td>number</td><td>Código de retorno específico del hook que se almacenará en los metadatos.<br /><br />Similar al código de salida de una aplicación en sistemas *nix. Por convención, los errores son valores distintos de cero.</td></tr></tbody></table>
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
<table><thead><tr><th width="123">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>int64_t</td><td>Rollback finaliza el hook, por lo que no devuelve valor al llamador. Por convención todas las APIs devuelven <code>int64_t</code>, pero en este caso no se retorna nada.</td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th width="123">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>number</td><td>Rollback finaliza el hook, por lo que no devuelve valor al llamador. Por convención todas las APIs devuelven <code>number</code>, pero en este caso no se retorna nada.</td></tr></tbody></table>
</TabItem>
</Tabs>

View File

@@ -0,0 +1,87 @@
---
title: cbak / Callback
description: La función de callback de tu hook
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/compiling-hooks">Compilación de Hooks</LinkButton>
### Comportamiento
* `cbak` es una función definida por el usuario que es llamada por `xahaud` para informar a tu hook sobre el estado de una transacción previamente emitida.
* Se pueden realizar cambios de estado y nuevas llamadas a `emit` desde `cbak`, pero no puede ejecutar `rollback`.
* Cuando se ejecuta `cbak`, la transacción emitida a la que se refiere el callback pasa a ser la transacción originaria.
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t cbak (
uint32_t what
)
````
</TabItem>
<TabItem label="JavaScript">
```javascript
type Callback = (reserved: number) => number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t cbak(uint32_t reserved)
{
return 0;
}
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const Callback = (reserved: number) => {
return 0
}
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| -------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| reserved | uint32_t | <p>si es <code>0</code>:<br />- la transacción emitida asociada a este callback fue aceptada correctamente en un ledger.<br /><br />si es <code>1</code>:<br />- la transacción emitida NO fue aceptada antes de expirar.</p> |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| -------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| reserved | number | <p>si es <code>0</code>:<br />- la transacción emitida asociada a este callback fue aceptada correctamente en un ledger.<br /><br />si es <code>1</code>:<br />- la transacción emitida NO fue aceptada antes de expirar.</p> |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | Un código de retorno arbitrario que desees devolver desde tu hook. Estará presente en los metadatos de la transacción originaria. |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| number | Un código de retorno arbitrario que desees devolver desde tu hook. Estará presente en los metadatos de la transacción originaria. |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,83 @@
---
title: hook
description: La función principal de tu hook
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/compiling-hooks">Compilación de Hooks</LinkButton>
### Comportamiento
* `hook` es una función definida por el usuario que es llamada por `xahaud` para ejecutar tu hook.
* Tu función `hook` debe llamar a `accept` o `rollback` para permitir o rechazar la transacción originaria.
* Si la ejecución llega al final de la función sin llamar a ninguna de ellas, se considera implícitamente un `accept`.
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t hook (
uint32_t reserved
)
````
</TabItem>
<TabItem label="JavaScript">
```javascript
type Hook = (reserved: number) => number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t hook(uint32_t reserved)
{
return 0;
}
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const Hook = (reserved: number) => {
return 0
}
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
<table><thead><tr><th width="183">Nombre</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>reserved</td><td>uint32_t</td><td>Reservado para uso futuro.</td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th width="183">Nombre</th><th>Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>reserved</td><td>number</td><td>Reservado para uso futuro.</td></tr></tbody></table>
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | Un código de retorno arbitrario que desees devolver desde tu hook. Estará presente en los metadatos de la transacción originaria. |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| number | Un código de retorno arbitrario que desees devolver desde tu hook. Estará presente en los metadatos de la transacción originaria. |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,93 @@
---
title: emit
description: Emite una nueva transacción desde el hook
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/emitted-transactions">Transacciones emitidas</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Lee una transacción desde `read_ptr`
* Valida la transacción según las reglas de emisión
* Emite la transacción al consenso si es válida
* Escribe el hash canónico de la transacción en `write_ptr`
</TabItem>
<TabItem label="JavaScript">
* Esta función emite el JSON de transacción proporcionado.
* En caso de éxito, devuelve el número de hashes de transacciones emitidas.
* Si hay un error, devuelve un código de error.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t emit (
uint32_t write_ptr,
uint32_t write_len,
uint32_t read_ptr,
uint32_t read_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function emit(
txJson: Record<string, any> | Transaction
): ErrorCode | ByteArray
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
if (emit(tx, tx_len) < 0)
rollback("¡Error al emitir!", 15, 1);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const emitResult = emit(txJson)
if(typeof emitResult === 'number')
rollback("¡Error al emitir!", 1)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
<table><thead><tr><th>Nombre</th><th width="124">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>write_ptr</td><td>uint32_t</td><td>Puntero a un buffer donde se escribirá el hash de la transacción</td></tr><tr><td>write_len</td><td>uint32_t</td><td>Tamaño del buffer donde se escribirá el hash (debe ser 32)</td></tr><tr><td>read_ptr</td><td>uint32_t</td><td>Puntero a la transacción a emitir</td></tr><tr><td>read_len</td><td>uint32_t</td><td>Longitud de la transacción</td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th>Nombre</th><th width="124">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>txJson</td><td>Record&#x3C;string, any> | Transaction</td><td>El JSON de la transacción a emitir.</td></tr></tbody></table>
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
<table><thead><tr><th width="127">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>int64_t</td><td>En caso de éxito, el número de bytes del hash de la transacción escritos (32), o:<br /><br />Si es negativo, un error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros/longitudes fuera de la memoria del hook.<br /><br /><code>PREREQUISITE_NOT_MET</code><br />- se debe llamar antes a <code>emit_reserve</code><br /><br /><code>TOO_MANY_EMITTED_TXN</code><br />- se han emitido más transacciones de las prometidas<br /><br /><code>EMISSION_FAILURE</code><br />- la transacción es inválida según las reglas de emisión.</td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th width="231">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>ErrorCode | ByteArray</td><td>Devuelve un ErrorCode si hay error, o un array de hashes de transacciones emitidas en caso de éxito.</td></tr></tbody></table>
</TabItem>
</Tabs>

View File

@@ -0,0 +1,61 @@
---
title: prepare
description: Prepara una transacción JSON para su emisión.
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/protocol-reference/transactions">Transacciones</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="JavaScript">
* Esta función toma un objeto JSON de transacción y lo prepara para su emisión.
* La transacción debe estar completa excepto el campo Account, que siempre debe ser la cuenta del Hook.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="JavaScript">
```javascript
function prepare(
txJson: Record<string, any> | Transaction
): ErrorCode | Record<string, any> | Transaction
````
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="JavaScript">
```javascript
const prepared_txn = prepare({
TransactionType: "Payment",
Destination: util_raddr(p1address_ns),
Amount: parseFloat(drops_sent)*2
})
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="JavaScript">
<table><thead><tr><th>Nombre</th><th width="124">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>txJson</td><td>Record&#x3C;string, any> | Transaction</td><td>El JSON de la transacción, debe estar completo excepto el campo Account (siempre la cuenta del Hook).</td></tr></tbody></table>
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="JavaScript">
<table><thead><tr><th width="231">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>ErrorCode | Record&#x3C;string, any> | Transaction</td><td>Devuelve un ErrorCode si hay un error, o el JSON de la transacción preparada o el objeto Transaction.</td></tr></tbody></table>
</TabItem>
</Tabs>

View File

@@ -0,0 +1,64 @@
---
title: etxn_burden
description: Obtiene la carga (burden) de una transacción hipotéticamente emitida
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/emitted-transactions">Transacciones emitidas</LinkButton>
### Comportamiento
* Devuelve la carga (burden) que tendrá una transacción emitida.
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t etxn_burden (
void
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function etxn_burden(): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t burden = etxn_burden();
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const burden = etxn_burden()
```
</TabItem>
</Tabs>
### Parámetros
Ninguno
### Código de retorno
<Tabs>
<TabItem label="C">
<table><thead><tr><th width="165">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>int64_t</td><td>La carga (burden) que necesitará una transacción emitida para poder pasar correctamente a <code>emit()</code></td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th width="165">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>number</td><td>Devuelve un ErrorCode si hay un error, o el valor actual de la carga en caso de éxito.</td></tr></tbody></table>
</TabItem>
</Tabs>

View File

@@ -0,0 +1,96 @@
---
title: etxn_details
description: Genera un sfEmitDetails adecuado para una transacción que está a punto de ser emitida
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/emitted-transactions">Transacciones emitidas</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Genera y escribe un objeto sfEmitDetails de 105 bytes en `write_ptr` si cbak no está definido
* Genera y escribe un objeto sfEmitDetails de 127 bytes en `write_ptr` si cbak está definido
</TabItem>
<TabItem label="JavaScript">
* Esta función proporciona información detallada sobre la transacción.
* Devuelve un ErrorCode si hay un error, o un array de detalles de la transacción en caso de éxito.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t etxn_details (
uint32_t write_ptr,
uint32_t write_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function etxn_details(): ErrorCode | ByteArray
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
uint8_t emitdet[105];
int64_t result =
etxn_details(emitdet, 105);
if (result != 105)
rollback("Etxndetails falló.", 19, 1);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const emitdet = etxn_details()
if (typeof emitdet === 'string || emitdet.length != 105)
rollback("Etxndetails falló.", 1)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ---------- | --------- | -------------------------------------------------------------- |
| write_ptr | uint32_t | Puntero al buffer que recibirá el registro sfEmitDetails |
| write_len | uint32_t | Longitud del buffer |
</TabItem>
<TabItem label="JavaScript">
Sin parámetros en JavaScript
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>Número de bytes escritos.<br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros/longitudes fuera de la memoria del hook.<br /><br /><code>TOO_SMALL</code><br />- el buffer no es lo suficientemente grande<br /><br /><code>PREREQUISITE_NOT_MET</code><br />- no se llamó previamente a <code>etxn_reserve(n)</code><br /><br /><code>FEE_TOO_LARGE</code><br />- la carga es demasiado alta para la red<br /><br /><code>INTERNAL_ERROR</code><br />- error interno al generar el campo requerido</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ---------------------- | -------------------------------------------------------------------------------------------- |
| ErrorCode \| ByteArray | Un ErrorCode si hay error, o un array de detalles de la transacción en caso de éxito. |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,81 @@
---
title: etxn_fee_base
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
<Aside type="caution">
Las comisiones en un ledger con Hooks no son triviales. Ver: [Hook Fees](/es/docs/hooks/concepts/hook-fees) para más detalles.
</Aside>
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/emitted-transactions">Transacciones emitidas</LinkButton>
### Comportamiento
* Devuelve la cantidad de comisión en drops recomendada para una transacción que va a ser emitida.
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t etxn_fee_base (
uint32_t read_ptr,
uint32_t read_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function etxn_fee_base(txblob: ByteArray | HexString): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t fee_to_pay =
etxn_fee_base(tx_blob, tx_blob_len);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const fee_to_pay = etxn_fee_base(tx_blob)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
<table><thead><tr><th>Nombre</th><th width="118">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>read_ptr</td><td>uint32_t</td><td>Puntero al buffer que contiene la transacción serializada que se desea emitir. El campo de comisión es obligatorio pero se ignora (puedes usar cero). Usa el resultado de esta función para rellenar correctamente el campo de comisión.</td></tr><tr><td>read_len</td><td>uint32_t</td><td>La longitud del blob de la transacción.</td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th>Nombre</th><th width="118">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>txblob</td><td>ByteArray | HexString</td><td>El blob de la transacción, que puede ser un array de números o una cadena.</td></tr></tbody></table>
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El número mínimo de drops que una transacción emitida necesita para ser aceptada.<br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- El buffer proporcionado no es válido dentro de la memoria del hook.<br /><br /><code>PREREQUISITE_NOT_MET</code><br />- No se ha llamado previamente a <code>etxn_reserve</code>.<br /><br /><code>INVALID_TXN</code><br />- El buffer no contiene una transacción serializada válida (fallo de deserialización o falta un campo requerido).</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | --------------------------------------------------------------------------- |
| number | Devuelve un ErrorCode si hay un error, o la comisión base calculada si tiene éxito. |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,69 @@
---
title: etxn_generation
description: Obtiene la generación de una transacción hipotéticamente emitida
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/emitted-transactions">Transacciones emitidas</LinkButton>
### Comportamiento
* Devuelve la generación que tendrá una transacción emitida.
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t etxn_generation (
void
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function etxn_generation(): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t generation =
etxn_generation();
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const generation = etxn_generation()
```
</TabItem>
</Tabs>
### Parámetros
Ninguno
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ----------------------------------------------------------------------------------------------- |
| int64_t | La generación que necesitará una transacción emitida para poder pasar correctamente a `emit()` |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| number | Devuelve un ErrorCode si hay un error, o un número que indica el resultado de la generación en caso de éxito. |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,86 @@
---
title: etxn_nonce
description: Genera un nonce de 32 bytes para usar en una transacción emitida
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/emitted-transactions">Transacciones emitidas</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Escribe el hash de 32 bytes en `write_ptr`
</TabItem>
<TabItem label="JavaScript">
* Devuelve un ErrorCode si hay un error, o un array que contiene el valor del nonce en caso de éxito.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t etxn_nonce (
uint32_t write_ptr,
uint32_t write_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function etxn_nonce(): ErrorCode | ByteArray
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
uint8_t n[32];
int64_t bytes_written =
etxn_nonce(n, 32);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const nonce = etxn_nonce()
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ---------- | --------- | ------------------------------------------------------------------------------------------- |
| write_ptr | uint32_t | Puntero a un buffer de tamaño adecuado para almacenar la salida. Debe ser al menos 32 bytes |
| write_len | uint32_t | Longitud del buffer de salida |
</TabItem>
<TabItem label="JavaScript">
Sin parámetros
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
<table><thead><tr><th width="187">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>int64_t</td><td>El número de bytes escritos<br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros/longitudes fuera de la memoria del hook.</td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th width="187">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>ErrorCode \| ByteArray</td><td>Devuelve un ErrorCode si hay un error, o un array con el valor del nonce en caso de éxito.</td></tr></tbody></table>
</TabItem>
</Tabs>

View File

@@ -0,0 +1,80 @@
---
title: etxn_reserve
description: Estima la comisión requerida para que una transacción sea emitida con éxito
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/emitted-transactions">Transacciones emitidas</LinkButton>
### Comportamiento
* Especifica el número de transacciones emitidas que este hook podría emitir durante su ejecución.
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t etxn_fee_base (
uint32_t count
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function etxn_reserve(count: number): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
etxn_reserve(2);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
etxn_reserve(2)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | --------- | -------------------------------------------------------------------------------------------- |
| count | uint32_t | El número máximo de transacciones que este hook podría emitir durante una ejecución. |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | ------------------------------------------------------------------------ |
| count | number | El número máximo de transacciones que este Hook puede emitir. |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El número máximo de transacciones emitidas que este hook puede emitir. Siempre será igual al parámetro <code>count</code> o un error como se indica a continuación.<br /><br />Si es negativo, error:<br /><code>ALREADY_SET</code><br />- El hook ya llamó a esta función anteriormente.<br /><br /><code>TOO_BIG</code><br />- El número de transacciones especificado es demasiado grande.</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | --------------------------------------------------------------------------- |
| number | Devuelve un ErrorCode si hay un error, o el número de transacciones configurado en caso de éxito. |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,110 @@
---
title: float_compare
description: Realiza una comparación entre dos números de punto flotante XFL
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Evalúa una comparación entre dos números de punto flotante XFL
* Devuelve el resultado de la comparación como un booleano codificado en un int64_t.
</TabItem>
<TabItem label="JavaScript">
* Evalúa una comparación entre dos números de punto flotante XFL
* Devuelve un código de error o el resultado de la comparación como un número.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_compare (
int64_t float1,
int64_t float2,
uint32_t mode
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_compare(
f1: bigint,
f2: bigint,
mode: number
): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
if (float_compare(pusd_to_send, 0, COMPARE_LESS) == 1)
{
// pusd_to_send es menor que 0
}
```
</TabItem>
<TabItem label="JavaScript">
```javascript
if (float_compare(pusd_to_send, 0n, COMPARE_LESS) == 1)
{
// pusd_to_send es menor que 0
}
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| float1 | int64_t | Número XFL que representa el primer operando de la comparación |
| float2 | int64_t | Número XFL que representa el segundo operando de la comparación |
| mode | uint32_t | Campo de flags que puede contener cualquiera de (o combinaciones válidas de) los siguientes valores:<br /><code>COMPARE_EQUAL</code> `1`<br /><code>COMPARE_LESS</code> `2`<br /><code>COMPARE_GREATER</code> `4`<br /><br />Combinaciones válidas:<br /><code>COMPARE_LESS</code> \| <code>COMPARE_GREATER</code><br />- Distinto<br /><br /><code>COMPARE_LESS</code> \| <code>COMPARE_EQUAL</code><br />- Menor o igual<br /><br /><code>COMPARE_GREATER</code> \| <code>COMPARE_EQUAL</code><br />- Mayor o igual |
<Aside type="caution">
Verifica siempre que la función devuelve `1` en lugar de simplemente `no cero`, ya que los códigos de error negativos también se consideran `no cero`.
</Aside>
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | ------------------------------------------------------------------ |
| f1 | bigint | El primer valor flotante a comparar |
| f2 | bigint | El segundo valor flotante a comparar |
| mode | number | El modo de comparación (por ejemplo: menor, igual, mayor) |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <code>0</code> si la comparación es falsa.<br /><code>1</code> si la comparación es verdadera.<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- alguno de los parámetros no es un número XFL válido<br /><br /><code>INVALID_ARGUMENT</code><br />- combinación inválida de flags de comparación |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ---------------------------------------------------------------- |
| ErrorCode o number | Devuelve un código de error o el resultado de la comparación |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,95 @@
---
title: float_divide
description: Divide un número XFL entre otro número de punto flotante XFL
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Divide un XFL entre otro XFL
* Devuelve un nuevo XFL como un int64_t
</TabItem>
<TabItem label="JavaScript">
* Divide una representación flotante entre otra.
* Devuelve un código de error o el cociente como bigint.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_divide (
int64_t float1,
int64_t float2
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_divide(f1: bigint, f2: bigint): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t still_one =
float_divide(float_one(), float_one());
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const still_one =
float_divide(float_one(), float_one())
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | -------- | ---------------------------------------------------------------- |
| float1 | int64_t | Número XFL que actúa como numerador |
| float2 | int64_t | Número XFL que actúa como denominador |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | ------------------------ |
| f1 | bigint | El dividendo |
| f2 | bigint | El divisor |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El número XFL (xls17) resultante<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- el parámetro no es un número XFL válido o el resultado no puede representarse<br /><br /><code>DIVISION_BY_ZERO</code><br />- el divisor es cero.</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ------------------------------------------- |
| bigint o ErrorCode | Devuelve un código de error o el cociente |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,67 @@
---
title: float_exponent
description: Obtiene el exponente de un número XFL
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
<Tabs>
<TabItem label="C">
<Aside type="caution" title="Reemplazado por macro">
Esta función ha sido reemplazada por una macro. Por favor, usa la macro mostrada abajo en tu código.
Para comprobar la validez del XFL, utiliza float_mantissa junto con esta macro.
</Aside>
</TabItem>
</Tabs>
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Devuelve la parte del exponente de un XFL como un entero con signo
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
Debido a que los exponentes pueden ser negativos, y los valores negativos están reservados para estados de error, los exponentes no pueden devolverse desde funciones. Por ello, esta función se ha convertido en una macro como se muestra a continuación.
```c
#define float_exponent(f)\
(((int32_t)(((f) >> 54U) & 0xFFU)) - 97)
````
</TabItem>
<TabItem label="JavaScript">
```javascript
const float_exponent = (f) => (Number(((f) >> 54n) & 0xFFn) - 97)
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t exponent =
float_exponent(float_one());
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | -------- | --------------------------------------- |
| float1 | int64_t | Número de punto flotante XFL |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,107 @@
---
title: float_int
description: Convierte un número de punto flotante XFL en un entero (floor)
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Desplaza a la izquierda (multiplica por 10) el XFL según el número de decimales especificado
* Convierte el XFL resultante a un entero, descartando cualquier resto
* Devuelve el entero
</TabItem>
<TabItem label="JavaScript">
* Convierte una representación flotante en un entero con un número específico de decimales.
* Devuelve un código de error o el entero resultante como número.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_int (
int64_t float1,
uint32_t decimal_places,
uint32_t absolute
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_int(
f1: bigint,
decimal_places: number,
abs: number
): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t drops =
float_int(xahbalance, 6, 0);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const drops =
float_int(xahbalance, 6, 0);
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| --------------- | -------- | ------------------------------------------------------------------------------------------------------------ |
| float1 | int64_t | Número XFL que representa el operando |
| decimal_places | uint32_t | Número de posiciones decimales a desplazar antes de calcular el valor entero |
| absolute | uint32_t | Si es `1`, devuelve el valor absoluto del resultado |
<Aside type="tip">
Los valores negativos están reservados para códigos de error. Si necesitas aplicar esta función a un XFL negativo, usa `absolute = 1`.
</Aside>
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| --------------- | ------ | ------------------------------------------------- |
| f1 | bigint | El número flotante a convertir |
| decimal_places | number | Número de decimales a considerar |
| abs | number | Indica si se debe tomar el valor absoluto |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El entero positivo calculado<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- uno de los parámetros no es un número XFL válido<br /><br /><code>INVALID_ARGUMENT</code><br />- se intentó usar más de 15 decimales<br /><br /><code>CANT_RETURN_NEGATIVE</code><br />- se intentó devolver un entero negativo, lo cual no está permitido; usa <code>absolute = 1</code></p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ---------------------------------------------------------------- |
| number o ErrorCode | Devuelve un código de error o el entero resultante |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,92 @@
---
title: float_invert
description: Divide uno entre un número de punto flotante XFL
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Invierte una representación flotante.
* Devuelve el valor invertido como un bigint o un ErrorCode
</TabItem>
<TabItem label="JavaScript">
* Divide `1` entre un XFL
* Devuelve un nuevo XFL como un int64_t
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_invert (
int64_t float1
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_invert(f1: bigint): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t still_one =
float_invert(float_one());
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const still_one =
float_invert(float_one())
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | -------- | --------------------------------------- |
| float1 | int64_t | Número de punto flotante XFL |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ----- | ----------------------- |
| f1 | float | El número a invertir |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El número XFL (xls17) resultante<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- el parámetro no es un número XFL válido o el resultado no puede representarse<br /><br /><code>DIVISION_BY_ZERO</code><br />- el parámetro es cero.</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | --------------------------------------------------- |
| ErrorCode \| bigint | Devuelve un código de error o el valor invertido |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,100 @@
---
title: float_log
description: Calcula el logaritmo decimal de un XFL
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Calcula el logaritmo decimal de un número XFL
* Devuelve un nuevo XFL
<Aside type="caution">
Debido a limitaciones de rendimiento, `float_log` convierte el argumento a un número de punto flotante de doble precisión IEEE base-2 antes de aplicar el logaritmo en base 10. Por lo tanto, el resultado puede tener menos precisión de la esperada.
</Aside>
</TabItem>
<TabItem label="JavaScript">
* Calcula el logaritmo de una representación flotante.
* Devuelve un código de error o el logaritmo como bigint.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_log (
int64_t float1
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_log(f1: bigint): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t zero =
float_log(float_one());
```
<Aside type="caution">
Si se pasa un número negativo, la función devolverá `COMPLEX_NOT_SUPPORTED` si el resultado implica un valor complejo.
</Aside>
</TabItem>
<TabItem label="JavaScript">
```javascript
const zero =
float_log(float_one())
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | -------- | ------------------------------------------------------------------------------------------------------------ |
| float1 | int64_t | Número XFL que representa el valor del cual se desea calcular el logaritmo |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | ------------------------------------------------ |
| f1 | bigint | El número flotante del que calcular el logaritmo |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El logaritmo calculado<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- el parámetro no es un número XFL válido<br /><br /><code>COMPLEX_NOT_SUPPORTED</code><br />- el parámetro es negativo y produciría un resultado complejo</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | --------------------------------------------------- |
| bigint o ErrorCode | Devuelve un código de error o el logaritmo como bigint |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,95 @@
---
title: float_mantissa
description: Obtiene la mantisa de un número XFL
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Devuelve la parte de la mantisa de un XFL como un entero sin signo
</TabItem>
<TabItem label="JavaScript">
* Obtiene la mantisa de una representación flotante.
* Devuelve un código de error o la mantisa como bigint.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_mantissa (
int64_t float1
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_mantissa(f1: bigint): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t mantissa =
float_mantissa(float_one());
```
<Aside type="tip">
La mantisa de un XFL negativo siempre es positiva. Usa `float_sign` para determinar el signo del número.
</Aside>
</TabItem>
<TabItem label="JavaScript">
```javascript
const mantissa =
float_mantissa(float_one());
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | ------ | ------------------------------------------- |
| f1 | bigint | El número flotante del que obtener la mantisa |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------- | -------- | --------------------------------------- |
| float1 | int64_t | Número de punto flotante XFL |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>La mantisa del XFL<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- el parámetro no es un número XFL válido</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ------------------------------------------- |
| bigint o ErrorCode | Devuelve un código de error o la mantisa |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,112 @@
---
title: float_mulratio
description: Multiplica un número de punto flotante XFL por un numerador y denominador no XFL
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Calcula la multiplicación de un número de punto flotante XFL (xls17) por el cociente de dos enteros
* Devuelve un nuevo XFL como un int64_t
</TabItem>
<TabItem label="JavaScript">
* Multiplica un número flotante por una razón definida por un numerador y un denominador.
* Devuelve un código de error o un nuevo XFL como bigint.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_mulratio (
int64_t float1,
uint32_t round_up,
uint32_t numerator,
uint32_t denominator
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_mulratio(
f1: bigint,
round_up: number,
numerator: number,
denominator: number
): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t max_vault_pusd =
float_mulratio(max_vault_pusd, 0,
COLLATERALIZATION_NUMERATOR, COLLATERALIZATION_DENOMINATOR);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const max_vault_pusd =
float_mulratio(max_vault_pusd, 0,
COLLATERALIZATION_NUMERATOR, COLLATERALIZATION_DENOMINATOR);
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ----------- | -------- | --------------------------------------------------------------------------------------------- |
| float1 | int64_t | Número XFL que representa el primer operando de la multiplicación |
| round_up | uint32_t | Si es distinto de cero, todos los cálculos se redondean hacia arriba |
| numerator | uint32_t | Numerador del cociente por el cual se multiplicará el valor flotante |
| denominator | uint32_t | Denominador del cociente por el cual se multiplicará el valor flotante |
<Aside type="caution">
Algunas multiplicaciones pueden producir overflow, lo que devuelve un error `INVALID_FLOAT`. Sin embargo, un **underflow** devuelve XFL Cero Canónico (es decir, número = 0).
</Aside>
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ----------- | ------ | --------------------------------------------------------------------------------------------- |
| f1 | bigint | Número XFL que representa el primer operando de la multiplicación |
| round_up | number | Si es distinto de cero, todos los cálculos se redondean hacia arriba |
| numerator | number | Numerador del cociente por el cual se multiplicará el valor flotante |
| denominator | number | Denominador del cociente por el cual se multiplicará el valor flotante |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El número XFL (xls17) resultante<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- alguno de los parámetros no es un número XFL válido<br /><br /><code>OVERFLOW</code><br />- el resultado es demasiado grande para representarse en XFL<br /><br /><code>DIVISION_BY_ZERO</code><br />- el denominador es cero.</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ----------------------------------------------------------------- |
| ErrorCode o bigint | Devuelve un código de error o el número XFL (xls17) resultante |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,99 @@
---
title: float_multiply
description: Multiplica dos números XFL
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Calcula la multiplicación de dos números de punto flotante XFL (xls17)
* Devuelve un nuevo XFL como un int64_t
</TabItem>
<TabItem label="JavaScript">
* Calcula la multiplicación de dos números de punto flotante XFL (xls17)
* Devuelve un código de error o un nuevo XFL como bigint.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_multiply (
int64_t float1,
int64_t float2
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_multiply(f1: bigint, f2: bigint): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t max_vault_pusd =
float_multiply(vault_xrp, exchange_rate);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const max_vault_pusd =
float_multiply(vault_xrp, exchange_rate)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | -------- | --------------------------------------------------------------------------------------------- |
| float1 | int64_t | Número XFL que representa el primer operando de la multiplicación |
| float2 | int64_t | Número XFL que representa el segundo operando de la multiplicación |
<Aside type="caution">
Algunas multiplicaciones pueden provocar overflow, devolviendo un error `INVALID_FLOAT`. Sin embargo, un **underflow** devuelve XFL Cero Canónico (es decir, número = 0).
</Aside>
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | --------------------------------------------------------------------------------------------- |
| f1 | bigint | Número XFL que representa el primer operando de la multiplicación |
| f2 | bigint | Número XFL que representa el segundo operando de la multiplicación |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El número XFL (xls17) resultante<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- alguno de los parámetros no es un número XFL válido<br /><br /><code>OVERFLOW</code><br />- el resultado es demasiado grande para representarse en XFL.</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ---------------------------------------------------- |
| ErrorCode o bigint | Devuelve un código de error o el número XFL resultante |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,96 @@
---
title: float_negate
description: Niega un número de punto flotante XFL
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Multiplica un XFL por `-1`
* Devuelve un nuevo XFL como un int64_t
</TabItem>
<TabItem label="JavaScript">
* Niega una representación flotante.
* Devuelve un código de error o el valor negado como bigint.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_negate (
int64_t float1
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_negate(f1: bigint): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t negative_one =
float_negate(float_one());
```
<Aside type="tip" title="Caso especial">
La negación de Cero Canónico es Cero Canónico. A diferencia de otros estándares de punto flotante (como IEEE), no existe el "cero negativo" en XFL.
</Aside>
</TabItem>
<TabItem label="JavaScript">
```javascript
const negative_one =
float_negate(float_one());
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | -------- | --------------------------------------- |
| float1 | int64_t | Número de punto flotante XFL |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | ------------------------ |
| f1 | bigint | El número a negar |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El número XFL (xls17) resultante<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- alguno de los parámetros no es un número XFL válido</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ---------------------------------------------------- |
| ErrorCode o bigint | Devuelve un código de error o el número XFL resultante |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,75 @@
---
title: float_one
description: Devuelve el número 1 representado como un número XFL
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Devuelve uno (`1`) como un XFL en formato int64_t
</TabItem>
<TabItem label="JavaScript">
* Obtiene la representación flotante del número uno.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_one();
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_one(): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t one =
float_one();
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const one = float_one()
```
</TabItem>
</Tabs>
### Parámetros
Esta función no tiene parámetros.
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ----------------------------------- |
| int64_t | El número XFL (xls17) |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ----------------------------------- |
| ErrorCode \| bigint | El número XFL (xls17) |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,103 @@
---
title: float_root
description: Calcula la raíz n-ésima de un XFL
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Calcula la raíz `n`-ésima de un número XFL
* Devuelve un nuevo XFL
<Aside type="caution">
Debido a limitaciones de rendimiento, `float_root` convierte el argumento a un número de punto flotante IEEE base-2 de doble precisión antes de aplicar la raíz n-ésima. Por lo tanto, el resultado puede tener menos precisión de la esperada. Si necesitas mayor precisión, puedes dividir el XFL en una parte alta y una baja, calcular las raíces cuadradas por separado y luego multiplicar los resultados.
</Aside>
</TabItem>
<TabItem label="JavaScript">
* Calcula la raíz n-ésima de una representación flotante.
* Devuelve un código de error o la raíz como bigint.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_root (
int64_t float1,
uint32_t n
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_root(f1: bigint, n: number): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t three =
float_root(nine, 2);
```
<Aside type="caution">
Si se pasa un número negativo, la función devolverá `COMPLEX_NOT_SUPPORTED` si la raíz es de grado par.
</Aside>
</TabItem>
<TabItem label="JavaScript">
```javascript
const three =
float_root(nine, 2)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | -------- | ----------------------------------------------------------------------------------------------------------- |
| float1 | int64_t | Número XFL del que se desea calcular la raíz |
| n | uint32_t | Grado de la raíz, por ejemplo `2` representa la raíz cuadrada |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | ------------------------------------------ |
| f1 | bigint | El número flotante del que calcular la raíz |
| n | number | El grado de la raíz a calcular |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>La raíz n-ésima calculada<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- el parámetro no es un número XFL válido<br /><br /><code>COMPLEX_NOT_SUPPORTED</code><br />- el parámetro es negativo y daría lugar a una raíz compleja</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | -------------------------------------------------------- |
| bigint o ErrorCode | Devuelve un código de error o la raíz resultante |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,102 @@
---
title: float_set
description: Crear un número flotante a partir de un exponente y una mantisa
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Calcula un número de punto flotante XFL (xls17) a partir del exponente y la mantisa proporcionados
* Devuelve ese XFL como un int64_t
</TabItem>
<TabItem label="JavaScript">
* Establece el exponente y la mantisa para una representación flotante.
* Devuelve un código de error o un nuevo XFL como bigint.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_set (
int32_t exponent,
int64_t mantissa
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_set(exponent: number, mantissa: number): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t small_amount =
float_set(-81, 1);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const small_amount = float_set(-81, 1);
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| -------- | -------- | ------------------------------------------------------------------- |
| exponent | int32_t | Un exponente en el rango `-96` a `80` |
| mantissa | int64_t | Una mantisa. Si es negativa, el signo del número será negativo. |
<Aside type="caution">
Al establecer una mantisa con más o menos de 16 dígitos decimales, el exponente se ajustará para garantizar que la mantisa tenga exactamente 16 dígitos. Este ajuste puede provocar un `INVALID_FLOAT` en algunos casos.
</Aside>
<Aside type="tip" title="Caso especial">
El XFL canónico 0 también es 0 en el número contenedor. Por lo tanto, nunca es necesario llamar a `float_set(0,0);`
</Aside>
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| -------- | ------ | ------------------------------------------------------------------- |
| exponent | bigint | Un exponente en el rango `-96` a `80` |
| mantissa | bigint | Una mantisa. Si es negativa, el signo del número será negativo. |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El número XFL (xls17)<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- El ajuste de la mantisa a 16 dígitos produjo un desbordamiento o subdesbordamiento.</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | -------------------------------------------------- |
| ErrorCode \| bigint | Un código de error o el número XFL (xls17). |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,94 @@
---
title: float_sign
description: Obtener el signo de un número XFL
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Devuelve `1` si el XFL es negativo, en caso contrario devuelve `0`
</TabItem>
<TabItem label="JavaScript">
* Devuelve `1` si el XFL es negativo, en caso contrario devuelve `0`
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_sign (
int64_t float1
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_sign(f1: bigint): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t sign =
float_sign(float_one());
```
<Aside type="tip">
El bit de signo dentro del XFL es `0` cuando el XFL es negativo, sin embargo esta función sigue la convención estándar y devuelve `1` si es negativo.
</Aside>
</TabItem>
<TabItem label="JavaScript">
```javascript
const sign =
float_sign(float_one());
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | -------- | -------------------------------------- |
| float1 | int64_t | Un número de punto flotante XFL |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | ---------------------------------------- |
| f1 | bigint | El número flotante del que obtener el signo |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El signo del XFL:<br /><code>0</code> si es positivo, <code>1</code> si es negativo.<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- el parámetro no es un número XFL válido</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ------------------------------------------------ |
| number o ErrorCode | Un código de error o el resultado del signo |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,123 @@
---
title: float_sto
description: Generar un XFL como objeto serializado
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
<LinkButton href="/es/docs/hooks/concepts/serialized-objects">Objetos serializados</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Lee un número de punto flotante XFL y opcionalmente un código de campo y código de moneda
* Escribe una cantidad serializada en `write_ptr` según los parámetros proporcionados
</TabItem>
<TabItem label="JavaScript">
* Almacena una representación flotante en un campo específico.
* Devuelve un código de error o el valor actualizado como un array de números.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_sto (
uint32_t write_ptr,
uint32_t write_len,
uint32_t cread_ptr,
uint32_t cread_len,
uint32_t iread_ptr,
uint32_t iread_len,
int64_t float1,
uint32_t field_code
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_sto(
currency: ByteArray | HexString | undefined,
issuer: ByteArray | HexString | undefined,
f1: bigint,
field_code: number
): ErrorCode | ByteArray
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
#define SBUF(str) (uint32_t)(str), sizeof(str)
uint8_t amt_out[48];
if (float_sto(SBUF(amt_out),
SBUF(currency), SBUF(hook_accid), pusd_to_send, -1) < 0)
rollback(SBUF("Peggy: No se pudo serializar la cantidad pusd"), 1);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const amt_out = float_sto(currency, hook_accid, pusd_to_send, -1)
if (typeof amt_out === 'number')
rollback("Peggy: No se pudo serializar la cantidad pusd", 1)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ----------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| write_ptr | uint32_t | Puntero a un buffer de tamaño adecuado para almacenar el campo serializado. Se recomiendan al menos 48 bytes. |
| write_len | uint32_t | Longitud del buffer de salida. |
| cread_ptr | uint32_t | Puntero a un buffer que contiene el código de moneda a serializar. _Puede ser null._ |
| cread_len | uint32_t | Longitud del código de moneda. Debe ser 20, 3 o 0 (null). |
| iread_ptr | uint32_t | Puntero a un buffer que contiene el Account ID del emisor. _Puede ser null._ |
| iread_len | uint32_t | Longitud del Account ID del emisor. Debe ser 20 o 0 (null). |
| float1 | int64_t | Número XFL a serializar. |
| field_code | uint32_t | <p>Código de campo <code>sf</code> para prefijar la cantidad serializada (ej. <code>sfAmount</code>).<br />Si es <code>0xFFFFFFFFU</code> (o <code>(uint32_t)(-1)</code>) no se añade código de campo ni moneda/emisor, pero se serializa como flotante.<br />Si es 0, tampoco se añade código de campo ni moneda/emisor, pero se serializa como cantidad nativa XRP.</p> |
<Aside type="tip">
Para generar una cantidad `XAH`, rellena previamente el código de campo en el buffer de salida y pasa el buffer desplazado junto con `0` como field_code.
</Aside>
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ---------- | ----------------------------------- | --------------------------------------------------------- |
| currency | ByteArray \| HexString \| undefined | Valor de moneda a almacenar |
| issuer | ByteArray \| HexString \| undefined | Emisor a almacenar |
| f1 | bigint | Número flotante XFL |
| field_code | number | Código de campo donde almacenar el valor |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>Número de bytes escritos en el buffer.<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- el número no es un XFL válido<br /><br /><code>OUT_OF_BOUNDS</code><br />- punteros fuera de memoria del hook<br /><br /><code>INVALID_ARGUMENT</code><br />- parámetros incorrectos para modo XRP o sin field code<br /><br /><code>TOO_SMALL</code><br />- buffer demasiado pequeño<br /><br /><code>XFL_OVERFLOW</code><br />- desbordamiento al normalizar</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ---------------------- | ------------------------------------------------------------------ |
| ErrorCode \| ByteArray | Código de error o array con el valor serializado |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,98 @@
---
title: float_sto_set
description: Leer una cantidad serializada en un XFL
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
<LinkButton href="/es/docs/hooks/concepts/serialized-objects">Objetos serializados</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Lee un número de punto flotante serializado.
* Si hay más campos/datos después del número flotante serializado, se ignoran.
* Lo devuelve como un número XFL
</TabItem>
<TabItem label="JavaScript">
* Establece el buffer para almacenar representaciones flotantes.
* Devuelve un ErrorCode o el resultado como número.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_sto_set (
uint32_t read_ptr,
uint32_t read_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_sto_set(buf: ByteArray | HexString): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t vault_pusd = float_sto_set(vault, 8);
if (vault_pusd < 0)
rollback("Failed to parse serialized float.", 33, 1);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const vault_pusd = float_sto_set(vault)
if (typeof vault_pusd === 'string')
rollback("Failed to parse serialized float.", 1)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| -------- | --------- | ------------------------------------------------------------------ |
| read_ptr | uint32_t | Puntero a un buffer que contiene el XFL serializado. _Puede ser null._ |
| read_len | uint32_t | Longitud del buffer. |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ---------------------- | ---------------------- |
| buf | ByteArray \| HexString | El buffer a procesar. |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| int64_t | <p>El número de bytes escritos en el buffer de salida.<br /><br />Si es negativo, error:<br /><code>NOT_AN_OBJECT</code><br />- el buffer no contiene un número flotante serializado válido<br /><br /><code>OUT_OF_BOUNDS</code><br />- los punteros/longitudes están fuera de la memoria del hook.</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ------------------------------------------ |
| ErrorCode o number | Un código de error o el resultado como número. |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,99 @@
---
title: float_sum
description: Sumar dos números XFL
---
import { Tabs, TabItem, LinkButton, Aside } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/floating-point-numbers-xfl">Números de punto flotante (XFL)</LinkButton>
### Comportamiento
<Tabs>
<TabItem label="C">
* Calcula la suma de dos números de punto flotante XFL (xls17)
* Devuelve un nuevo XFL como un int64_t
</TabItem>
<TabItem label="JavaScript">
* Suma dos representaciones flotantes.
* Devuelve un código de error o la suma como bigint.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t float_sum (
int64_t float1,
int64_t float2
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function float_sum(f1: bigint, f2: bigint): ErrorCode | bigint
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t two =
float_sum(float_one(), float_one());
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const two =
float_sum(float_one(), float_one());
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------ | -------- | --------------------------------------------------------------------------- |
| float1 | int64_t | Número XFL que representa el primer operando de la suma |
| float2 | int64_t | Número XFL que representa el segundo operando de la suma |
<Aside type="tip">
Para restar dos valores flotantes, usa `float_negate` en el segundo valor y luego `float_sum`.
</Aside>
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | --------------------------- |
| f1 | bigint | Primer número a sumar |
| f2 | bigint | Segundo número a sumar |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El número XFL (xls17)<br /><br />Si es negativo, error:<br /><code>INVALID_FLOAT</code><br />- alguno de los parámetros no es válido<br /><br /><code>OVERFLOW</code><br />- la suma es demasiado grande</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ------------------------------------ |
| ErrorCode o bigint | Un código de error o la suma |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,86 @@
---
title: hook_account
description: Obtener el Account ID de 20 bytes en el que se está ejecutando el Hook
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
<Tabs>
<TabItem label="C">
* Escribe el Account ID de 20 bytes en `write_ptr`
</TabItem>
<TabItem label="JavaScript">
* Obtiene el Account ID de 20 bytes en el que se está ejecutando el Hook.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t hook_account (
uint32_t write_ptr,
uint32_t write_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function hook_account(): ErrorCode | ByteArray
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
uint8_t hook_acc_id[20];
int64_t bytes_written =
hook_account(hook_acc_id, 20);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const hook_acc_id = hook_account()
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| --------- | -------- | --------------------------------------------------------------------------- |
| write_ptr | uint32_t | Puntero a un buffer adecuado para almacenar la salida (mínimo 20 bytes) |
| write_len | uint32_t | Longitud del buffer de salida |
</TabItem>
<TabItem label="JavaScript">
Sin parámetros
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>Número de bytes escritos<br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros fuera de la memoria del hook</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ---------------------- | --------------------------------------------------------------------------------------------- |
| ErrorCode o ByteArray | Devuelve el Account ID del Hook o un código de error si falla la obtención |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,57 @@
---
title: hook_again
description: Devuelve la posición en la cadena de hooks que ocupa el hook en ejecución
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
* Si el hook se está ejecutando en modo fuerte, marca este hook en la cadena para [Again As Weak Execution](/es/docs/hooks/concepts/weak-and-strong).
* Si la transacción originaria se aplica correctamente, el hook será llamado de nuevo en una segunda ejecución débil.
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t hook_again(void);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function hook_again(): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t result =
hook_again();
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const result = hook_again()
```
</TabItem>
</Tabs>
### Parámetros
Esta API no tiene parámetros
### Código de retorno
<Tabs>
<TabItem label="C">
<table><thead><tr><th width="176">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>int64_t</td><td><code>1</code> si se marcó correctamente para Again As Weak.<br /><br /><code>PREREQUISITE_NOT_MET</code><br />- Este hook ya se está ejecutando en modo débil en el momento de la llamada.<br /><br /><code>ALREADY_SET</code><br />- La función ya fue llamada en esta ejecución.</td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th width="176">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>number</td><td>Devuelve un código de estado que indica el resultado de la operación.</td></tr></tbody></table>
</TabItem>
</Tabs>

View File

@@ -0,0 +1,87 @@
---
title: hook_hash
description: Obtener el SHA512H (con sesgo de namespace) de 32 bytes del Hook en ejecución
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
<Tabs>
<TabItem label="C">
* Busca el hash del hook instalado en la cuenta del hook en la posición `hook_no`
* Escribe el hash de 32 bytes en `write_ptr`
</TabItem>
<TabItem label="JavaScript">
* Obtiene el hash del hook instalado en la cuenta del hook en la posición indicada.
* Devuelve el SHA512H (con sesgo de namespace) del hook en ejecución, o un código de error si falla.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t hook_hash (
uint32_t write_ptr,
uint32_t write_len,
int32_t hook_no
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function hook_hash(hookno: number): ErrorCode | ByteArray
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
uint8_t hash[32];
int64_t bytes_written =
hook_hash(hash, 32, -1);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const hash = hook_hash(hookno)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| --------- | -------- | ------------------------------------------------------------------------------------------------ |
| write_ptr | uint32_t | Puntero a un buffer adecuado para almacenar la salida (mínimo 32 bytes) |
| write_len | uint32_t | Longitud del buffer de salida |
| hook_no | int32_t | Posición del hook en la cadena, o `-1` para el hook en ejecución |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------- | ------ | ------------------------------------------------------------------------------------------------ |
| hook_no | number | Posición del hook en la cadena, o `-1` para el hook en ejecución |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>Número de bytes escritos<br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros fuera de memoria<br /><br /><code>DOESNT_EXIST</code><br />- el hook indicado no existe en la cadena</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ---------------------- | --------------------------------------------------------------------------------------------------------- |
| ByteArray o ErrorCode | Devuelve el SHA512H del hook en ejecución o un código de error si falla la operación |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,96 @@
---
title: hook_param
description: Obtener el valor de un parámetro de hook por nombre
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
<Tabs>
<TabItem label="C">
* Busca el valor de un parámetro con nombre especificado en `read_ptr`
* Escribe el valor del parámetro en `write_ptr`
</TabItem>
<TabItem label="JavaScript">
* Obtiene el valor de un parámetro asociado a la clave especificada.
* Devuelve el valor asociado a la clave, o un código de error si falla la operación.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t hook_param (
uint32_t write_ptr,
uint32_t write_len,
uint32_t read_ptr,
uint32_t read_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function hook_param(key: ByteArray | HexString): ErrorCode | ByteArray
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
uint8_t pname[] = {0xCAU, 0xFEU};
uint8_t pvalue[32];
int64_t value_len =
hook_param(pvalue, 32, pname, 2);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const pname = [0xCA, 0xFE]
const pvalue = hook_param(pname)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| --------- | -------- | --------------------------------------------------------------------------- |
| write_ptr | uint32_t | Puntero a un buffer adecuado para almacenar la salida (mínimo 32 bytes) |
| write_len | uint32_t | Longitud del buffer de salida |
| read_ptr | uint32_t | Puntero a un buffer que contiene el nombre del parámetro |
| read_len | uint32_t | Longitud del nombre del parámetro |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ---------------------- | ------------------------------------------------ |
| key | ByteArray o HexString | Clave del parámetro a recuperar |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>Número de bytes escritos<br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros fuera de memoria<br /><br /><code>DOESNT_EXIST</code><br />- el parámetro no existe o es nulo<br /><br /><code>TOO_SMALL</code><br />- el nombre del parámetro no puede ser nulo<br /><br /><code>TOO_BIG</code><br />- el nombre supera los 32 bytes</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ---------------------- | --------------------------------------------------------------------------------- |
| ByteArray o ErrorCode | Devuelve el valor del parámetro o un código de error si falla la operación |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,115 @@
---
title: hook_param_set
description: >-
Establecer o eliminar un parámetro en un hook de la misma cuenta más adelante
en la cadena de ejecución
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
<Tabs>
<TabItem label="C">
* Busca en la cadena de hooks de la cuenta un hash de 32 bytes indicado por `hread_ptr`
* Si se encuentra: establece un parámetro:
* Con el nombre indicado por `kread_ptr` y
* El valor indicado por `read_ptr`
</TabItem>
<TabItem label="JavaScript">
* Establece un parámetro para el hook con la clave y valor especificados, asociado a un hash.
* Devuelve un código de estado que indica el resultado de la operación.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t hook_param_set (
uint32_t read_ptr,
uint32_t read_len,
uint32_t kread_ptr,
uint32_t kread_len,
uint32_t hread_ptr,
uint32_t hread_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function hook_param_set(
val: ByteArray | HexString,
key: ByteArray | HexString,
hash: ByteArray | HexString
): number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
uint8_t pvalue[] = "valor de parámetro";
uint8_t pname[] = "nombre_param";
uint8_t phash[] = { 0x19U, 0xFEU, 0x69U, 0xF1U, 0x53U, 0x66U, 0x4EU, 0x8CU,
0x97U, 0xF4U, 0x4CU, 0x5CU, 0x3CU, 0x65U, 0x63U, 0x79U,
0xC2U, 0xD0U, 0x26U, 0xE7U, 0x90U, 0xEFU, 0x38U, 0xF7U,
0xEDU, 0x73U, 0xE9U, 0xCEU, 0x9CU, 0x9DU, 0xBFU, 0x03U };
int64_t result =
hook_param_set(pvalue, sizeof(pvalue),
pname, sizeof(pname),
phash, sizeof(phash));
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const pvalue = "valor de parámetro"
const pname = "nombre_param"
const phash = [ 0x19, 0xFE, 0x69, 0xF1, 0x53, 0x66, 0x4E, 0x8C,
0x97, 0xF4, 0x4C, 0x5C, 0x3C, 0x65, 0x63, 0x79,
0xC2, 0xD0, 0x26, 0xE7, 0x90, 0xEF, 0x38, 0xF7,
0xED, 0x73, 0xE9, 0xCE, 0x9C, 0x9D, 0xBF, 0x03 ]
const result = hook_param_set(str2hex(pvalue), str2hex(pname), phash)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| --------- | -------- | ---------------------------------------- |
| read_ptr | uint32_t | Puntero al valor del parámetro |
| read_len | uint32_t | Longitud del valor del parámetro |
| kread_ptr | uint32_t | Puntero al nombre del parámetro |
| kread_len | uint32_t | Longitud del nombre del parámetro |
| hread_ptr | uint32_t | Puntero al hash del hook |
| hread_len | uint32_t | Longitud del hash (siempre 32) |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ---------------------- | ------------------------------------------- |
| val | ByteArray o HexString | Valor del parámetro |
| key | ByteArray o HexString | Clave asociada al parámetro |
| hash | ByteArray o HexString | Hash asociado al parámetro |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
<table><thead><tr><th width="148">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>int64_t</td><td>Longitud del valor del parámetro establecido correctamente<br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros fuera de la memoria del hook.<br /><br /><code>TOO_SMALL</code><br />- el nombre del parámetro no puede ser nulo<br /><br /><code>TOO_BIG</code><br />- el nombre del parámetro supera los 32 bytes</td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th width="148">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>number</td><td>Devuelve un código de estado que indica el resultado de la operación.</td></tr></tbody></table>
</TabItem>
</Tabs>

View File

@@ -0,0 +1,60 @@
---
title: hook_pos
description: Devuelve la posición en la cadena de hooks que ocupa el hook en ejecución
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
* Devuelve la posición en la cadena de hooks que ocupa el hook en ejecución.
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t hook_pos(void);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
hook_pos()
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t pos =
hook_pos();
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const pos = hook_pos()
```
</TabItem>
</Tabs>
### Parámetros
Esta API no tiene parámetros
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | -------------------------------------------------------------------------------------------- |
| int64_t | Posición en la cadena del hook en ejecución. La primera posición es 0. |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | -------------------------------------------------------------------------------------------- |
| number | Devuelve la posición actual en la cadena de hooks o un código de error si falla la operación |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,97 @@
---
title: hook_skip
description: Omitir un hook que aparece más adelante en la cadena de hooks de la cuenta
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
<Tabs>
<TabItem label="C">
* Busca en la cadena de hooks un hook identificado por el hash en `read_ptr`
* Lo marca como deshabilitado para esta ejecución de la cadena
</TabItem>
<TabItem label="JavaScript">
* Omite la ejecución de un hook basándose en el hash y el flag proporcionados.
* Devuelve un código de estado indicando el resultado de la operación.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t hook_skip (
uint32_t read_ptr,
uint32_t read_len,
uint32_t flags
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function hook_skip(
hash: ByteArray | HexString,
flag: number
): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
uint8_t phash[] = { 0x19U, 0xFEU, 0x69U, 0xF1U, 0x53U, 0x66U, 0x4EU, 0x8CU,
0x97U, 0xF4U, 0x4CU, 0x5CU, 0x3CU, 0x65U, 0x63U, 0x79U,
0xC2U, 0xD0U, 0x26U, 0xE7U, 0x90U, 0xEFU, 0x38U, 0xF7U,
0xEDU, 0x73U, 0xE9U, 0xCEU, 0x9CU, 0x9DU, 0xBFU, 0x03U };
int64_t result =
hook_skip(phash, 32, 0);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const phash = [ 0x19, 0xFE, 0x69, 0xF1, 0x53, 0x66, 0x4E, 0x8C,
0x97, 0xF4, 0x4C, 0x5C, 0x3C, 0x65, 0x63, 0x79,
0xC2, 0xD0, 0x26, 0xE7, 0x90, 0xEF, 0x38, 0xF7,
0xED, 0x73, 0xE9, 0xCE, 0x9C, 0x9D, 0xBF, 0x03 ]
const result = hook_skip(phash, 0);
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| -------- | -------- | ---------------------------------------------------------------------------------------------------- |
| read_ptr | uint32_t | Puntero a un buffer que contiene el hash del hook |
| read_len | uint32_t | Longitud del hash (siempre 32) |
| flags | uint32_t | <p>Si es 0:<br />- añade el hash a la lista de hooks omitidos<br /><br />Si es 1:<br />- elimina el hash de la lista de hooks omitidos</p> |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ---------------------- | --------------------------------------------- |
| hash | ByteArray o HexString | Hash del hook a omitir |
| flag | number | Indicador de la acción (añadir o eliminar) |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
<table><thead><tr><th width="163">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>int64_t</td><td>Si tiene éxito: <code>1</code><br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros fuera de memoria<br /><br /><code>DOESNT_EXIST</code><br />- el parámetro no existe o es nulo<br /><br /><code>INVALID_ARGUMENT</code><br />- el hash no tiene 32 bytes</td></tr></tbody></table>
</TabItem>
<TabItem label="JavaScript">
<table><thead><tr><th width="163">Tipo</th><th>Descripción</th></tr></thead><tbody><tr><td>number o ErrorCode</td><td>Devuelve un código de estado indicando el resultado de la operación.</td></tr></tbody></table>
</TabItem>
</Tabs>

View File

@@ -0,0 +1,67 @@
---
title: fee_base
description: Obtener la tarifa base del ledger actual
---
import { Tabs, TabItem, LinkButton } from '@astrojs/starlight/components';
### Conceptos
<LinkButton href="/es/docs/hooks/concepts/hook-fees">Comisiones de Hooks</LinkButton>
### Comportamiento
* Devuelve la tarifa base del ledger actual
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t fee_base();
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function fee_base(): number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t fee =
fee_base();
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const fee = fee_base()
```
</TabItem>
</Tabs>
### Parámetros
Esta API no recibe parámetros.
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ---------------------------------------- |
| int64_t | La tarifa base del ledger actual |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | ---------------------------------------- |
| number | La tarifa base del ledger actual |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,106 @@
---
title: ledger_keylet
description: Buscar un keylet dentro de un rango especificado en el ledger actual
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
<Tabs>
<TabItem label="C">
* Lee un Keylet de 34 bytes desde `lread_ptr`
* Lee un Keylet de 34 bytes desde `hread_ptr`
* Busca en el ledger el primer (más bajo) Keylet de este tipo dentro de ese rango
* Si se encuentra alguno, lo escribe en `write_ptr`
</TabItem>
<TabItem label="JavaScript">
* Esta función busca en el ledger el primer (más bajo) Keylet de este tipo dentro del rango indicado.
* Devuelve el número de bytes escritos (34 bytes) en caso de éxito, o un código de error si ocurre un fallo.
</TabItem>
</Tabs>
### Definición
C
<Tabs>
<TabItem label="C">
```c
int64_t ledger_keylet (
uint32_t write_ptr,
uint32_t write_len,
uint32_t lread_ptr,
uint32_t lread_len,
uint32_t hread_ptr,
uint32_t hread_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function ledger_keylet(
low: ByteArray | HexString,
high: ByteArray | HexString
): ErrorCode | ByteArray
```
</TabItem>
</Tabs>
### Ejemplo
C
<Tabs>
<TabItem label="C">
```c
//TODO
```
</TabItem>
<TabItem label="JavaScript">
```javascript
ledger_keylet(low, high)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| --------- | -------- | ------------------------------------------------------------------------------------------------------------- |
| write_ptr | uint32_t | Puntero a un buffer donde almacenar el Keylet serializado |
| write_len | uint32_t | Longitud del buffer de salida (debe ser 34 bytes) |
| lread_ptr | uint32_t | Puntero al Keylet serializado de 34 bytes que representa el límite inferior del rango |
| lread_len | uint32_t | Siempre 34 bytes |
| hread_ptr | uint32_t | Puntero al Keylet serializado de 34 bytes que representa el límite superior del rango |
| hread_len | uint32_t | Siempre 34 bytes |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ---------------------- | ------------------------------------------------------------------------------------------------------------- |
| low | ByteArray \| HexString | Keylet serializado de 34 bytes que representa el límite inferior del rango |
| high | ByteArray \| HexString | Keylet serializado de 34 bytes que representa el límite superior del rango |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>Número de bytes escritos (34 bytes) en caso de éxito.<br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros fuera de la memoria del hook<br /><br /><code>TOO_SMALL</code> / <code>TOO_BIG</code><br />- los tamaños no son 34 bytes<br /><br /><code>INVALID_ARGUMENT</code><br />- uno o más Keylets no son válidos<br /><br /><code>DOES_NOT_MATCH</code><br />- los Keylets no son del mismo tipo<br /><br /><code>DOESNT_EXIST</code><br />- no se encontró ningún Keylet en el rango</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ---------------------- | ----------------------------------------------------------------------------------------------- |
| ErrorCode \| ByteArray | Devuelve los 34 bytes del Keylet o un código de error si falla |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,86 @@
---
title: ledger_last_hash
description: Obtener el SHA512H de 32 bytes (con sesgo de namespace) del último ledger cerrado
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
<Tabs>
<TabItem label="C">
* Escribe el hash de 32 bytes en `write_ptr`
</TabItem>
<TabItem label="JavaScript">
* Obtiene el hash del último ledger.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t ledger_last_hash (
uint32_t write_ptr,
uint32_t write_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function ledger_last_hash(): ErrorCode | ByteArray
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
uint8_t hash[32];
int64_t bytes_written =
ledger_last_hash(hash, 32);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const hash = ledger_last_hash()
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| --------- | -------- | --------------------------------------------------------------------------- |
| write_ptr | uint32_t | Puntero a un buffer adecuado para almacenar la salida (mínimo 32 bytes) |
| write_len | uint32_t | Longitud del buffer de salida |
</TabItem>
<TabItem label="JavaScript">
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>Número de bytes escritos<br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros fuera de la memoria del hook</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | ---------------------------------------------------------------------------------------------------- |
| number | Devuelve un código de error si ocurre un error, o un array que representa el hash del último ledger |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,69 @@
---
title: ledger_last_time
description: Obtener la marca de tiempo del último ledger cerrado
---
import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
* Devuelve la marca de tiempo de Xahau del último ledger cerrado.
<Aside type="tip">
Las marcas de tiempo de Xahau son idénticas a las marcas de tiempo Unix, excepto que tienen un desplazamiento de `-946684800`.
La marca de tiempo Unix equivalente es: `ledger_last_time() + 946684800;`
</Aside>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t ledger_last_time();
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function ledger_last_time(): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t ts =
ledger_last_time();
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const ts = ledger_last_time()
```
</TabItem>
</Tabs>
### Parámetros
Esta API no recibe parámetros.
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ----------------------------------------------------- |
| int64_t | La marca de tiempo XRPL del último ledger cerrado |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | ---------------------------------------------------------------------------------------------------- |
| number | Devuelve un código de error si ocurre un fallo, o un número que representa la marca de tiempo del último ledger |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,88 @@
---
title: ledger_nonce
description: Generar un nonce de 32 bytes para usar en una transacción emitida
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
<Tabs>
<TabItem label="C">
* Escribe un valor aleatorio de 32 bytes en `write_ptr`
</TabItem>
<TabItem label="JavaScript">
* Obtiene el nonce del ledger actual.
</TabItem>
</Tabs>
### Definición
C
<Tabs>
<TabItem label="C">
```c
int64_t ledger_nonce (
uint32_t write_ptr,
uint32_t write_len
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function ledger_nonce(): ErrorCode | ByteArray
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
uint8_t n[32];
int64_t bytes_written =
ledger_nonce(n, 32);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const nonce = ledger_nonce()
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| --------- | -------- | --------------------------------------------------------------------------- |
| write_ptr | uint32_t | Puntero a un buffer adecuado para almacenar la salida (mínimo 32 bytes) |
| write_len | uint32_t | Longitud del buffer de salida |
</TabItem>
<TabItem label="JavaScript">
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>Número de bytes escritos<br /><br />Si es negativo, error:<br /><code>OUT_OF_BOUNDS</code><br />- punteros fuera de la memoria del hook</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ---------------------- | ---------------------------------------------------------------------------------------------------- |
| ErrorCode \| ByteArray | Devuelve un código de error o un array que representa el nonce del ledger actual |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,65 @@
---
title: ledger_seq
description: Obtener el número de secuencia del ledger actual
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
* Devuelve el número de secuencia del ledger actual
### Definición
C
<Tabs>
<TabItem label="C">
```c
int64_t ledger_seq();
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function ledger_seq(): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t seq =
ledger_seq();
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const seq = ledger_seq()
```
</TabItem>
</Tabs>
### Parámetros
Esta API no recibe parámetros.
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ------------------------------------------- |
| int64_t | El número de secuencia del ledger actual |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------ | ------------------------------------------- |
| number | El número de secuencia del ledger actual |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,77 @@
---
title: meta_slot
description: Cargar los metadatos de la transacción origen en un slot
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
* Si el Hook se está ejecutando de forma [débil (Weak Execution)](/es/docs/hooks/concepts/weak-and-strong), coloca los metadatos de la transacción origen en el slot especificado o en uno nuevo si no se especifica ninguno
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t meta_slot (
uint32_t slot_no
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function meta_slot(slotno: number): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t meta_slot_no =
meta_slot(0);
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const meta_slot_no = meta_slot(0)
```
</TabItem>
</Tabs>
### Parámetros
<Tabs>
<TabItem label="C">
| Nombre | Tipo | Descripción |
| ------- | -------- | --------------------------------------------------------------------------- |
| slot_no | uint32_t | Número de slot donde colocar los datos, o 0 para usar el siguiente disponible |
</TabItem>
<TabItem label="JavaScript">
| Nombre | Tipo | Descripción |
| ------ | ------ | ------------------------------------------- |
| slotno | number | El número de slot del que obtener metadatos |
</TabItem>
</Tabs>
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| int64_t | <p>El slot en el que se colocó la transacción origen<br /><br /><code>INVALID_ARGUMENT</code><br />- el número de slot especificado excede el máximo permitido<br /><br /><code>NO_FREE_SLOTS</code><br />- no hay slots disponibles para almacenar la transacción<br /><br /><code>PREREQUISITE_NOT_MET</code><br />- el hook se está ejecutando de forma fuerte (Strong Execution) y no hay metadatos disponibles</p> |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | --------------------------------------------------------- |
| ErrorCode \| number | Devuelve un código de error o los metadatos del slot |
</TabItem>
</Tabs>

View File

@@ -0,0 +1,74 @@
---
title: otxn_burden
description: Obtener la carga (burden) de la transacción origen
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
### Comportamiento
<Tabs>
<TabItem label="C">
* Devuelve la carga de la transacción origen o `1` si no existe el campo burden.
</TabItem>
<TabItem label="JavaScript">
* Obtiene la carga de la transacción origen.
* Devuelve la carga como un número, o un ErrorCode si falla.
</TabItem>
</Tabs>
### Definición
<Tabs>
<TabItem label="C">
```c
int64_t otxn_burden (
void
);
````
</TabItem>
<TabItem label="JavaScript">
```javascript
function otxn_burden(): ErrorCode | number
```
</TabItem>
</Tabs>
### Ejemplo
<Tabs>
<TabItem label="C">
```c
int64_t burden =
otxn_burden();
```
</TabItem>
<TabItem label="JavaScript">
```javascript
const burden = otxn_burden()
```
</TabItem>
</Tabs>
### Parámetros
Ninguno
### Código de retorno
<Tabs>
<TabItem label="C">
| Tipo | Descripción |
| -------- | ---------------------------------------------------------------------------------------------------------------- |
| int64_t | La carga de la transacción origen, o `1` si no existe el campo burden en la transacción origen |
</TabItem>
<TabItem label="JavaScript">
| Tipo | Descripción |
| ------------------- | ------------------------------------------------------------------------ |
| number o ErrorCode | Devuelve la carga como número o un ErrorCode si falla la obtención |
</TabItem>
</Tabs>

Some files were not shown because too many files have changed in this diff Show More