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 {