Saltar al contenido principal

Emitir un activo Tutorial

En este tutorial, recorreremos los pasos para emitir un activo en la red de prueba Stellar.

nota

Si deseas interactuar con un activo emitido en la red Stellar en contratos inteligentes, puedes crear o desplegar el Contrato de Activo Stellar para ese activo.

Requisitos previos

Debes asegurarte de tener la cantidad requerida de XLM para crear tus cuentas de emisión y distribución y cubrir el saldo mínimo y las tarifas de transacción. Si estás emitiendo un activo en la red de prueba, puedes financiar tu cuenta obteniendo XLM de prueba de friendbot. Si estás emitiendo un activo en producción, necesitarás adquirir XLM de otra billetera o exchange.

Si deseas evitar que tus usuarios tengan que lidiar con tarifas de transacción, considera usar transacciones de incremento de tarifas. Lee más en nuestra Entrada de Enciclopedia sobre Transacciones de Incremento de Tarifas.

Aprende sobre la red de prueba y la red principal en nuestra sección de Redes.

Aprende más sobre las tarifas en nuestra sección de Tarifas, Límites de Recursos y Medición.

Herramientas fundamentales

Keypair de cuenta emisora

Primero, debes generar un keypair único. La clave pública actuará como tu identidad de emisión en la red, mientras que utilizarás la clave secreta para firmar transacciones.

const issuerKeypair = StellarSdk.Keypair.random();

console.log("Issuer Public Key:", issuerKeypair.publicKey());
console.log("Issuer Secret Key:", issuerKeypair.secret());
información

Tu dirección de cuenta no cambiará una vez que emitas tu activo, incluso si modificas sus firmantes. Muchos emisores emplean claves públicas de vanity relacionadas con su activo. Por ejemplo, podrías configurar un firmante personalizado en base32 como GASTRO...USD.

nota

Muchos usuarios aseguran su cuenta emisora con técnicas de almacenamiento en frío, como una billetera de hardware o una configuración de múltiples firmas. Esto añade una capa adicional de protección al mantener tu clave secreta fuera de línea o requerir múltiples aprobaciones para transacciones.

Keypair de cuenta de distribución

Tu activo puede ser emitido y transferido entre cuentas a través de un pago, contrato, o saldo reclamable. Aunque no es necesario crear una cuenta de distribución, es una práctica recomendada, así que lo haremos en este ejemplo. Lee más en nuestra sección de Cuentas de Emisión y Distribución.

Tres Operaciones

Generar un nuevo keypair
const distributorKeypair = StellarSdk.Keypair.random();
Importar un keypair existente
const distributorKeypair = StellarSdk.Keypair.fromSecret(SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4)
Emplear múltiples firmas
peligro

Ten cuidado al trabajar con claves secretas en bruto. Si no tienes habilitada la recuperación de confianza del emisor, cualquier error aquí podría hacer que los activos se pierdan de manera permanente. Muchos usuarios colocan sus primeros proyectos en testnet o prueban Quests que ofrecen un entorno de baja presión para principiantes.

Objeto de activo local

El objeto activo es una combinación de tu código y tu clave pública de emisión. Después de tu emisión, cualquiera puede buscar en la red tu activo único.

const astroDollar = new StellarSdk.Asset(
"AstroDollar",
issuerKeypair.publicKey(),
);
información

Aunque cualquiera puede crear un activo, puede haber implicaciones de cumplimiento del mundo real relevantes para tu caso de uso.

nota

Querrás asegurarte de publicar información sobre tu activo para establecer confianza con tus usuarios y prevenir errores. Aprende cómo hacerlo en nuestra sección de Publicar Información Sobre Tu Activo.

Transacciones de red

Establecer línea de confianza del distribuidor

Las cuentas deben establecer una línea de confianza con la cuenta emisora para tener el activo de ese emisor. Esto es cierto para todos los activos excepto para el token nativo de la red, Lumens.

nota

Si deseas evitar que tus usuarios tengan que lidiar con líneas de confianza o XLM, considera usar reservas patrocinadas. Lee más en nuestra Entrada de Enciclopedia sobre Reservas Patrocinadas.

const StellarSdk = require("stellar-sdk");
const server = new StellarSdk.Horizon.Server(
"https://horizon-testnet.stellar.org",
);
const account = await server.loadAccount(distributorKeypair.publicKey());

