Development
...
Smart Contracts
Call Contract Method
6 min
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 https //github com/deleterium/smartc/blob/main/samples/publicmethodsonsmartc md 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()] }) contract c / this is an excerpt from the real world contract, showing how to process commands/method calls / // void main(void) { while ((currenttx txid = getnexttx()) != 0) { currenttx sender = getsender(currenttx txid); currenttx amount = getamount(currenttx txid); if(!isalive){ sendamount(currenttx amount, currenttx sender); return; } readmessage(currenttx txid, 0, currenttx message); switch(currenttx message\[0]){ case 'die' deactivate(); break; case 'cthsig' changesignathreshold(currenttx message\[1]); break; case 'cthzth' changezththreshold(currenttx message\[1]); break; default txreceived(); } } } //