Saltar al contenido principal

Invocar una función de contrato en una transacción Stellar utilizando SDKs

Este es un ejemplo simple que utiliza el SDK de Stellar para crear, simular y luego ensamblar una transacción Stellar que invoca una función increment del contrato de ejemplo auth.

consejo

Por favor, dirígete a la página de inicio del proyecto del SDK de JavaScript para aprender cómo instalarlo.

Primero, sube los bytes del contrato de ejemplo a la blockchain usando Stellar CLI. Esto se llama "instalar" porque, desde la perspectiva de la blockchain misma, este contrato ha sido instalado.

stellar contract build
stellar contract install --wasm target/wasm32-unknown-unknown/release/test_auth_contract.wasm --network testnet

Esto devolverá un hash; guárdalo, lo usarás pronto. Para este ejemplo, usaremos bc7d436bab44815c03956b344dc814fac3ef60e9aca34c3a0dfe358fcef7527f.

Aún no se ha desplegado ningún contrato con este hash. En Soroban, puedes tener muchos contratos inteligentes que todos referencian el mismo hash de Wasm, definiendo su comportamiento. Lo haremos desde el propio código de JavaScript a continuación.

import { Keypair } from "@stellar/stellar-sdk"
import { Client, basicNodeSigner } from "@stellar/stellar-sdk/contract"
import { Server } from "@stellar/stellar-sdk/rpc"

// As mentioned, we are using Testnet for this example
const rpcUrl = "https://soroban-testnet.stellar.org"
const networkPassphrase = "Test SDF Network ; September 2015"
const wasmHash = "bc7d436bab44815c03956b344dc814fac3ef60e9aca34c3a0dfe358fcef7527f"

/**
* Generate a random keypair and fund it
*/
async function generateFundedKeypair() {
const keypair = Keypair.random();
const server = new Server(rpcUrl);
await server.requestAirdrop(keypair.publicKey());
return keypair
}

(async () => {
// The source account will be used to sign and send the transaction.
const sourceKeypair = await generateFundedKeypair()

// If you are using a browser, you can pass in `signTransaction` from your
// Wallet extension such as Freighter. If you're using Node, you can use
// `signTransaction` from `basicNodeSigner`.
const { signTransaction } = basicNodeSigner(sourceKeypair, networkPassphrase)

// This constructs and simulates a deploy transaction. Once we sign and send
// this below, it will create a brand new smart contract instance that
// references the wasm we uploaded with the CLI.
const deployTx = await Client.deploy(
null, // if the contract has a `__constructor` function, its arguments go here
{
networkPassphrase,
rpcUrl,
wasmHash,
publicKey: sourceKeypair.publicKey(),
signTransaction,
}
)
// Like other `Client` methods, `deploy` returns an `AssembledTransaction`,
// which wraps logic for signing, sending, and awaiting completion of the
// transaction. Once that all completes, the `result` of this transaction
// will contain the final `Client` instance, which we can use to invoke
// methods on the new contract. Here we are using JS destructuring to get the
// `result` key from the object returned by `signAndSend`, and put it in a
// local variable called `client`.
const { result: client } = await deployTx.signAndSend()

...
Cliente de un contrato existente

Si no necesitas desplegar un contrato, y en su lugar ya conoces el ID de un contrato desplegado, puedes instanciar un Cliente para él directamente. Esto usa argumentos similares a los que se utilizan para Client.deploy arriba, con la adición de contractId:

-const deployTx = await Client.deploy(
- null,
- {
+const client = await Client.from({
+ contractId: "C123abc…",
networkPassphrase,
rpcUrl,
wasmHash,
publicKey: sourceKeypair.publicKey(),
signTransaction,
})

Ahora que hemos instanciado un client, podemos usarlo para llamar a métodos en el contrato. Retomando donde nos quedamos:

  ...

// This will construct and simulate an `increment` transaction. Since the
// `auth` contract requires that this transaction be signed, we will need to
// call `signAndSend` on it, like we did with `deployTx` above.
const incrementTx = await client.increment({
user: sourceKeypair.publicKey(), // who needs to sign
value: 1, // how much to increment by
})

// For calls that don't need to be signed, you can get the `result` of their
// simulation right away, on a call like `client.increment()` above.
const { result } = await incrementTx.signAndSend()

// Now you can do whatever you need to with the `result`, which in this case
// contains the new value of the incrementor/counter.
console.log("New incremented value:", result)
})();