You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@resilientdb.apache.org by bi...@apache.org on 2026/03/30 00:58:48 UTC
(incubator-resilientdb) branch development updated: Added execution command in rescontract, fixed sc-graphql accordingly
This is an automated email from the ASF dual-hosted git repository.
bisman pushed a commit to branch development
in repository https://gitbox.apache.org/repos/asf/incubator-resilientdb.git
The following commit(s) were added to refs/heads/development by this push:
new 30ca97e7 Added execution command in rescontract, fixed sc-graphql accordingly
30ca97e7 is described below
commit 30ca97e71f1e92de9d30bdf0d93443c7148b7fb2
Author: Bismanpal-Singh <bi...@gmail.com>
AuthorDate: Mon Mar 30 00:58:43 2026 +0000
Added execution command in rescontract, fixed sc-graphql accordingly
---
.../rescontract/compiled_contracts/Token.json | 12 +++
ecosystem/smart-contract/rescontract/config.yaml | 2 +-
ecosystem/smart-contract/rescontract/index.js | 105 +++++++++++++++++++++
.../smart-contract-graphql/cli-functions.js | 40 +++++++-
4 files changed, 155 insertions(+), 4 deletions(-)
diff --git a/ecosystem/smart-contract/rescontract/compiled_contracts/Token.json b/ecosystem/smart-contract/rescontract/compiled_contracts/Token.json
new file mode 100644
index 00000000..44f44bba
--- /dev/null
+++ b/ecosystem/smart-contract/rescontract/compiled_contracts/Token.json
@@ -0,0 +1,12 @@
+{
+ "contracts": {
+ "token.sol:Token": {
+ "bin": "6080604052348015600f57600080fd5b506040516102c93803806102c9833981016040819052602c916040565b336000908152602081905260409020556058565b600060208284031215605157600080fd5b5051919050565b610262806100676000396000f3fe608060405234801561001057600080fd5b5060043610610052577c0100000000000000000000000000000000000000000000000000000000600035046370a082318114610057578063a9059cbb14610093575b600080fd5b61008061006536600461018b565b600160a060020a031660009081526020819052604090205490565b60405190815260 [...]
+ "hashes": {
+ "balanceOf(address)": "70a08231",
+ "transfer(address,uint256)": "a9059cbb"
+ }
+ }
+ },
+ "version": "0.8.30+commit.73712a01.Linux.g++"
+}
diff --git a/ecosystem/smart-contract/rescontract/config.yaml b/ecosystem/smart-contract/rescontract/config.yaml
index 576c5460..19db46ee 100644
--- a/ecosystem/smart-contract/rescontract/config.yaml
+++ b/ecosystem/smart-contract/rescontract/config.yaml
@@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-ResDB_Home:
+ResDB_Home: /home/ubuntu/production/incubator-resilientdb
diff --git a/ecosystem/smart-contract/rescontract/index.js b/ecosystem/smart-contract/rescontract/index.js
index 31af9989..329eb161 100755
--- a/ecosystem/smart-contract/rescontract/index.js
+++ b/ecosystem/smart-contract/rescontract/index.js
@@ -367,6 +367,111 @@ program
}
});
+program
+ .command('execute')
+ .description('Execute a function on a deployed smart contract')
+ .requiredOption('-c, --config <configPath>', 'Client configuration path')
+ .requiredOption(
+ '-m, --sender <senderAddress>',
+ 'Address of the account calling the function'
+ )
+ .requiredOption(
+ '-s, --contract <contractAddress>',
+ 'Address of the deployed contract'
+ )
+ .requiredOption(
+ '-f, --function-name <name>',
+ 'Function to call (include parameter types), e.g. transfer(address,uint256)'
+ )
+ .requiredOption(
+ '-a, --arguments <parameters>',
+ 'Function arguments as a comma-separated list (no spaces unless inside quotes)'
+ )
+ .action(async (options) => {
+ try {
+ const {
+ config: configPath,
+ sender,
+ contract: contractAddress,
+ functionName,
+ arguments: funcArgs,
+ } = options;
+
+ if (!fs.existsSync(configPath)) {
+ logger.error(`Config file not found at ${configPath}`);
+ console.error(`Error: Config file not found at ${configPath}`);
+ process.exit(1);
+ }
+
+ const resDBHome = await ensureResDBHome();
+ const commandPath = path.join(
+ resDBHome,
+ 'bazel-bin',
+ 'service',
+ 'tools',
+ 'kv',
+ 'api_tools',
+ 'contract_service_tools'
+ );
+
+ const jsonConfig = {
+ command: 'execute',
+ caller_address: sender,
+ contract_address: contractAddress,
+ func_name: functionName,
+ params: funcArgs,
+ };
+ const jsonConfigPath = path.join(
+ os.tmpdir(),
+ `execute_${Date.now()}.json`
+ );
+ fs.writeFileSync(jsonConfigPath, JSON.stringify(jsonConfig, null, 2));
+
+ let output;
+ try {
+ output = await handleSpawnProcess(commandPath, [
+ '-c',
+ configPath,
+ '--config_file',
+ jsonConfigPath,
+ ]);
+ } finally {
+ if (fs.existsSync(jsonConfigPath)) {
+ fs.unlinkSync(jsonConfigPath);
+ }
+ }
+
+ if (output.includes('execute contract fail')) {
+ console.error(
+ JSON.stringify({
+ error: 'Contract execution failed (see stderr output above).',
+ })
+ );
+ process.exit(1);
+ }
+
+ let result = null;
+ const idx = output.lastIndexOf('execute result:');
+ if (idx !== -1) {
+ result = output.slice(idx + 'execute result:'.length).trim();
+ result = result.replace(/^\[[^\]]+\]\s*/m, '').trim();
+ }
+
+ if (result !== null && result.length > 0) {
+ console.log(JSON.stringify({ result }));
+ } else {
+ console.log(JSON.stringify({ output: output.trim() }));
+ }
+ } catch (error) {
+ console.error(
+ JSON.stringify({
+ error: error.message,
+ })
+ );
+ process.exit(1);
+ }
+ });
+
program
.command('add_address')
.description('Add an external address to the system')
diff --git a/ecosystem/smart-contract/smart-contract-graphql/cli-functions.js b/ecosystem/smart-contract/smart-contract-graphql/cli-functions.js
index a5fac3a1..c3b97d83 100644
--- a/ecosystem/smart-contract/smart-contract-graphql/cli-functions.js
+++ b/ecosystem/smart-contract/smart-contract-graphql/cli-functions.js
@@ -234,9 +234,43 @@ export async function executeContract(config, sender, contract, functionName, ar
try {
const result = await handleExecFile(command, cliArgs);
- const success = result.includes("0x0000000000000000000000000000000000000000000000000000000000000001");
- return success ? "Execution successful" : "Execution failed";
- return result;
+ if (result.includes('execute contract fail')) {
+ throw new Error(result);
+ }
+
+ const lines = result.split('\n');
+ for (let i = lines.length - 1; i >= 0; i--) {
+ const line = lines[i].trim();
+ if (line.startsWith('{') && line.includes('"result"')) {
+ try {
+ const o = JSON.parse(line);
+ if (o.error) {
+ throw new Error(o.error);
+ }
+ if (o.result != null) {
+ const firstLine = String(o.result).split('\n')[0].trim();
+ return firstLine || String(o.result).trim();
+ }
+ } catch (e) {
+ if (e instanceof SyntaxError) {
+ /* not valid JSON on this line */
+ } else {
+ throw e;
+ }
+ }
+ }
+ }
+
+ const idx = result.lastIndexOf('execute result:');
+ if (idx !== -1) {
+ const after = result.slice(idx + 'execute result:'.length).trim();
+ const firstLine = after.split('\n')[0].trim();
+ if (firstLine) {
+ return firstLine;
+ }
+ }
+
+ return result.trim();
} catch (error) {
throw error;
} finally {