const transaction = new StellarSdk.TransactionBuilder(account, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
// The `changeTrust` operation creates (or alters) a trustline
.addOperation(
StellarSdk.Operation.changeTrust({
asset: astroDollar,
limit: "1000", // optional
source: distributorKeypair.publicKey(),
}),
)
.setTimeout(100)
.build();

Pago de emisor al distribuidor

Los pagos son la operación más popular para realmente emitir (o acuñar) tu activo, en comparación con otras emisiones. Un pago crea la cantidad de un activo especificado, hasta el máximo entero de 64 bits. Es relevante mencionar que no necesitas aumentar la cantidad de emisión de tu activo por el incremento mínimo de XDR.

// We're using TransactionBuilder(...) as a short-hand here
// to show that these operations can be "chained" together.
const transaction = new StellarSdk.TransactionBuilder(...)
// The `payment` operation sends the `amount` of the specified
// `asset` to our distributor account
.addOperation(StellarSdk.Operation.payment({
destination: distributorKeypair.publicKey(),
asset: astroDollar,
amount: '1000',
source: issuerKeypair.publicKey()
}))
nota

También puedes crear un mercado directamente desde la cuenta emisora y emitir tokens a través del comercio.

Transacciones opcionales

Configurar suministro máximo

peligro

Esta sección detalla cómo bloquear tu cuenta con el propósito de limitar el suministro de tu activo emitido. However, locking your account means you’ll never be able to do anything with it ever again—whether that’s adjusting signers, changing the home domain, claiming any held XLM, or any other operation. Tu cuenta estará completamente congelada.

Puedes configurar permanentemente el número exacto de un activo que existirá alguna vez. Aprende más sobre el suministro de activos en nuestra sección sobre Limitando el Suministro de un Activo

const lockAccountTransaction = new StellarSdk.TransactionBuilder(...)
// This `setOptions` operation locks the issuer account
// so there can never be any more of the asset minted
.addOperation(StellarSdk.Operation.setOptions({
masterWeight: 0,
source: issuerKeypair.publicKey()
}))

Aprobar la línea de confianza del distribuidor

Si habilitas la bandera de autorización, la cuenta emisora también necesita aprobar la solicitud de línea de confianza de la cuenta distribuidora antes del pago de emisión. Necesitarás hacer esto para todas las nuevas cuentas cuando se configuró para tu activo.

const issuingAccount = await server.loadAccount(issuerKeypair.publicKey());
const transaction = new StellarSdk.TransactionBuilder(...)
.addOperation(
StellarSdk.Operation.setTrustLineFlags({
trustor: distributorKeypair.publicKey(),
asset: astroDollar,
flags: {
authorized: true,
},
}),
)
.setTimeout(100)
.build();

Ejemplo de código completo

var StellarSdk = require("stellar-sdk");
var server = new StellarSdk.Horizon.Server(
"https://horizon-testnet.stellar.org",
);

// Keys for accounts to issue and receive the new asset
var issuerKeys = StellarSdk.Keypair.fromSecret(
"SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4",
);
var receivingKeys = StellarSdk.Keypair.fromSecret(
"SDSAVCRE5JRAI7UFAVLE5IMIZRD6N6WOJUWKY4GFN34LOBEEUS4W2T2D",
);

// Create an object to represent the new asset
var astroDollar = new StellarSdk.Asset("AstroDollar", issuerKeys.publicKey());

// First, the receiving account must trust the asset
server
.loadAccount(receivingKeys.publicKey())
.then(function (receiver) {
var transaction = new StellarSdk.TransactionBuilder(receiver, {
fee: 100,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
// The `changeTrust` operation creates (or alters) a trustline
// The `limit` parameter below is optional
.addOperation(
StellarSdk.Operation.changeTrust({
asset: astroDollar,
limit: "1000",
}),
)
// setTimeout is required for a transaction
.setTimeout(100)
.build();
transaction.sign(receivingKeys);
return server.submitTransaction(transaction);
})
.then(console.log)

// Second, the issuing account actually sends a payment using the asset
.then(function () {
return server.loadAccount(issuerKeys.publicKey());
})
.then(function (issuer) {
var transaction = new StellarSdk.TransactionBuilder(issuer, {
fee: 100,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
.addOperation(
StellarSdk.Operation.payment({
destination: receivingKeys.publicKey(),
asset: astroDollar,
amount: "10",
}),
)
// setTimeout is required for a transaction
.setTimeout(100)
.build();
transaction.sign(issuerKeys);
return server.submitTransaction(transaction);
})
.then(console.log)
.catch(function (error) {
console.error("Error!", error);
});