quantumcoin 7.0.10 → 7.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-SDK.md +0 -5
- package/README.md +1 -3
- package/SPEC.md +2 -63
- package/config.js +10 -2
- package/examples/example.js +0 -5
- package/examples/example.ts +0 -5
- package/examples/node_modules/.bin/esbuild +16 -0
- package/examples/node_modules/.bin/esbuild.cmd +17 -0
- package/examples/node_modules/.bin/esbuild.ps1 +28 -0
- package/examples/node_modules/.bin/sdkgen +16 -0
- package/examples/node_modules/.bin/sdkgen.cmd +17 -0
- package/examples/node_modules/.bin/sdkgen.ps1 +28 -0
- package/examples/node_modules/.bin/tsx +16 -0
- package/examples/node_modules/.bin/tsx.cmd +17 -0
- package/examples/node_modules/.bin/tsx.ps1 +28 -0
- package/examples/node_modules/.package-lock.json +235 -0
- package/examples/node_modules/@esbuild/win32-x64/README.md +3 -0
- package/examples/node_modules/@esbuild/win32-x64/esbuild.exe +0 -0
- package/examples/node_modules/@esbuild/win32-x64/package.json +20 -0
- package/examples/node_modules/esbuild/LICENSE.md +21 -0
- package/examples/node_modules/esbuild/README.md +3 -0
- package/examples/node_modules/esbuild/bin/esbuild +223 -0
- package/examples/node_modules/esbuild/install.js +289 -0
- package/examples/node_modules/esbuild/lib/main.d.ts +716 -0
- package/examples/node_modules/esbuild/lib/main.js +2532 -0
- package/examples/node_modules/esbuild/package.json +49 -0
- package/examples/node_modules/get-tsconfig/LICENSE +21 -0
- package/examples/node_modules/get-tsconfig/README.md +235 -0
- package/examples/node_modules/get-tsconfig/dist/index.cjs +7 -0
- package/examples/node_modules/get-tsconfig/dist/index.d.cts +2088 -0
- package/examples/node_modules/get-tsconfig/dist/index.d.mts +2088 -0
- package/examples/node_modules/get-tsconfig/dist/index.mjs +7 -0
- package/examples/node_modules/get-tsconfig/package.json +46 -0
- package/examples/node_modules/quantum-coin-js-sdk/.github/workflows/publish-npmjs.yaml +22 -0
- package/examples/node_modules/quantum-coin-js-sdk/LICENSE +21 -0
- package/examples/node_modules/quantum-coin-js-sdk/LICENSE-wasm_exec.js.txt +30 -0
- package/examples/node_modules/quantum-coin-js-sdk/README.md +1665 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/README.md +14 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/conversion-example.js +19 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-create-contract.js +396 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-encode-decode-rlp.js +225 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-event-pack-unpack.js +391 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-misc.js +101 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-rpc-send-signRawTransaction.js +318 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-rpc-send.js +116 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-send.js +70 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-token-pack-unpack.js +961 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-wallet-version4.js +35 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example-wallet.js +43 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/example.js +405 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/package-lock.json +134 -0
- package/examples/node_modules/quantum-coin-js-sdk/example/package.json +15 -0
- package/examples/node_modules/quantum-coin-js-sdk/index.d.ts +1024 -0
- package/examples/node_modules/quantum-coin-js-sdk/index.js +3062 -0
- package/examples/node_modules/quantum-coin-js-sdk/package.json +34 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-32.json +1 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-36.json +1 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/encrypted-48.json +1 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/generate-verify-vectors.js +91 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/non-transactional.preinit.test.js +41 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/non-transactional.test.js +686 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/sign-raw-keytype5-context-null.test.js +107 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/sign-raw-transaction.test.js +196 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/sign-verify.test.js +311 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/transactional.relay.test.js +131 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/transactional.rpc.test.js +103 -0
- package/examples/node_modules/quantum-coin-js-sdk/tests/verify-vectors.json +95035 -0
- package/examples/node_modules/quantum-coin-js-sdk/wasmBase64.d.ts +9 -0
- package/examples/node_modules/quantum-coin-js-sdk/wasmBase64.js +16 -0
- package/examples/node_modules/quantum-coin-js-sdk/wasm_exec.d.ts +0 -0
- package/examples/node_modules/quantum-coin-js-sdk/wasm_exec.js +587 -0
- package/examples/node_modules/resolve-pkg-maps/LICENSE +21 -0
- package/examples/node_modules/resolve-pkg-maps/README.md +216 -0
- package/examples/node_modules/resolve-pkg-maps/dist/index.cjs +1 -0
- package/examples/node_modules/resolve-pkg-maps/dist/index.d.cts +11 -0
- package/examples/node_modules/resolve-pkg-maps/dist/index.d.mts +11 -0
- package/examples/node_modules/resolve-pkg-maps/dist/index.mjs +1 -0
- package/examples/node_modules/resolve-pkg-maps/package.json +42 -0
- package/examples/node_modules/seed-words/.github/workflows/publish-npmjs.yaml +22 -0
- package/examples/node_modules/seed-words/BUILD.md +7 -0
- package/examples/node_modules/seed-words/LICENSE +121 -0
- package/examples/node_modules/seed-words/README.md +67 -0
- package/examples/node_modules/seed-words/dist/seedwords.d.ts +39 -0
- package/examples/node_modules/seed-words/package.json +27 -0
- package/examples/node_modules/seed-words/seedwords.js +315 -0
- package/examples/node_modules/seed-words/seedwords.txt +65536 -0
- package/examples/node_modules/seed-words/tsconfig.json +21 -0
- package/examples/node_modules/tsx/LICENSE +21 -0
- package/examples/node_modules/tsx/README.md +32 -0
- package/examples/node_modules/tsx/dist/cjs/api/index.cjs +1 -0
- package/examples/node_modules/tsx/dist/cjs/api/index.d.cts +35 -0
- package/examples/node_modules/tsx/dist/cjs/api/index.d.mts +35 -0
- package/examples/node_modules/tsx/dist/cjs/api/index.mjs +1 -0
- package/examples/node_modules/tsx/dist/cjs/index.cjs +1 -0
- package/examples/node_modules/tsx/dist/cjs/index.mjs +1 -0
- package/examples/node_modules/tsx/dist/cli.cjs +54 -0
- package/examples/node_modules/tsx/dist/cli.mjs +55 -0
- package/examples/node_modules/tsx/dist/client-BQVF1NaW.mjs +1 -0
- package/examples/node_modules/tsx/dist/client-D6NvIMSC.cjs +1 -0
- package/examples/node_modules/tsx/dist/esm/api/index.cjs +1 -0
- package/examples/node_modules/tsx/dist/esm/api/index.d.cts +35 -0
- package/examples/node_modules/tsx/dist/esm/api/index.d.mts +35 -0
- package/examples/node_modules/tsx/dist/esm/api/index.mjs +1 -0
- package/examples/node_modules/tsx/dist/esm/index.cjs +2 -0
- package/examples/node_modules/tsx/dist/esm/index.mjs +2 -0
- package/examples/node_modules/tsx/dist/get-pipe-path-BHW2eJdv.mjs +1 -0
- package/examples/node_modules/tsx/dist/get-pipe-path-BoR10qr8.cjs +1 -0
- package/examples/node_modules/tsx/dist/index-7AaEi15b.mjs +14 -0
- package/examples/node_modules/tsx/dist/index-BWFBUo6r.cjs +1 -0
- package/examples/node_modules/tsx/dist/index-gbaejti9.mjs +1 -0
- package/examples/node_modules/tsx/dist/index-gckBtVBf.cjs +14 -0
- package/examples/node_modules/tsx/dist/lexer-DQCqS3nf.mjs +3 -0
- package/examples/node_modules/tsx/dist/lexer-DgIbo0BU.cjs +3 -0
- package/examples/node_modules/tsx/dist/loader.cjs +1 -0
- package/examples/node_modules/tsx/dist/loader.mjs +1 -0
- package/examples/node_modules/tsx/dist/node-features-_8ZFwP_x.mjs +1 -0
- package/examples/node_modules/tsx/dist/node-features-roYmp9jK.cjs +1 -0
- package/examples/node_modules/tsx/dist/package-CeBgXWuR.mjs +1 -0
- package/examples/node_modules/tsx/dist/package-Dxt5kIHw.cjs +1 -0
- package/examples/node_modules/tsx/dist/patch-repl.cjs +1 -0
- package/examples/node_modules/tsx/dist/patch-repl.mjs +1 -0
- package/examples/node_modules/tsx/dist/preflight.cjs +1 -0
- package/examples/node_modules/tsx/dist/preflight.mjs +1 -0
- package/examples/node_modules/tsx/dist/register-2sWVXuRQ.cjs +1 -0
- package/examples/node_modules/tsx/dist/register-B7jrtLTO.mjs +1 -0
- package/examples/node_modules/tsx/dist/register-CFH5oNdT.mjs +4 -0
- package/examples/node_modules/tsx/dist/register-D46fvsV_.cjs +4 -0
- package/examples/node_modules/tsx/dist/repl.cjs +3 -0
- package/examples/node_modules/tsx/dist/repl.mjs +3 -0
- package/examples/node_modules/tsx/dist/require-D4F1Lv60.cjs +1 -0
- package/examples/node_modules/tsx/dist/require-DQxpCAr4.mjs +1 -0
- package/examples/node_modules/tsx/dist/suppress-warnings.cjs +1 -0
- package/examples/node_modules/tsx/dist/suppress-warnings.mjs +1 -0
- package/examples/node_modules/tsx/dist/temporary-directory-B83uKxJF.cjs +1 -0
- package/examples/node_modules/tsx/dist/temporary-directory-CwHp0_NW.mjs +1 -0
- package/examples/node_modules/tsx/dist/types-Cxp8y2TL.d.ts +5 -0
- package/examples/node_modules/tsx/package.json +68 -0
- package/examples/offline-signing.js +0 -2
- package/examples/offline-signing.ts +0 -1
- package/examples/package-lock.json +422 -73
- package/examples/package.json +1 -1
- package/examples/wallet-offline.js +1 -9
- package/examples/wallet-offline.ts +1 -9
- package/generate-sdk.js +4 -6
- package/package.json +2 -2
- package/src/abi/interface.js +13 -7
- package/src/abi/js-abi-coder.js +23 -18
- package/src/constants.d.ts +0 -5
- package/src/constants.js +0 -7
- package/src/contract/contract-factory.js +9 -3
- package/src/contract/contract.js +9 -3
- package/src/errors/index.js +12 -0
- package/src/index.d.ts +0 -3
- package/src/providers/extra-providers.js +20 -6
- package/src/providers/json-rpc-provider.js +15 -5
- package/src/providers/provider.d.ts +0 -2
- package/src/providers/provider.js +1 -3
- package/src/utils/address.d.ts +0 -14
- package/src/utils/address.js +12 -49
- package/src/utils/hashing.d.ts +0 -6
- package/src/utils/hashing.js +8 -23
- package/src/utils/index.d.ts +0 -3
- package/src/utils/rlp.js +7 -4
- package/src/wallet/wallet.d.ts +2 -13
- package/src/wallet/wallet.js +116 -97
- package/test/security/malformed-input.test.js +295 -1
- package/test/unit/address-wallet.test.js +188 -129
- package/test/unit/address-wallet.test.ts +187 -128
- package/test/unit/hashing.test.js +0 -11
- package/test/unit/hashing.test.ts +0 -11
- package/test/unit/providers.test.js +3 -1
- package/test/unit/providers.test.ts +3 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## Quantum Coin SDK Example
|
|
2
|
+
|
|
3
|
+
Example for using Quantum Coin SDK
|
|
4
|
+
|
|
5
|
+
Requires Node.js version v20.18.1 or higher
|
|
6
|
+
|
|
7
|
+
To run the project:
|
|
8
|
+
|
|
9
|
+
npm install
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
node example.js
|
|
13
|
+
|
|
14
|
+
The example contains many async API calls, hence you might notice that the log output will be skewed.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const ethers = require('ethers');
|
|
2
|
+
|
|
3
|
+
let hexValue = "0xDE0B6B3A7640000";
|
|
4
|
+
|
|
5
|
+
//Convert hex to wei
|
|
6
|
+
let weiValueExample = BigInt(hexValue).toString();
|
|
7
|
+
console.log("hex to wei example: hex:" + hexValue + ", wei: " + weiValueExample);
|
|
8
|
+
|
|
9
|
+
//Convert wei to eth
|
|
10
|
+
let ethValueExample = ethers.formatEther(weiValueExample);
|
|
11
|
+
console.log("wei to eth example: wei:" + weiValueExample + ", eth (coins): " + ethValueExample);
|
|
12
|
+
|
|
13
|
+
//Convert eth to wei
|
|
14
|
+
let weiValueExample2 = ethers.parseUnits(ethValueExample, "ether");
|
|
15
|
+
console.log("eth to wei example: eth (coins):" + ethValueExample + ", wei: " + weiValueExample2);
|
|
16
|
+
|
|
17
|
+
//Convert wei to hex
|
|
18
|
+
let hexValue2 = ethers.toBeHex(weiValueExample2);
|
|
19
|
+
console.log("wei to hex example : hex: " + hexValue2 + ", wei: " + weiValueExample2);
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
const qcsdk = require('quantum-coin-js-sdk');
|
|
2
|
+
const readline = require('readline');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Example: Creating a Smart Contract using signRawTransaction
|
|
6
|
+
*
|
|
7
|
+
* This example demonstrates how to create a smart contract on the Quantum Coin blockchain
|
|
8
|
+
* using signRawTransaction and sendRawTransaction.
|
|
9
|
+
*
|
|
10
|
+
* STEPS TO COMPILE THE SOLIDITY CONTRACT:
|
|
11
|
+
*
|
|
12
|
+
* 1. Download the Solidity compiler (solc.exe) from:
|
|
13
|
+
* https://github.com/quantumcoinproject/Solidity/releases/tag/v32b.8.12
|
|
14
|
+
*
|
|
15
|
+
* 2. Save the Solidity contract code below to a file (e.g., SimpleStorage.sol)
|
|
16
|
+
*
|
|
17
|
+
* 3. Compile the contract using the following command:
|
|
18
|
+
* c:\solc\solc.exe --bin SimpleStorage.sol
|
|
19
|
+
*
|
|
20
|
+
* This will output the bytecode. Look for the "Binary:" section in the output.
|
|
21
|
+
*
|
|
22
|
+
* 4. Copy the bytecode (without the 0x prefix if present) and paste it into the
|
|
23
|
+
* CONTRACT_BYTECODE variable below, ensuring it starts with "0x"
|
|
24
|
+
*
|
|
25
|
+
* Example compilation output format:
|
|
26
|
+
* ======= SimpleStorage.sol:SimpleStorage =======
|
|
27
|
+
* Binary:
|
|
28
|
+
* 608060405234801561001057600080fd5b50...
|
|
29
|
+
*
|
|
30
|
+
* 5. Replace the CONTRACT_BYTECODE placeholder below with the actual compiled bytecode
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Simple Solidity Contract Example:
|
|
35
|
+
|
|
36
|
+
Save this to a file named SimpleStorage.sol for compilation
|
|
37
|
+
|
|
38
|
+
// SPDX-License-Identifier: MIT
|
|
39
|
+
pragma solidity ^0.7.6;
|
|
40
|
+
|
|
41
|
+
contract SimpleStorage {
|
|
42
|
+
uint256 private storedValue;
|
|
43
|
+
|
|
44
|
+
event ValueChanged(uint256 newValue);
|
|
45
|
+
|
|
46
|
+
function set(uint256 value) public {
|
|
47
|
+
storedValue = value;
|
|
48
|
+
emit ValueChanged(value);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function get() public view returns (uint256) {
|
|
52
|
+
return storedValue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
// ============================================
|
|
58
|
+
// COMPILATION INSTRUCTIONS:
|
|
59
|
+
// ============================================
|
|
60
|
+
// 1. Download solc.exe from: https://github.com/quantumcoinproject/Solidity/releases/tag/v32b.8.12
|
|
61
|
+
// 2. Save the Solidity code above to SimpleStorage.sol
|
|
62
|
+
// 3. Run: c:\gethbuild\solc.exe --bin SimpleStorage.sol
|
|
63
|
+
// 4. Copy the bytecode from the "Binary:" section
|
|
64
|
+
// 5. Paste it below in CONTRACT_BYTECODE, ensuring it starts with "0x"
|
|
65
|
+
// ============================================
|
|
66
|
+
|
|
67
|
+
// Replace below placeholder CONTRACT_BYTECODE with the actual compiled bytecode from solc.exe
|
|
68
|
+
// The bytecode should be a hex string starting with "0x"
|
|
69
|
+
// After compiling with: c:\gethbuild\solc.exe --bin SimpleStorage.sol
|
|
70
|
+
// Copy the bytecode from the "Binary:" section and paste it here
|
|
71
|
+
const CONTRACT_BYTECODE = "0x608060405234801561001057600080fd5b5060fe8061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c806360fe47b11460375780636d4ce63c146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050607e565b005b606860bf565b6040518082815260200191505060405180910390f35b806000819055507f93fe6d397c74fdf1402a8b72e47b68512f0510d7b98a4bc4cbdf6ac7108b3c59816040518082815260200191505060405180910390a150565b6000805490509056fea26469706673582212204638427ab77bf9babc9db8fb5d8f69323478e00367c47884b65ee0677a337f8e64736f6c63430007060033";
|
|
72
|
+
|
|
73
|
+
// Configuration
|
|
74
|
+
var clientConfigVal = new qcsdk.Config("", "", 123123, "", ""); //Mainnet
|
|
75
|
+
//Mainnet Block Explorer: https://scan.quantumcoin.org
|
|
76
|
+
|
|
77
|
+
const rpcEndpointUrl = 'https://public.rpc.quantumcoinapi.com';
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Helper function to get transaction count (nonce) from RPC
|
|
81
|
+
*/
|
|
82
|
+
async function getTransactionCount(address) {
|
|
83
|
+
try {
|
|
84
|
+
const params = [address, "latest"];
|
|
85
|
+
const response = await fetch(rpcEndpointUrl, {
|
|
86
|
+
method: 'POST',
|
|
87
|
+
headers: {
|
|
88
|
+
'Content-Type': 'application/json',
|
|
89
|
+
},
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
jsonrpc: '2.0',
|
|
92
|
+
id: 1,
|
|
93
|
+
method: 'eth_getTransactionCount',
|
|
94
|
+
params: params,
|
|
95
|
+
}),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (!response.ok) {
|
|
99
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const result = await response.json();
|
|
103
|
+
if (result.error) {
|
|
104
|
+
throw new Error(result.error.message);
|
|
105
|
+
}
|
|
106
|
+
return parseInt(result.result, 16);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error('Could not get transaction count:', error);
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Helper function to calculate gas price
|
|
115
|
+
* QuantumCoin uses a fixed gas price: 1000 coins per 21000 gas units
|
|
116
|
+
* Gas price = (1000 coins * 10^18 wei) / 21000 gas = wei per gas unit
|
|
117
|
+
*/
|
|
118
|
+
function getGasPrice() {
|
|
119
|
+
const gasPriceWei = BigInt("47619047619047600");
|
|
120
|
+
|
|
121
|
+
return gasPriceWei;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Helper function to prompt user for confirmation
|
|
126
|
+
*/
|
|
127
|
+
function promptUser(question) {
|
|
128
|
+
const rl = readline.createInterface({
|
|
129
|
+
input: process.stdin,
|
|
130
|
+
output: process.stdout
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return new Promise((resolve) => {
|
|
134
|
+
rl.question(question, (answer) => {
|
|
135
|
+
rl.close();
|
|
136
|
+
resolve(answer.toLowerCase().trim());
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Helper function to convert wei to coins
|
|
143
|
+
*/
|
|
144
|
+
function weiToCoins(wei) {
|
|
145
|
+
const oneCoinInWei = BigInt("1000000000000000000");
|
|
146
|
+
const coins = Number(wei) / Number(oneCoinInWei);
|
|
147
|
+
return coins;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Helper function to estimate gas for a transaction via RPC
|
|
152
|
+
*/
|
|
153
|
+
async function estimateGas(fromAddress, toAddress, value, data) {
|
|
154
|
+
try {
|
|
155
|
+
const txObject = {
|
|
156
|
+
from: fromAddress,
|
|
157
|
+
to: toAddress, // null for contract creation
|
|
158
|
+
value: value,
|
|
159
|
+
data: data
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const params = [txObject, "latest"];
|
|
163
|
+
const response = await fetch(rpcEndpointUrl, {
|
|
164
|
+
method: 'POST',
|
|
165
|
+
headers: {
|
|
166
|
+
'Content-Type': 'application/json',
|
|
167
|
+
},
|
|
168
|
+
body: JSON.stringify({
|
|
169
|
+
jsonrpc: '2.0',
|
|
170
|
+
id: 1,
|
|
171
|
+
method: 'eth_estimateGas',
|
|
172
|
+
params: params,
|
|
173
|
+
}),
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
if (!response.ok) {
|
|
177
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const result = await response.json();
|
|
181
|
+
if (result.error) {
|
|
182
|
+
throw new Error(result.error.message);
|
|
183
|
+
}
|
|
184
|
+
return parseInt(result.result, 16);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
console.error('Could not estimate gas:', error);
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Helper function to send raw transaction via RPC
|
|
193
|
+
*/
|
|
194
|
+
async function sendRawTransaction(signedTxData) {
|
|
195
|
+
try {
|
|
196
|
+
const params = [signedTxData];
|
|
197
|
+
const response = await fetch(rpcEndpointUrl, {
|
|
198
|
+
method: 'POST',
|
|
199
|
+
headers: {
|
|
200
|
+
'Content-Type': 'application/json',
|
|
201
|
+
},
|
|
202
|
+
body: JSON.stringify({
|
|
203
|
+
jsonrpc: '2.0',
|
|
204
|
+
id: 1,
|
|
205
|
+
method: 'eth_sendRawTransaction',
|
|
206
|
+
params: params,
|
|
207
|
+
}),
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
if (!response.ok) {
|
|
211
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const result = await response.json();
|
|
215
|
+
if (result.error) {
|
|
216
|
+
throw new Error(result.error.message);
|
|
217
|
+
}
|
|
218
|
+
return result.result; // Returns transaction hash
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error('Could not send raw transaction:', error);
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
//Initialize the SDK
|
|
226
|
+
qcsdk.initialize(clientConfigVal).then(async (initResult) => {
|
|
227
|
+
if (initResult === false) {
|
|
228
|
+
console.error("Initialize failed");
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
console.log("=== Example: Creating a Smart Contract ===\n");
|
|
233
|
+
|
|
234
|
+
// Open a wallet
|
|
235
|
+
let examplePassphrase = "QuantumCoinExample123!";
|
|
236
|
+
const walletEncryptedJson = "{\"address\":\"45dc00282f80628911a15775cd821a3747d2c62e14e54d1339f057c9e921be71\",\"crypto\":{\"cipher\":\"aes-256-ctr\",\"ciphertext\":\"a831e40b8e99a534df5b6dee638742f5d5ebddf07d0aa5603ff4c32d62de8442d1252f84c6777d12d14ca3be80538d5e69cc70e75363730427194cda709dee33da97452fcd4284898afebac2d5b298b10be30a89416afa66edfa46b3a396b880f030d5f2c64a7fcfd458ee8705f160cc98335cf7a7849908e33cd5af88a989c092c5453315436b0d3dd18f9357f68b37c95f30b5e3c6b1a29c39dd1c32af13c39398c137fa45334fd46b0601046818afa0710e38fb780fa47d8cf8392ce43461ef730fc8464fd4c39b75c27017e8a4344855edd16b7ac2e3a4c6a87a077314ada08def8ebde528c40e3d8b32f3ef9f9c8708020d86e99e89b3e5500aa6d9e628a2cc8b1dd17b0bbdd445f69c443b09433c3b8b94a6b1fd7e8af1b88cef8e6078dd010422e85ad3bd2d2e0344c7517f9530073c5f225c602eb61a138e13f79bf12c05bb01c61a2b13aed3d05d601ee42fa04af0ee6b2b37856b67e45348407ce43520e18e5bc639a9bfd0df9fedb8f91858bd3c220a78fc4aeeeaa8d7b3aa420964549b746fcb5b53177089b2ec59658c99b77e1b1e303233c041271a50c6e831379fd168f943563638341cca44ba63b3fe2fdd254386a4c325a881f3fb96f118169a56fed4b002f48bbfdfda728c50cff6529754359f29d44a66762f3a0ea39840a733852faa4a7be1ed6d8afc8291493cbdb55b17b4ef63dbe0f7bfb97c82986974f51a5da2b8dcdcf7f126f08389360164cd666f13ec64b9a63609c56fd154b6322f51d0b1d448dafe7806b59d00ce2fbbf34e6281f8c446012f124a4ea52955ff995dd642b1650cb4cdd9806038d2e3f3c0432a5a35307eae4ffdc49a8b9b83172804767ff8f082c8aa9e12315536ca6cb3b98cd80e438477ff5e53c9184db543fb6f3df0a7017bd9e513e83b707dd6917efd6990e609fd57abc1285e3e72899a1a6f0943539ea8e992050b681437a80b970f6e8d2bcdfa635acc270d7dec1b80bdb373dce18adb924b4ccf1ea61796a10f69eadb9da3ceea7e636e84fa0972e0cfea5237d19f488d31a0280e8a59f59dc44f825fd3bc41b92f1289042f45e892cab5a60a3036d594791143c737f2082cfcecf88f3a34d6cf6e50719c310e92e8e0fadbdce07f992006d5fc5869452ab572f6e4e864d5d72bde42d6ae26a909fa9a3964bc688052451e65a3612ef3e25392edd7388ebdeb3ee51d63ea3951a8ee653e7389d3a20cd7da5292fadad41e2decc398a9318d09d2b0c589c193f9411212e6eb76480adf62f6345e6b7ad980866cfe4921468618d3e29614450052be793c006e784f3180c97058aedd751a7db1b1d676285e7793acdc02642fbe45803ed837f6f518b63bf363ff2b73ac8215b5db7cebff2197467f5f89de7080cd83779ac94d0732deec47bd9473bdf5c45428e961d057c642336257390daa2784f82289941015e7ac2ff399710d4a123e30f9867a62c6ed1f07bfa5059487b558e9aeda68a6171b55c03f85c00fad075f57b344a84b0c098f922b89ed572e578e3d2951eeaa051d5f26339776f51f390af1f5fc62e6ea42fae34da1676d0410a96b7e1d3c88f37c753dcf6a19512c7f619aa0beb27b318c128f5728232b0fc86e4eb9dabca731ffbe8b09a93d82aa95010ef621ed33a319984d3e12b9e856d81f46602c7fe13d24716362ebfc70b43eb46495db78d2dbf509413a0162179023d22a4584f1421622e1151de4e4c80f12114b22d3d06f434a2f85cc5606cdad1d6fa3044a3dd6175049d137eb1a5d764715f1289dda9a8f55fd856275a3650ce7d67e20d025ef1c1c9c2a1f17613b41e4917edab30d31ae7d8c4351e9c8bb83726998e9cffc82f92d7ba1b1fd104d4f013a0496daf75ce2b50d21c4eb20c5d295832f3bd6501f6f1f491783aa476664e058cb2b4d22411bc5ecca5ec53b763f70e9223d9915c83b35e79aa86417b3505c8b952265c6a48ab266fade009c1faacce9d9a89516223593e5f1d5039f82ca0a043eceb78f5ea20d180b22d3f11a7ca5ae0792b5dc9685ba46fc87326eb468295f0890cf9338b69dabd5f826046e216bb7306333120bb36aa902f54dd28cbeb8580f3483cf69f8f9fdb3c7ff936f055f9323fa02db8237db7b2d6d26e137fc5fa728c387dbca015f34228915088a95fdfc09a5d2c42ea8189a1dff888ea53f52541232689ba396d96bffb13bab2d65f94a422ea762b6446d5a8e4e2f0c5b2398fcabba825e532a4bae96b45c2a88ca138ae9118653f71d1d9c7819755febcf15b203e1402522b2762985fdbd70dfc37cd0b6943d50cbbaf42f01b442e6f4445f986c09bc55835bb6a03431d1bfa1916db455c822972ff9fba37b2d4477cbf2138325949c4a15d1e0457b51cb06d35c9bf3478c79256989c36d9ec35b3d7f67eb23e476250f9424835be56ef00406c395d60c608100258b97cd51f853960c44ca48e2ea2696793e825db9e9a52ea840c8dd252273eec1212482738be81301acd8c79e5fd54b218c4e27b139c6e8eb5729b01326273a70f64785878dd3f0b10462bf11b152229dd5b1ef9d5cc7bffc44a85384163de88bb421a2999e0f01cec8b74c8dce0b0a40fd0409c26a9c967940592e61936a70f7c8be7d95d45b9a003b5dc1d33121cb7901afec1c8d98103e29d64a370ac6344600ceb067b921067ce2760a5a7e07c9396606458eb3f404713a8bb8d12211b64fd98bf9a88031cf9bbccab00a9f6a7b5c7033dfa90ff1aee6d95a9af74926ea83332523bbf4df7c4cd8769e0a56e50205b529bbafb37438c8ce05ed02e8dbcb6a60f03a0142e701ab2d2520e159ac2c5ce1a2d0f342bc837f60c7ca912241a55d8ed174f9b714950cc7d3eddd06d23f31d6fc46eb2bc248cfcac8fbb7a0d8bc6f972c9bd9f5ef29942bac1b117675c33664b50fcc6f049528b76dc2fffa766fca42c2968ff6960e33efd2984db268412543c07682f0ddb9bd59ce111820d6f1bd1a76063b0c60479b19b8a49631a722747c6d20133a77f7072330c134d006352e44443230c7eddfc9fd645a50b3e3ee780ef7097198d7c87ad9969d4afe414314b57f248e4237dc164e084be7534f2c3c55f5110fe7d202a5737f067b7a282f8090cfcdd2d34f64aee499c075e50f480272e3d981b3c0e553b8bd04279dcd0097cc035d8016f4e4d40d3b5526b617533e1f1db0d90b4071bd4e2ada7b6ad172beff1edda9c8c750f77895880a0cea9c5b35f70cc32d9b83d088ae66662182c0f41db5c3faaacd7773846d7cee72d3748533ec9983964749f1f5694218d357ecab2d330206dfc11dfaa5c29a6441890faf607d73f33732c07097da08d84231eed7346e706d24bc695df684c6670cc5b10662638f7c01534833f8b6fc6eab95f3841cea2069b7a25d97c390b58d04519a62bc93c56803ee773ba80309917202ddf8fe9cb128869a42e206126c282c4e896e74981db12f4d0f2bddec9a674b75c86e8cbd18d29ddca4dadc11141d066ebe424ace546ec974a6ec8b7ee352fcdc96a88a65c90166cd9c8b5b03640614632aa3eb0d1516b40128b065c3e377ceac6a5be1217351da75534c9d651d80551b3150732389e35025d0769bbb3d9885e83450eb262ed091bcd181979ecfc56d2301b3d3c7941e52a55f7e3460e1056612010cd286aa193a5dbe015b22bca180f239c36eeacbb6f6d5884f469163260fdf015203a8523059d8da4b869be00cb938d318a8215b212dd0bd6a7bd6e336bca3c67ba74872eb19c450982796d794b013f27e3cf889a928fcd94caff8692a29266befe74420edd2117bf947d4730dda838640128bdb17869eab8dfa228d4c4bb5ff5b00a57c6c8d1123487039338e3f342cf273e0e4995e95ff4c8e2a23974bf16c20f5443c21eb9aadf69aaacefddeacb2844f9a5f354cad0a94af5be824e9a2ec4c03828fdab7415d9be05372e8c515c0cd5fcd44e69f1b380df484c860539773ce68b402a6585fcd826a92ce05162cf7f17ca02d7fdd80b9cfa8bb3a37cf62ff6f3ecbe03c186075a5dbce6e36fe46ed9059fa60e347c978f0f3b71bc9d05e4a4e1ce6b48e0593a1acdf9899f4d709e005b972411349fda2c544396eb73c10d89c6db2b5a7506a34d7f5b66b3ff37e8088f2dcd9c2dd76b21818674f8ceb8bbda6c38b58dd5f5de09c8a25949e28aa04a8ccba10275c032309e9b61de148f8495640cfbf3d46e342c3859bfb5e6ab10b4df4a39bc20a2eb48fbaee4c01f5661b4129b15414842eaa46154c77df5484fab490185cfa83f21ec5b72abfa507b6b998654aec4b1031ac1dfc919022423d6020fa1a702fd65f98e0b6f64210f7d2d326de960a51c7c5b357c42073fac112a393c7f40a0f368600ba00010530aa782460098f559f42b37d3510afb425a249c0c17cf0380c40793b068d565fcc2fd70df74dc2b8cbda4849164c30631554517f0ba2c9e94977959012bc7f371b5c375214a5ed4f2d3920746cb5a01c0356c187bb186a7d5ae7bd57e13befa101813dce482b49ad0d41fbe5bc542cf55445136db1f8442003e48a75bb6637be93626178bed28402c91610d067d94d06136b337d4ada511376a84fb6bde4215828359058cb2f5b1d0281ff93743d43b8881d4f7591800166621141cca2b122f1ed63baaca752f7de0cf6d2e92dc6caa2a43df580d8b472400065aeeffc71d5a7a5f52f02d26a26225c53591a60e29a8ae7e9cd0d3f9f8ab8bb5176ae1fd4e881db04f8239b282123147036019a560fb450baf8fc3dbaa7989c04e8e8f674acdadf59048f7fcc5efd8ac3577e9204837dd6bec8c72c52d019e9172825ff27bc9cef950d729a02c26e00167872c53a2c303cb260035a5184519cdb9dc0ae32b1b3d0375b248fe4c5b98a37368cf0d548c48904d87d4f3ff4e9a989b3f28a5747cfd5f7a67d3b8dc30bdf709bfa56075d28e375d24c7409ff442913c1209f1587f8e252a35c6bfdcf581d7fb1bd693329eafd872078de4c1b31a7d5d5f3466adf41b0ee17c9aba8b88bbba6a868ddddfed5085947da0859d16641abc2e869e7a120c807d1a2092ed79f43f287dfdffc044cd3c246f87dc12727dc8b6151ea19f1d919ebd23ba46e5ae7fcc7cfd7a746db70dd0adeef889e5ae74941fbe7f97021fc95e8423ba91b735d8e9587f5ad515d595600abc96c08d796e640def566e990d9f4c6a5e7270f949284221c81df4e57a9c129a45d508820938365093d6dd672f4d4418c7bff35ca1603aa068beeee04060251722f04718303e1fd4c5bc64ef07b13408516ec92581d2de93a93693148ba416615fe1f1b64d5bd8975777337242e0ea9f7586599fdba8dd87c81a4c6bf4eab14d6ebac32cb3310cbbe5cf23620973b4ed7e688bec9e2d5569594c2377ba60f998750dd828bc704aeda55f5608ea12649e91a3733cb9b4a34d9886ea6b4a8d2cfbd883b9997ef1042f8d40b4cd870698585bb409cd5c21365d38e3c95dcd91244a62d766ba728aa822390c2def2166c46f45c275790f2a6dd11f906312214c120bf27efda0afd4cd8d6482d16a4ab72d2e69a49cb3e1b4ebb9025d81479fd2ccb4f66eee4248657c3f8dca13aa7201824bff06c543e0200c4cdff612ab0bb29b89fdb82c3a7abb14edd78f6e224c61c4d3d3b1c1c7038aa54afb4d32c3039d58e057185906c89887cc101b577c97b363d7c587c652a358c4025f690be410171b2c76723433da12a9163a4420f13aa\",\"cipherparams\":{\"iv\":\"664b1a53b2ecf34d3305397defd89b38\"},\"kdf\":\"scrypt\",\"kdfparams\":{\"dklen\":48,\"n\":262144,\"p\":1,\"r\":8,\"salt\":\"d48fb344fbec36d5a3787e4271561bdc61a6c100e20641521fceba2af6bc0668\"},\"mac\":\"ba8bebc33fe945df3340b9e761c199304655ac1c24dbef92b69cc5e6a84fb649\"},\"id\":\"a4d92ffd-9dc9-41ab-9eaa-04ef14b8a4bc\",\"version\":4}";
|
|
237
|
+
console.log(walletEncryptedJson);
|
|
238
|
+
let wallet = qcsdk.deserializeEncryptedWallet(walletEncryptedJson, examplePassphrase);
|
|
239
|
+
if (wallet === null) {
|
|
240
|
+
console.log("Error opening wallet");
|
|
241
|
+
} else {
|
|
242
|
+
console.log("From wallet address: " + wallet.address);
|
|
243
|
+
}
|
|
244
|
+
console.log("Note: This wallet needs to have sufficient balance for gas fees\n");
|
|
245
|
+
|
|
246
|
+
try {
|
|
247
|
+
// Get nonce from RPC
|
|
248
|
+
const nonce = await getTransactionCount(wallet.address);
|
|
249
|
+
console.log("Nonce (transaction count) is:", nonce);
|
|
250
|
+
|
|
251
|
+
// Verify that bytecode has been set
|
|
252
|
+
if (CONTRACT_BYTECODE === "0xPLACEHOLDER_REPLACE_WITH_COMPILED_BYTECODE" || CONTRACT_BYTECODE.length < 10) {
|
|
253
|
+
console.error("\n❌ ERROR: CONTRACT_BYTECODE has not been set!");
|
|
254
|
+
console.error("Please compile the Solidity contract and update CONTRACT_BYTECODE with the actual bytecode.");
|
|
255
|
+
console.error("Steps:");
|
|
256
|
+
console.error("1. Download solc.exe from: https://github.com/quantumcoinproject/Solidity/releases/tag/v32b.8.12");
|
|
257
|
+
console.error("2. Save the Solidity code from the comments above to SimpleStorage.sol");
|
|
258
|
+
console.error("3. Run: c:\\gethbuild\\solc.exe --bin SimpleStorage.sol");
|
|
259
|
+
console.error("4. Copy the bytecode from the 'Binary:' section");
|
|
260
|
+
console.error("5. Paste it in CONTRACT_BYTECODE variable, ensuring it starts with '0x'\n");
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Contract creation parameters
|
|
265
|
+
const toAddress = null; // null for contract creation
|
|
266
|
+
const valueInWei = "0x0"; // No value sent with contract creation (or use BigInt(0))
|
|
267
|
+
const remarks = null; // No remarks
|
|
268
|
+
|
|
269
|
+
// Pack contract creation data using packCreateContractData
|
|
270
|
+
// This matches the Go pattern: Pack("", params...) and append(bytecode, input...)
|
|
271
|
+
// For a constructor with no parameters, we pass no args
|
|
272
|
+
console.log("Packing contract creation data...");
|
|
273
|
+
const CONTRACT_ABI = [
|
|
274
|
+
{
|
|
275
|
+
"type": "constructor",
|
|
276
|
+
"inputs": [],
|
|
277
|
+
"stateMutability": "nonpayable"
|
|
278
|
+
}
|
|
279
|
+
];
|
|
280
|
+
const abiJSON = JSON.stringify(CONTRACT_ABI);
|
|
281
|
+
const packResult = qcsdk.packCreateContractData(abiJSON, CONTRACT_BYTECODE /* no constructor params */);
|
|
282
|
+
|
|
283
|
+
if (packResult.error) {
|
|
284
|
+
console.error("❌ Error packing contract creation data:", packResult.error);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const data = packResult.result; // Packed bytecode + constructor data
|
|
289
|
+
console.log("Contract creation data packed successfully");
|
|
290
|
+
console.log("Data length:", data.length, "characters");
|
|
291
|
+
|
|
292
|
+
// Calculate and display the contract address that will be created
|
|
293
|
+
console.log("\nCalculating contract address...");
|
|
294
|
+
const contractAddress = qcsdk.createAddress(wallet.address, nonce);
|
|
295
|
+
if (contractAddress) {
|
|
296
|
+
console.log("✅ Contract will be deployed at address:", contractAddress);
|
|
297
|
+
} else {
|
|
298
|
+
console.warn("⚠️ Could not calculate contract address");
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Estimate gas for contract creation
|
|
302
|
+
console.log("Estimating gas for contract creation...");
|
|
303
|
+
let gasLimit;
|
|
304
|
+
try {
|
|
305
|
+
const estimatedGas = await estimateGas(wallet.address, toAddress, valueInWei, data);
|
|
306
|
+
console.log("Estimated gas:", estimatedGas);
|
|
307
|
+
|
|
308
|
+
// Add 20% buffer to estimated gas to ensure transaction doesn't fail
|
|
309
|
+
const gasBuffer = Math.ceil(estimatedGas * 0.2);
|
|
310
|
+
gasLimit = estimatedGas + gasBuffer;
|
|
311
|
+
console.log("Gas limit (with 20% buffer):", gasLimit);
|
|
312
|
+
} catch (error) {
|
|
313
|
+
console.warn("⚠️ Could not estimate gas, using default gas limit:", error.message);
|
|
314
|
+
// Fallback to a default gas limit if estimation fails
|
|
315
|
+
gasLimit = 500000;
|
|
316
|
+
console.log("Using default gas limit:", gasLimit);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Calculate gas price (fixed: 1000 coins per 21000 gas)
|
|
320
|
+
console.log("\nCalculating gas price...");
|
|
321
|
+
const gasPrice = getGasPrice();
|
|
322
|
+
console.log("Gas price (wei per gas unit):", gasPrice.toString());
|
|
323
|
+
console.log("Note: QuantumCoin uses a fixed rate of 1000 coins per 21000 gas units");
|
|
324
|
+
|
|
325
|
+
// Calculate total fee
|
|
326
|
+
const totalFeeWei = BigInt(gasLimit) * gasPrice;
|
|
327
|
+
const totalFeeCoins = weiToCoins(totalFeeWei);
|
|
328
|
+
|
|
329
|
+
// Display transaction details and request confirmation
|
|
330
|
+
console.log("\n" + "=".repeat(60));
|
|
331
|
+
console.log("TRANSACTION DETAILS");
|
|
332
|
+
console.log("=".repeat(60));
|
|
333
|
+
console.log("Gas Limit: ", gasLimit.toLocaleString());
|
|
334
|
+
console.log("Gas Price: ", gasPrice.toString(), "wei");
|
|
335
|
+
console.log("Total Fee: ", totalFeeWei.toString(), "wei");
|
|
336
|
+
console.log("Total Fee: ", totalFeeCoins.toFixed(9), "coins");
|
|
337
|
+
console.log("=".repeat(60));
|
|
338
|
+
|
|
339
|
+
// Request user confirmation
|
|
340
|
+
const confirmation = await promptUser("\nDo you want to proceed with this transaction? (yes/no): ");
|
|
341
|
+
|
|
342
|
+
if (confirmation !== 'yes' && confirmation !== 'y') {
|
|
343
|
+
console.log("Transaction cancelled by user.");
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
console.log("\nProceeding with transaction...");
|
|
348
|
+
|
|
349
|
+
// Create transaction signing request
|
|
350
|
+
const transactionRequest = new qcsdk.TransactionSigningRequest(
|
|
351
|
+
wallet,
|
|
352
|
+
toAddress, // null for contract creation
|
|
353
|
+
valueInWei,
|
|
354
|
+
nonce,
|
|
355
|
+
data, // Contract bytecode
|
|
356
|
+
gasLimit,
|
|
357
|
+
remarks
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
// Sign the transaction
|
|
361
|
+
console.log("\nSigning transaction...");
|
|
362
|
+
const signResult = qcsdk.signRawTransaction(transactionRequest);
|
|
363
|
+
|
|
364
|
+
if (signResult.resultCode !== 0) {
|
|
365
|
+
console.error("Failed to sign transaction. Result code:", signResult.resultCode);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
console.log("Transaction signed successfully");
|
|
370
|
+
console.log("Transaction hash:", signResult.txnHash);
|
|
371
|
+
console.log("Transaction data length:", signResult.txnData.length, "characters");
|
|
372
|
+
console.log("Transaction data:", signResult.txnData);
|
|
373
|
+
|
|
374
|
+
// Send transaction via RPC
|
|
375
|
+
console.log("\nSending transaction to network...");
|
|
376
|
+
try {
|
|
377
|
+
const txHash = await sendRawTransaction(signResult.txnData);
|
|
378
|
+
console.log("✅ Transaction submitted successfully!");
|
|
379
|
+
console.log("Transaction hash from RPC:", txHash);
|
|
380
|
+
if (contractAddress) {
|
|
381
|
+
console.log("\n📝 Contract Address:", contractAddress);
|
|
382
|
+
console.log("Note: The contract will be deployed at the address shown above once the transaction is confirmed.");
|
|
383
|
+
} else {
|
|
384
|
+
console.log("\nNote: The contract will be deployed at an address determined by the transaction.");
|
|
385
|
+
}
|
|
386
|
+
console.log("You can check the transaction status on the block explorer.");
|
|
387
|
+
} catch (error) {
|
|
388
|
+
console.error("❌ Error sending transaction:", error.message);
|
|
389
|
+
console.error("Make sure the wallet has sufficient balance for gas fees.");
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
} catch (error) {
|
|
393
|
+
console.error("Error creating contract:", error);
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: RLP Encoding and Decoding
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to use the encodeRlp and decodeRlp functions
|
|
5
|
+
* to encode and decode various JavaScript values using RLP (Recursive Length Prefix) encoding.
|
|
6
|
+
*
|
|
7
|
+
* RLP is used in Ethereum and Quantum Coin for encoding structured data.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const qcsdk = require('../index');
|
|
11
|
+
|
|
12
|
+
// Initialize the SDK
|
|
13
|
+
async function main() {
|
|
14
|
+
console.log('=== RLP Encoding and Decoding Examples ===\n');
|
|
15
|
+
|
|
16
|
+
// Initialize SDK with default mainnet config
|
|
17
|
+
const initResult = await qcsdk.initialize(null);
|
|
18
|
+
if (initResult === false) {
|
|
19
|
+
console.error('Failed to initialize SDK');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
console.log('SDK initialized successfully\n');
|
|
23
|
+
|
|
24
|
+
// Example 1: Encode and decode a string
|
|
25
|
+
console.log('--- Example 1: String ---');
|
|
26
|
+
const stringValue = 'Hello, World!';
|
|
27
|
+
console.log('Original value:', stringValue);
|
|
28
|
+
|
|
29
|
+
const encodeResult1 = qcsdk.encodeRlp(stringValue);
|
|
30
|
+
if (encodeResult1.error) {
|
|
31
|
+
console.error('Encoding error:', encodeResult1.error);
|
|
32
|
+
} else {
|
|
33
|
+
console.log('Encoded (hex):', encodeResult1.result);
|
|
34
|
+
|
|
35
|
+
const decodeResult1 = qcsdk.decodeRlp(encodeResult1.result);
|
|
36
|
+
if (decodeResult1.error) {
|
|
37
|
+
console.error('Decoding error:', decodeResult1.error);
|
|
38
|
+
} else {
|
|
39
|
+
const decoded = JSON.parse(decodeResult1.result);
|
|
40
|
+
console.log('Decoded value:', decoded);
|
|
41
|
+
console.log('Round-trip successful:', decoded === stringValue);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
console.log();
|
|
45
|
+
|
|
46
|
+
// Example 2: Encode and decode a number
|
|
47
|
+
console.log('--- Example 2: Number ---');
|
|
48
|
+
const numberValue = 42;
|
|
49
|
+
console.log('Original value:', numberValue);
|
|
50
|
+
|
|
51
|
+
const encodeResult2 = qcsdk.encodeRlp(numberValue);
|
|
52
|
+
if (encodeResult2.error) {
|
|
53
|
+
console.error('Encoding error:', encodeResult2.error);
|
|
54
|
+
} else {
|
|
55
|
+
console.log('Encoded (hex):', encodeResult2.result);
|
|
56
|
+
|
|
57
|
+
const decodeResult2 = qcsdk.decodeRlp(encodeResult2.result);
|
|
58
|
+
if (decodeResult2.error) {
|
|
59
|
+
console.error('Decoding error:', decodeResult2.error);
|
|
60
|
+
} else {
|
|
61
|
+
const decoded = JSON.parse(decodeResult2.result);
|
|
62
|
+
console.log('Decoded value:', decoded);
|
|
63
|
+
console.log('Round-trip successful:', decoded === numberValue);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
console.log();
|
|
67
|
+
|
|
68
|
+
// Example 3: Encode and decode a boolean
|
|
69
|
+
console.log('--- Example 3: Boolean ---');
|
|
70
|
+
const boolValue = true;
|
|
71
|
+
console.log('Original value:', boolValue);
|
|
72
|
+
|
|
73
|
+
const encodeResult3 = qcsdk.encodeRlp(boolValue);
|
|
74
|
+
if (encodeResult3.error) {
|
|
75
|
+
console.error('Encoding error:', encodeResult3.error);
|
|
76
|
+
} else {
|
|
77
|
+
console.log('Encoded (hex):', encodeResult3.result);
|
|
78
|
+
|
|
79
|
+
const decodeResult3 = qcsdk.decodeRlp(encodeResult3.result);
|
|
80
|
+
if (decodeResult3.error) {
|
|
81
|
+
console.error('Decoding error:', decodeResult3.error);
|
|
82
|
+
} else {
|
|
83
|
+
const decoded = JSON.parse(decodeResult3.result);
|
|
84
|
+
console.log('Decoded value:', decoded);
|
|
85
|
+
console.log('Round-trip successful:', decoded === boolValue);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
console.log();
|
|
89
|
+
|
|
90
|
+
// Example 4: Encode and decode an array
|
|
91
|
+
console.log('--- Example 4: Array ---');
|
|
92
|
+
const arrayValue = ['hello', 123, true];
|
|
93
|
+
console.log('Original value:', JSON.stringify(arrayValue));
|
|
94
|
+
|
|
95
|
+
const encodeResult4 = qcsdk.encodeRlp(arrayValue);
|
|
96
|
+
if (encodeResult4.error) {
|
|
97
|
+
console.error('Encoding error:', encodeResult4.error);
|
|
98
|
+
} else {
|
|
99
|
+
console.log('Encoded (hex):', encodeResult4.result);
|
|
100
|
+
|
|
101
|
+
const decodeResult4 = qcsdk.decodeRlp(encodeResult4.result);
|
|
102
|
+
if (decodeResult4.error) {
|
|
103
|
+
console.error('Decoding error:', decodeResult4.error);
|
|
104
|
+
} else {
|
|
105
|
+
const decoded = JSON.parse(decodeResult4.result);
|
|
106
|
+
console.log('Decoded value:', JSON.stringify(decoded));
|
|
107
|
+
console.log('Round-trip successful:', JSON.stringify(decoded) === JSON.stringify(arrayValue));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
console.log();
|
|
111
|
+
|
|
112
|
+
// Example 5: Encode and decode an object (map)
|
|
113
|
+
console.log('--- Example 5: Object (Map) ---');
|
|
114
|
+
const objectValue = { name: 'Alice', age: 30, active: true };
|
|
115
|
+
console.log('Original value:', JSON.stringify(objectValue));
|
|
116
|
+
|
|
117
|
+
const encodeResult5 = qcsdk.encodeRlp(objectValue);
|
|
118
|
+
if (encodeResult5.error) {
|
|
119
|
+
console.error('Encoding error:', encodeResult5.error);
|
|
120
|
+
} else {
|
|
121
|
+
console.log('Encoded (hex):', encodeResult5.result);
|
|
122
|
+
|
|
123
|
+
const decodeResult5 = qcsdk.decodeRlp(encodeResult5.result);
|
|
124
|
+
if (decodeResult5.error) {
|
|
125
|
+
console.error('Decoding error:', decodeResult5.error);
|
|
126
|
+
} else {
|
|
127
|
+
const decoded = JSON.parse(decodeResult5.result);
|
|
128
|
+
console.log('Decoded value:', JSON.stringify(decoded));
|
|
129
|
+
// Note: Objects are encoded as arrays of key-value pairs in RLP
|
|
130
|
+
// The decoded structure may differ from the original object
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
console.log();
|
|
134
|
+
|
|
135
|
+
// Example 6: Encode and decode a hex string
|
|
136
|
+
console.log('--- Example 6: Hex String ---');
|
|
137
|
+
const hexValue = '0x48656c6c6f'; // "Hello" in hex
|
|
138
|
+
console.log('Original value:', hexValue);
|
|
139
|
+
|
|
140
|
+
const encodeResult6 = qcsdk.encodeRlp(hexValue);
|
|
141
|
+
if (encodeResult6.error) {
|
|
142
|
+
console.error('Encoding error:', encodeResult6.error);
|
|
143
|
+
} else {
|
|
144
|
+
console.log('Encoded (hex):', encodeResult6.result);
|
|
145
|
+
|
|
146
|
+
const decodeResult6 = qcsdk.decodeRlp(encodeResult6.result);
|
|
147
|
+
if (decodeResult6.error) {
|
|
148
|
+
console.error('Decoding error:', decodeResult6.error);
|
|
149
|
+
} else {
|
|
150
|
+
const decoded = JSON.parse(decodeResult6.result);
|
|
151
|
+
console.log('Decoded value:', decoded);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
console.log();
|
|
155
|
+
|
|
156
|
+
// Example 7: Encode and decode a nested array
|
|
157
|
+
console.log('--- Example 7: Nested Array ---');
|
|
158
|
+
const nestedArrayValue = [1, [2, 3], [4, [5, 6]]];
|
|
159
|
+
console.log('Original value:', JSON.stringify(nestedArrayValue));
|
|
160
|
+
|
|
161
|
+
const encodeResult7 = qcsdk.encodeRlp(nestedArrayValue);
|
|
162
|
+
if (encodeResult7.error) {
|
|
163
|
+
console.error('Encoding error:', encodeResult7.error);
|
|
164
|
+
} else {
|
|
165
|
+
console.log('Encoded (hex):', encodeResult7.result);
|
|
166
|
+
|
|
167
|
+
const decodeResult7 = qcsdk.decodeRlp(encodeResult7.result);
|
|
168
|
+
if (decodeResult7.error) {
|
|
169
|
+
console.error('Decoding error:', decodeResult7.error);
|
|
170
|
+
} else {
|
|
171
|
+
const decoded = JSON.parse(decodeResult7.result);
|
|
172
|
+
console.log('Decoded value:', JSON.stringify(decoded));
|
|
173
|
+
console.log('Round-trip successful:', JSON.stringify(decoded) === JSON.stringify(nestedArrayValue));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
console.log();
|
|
177
|
+
|
|
178
|
+
// Example 8: Encode and decode a large number (BigInt)
|
|
179
|
+
console.log('--- Example 8: Large Number (BigInt) ---');
|
|
180
|
+
const bigIntValue = '1000000000000000000'; // 1 ether in wei
|
|
181
|
+
console.log('Original value:', bigIntValue);
|
|
182
|
+
|
|
183
|
+
const encodeResult8 = qcsdk.encodeRlp(bigIntValue);
|
|
184
|
+
if (encodeResult8.error) {
|
|
185
|
+
console.error('Encoding error:', encodeResult8.error);
|
|
186
|
+
} else {
|
|
187
|
+
console.log('Encoded (hex):', encodeResult8.result);
|
|
188
|
+
|
|
189
|
+
const decodeResult8 = qcsdk.decodeRlp(encodeResult8.result);
|
|
190
|
+
if (decodeResult8.error) {
|
|
191
|
+
console.error('Decoding error:', decodeResult8.error);
|
|
192
|
+
} else {
|
|
193
|
+
const decoded = JSON.parse(decodeResult8.result);
|
|
194
|
+
console.log('Decoded value:', decoded);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
console.log();
|
|
198
|
+
|
|
199
|
+
// Example 9: Empty array
|
|
200
|
+
console.log('--- Example 9: Empty Array ---');
|
|
201
|
+
const emptyArrayValue = [];
|
|
202
|
+
console.log('Original value:', JSON.stringify(emptyArrayValue));
|
|
203
|
+
|
|
204
|
+
const encodeResult9 = qcsdk.encodeRlp(emptyArrayValue);
|
|
205
|
+
if (encodeResult9.error) {
|
|
206
|
+
console.error('Encoding error:', encodeResult9.error);
|
|
207
|
+
} else {
|
|
208
|
+
console.log('Encoded (hex):', encodeResult9.result);
|
|
209
|
+
|
|
210
|
+
const decodeResult9 = qcsdk.decodeRlp(encodeResult9.result);
|
|
211
|
+
if (decodeResult9.error) {
|
|
212
|
+
console.error('Decoding error:', decodeResult9.error);
|
|
213
|
+
} else {
|
|
214
|
+
const decoded = JSON.parse(decodeResult9.result);
|
|
215
|
+
console.log('Decoded value:', JSON.stringify(decoded));
|
|
216
|
+
console.log('Round-trip successful:', JSON.stringify(decoded) === JSON.stringify(emptyArrayValue));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
console.log();
|
|
220
|
+
|
|
221
|
+
console.log('=== All Examples Completed ===');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Run the examples
|
|
225
|
+
main().catch(console.error);
|