Call Contract Method
It is possible to write contracts with an additional set of callable methods. If a method is exposed by the Smart Contract, it can be executed when sending a transaction with an attached hexdecimal message.
Note that Smart Contracts cannot read encrypted messages.
Anatomy of callable methods
A method call consists of at maximum four parameters with each 8 bytes.

A method call can have 0 to 3 additional arguments, which needs to be converted into hexdecimal representation respecting Big Endian Byte Order. The way how method calls are handled in the Smart Contracts is not defined. This is especially true for the method identifier
Methods in SmartJ
The method identifiers in SmartJ are long numbers (int64) and a hashed variant of a methods signature. On compilation the compiler shows the related method hashes in the development console.

Intuitively, publicly callable methods in SmartJ need to be public, as this reflects the expected behavior in Java.
Methods in SmartC
SmartC does not implicitely define how methods can be called and it is up to the developer to define the behavior. This can be either a numeric or alphabetical identifier. A pattern to deal with "public" methods can be found here. This proposal considers compatibility to SmartJ public method calls.
SignumJS Example
Finally, time to show some code. It's actually pretty simple, as SignumJS does most of the black magic behind the scenes.
const {Address} = require("@signumjs/core");
const {generateMasterKeys} = require("@signumjs/crypto");
const {Amount} = require("@signumjs/util");
const LedgerHostUrls = {
'TestNet': 'https://europe3.testnet.signum.network',
'MainNet': 'https://europe.signum.network',
}
/**
* This is an example of mapping between the hashes (generated on compilation with SmartJ)
* and more readable names. Of course, this depends on each contract
*
* Using constants is a good practice.
*/
const ContractMethods = {
TransferRoyalties: '7174296962751784077',
Transfer: '-8011735560658290665',
PutForAuction: '4465321042251021641',
SetNotForSale: '-1462395320800038545',
PutForSale: '483064598096680683',
}
/**
* This advanced example shows how to interact with smart contracts, i.e. how to call methods
*/
async function callMethodOfContract(params) {
try {
const {ledger: ledgerType, passphrase, contract, amount, method, arg1 = 0, arg2 = 0, arg3 = 0} = params;
const ledger = LedgerClientFactory.create({
nodeHost: LedgerHostUrls[ledgerType])
}
const contractId = Address.create(contract).getNumericId()
const senderKeys = generateMasterKeys(passphrase);
// finally, we call the contracts method
// as you can see it's pretty easy, just use the method hash and add the args as array
const {transaction} = await ledger.contract.callContractMethod({
contractId,
amountPlanck: Amount.fromSigna(amount).getPlanck(),
senderPublicKey: senderKeys.publicKey,
senderPrivateKey: senderKeys.signPrivateKey,
feePlanck: Amount.fromSigna(0.01).getPlanck(),
methodHash: ContractMethods[method],
methodArgs: [arg1, arg2, arg3]
}
)
console.info('Call successful - tx id:', transaction)
} catch (e) {
console.error(e)
}
}
(async () => {
await callMethodOfContract({
ledger: 'TestNet',
contract: '12355673...',
amount: 0.5,
method: 'SetNotForSale',
arg1: Amount.fromSigna(50_000),getPlanck(),
});
})();Alphanumeric method names in SmartC
If you use SmartC and want to use alphanumeric names within your code, please consider the correct conversion for the methodHash argument
In the following example the contract uses the abbreviated command cthzth as method identifier
const {convertHexStringToDecString, convertHexEndianess, convertStringToHexString} = require("@signumjs/util");
// This way it is possible to convert short alphanumeric strings into
// correct values
function convertMethodCommand(text) {
if (text.length > 8) {
throw new Error('Text Argument cannot be larger than 8 bytes')
}
return convertHexStringToDecString(
convertHexEndianess(
convertStringToHexString(text)
)
);
}
// ...
ledger.contract.callContractMethod({
feePlanck: Amount.fromSigna(0.01).getPlanck(),
amountPlanck: Amount.fromSigna(ActivationFee).getPlanck(),
senderPublicKey: keys.publicKey,
senderPrivateKey: keys.signPrivateKey,
contractId: ContractId,
methodHash: convertMethodCommand('cthzth'),
methodArgs: [ChainValue.create(1).setCompound(amount).getAtomic()]
})