How to build and broadcast a SmartContract (type 63) transaction using @klever/sdk-node?

Hello,

I’m using @klever/sdk-node to build transactions in a Node.js backend. Transfer transactions (type 0) work perfectly with account.buildTransaction():

const unsignedTx = await account.buildTransaction([{
  payload: { receiver, amount, kda: 'KLV' },
  type: TransactionType.Transfer,
}]);
```

However, when I try to build a SmartContract invoke (type 63), I always get:
```
validation error: invalid argument: tokenize failed - (cannot create VMInput, check the transaction data field)

I’ve tried multiple payload formats:

// Attempt 1: data as plain text
{ address: contractAddr, callValue: { KLV: amount }, scType: 0, data: "register@hexArg1@hexArg2" }

// Attempt 2: data as hex
{ address: contractAddr, callValue: { KLV: amount }, scType: 0, data: hexEncodedString }

// Attempt 3: function + args separated
{ address: contractAddr, callValue: { KLV: amount }, scType: 0, function: "register", args: ["hexArg1", "hexArg2"] }
```

All fail with the same `tokenize failed` error from `buildTransaction()`.

I also tried the offline `Transaction` builder with `addContract(63, smartContractProto)` + `tx.sign()` + `utils.broadcastTransactions()`, but that gives:
```
proto: mismatched message type: got "proto.SmartContract", want ""

What is the correct payload format for TransactionType.SmartContract with buildTransaction()? Or is there another way to invoke a smart contract function using sdk-node?

SDK version: latest @klever/sdk-node Network: Testnet

1 Like

Hi @Jose_Luis_Latas !

That error usually means the transaction data field isn’t encoded in the format the VM expects (so it can’t tokenize it to create the VM input). In most cases it’s caused by invalid/incorrect ABI encoding for the smart contract function call.

Since you didn’t include the contract ABI (or at least the exact function signature + argument types), I can’t say the exact encoding you should use. But based on your attempts, the key change is: the data field must be Base64-encoded.

For example, if your contract has a method like:

{
  "name": "bet",
  "mutability": "mutable",
  "payableInTokens": ["KLV"],
  "inputs": [
    { "name": "bet_type", "type": "BetType" },
    { "name": "bet_value", "type": "u32" }
  ],
  "outputs": [{ "type": "Bet" }]
}

Where bet_type is an enum, the call data would be something like:

  • raw call: bet@00@32
  • transaction data: Base64( bet@00@32 )

Please also check this other thread (I’ll send the link next). If you try the suggestions there and it still doesn’t work, share:

  • the function signature + argument types you’re calling.

and we can help you validate the expected encoding/payload.

3 Likes

@Jose_Luis_Latas bro, did the instructions that @Romulo_Siebra has sent to you work?