Referencia de Smart Contracts
Los smart contracts de ULedger se escriben en WebAssembly Text Format (.wat) y son ejecutados por la ULVM — la máquina virtual WebAssembly propia de ULedger. Cada despliegue, actualización e invocación es una transaction firmada en la blockchain.
Desplegar Contrato
Despliega un smart contract .wat en una blockchain. La solicitud es multiparte — el archivo del contrato se sube junto con los parámetros de la transaction. El wallet ya debe estar registrado en la blockchain de destino.
Solicitud
POST /api/v1/smartcontracts/deploy
Encabezados
X-AccessKey— Tu clave de acceso de entidadContent-Type: multipart/form-data
Campos del formulario
walletAddress(requerido) — El wallet que despliega el contratoblockchainId(requerido) — ID de la blockchain de destinofrom(requerido) — Dirección del remitente (generalmente igual quewalletAddress)file(requerido) — El archivo de contrato.watpayload— Etiqueta o nota de despliegue opcionalpassphrase— Solo si el wallet fue creado con una
Respuesta
Devuelve el resultado de la transaction en caso de éxito. La dirección del contrato se deriva del ID de la transaction — recupera el bloque en la altura actual para encontrarla.
- cURL
- TypeScript
curl -X POST \
'https://your-tms-url/api/v1/smartcontracts/deploy' \
-H 'X-AccessKey: your-entity-access-key' \
-F 'walletAddress=54677be320b0bd704a99ee1f3d60c7309dfdee4810b1846d7b66ddbe0e84f585' \
-F 'blockchainId=08c28f29a62819120958984b761ddf8ccb45951612731409873994958fd150a2' \
-F 'from=54677be320b0bd704a99ee1f3d60c7309dfdee4810b1846d7b66ddbe0e84f585' \
-F 'payload=my first contract' \
-F 'file=@./contract.wat'
import fs from 'fs';
import FormData from 'form-data';
const form = new FormData();
form.append('walletAddress', '54677be320b0bd704a99ee1f3d60c7309dfdee4810b1846d7b66ddbe0e84f585');
form.append('blockchainId', '08c28f29a62819120958984b761ddf8ccb45951612731409873994958fd150a2');
form.append('from', '54677be320b0bd704a99ee1f3d60c7309dfdee4810b1846d7b66ddbe0e84f585');
form.append('payload', 'my first contract');
form.append('file', fs.createReadStream('./contract.wat'));
const res = await fetch('https://your-tms-url/api/v1/smartcontracts/deploy', {
method: 'POST',
headers: {
'X-AccessKey': 'your-entity-access-key',
...form.getHeaders(),
},
body: form,
});
const data = await res.json();
console.log(data);
Actualizar Contrato
Actualiza un contrato desplegado existente con un nuevo archivo .wat. La dirección del contrato permanece igual — solo cambia el código. Las versiones anteriores se conservan en la blockchain.
Solicitud
POST /api/v1/smartcontracts/upgrade
Encabezados
X-AccessKey— Tu clave de acceso de entidadContent-Type: multipart/form-data
Campos del formulario
walletAddress(requerido) — El wallet que realiza la actualizaciónblockchainId(requerido) — ID de la blockchain de destinocontractAddress(requerido) — Dirección del contrato a actualizarfile(requerido) — El nuevo archivo de contrato.watupgradeReason— Una nota que describe qué cambiópassphrase— Solo si el wallet fue creado con una
Respuesta
Devuelve el resultado de la transaction de actualización en caso de éxito.
- cURL
- TypeScript
curl -X POST \
'https://your-tms-url/api/v1/smartcontracts/upgrade' \
-H 'X-AccessKey: your-entity-access-key' \
-F 'walletAddress=54677be320b0bd704a99ee1f3d60c7309dfdee4810b1846d7b66ddbe0e84f585' \
-F 'blockchainId=08c28f29a62819120958984b761ddf8ccb45951612731409873994958fd150a2' \
-F 'contractAddress=your-contract-address' \
-F 'upgradeReason=fixed a bug in the main function' \
-F 'file=@./contract-v2.wat'
import fs from 'fs';
import FormData from 'form-data';
const form = new FormData();
form.append('walletAddress', '54677be320b0bd704a99ee1f3d60c7309dfdee4810b1846d7b66ddbe0e84f585');
form.append('blockchainId', '08c28f29a62819120958984b761ddf8ccb45951612731409873994958fd150a2');
form.append('contractAddress', 'your-contract-address');
form.append('upgradeReason', 'fixed a bug in the main function');
form.append('file', fs.createReadStream('./contract-v2.wat'));
const res = await fetch('https://your-tms-url/api/v1/smartcontracts/upgrade', {
method: 'POST',
headers: {
'X-AccessKey': 'your-entity-access-key',
...form.getHeaders(),
},
body: form,
});
const data = await res.json();
console.log(data);
Invocar Contrato
Llama a una función en un smart contract desplegado. Los argumentos tienen tipos definidos — la ULVM necesita conocer el tipo de cada argumento para codificarlo correctamente antes de la ejecución.
Solicitud
POST /api/v1/smartcontracts/invoke/payload
Encabezados
X-AccessKey— Tu clave de acceso de entidadContent-Type: application/json
Cuerpo
walletAddress— El wallet que firma la invocaciónblockchainId— ID de la blockchain de destinocontractAddress(requerido) — La dirección del contrato desplegadofunctionName(requerido) — La función exportada a llamararguments— Array de argumentos tipados. Cada entrada tiene untypeyvalue. Tipos soportados:int32,int64,float32,float64,bool,string,bytesgasLimit— Gas máximo para la ejecución. Usa0para sin límite.passphrase— Solo si el wallet fue creado con una
Respuesta
Devuelve el resultado de la transaction de invocación incluyendo cualquier salida de la función del contrato.
Ejemplo de respuesta
{
"transactionId": "a1b2c3...",
"status": "confirmed",
"output": "42",
"gasUsed": 100
}
- cURL
- TypeScript
curl -X POST \
'https://your-tms-url/api/v1/smartcontracts/invoke/payload' \
-H 'X-AccessKey: your-entity-access-key' \
-H 'Content-Type: application/json' \
-d '{
"walletAddress": "54677be320b0bd704a99ee1f3d60c7309dfdee4810b1846d7b66ddbe0e84f585",
"blockchainId": "08c28f29a62819120958984b761ddf8ccb45951612731409873994958fd150a2",
"contractAddress": "your-contract-address",
"functionName": "main",
"arguments": [
{ "type": "string", "value": "hello" },
{ "type": "int32", "value": "42" }
],
"gasLimit": 0
}'
const res = await fetch('https://your-tms-url/api/v1/smartcontracts/invoke/payload', {
method: 'POST',
headers: {
'X-AccessKey': 'your-entity-access-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
walletAddress: '54677be320b0bd704a99ee1f3d60c7309dfdee4810b1846d7b66ddbe0e84f585',
blockchainId: '08c28f29a62819120958984b761ddf8ccb45951612731409873994958fd150a2',
contractAddress: 'your-contract-address',
functionName: 'main',
arguments: [
{ type: 'string', value: 'hello' },
{ type: 'int32', value: '42' },
],
gasLimit: 0,
}),
});
const data = await res.json();
console.log('Output:', data.output);
Revertir Contrato
Revierte un smart contract desplegado a una versión anteriormente desplegada. Todas las versiones se conservan en la cadena — esto simplemente vuelve a activar el bytecode de la versión especificada sin perder el historial.
Solicitud
POST /api/v1/smartcontracts/rollback
Encabezados
X-AccessKey— Tu clave de acceso de entidadContent-Type: application/json
Cuerpo
walletAddress(requerido) — El wallet que desplegó el contratoblockchainId(requerido) — ID del blockchain de destinocontractAddress(requerido) — El contrato a revertirtargetVersion(requerido) — El número de versión a restaurar (p. ej.1)passphrase(opcional) — Solo si el wallet fue creado con unarollbackReason(opcional) — Una nota que describe por qué se revierte
Respuesta
Devuelve el resultado de la transaction de reversión en caso de éxito.
Ejemplo de respuesta
{
"transactionId": "rb1b2c3...",
"status": "confirmed",
"contractAddress": "your-contract-address",
"targetVersion": 1
}
- cURL
- TypeScript
curl -X POST \
'https://your-tms-url/api/v1/smartcontracts/rollback' \
-H 'X-AccessKey: your-entity-access-key' \
-H 'Content-Type: application/json' \
-d '{
"walletAddress": "54677be320b0bd704a99ee1f3d60c7309dfdee4810b1846d7b66ddbe0e84f585",
"blockchainId": "08c28f29a62819120958984b761ddf8ccb45951612731409873994958fd150a2",
"contractAddress": "your-contract-address",
"targetVersion": 1,
"rollbackReason": "Error crítico encontrado en V2"
}'
const res = await fetch('https://your-tms-url/api/v1/smartcontracts/rollback', {
method: 'POST',
headers: {
'X-AccessKey': 'your-entity-access-key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
walletAddress: '54677be320b0bd704a99ee1f3d60c7309dfdee4810b1846d7b66ddbe0e84f585',
blockchainId: '08c28f29a62819120958984b761ddf8ccb45951612731409873994958fd150a2',
contractAddress: 'your-contract-address',
targetVersion: 1,
rollbackReason: 'Error crítico encontrado en V2',
}),
});
const data = await res.json();
console.log('Transaction de rollback:', data.transactionId);
Obtener Estado del Contrato
Recupera el estado clave-valor actual almacenado por un smart contract. El estado es escrito por las funciones del contrato durante la invocación y persiste entre llamadas.
Solicitud
GET /api/v1/smartcontracts/{blockchainId}/{contractAddress}/state
Encabezados
X-AccessKey— Tu clave de acceso de entidad
Parámetros de ruta
blockchainId— El blockchain en el que está desplegado el contratocontractAddress— La dirección del contrato
Respuesta
Devuelve un mapa de todas las claves y valores que el contrato ha escrito en el almacenamiento de estado.
Ejemplo de respuesta
{
"contract:version": "1",
"contract:owner": "54677be3...",
"counter": "42"
}
- cURL
- TypeScript
curl -X GET \
'https://your-tms-url/api/v1/smartcontracts/08c28f29.../your-contract-address/state' \
-H 'X-AccessKey: your-entity-access-key' \
-H 'Accept: application/json'
const blockchainId = '08c28f29a62819120958984b761ddf8ccb45951612731409873994958fd150a2';
const contractAddress = 'your-contract-address';
const res = await fetch(
`https://your-tms-url/api/v1/smartcontracts/${blockchainId}/${contractAddress}/state`,
{
headers: {
'X-AccessKey': 'your-entity-access-key',
'Accept': 'application/json',
},
}
);
const state = await res.json();
console.log('Estado del contrato:', state);
Obtener Traza de Ejecución del Contrato
Devuelve la traza de ejecución de una invocación específica del contrato. Útil para depuración — muestra qué instrucciones WASM se ejecutaron, su costo en gas y los valores leídos o escritos durante la llamada.
Solicitud
GET /api/v1/smartcontracts/{blockchainId}/{contractAddress}/trace/{txId}
Encabezados
X-AccessKey— Tu clave de acceso de entidad
Parámetros de ruta
blockchainId— El blockchain en el que está desplegado el contratocontractAddress— La dirección del contratotxId— El ID de transaction de la invocación a rastrear
Respuesta
Devuelve la traza de ejecución completa para la transaction de invocación dada.
Ejemplo de respuesta
{
"txId": "a1b2c3...",
"functionName": "getVersion",
"gasUsed": 120,
"output": "2",
"steps": [
{ "op": "i32.const", "value": 2 },
{ "op": "return" }
]
}
- cURL
- TypeScript
curl -X GET \
'https://your-tms-url/api/v1/smartcontracts/08c28f29.../your-contract-address/trace/a1b2c3...' \
-H 'X-AccessKey: your-entity-access-key' \
-H 'Accept: application/json'
const blockchainId = '08c28f29a62819120958984b761ddf8ccb45951612731409873994958fd150a2';
const contractAddress = 'your-contract-address';
const txId = 'a1b2c3d4e5f6...';
const res = await fetch(
`https://your-tms-url/api/v1/smartcontracts/${blockchainId}/${contractAddress}/trace/${txId}`,
{
headers: {
'X-AccessKey': 'your-entity-access-key',
'Accept': 'application/json',
},
}
);
const trace = await res.json();
console.log('Gas utilizado:', trace.gasUsed);
console.log('Salida:', trace.output);