diff --git a/858c75ea-f43b-43a6-b03a-3adf8c74d3d1.csv.txt b/858c75ea-f43b-43a6-b03a-3adf8c74d3d1.csv.txt new file mode 100644 index 0000000000..e4b17d8c88 --- /dev/null +++ b/858c75ea-f43b-43a6-b03a-3adf8c74d3d1.csv.txt @@ -0,0 +1,3 @@ +"""'Workflow""","""'Source repository""","""'Total minutes""","""'Workflow runs""","""'Jobs""","""'Runner type""","""'Runtime OS""" +"""'.github/workflows/node.js.yml""","""'literate-goggles""",12,4,3,"""'hosted""","""'linux""" +"""'.github/workflows/node.js.yml""","""'j1""",6,3,3,"""'hosted""","""'linux""" diff --git a/README.md (1).txt b/README.md (1).txt new file mode 100644 index 0000000000..b9ab4d4b89 --- /dev/null +++ b/README.md (1).txt @@ -0,0 +1,31 @@ +# TypeScript Template + +This is a TypeScript project template using webpack for Spck for NodeJS. This project template was made with the help of `createapp.dev`. + +## Building and Running + +Pressing the ▶ button will call the command `build` in `package.json`. If `dist/bundle.js` file does not exist, it indicates this may be the first run and `install-dep` in `package.json` will be called. The `spck.config.json` file controls which command to call when pressing ▶ (which can be modified in **Run Settings**). + +The task `build` creates a development build of the project and generates: + +- `dist/bundle.js` + +When `build` finishes, the preview window will launch. + +## Limitations in Android + +Due to security restrictions in Android, execute permissions on write-allowed storage is likely forbidden on most stock devices. This prevents some npm scripts from working properly as `npm run` rely on the use of `sh` which requires exec permissions. + +The `node` program is also built as a shared library for compatibility with future versions of Android and can only be accessed from the terminal and not `sh`. + +For these reasons, using `npm run ...` will not work from the terminal, but entering the command (`webpack`) directly in the terminal will work. + +## NPM Install + +On external storage and SD cards, it is commonly using FAT32 or exFAT filesystems. These filesystems do not support symbolic links which is why npm dependencies that uses symlinks (mostly npm dependencies with command line usage symlinks) will fail on external storage. + +Add the `--no-bin-links` option to `npm install` to prevent creation of symlinks. + +```bash +npm i @babel/preset-env --no-bin-links +``` diff --git a/Re2906.js (1) b/Re2906.js (1) new file mode 100644 index 0000000000..8762ab4af3 --- /dev/null +++ b/Re2906.js (1) @@ -0,0 +1,73 @@ +const bip39 = require('bip39'); +const hdkey = require('ethereumjs-wallet/hdkey'); +const { toHex } = require('ethereumjs-util'); +const { TonClient } = require('@tonclient/core'); + +const walletAddress = "4818f679ede118884806590b9b705a00fa6aa0cf7009d4b3d128ff263b031c88"; +const seedPhrase = "kingdom hungry number apple plug borrow flame dose broken reject roof worry gallery gaze cost mind similar stool retire nephew unable prize involve slim"; + +// Derive keys from seed phrase +const seed = bip39.mnemonicToSeedSync(seedPhrase); +const hdWallet = hdkey.fromMasterSeed(seed); +const wallet = hdWallet.derivePath(`m/44'/60'/0'/0/0`).getWallet(); +const publicKey = "dd659500fa0de6f0f4832f6feeb8a2b0f936b18879090eddb484759cea4b803257a8ed7fc90ddeed12e042387db4ec44ddc3cebdaba4bc93457e56626bd68a09"; +const secretKey = toHex(wallet.getPrivateKey()); + +const callSet = { + function_name: "setWalletType", + input: { + new_wallet_type: "wallet_v3R2" + } +}; + +const signer = { + type: "Keys", + keys: { + public: publicKey, + secret: secretKey + } +}; + +const dataCells = "x{000003A829A9A31720CC7B53E49B682279104AE905DA0D456D45ADE97DDB547E22B28069095F09154_}"; + +async function updateWalletType() { + try { + const client = new TonClient({ network: { server_address: 'https://main.ton.dev' } }); + await client.setup(); + const { message } = await client.abi.encode_message({ + address: walletAddress, + call_set: callSet, + signer: signer, + abi: { + type: "Contract", + value: { + "ABI version": 2, + header: ["time", "expire"], + functions: [ + { + name: "setWalletType", + inputs: [ + { name: "new_wallet_type", type: "string" } + ], + outputs: [] + ] + ], + data: [], + events: [] + } + }, + data: dataCells // Add the data cells here if needed + }); + + await client.processing.send_message({ + message, + send_events: false + }); + console.log("Wallet type successfully updated to v3R2"); + } catch (error) { + console.error("Error updating wallet type:", error); + } +} + +// Call the function +updateWalletType(); \ No newline at end of file diff --git a/Re2906.js (2) b/Re2906.js (2) new file mode 100644 index 0000000000..0c20f40b0c --- /dev/null +++ b/Re2906.js (2) @@ -0,0 +1,73 @@ +const bip39 = require('bip39'); +const hdkey = require('ethereumjs-wallet/hdkey'); +const { toHex } = require('ethereumjs-util'); +const { TonClient } = require('@tonclient/core'); + +const walletAddress = "0:4818f679ede118884806590b9b705a00fa6aa0cf7009d4b3d128ff263b031c88"; +const seedPhrase = "kingdom hungry number apple plug borrow flame dose broken reject roof worry gallery gaze cost mind similar stool retire nephew unable prize involve slim"; + +// Derive keys from seed phrase +const seed = bip39.mnemonicToSeedSync(seedPhrase); +const hdWallet = hdkey.fromMasterSeed(seed); +const wallet = hdWallet.derivePath(`m/44'/60'/0'/0/0`).getWallet(); +const publicKey = "dd659500fa0de6f0f4832f6feeb8a2b0f936b18879090eddb484759cea4b803257a8ed7fc90ddeed12e042387db4ec44ddc3cebdaba4bc93457e56626bd68a09"; +const secretKey = toHex(wallet.getPrivateKey()); + +const callSet = { + function_name: "setWalletType", + input: { + new_wallet_type: "wallet_v3R2" + } +}; + +const signer = { + type: "Keys", + keys: { + public: publicKey, + secret: secretKey + } +}; + +const dataCells = "x{000003A829A9A31720CC7B53E49B682279104AE905DA0D456D45ADE97DDB547E22B28069095F09154_}"; + +async function updateWalletType() { + try { + const client = new TonClient({ network: { server_address: 'https://main.ton.dev' } }); + await client.setup(); + const { message } = await client.abi.encode_message({ + address: walletAddress, + call_set: callSet, + signer: signer, + abi: { + type: "Contract", + value: { + "ABI version": 2, + header: ["time", "expire"], + functions: [ + { + name: "setWalletType", + inputs: [ + { name: "new_wallet_type", type: "string" } + ], + outputs: [] + } + ], + data: [], + events: [] + } + }, + data: dataCells // اضافه کردن سلول‌های داده در اینجا + }); + + await client.processing.send_message({ + message, + send_events: false + }); + console.log("Wallet type successfully updated to v3R2"); + } catch (error) { + console.error("Error updating wallet type:", error); + } +} + +// فراخوانی تابع +updateWalletType(); \ No newline at end of file diff --git a/Re29066.js b/Re29066.js new file mode 100644 index 0000000000..c3696c25ac --- /dev/null +++ b/Re29066.js @@ -0,0 +1,75 @@ +const { TonClient, abi } = require("@tonclient/core"); +const { libNode } = require("@tonclient/lib-node"); +TonClient.useBinaryLibrary(libNode); +const bip39 = require("bip39"); +const hdkey = require("ethereumjs-wallet/hdkey"); +const { toHex } = require("web3-utils"); + +const setupWallet = async () => { + const client = new TonClient({ + network: { + endpoints: ["https://toncenter.com/api/v2/jsonRPC"] + } + }); + + const walletAddress = "EQA_gft901TRFYjWatkOSpFM0bB0EJuqGst9Akz5iYSdJYbj"; // Your wallet address + const seedPhrase = "kingdom hungry number apple plug borrow flame dose broken reject roof worry gallery gaze cost mind similar stool retire nephew unable prize involve slim"; // 24-word seed phrase + + // Derive keys from seed phrase + const seed = bip39.mnemonicToSeedSync(seedPhrase); + const hdWallet = hdkey.fromMasterSeed(seed); + const wallet = hdWallet.derivePath(`m/44'/60'/0'/0/0`).getWallet(); + const publicKey = toHex(wallet.getPublicKey()); + const secretKey = toHex(wallet.getPrivateKey()); + + const callSet = { + function_name: "setWalletType", + input: { + new_wallet_type: "wallet_v3R2" + } + }; + + const signer = { + type: "Keys", + keys: { + public: publicKey, + secret: secretKey + } + }; + + try { + const { message } = await client.abi.encode_message({ + address: walletAddress, + call_set: callSet, + signer: signer, + abi: { + type: "Contract", + value: { + "ABI version": 2, + header: ["time", "expire"], + functions: [ + { + name: "setWalletType", + inputs: [ + { name: "new_wallet_type", type: "string" } + ], + outputs: [] + } + ], + data: [], + events: [] + } + } + }); + + await client.processing.send_message({ + message, + send_events: false + }); + console.log("Wallet type successfully updated to v3R2"); + } catch (error) { + console.error("Error updating wallet type:", error); + } +}; + +setupWallet(); \ No newline at end of file diff --git a/fift-func-wasm-build-ubuntu.sh.txt b/fift-func-wasm-build-ubuntu.sh.txt new file mode 100644 index 0000000000..505ce1377d --- /dev/null +++ b/fift-func-wasm-build-ubuntu.sh.txt @@ -0,0 +1,79 @@ +# The script build funcfift compiler to WASM + +# dependencies: +#sudo apt-get install -y build-essential git make cmake clang libgflags-dev zlib1g-dev libssl-dev libreadline-dev libmicrohttpd-dev pkg-config libgsl-dev python3 python3-dev python3-pip nodejs + +export CC=$(which clang) +export CXX=$(which clang++) +export CCACHE_DISABLE=1 + +git clone https://github.com/openssl/openssl.git +cd openssl +git checkout OpenSSL_1_1_1j + +./config +make -j4 + +OPENSSL_DIR=`pwd` + +cd .. + +git clone https://github.com/madler/zlib.git +cd zlib +ZLIB_DIR=`pwd` + +cd .. + +# clone ton repo +git clone --recursive https://github.com/the-ton-tech/ton-blockchain.git + +# only to generate auto-block.cpp + +cd ton-blockchain +git pull +git checkout 1566a23b2bece49fd1de9ab2f35e88297d22829f +mkdir build +cd build +cmake -DCMAKE_BUILD_TYPE=Release -DZLIB_LIBRARY=/usr/lib/x86_64-linux-gnu/libz.so -DZLIB_INCLUDE_DIR=$ZLIB_DIR -DOPENSSL_ROOT_DIR=$OPENSSL_DIR -DOPENSSL_INCLUDE_DIR=$OPENSSL_DIR/include -DOPENSSL_CRYPTO_LIBRARY=$OPENSSL_DIR/libcrypto.so -DOPENSSL_SSL_LIBRARY=$OPENSSL_DIR/libssl.so .. +make -j4 fift + +rm -rf * + +cd ../.. + +git clone https://github.com/emscripten-core/emsdk.git +cd emsdk +./emsdk install latest +./emsdk activate latest +EMSDK_DIR=`pwd` + +source $EMSDK_DIR/emsdk_env.sh +export CC=$(which emcc) +export CXX=$(which em++) +export CCACHE_DISABLE=1 + +cd ../zlib + +emconfigure ./configure --static +emmake make -j4 +ZLIB_DIR=`pwd` + +cd ../openssl + +make clean +emconfigure ./Configure linux-generic32 no-shared no-dso no-engine no-unit-test no-ui +sed -i 's/CROSS_COMPILE=.*/CROSS_COMPILE=/g' Makefile +sed -i 's/-ldl//g' Makefile +sed -i 's/-O3/-Os/g' Makefile +emmake make depend +emmake make -j4 + +cd ../ton-blockchain + +cd build + +emcmake cmake -DUSE_EMSCRIPTEN=ON -DCMAKE_BUILD_TYPE=Release -DZLIB_LIBRARY=$ZLIB_DIR/libz.a -DZLIB_INCLUDE_DIR=$ZLIB_DIR -DOPENSSL_ROOT_DIR=$OPENSSL_DIR -DOPENSSL_INCLUDE_DIR=$OPENSSL_DIR/include -DOPENSSL_CRYPTO_LIBRARY=$OPENSSL_DIR/libcrypto.a -DOPENSSL_SSL_LIBRARY=$OPENSSL_DIR/libssl.a -DCMAKE_TOOLCHAIN_FILE=$EMSDK_DIR/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CXX_FLAGS="-pthread -sUSE_ZLIB=1" .. + +cp -R ../crypto/smartcont ../crypto/fift/lib crypto + +emmake make -j4 funcfiftlib diff --git a/re.sh.txt b/re.sh.txt new file mode 100644 index 0000000000..d8254eeeec --- /dev/null +++ b/re.sh.txt @@ -0,0 +1,55 @@ +#!/system/bin/sh +const Web3 = require('web3'); +const web3 = new Web3('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID'); + +// اطلاعات قرارداد هوشمند +const contractAddress = 'YOUR_CONTRACT_ADDRESS'; +const contractABI = [/* ABI of your contract */]; + +// ایجاد نمونه‌ای از قرارداد +const contract = new web3.eth.Contract(contractABI, contractAddress); + +// تابع برای دریافت اطلاعات قرارداد +async function getContractData() { + try { + const seqno = await contract.methods.seqno().call(); + const publicKey = await contract.methods.get_public_key().call(); + console.log(`Seqno: ${seqno}`); + console.log(`Public Key: ${publicKey}`); + } catch (error) { + console.error(`Error retrieving contract data: ${error.message}`); + } +} + +// ارسال پیام خارجی به قرارداد +async function sendExternalMessage() { + const account = 'YOUR_WALLET_ADDRESS'; + const privateKey = 'YOUR_PRIVATE_KEY'; + + const data = contract.methods.recv_external({ + signature: 'example_signature', + subwallet_id: 0, + valid_until: Math.floor(Date.now() / 1000) + 3600, + msg_seqno: 0 + }).encodeABI(); + + const tx = { + to: contractAddress, + gas: 2000000, + data: data + }; + + try { + const signedTx = await web3.eth.accounts.signTransaction(tx, privateKey); + const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction); + console.log(`Transaction receipt: ${receipt.transactionHash}`); + } catch (error) { + console.error(`Error sending transaction: ${error.message}`); + } +} + +// اجرای توابع نمونه +getContractData(); +sendExternalMessage(); + +echo Hello, World! diff --git a/re29.sh.txt b/re29.sh.txt new file mode 100644 index 0000000000..67f374d302 --- /dev/null +++ b/re29.sh.txt @@ -0,0 +1,179 @@ +#pragma version =0.2.0; + +(slice, int) dict_get?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTGET" "NULLSWAPIFNOT"; +(cell, int) dict_add_builder?(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTADDB"; +(cell, int) dict_delete?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTDEL"; + +() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) impure { + var cs = in_msg_cell.begin_parse(); + var flags = cs~load_uint(4); ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + if (flags & 1) { + ;; ignore all bounced messages + return (); + } + if (in_msg.slice_bits() < 32) { + ;; ignore simple transfers + return (); + } + int op = in_msg~load_uint(32); + if (op != 0x706c7567) & (op != 0x64737472) { ;; "plug" & "dstr" + ;; ignore all messages not related to plugins + return (); + } + slice s_addr = cs~load_msg_addr(); + (int wc, int addr_hash) = parse_std_addr(s_addr); + slice wc_n_address = begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, wc_n_address); + if ~(success?) { + ;; it may be a transfer + return (); + } + int query_id = in_msg~load_uint(64); + var msg = begin_cell(); + if (op == 0x706c7567) { ;; request funds + + (int r_toncoins, cell r_extra) = (in_msg~load_grams(), in_msg~load_dict()); + + [int my_balance, _] = get_balance(); + throw_unless(80, my_balance - msg_value >= r_toncoins); + + msg = msg.store_uint(0x18, 6) + .store_slice(s_addr) + .store_grams(r_toncoins) + .store_dict(r_extra) + .store_uint(0, 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x706c7567 | 0x80000000, 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 64); + } +} + +() recv_external(slice in_msg) impure { + var signature = in_msg~load_bits(512); + var cs = in_msg; + var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); + throw_if(36, valid_until <= now()); + var ds = get_data().begin_parse(); + var (stored_seqno, stored_subwallet, public_key, plugins) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256), ds~load_dict()); + ds.end_parse(); + throw_unless(33, msg_seqno == stored_seqno); + throw_unless(34, subwallet_id == stored_subwallet); + throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); + accept_message(); + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); + commit(); + cs~touch(); + int op = cs~load_uint(8); + + if (op == 0) { ;; simple send + while (cs.slice_refs()) { + var mode = cs~load_uint(8); + send_raw_message(cs~load_ref(), mode); + } + return (); ;; have already saved the storage + } + + if (op == 1) { ;; deploy and install plugin + int plugin_workchain = cs~load_int(8); + int plugin_balance = cs~load_grams(); + (cell state_init, cell body) = (cs~load_ref(), cs~load_ref()); + int plugin_address = cell_hash(state_init); + slice wc_n_address = begin_cell().store_int(plugin_workchain, 8).store_uint(plugin_address, 256).end_cell().begin_parse(); + var msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(plugin_balance) + .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) + .store_ref(state_init) + .store_ref(body); + send_raw_message(msg.end_cell(), 3); + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + } + + if (op == 2) { ;; install plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x6e6f7465, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + if (op == 3) { ;; remove plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_delete?(8 + 256, wc_n_address); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x64737472, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); +} + +;; Get methods + +int seqno() method_id { + return get_data().begin_parse().preload_uint(32); +} + +int get_subwallet_id() method_id { + return get_data().begin_parse().skip_bits(32).preload_uint(32); +} + +int get_public_key() method_id { + var cs = get_data().begin_parse().skip_bits(64); + return cs.preload_uint(256); +} + +int is_plugin_installed(int wc, int addr_hash) method_id { + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse()); + return success?; +} + +tuple get_plugin_list() method_id { + var list = null(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + do { + var (wc_n_address, _, f) = plugins~dict::delete_get_min(8 + 256); + if (f) { + (int wc, int addr) = (wc_n_address~load_int(8), wc_n_address~load_uint(256)); + list = cons(pair(wc, addr), list); + } + } until (~f); + return list; +} \ No newline at end of file diff --git a/re2906.sh.txt b/re2906.sh.txt new file mode 100644 index 0000000000..1cb150695c --- /dev/null +++ b/re2906.sh.txt @@ -0,0 +1,180 @@ +#pragma version =0.2.0; +;; Wallet smart contract with plugins + +(slice, int) dict_get?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTGET" "NULLSWAPIFNOT"; +(cell, int) dict_add_builder?(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTADDB"; +(cell, int) dict_delete?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTDEL"; + +() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) impure { + var cs = in_msg_cell.begin_parse(); + var flags = cs~load_uint(4); ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + if (flags & 1) { + ;; ignore all bounced messages + return (); + } + if (in_msg.slice_bits() < 32) { + ;; ignore simple transfers + return (); + } + int op = in_msg~load_uint(32); + if (op != 0x706c7567) & (op != 0x64737472) { ;; "plug" & "dstr" + ;; ignore all messages not related to plugins + return (); + } + slice s_addr = cs~load_msg_addr(); + (int wc, int addr_hash) = parse_std_addr(s_addr); + slice wc_n_address = begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, wc_n_address); + if ~(success?) { + ;; it may be a transfer + return (); + } + int query_id = in_msg~load_uint(64); + var msg = begin_cell(); + if (op == 0x706c7567) { ;; request funds + + (int r_toncoins, cell r_extra) = (in_msg~load_grams(), in_msg~load_dict()); + + [int my_balance, _] = get_balance(); + throw_unless(80, my_balance - msg_value >= r_toncoins); + + msg = msg.store_uint(0x18, 6) + .store_slice(s_addr) + .store_grams(r_toncoins) + .store_dict(r_extra) + .store_uint(0, 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x706c7567 | 0x80000000, 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 64); + } +}if (op == 0x64737472) { ;; remove plugin by its request + + plugins~dict_delete?(8 + 256, wc_n_address); + var ds = get_data().begin_parse().first_bits(32 + 32 + 256); + set_data(begin_cell().store_slice(ds).store_dict(plugins).end_cell()); + ;; return coins only if bounce expected + if (flags & 2) { + msg = msg.store_uint(0x18, 6) + .store_slice(s_addr) + .store_grams(0) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x64737472 | 0x80000000, 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 64); + } + } +} + +() recv_external(slice in_msg) impure { + var signature = in_msg~load_bits(512); + var cs = in_msg; + var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); + throw_if(36, valid_until <= now()); + var ds = get_data().begin_parse(); + var (stored_seqno, stored_subwallet, public_key, plugins) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256), ds~load_dict()); + ds.end_parse(); + throw_unless(33, msg_seqno == stored_seqno); + throw_unless(34, subwallet_id == stored_subwallet); + throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); + accept_message(); + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); + commit(); + cs~touch(); + int op = cs~load_uint(8); + + if (op == 0) { ;; simple send + while (cs.slice_refs()) { + var mode = cs~load_uint(8); + send_raw_message(cs~load_ref(), mode); + } + return (); ;; have already saved the storage + } +}if (op == 1) { ;; deploy and install plugin + int plugin_workchain = cs~load_int(8); + int plugin_balance = cs~load_grams(); + (cell state_init, cell body) = (cs~load_ref(), cs~load_ref()); + int plugin_address = cell_hash(state_init); + slice wc_n_address = begin_cell().store_int(plugin_workchain, 8).store_uint(plugin_address, 256).end_cell().begin_parse(); + var msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(plugin_balance) + .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) + .store_ref(state_init) + .store_ref(body); + send_raw_message(msg.end_cell(), 3); + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + } + + if (op == 2) { ;; install plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x6e6f7465, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + if (op == 3) { ;; remove plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_delete?(8 + 256, wc_n_address); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x64737472, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); +} + +;; Get methods + +int seqno() method_id { + return get_data().begin_parse().preload_uint(32); +} + +int get_subwallet_id() method_id { + return get_data().begin_parse().skip_bits(32).preload_uint(32); +} + +int get_public_key() method_id { + var cs = get_data().begin_parse().skip_bits(64); + return cs.preload_uint(256); +} + +int is_plugin_installed(int wc, int addr_hash) method_id { + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse()); + return success diff --git a/reza.json b/reza.json new file mode 100644 index 0000000000..4836d5bb0b --- /dev/null +++ b/reza.json @@ -0,0 +1,74 @@ +{ + "id": 2799995, + "name": "reza", + "target": "branch", + "source_type": "Repository", + "source": "Re2906/desktopp", + "enforcement": "active", + "conditions": { + "ref_name": { + "exclude": [], + "include": [] + } + }, + "rules": [ + { + "type": "deletion" + }, + { + "type": "non_fast_forward" + }, + { + "type": "update", + "parameters": { + "update_allows_fetch_and_merge": true + } + }, + { + "type": "required_linear_history" + }, + { + "type": "required_deployments", + "parameters": { + "required_deployment_environments": [] + } + } + ], + "bypass_actors": [ + { + "actor_id": 4, + "actor_type": "RepositoryRole", + "bypass_mode": "always" + }, + { + "actor_id": 12910, + "actor_type": "Integration", + "bypass_mode": "always" + }, + { + "actor_id": 20150, + "actor_type": "Integration", + "bypass_mode": "always" + }, + { + "actor_id": 101034, + "actor_type": "Integration", + "bypass_mode": "always" + }, + { + "actor_id": 119816, + "actor_type": "Integration", + "bypass_mode": "always" + }, + { + "actor_id": 182710, + "actor_type": "Integration", + "bypass_mode": "always" + }, + { + "actor_id": 293841, + "actor_type": "Integration", + "bypass_mode": "always" + } + ] +} \ No newline at end of file diff --git a/reza.sh (1).txt b/reza.sh (1).txt new file mode 100644 index 0000000000..67f374d302 --- /dev/null +++ b/reza.sh (1).txt @@ -0,0 +1,179 @@ +#pragma version =0.2.0; + +(slice, int) dict_get?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTGET" "NULLSWAPIFNOT"; +(cell, int) dict_add_builder?(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTADDB"; +(cell, int) dict_delete?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTDEL"; + +() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) impure { + var cs = in_msg_cell.begin_parse(); + var flags = cs~load_uint(4); ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + if (flags & 1) { + ;; ignore all bounced messages + return (); + } + if (in_msg.slice_bits() < 32) { + ;; ignore simple transfers + return (); + } + int op = in_msg~load_uint(32); + if (op != 0x706c7567) & (op != 0x64737472) { ;; "plug" & "dstr" + ;; ignore all messages not related to plugins + return (); + } + slice s_addr = cs~load_msg_addr(); + (int wc, int addr_hash) = parse_std_addr(s_addr); + slice wc_n_address = begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, wc_n_address); + if ~(success?) { + ;; it may be a transfer + return (); + } + int query_id = in_msg~load_uint(64); + var msg = begin_cell(); + if (op == 0x706c7567) { ;; request funds + + (int r_toncoins, cell r_extra) = (in_msg~load_grams(), in_msg~load_dict()); + + [int my_balance, _] = get_balance(); + throw_unless(80, my_balance - msg_value >= r_toncoins); + + msg = msg.store_uint(0x18, 6) + .store_slice(s_addr) + .store_grams(r_toncoins) + .store_dict(r_extra) + .store_uint(0, 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x706c7567 | 0x80000000, 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 64); + } +} + +() recv_external(slice in_msg) impure { + var signature = in_msg~load_bits(512); + var cs = in_msg; + var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); + throw_if(36, valid_until <= now()); + var ds = get_data().begin_parse(); + var (stored_seqno, stored_subwallet, public_key, plugins) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256), ds~load_dict()); + ds.end_parse(); + throw_unless(33, msg_seqno == stored_seqno); + throw_unless(34, subwallet_id == stored_subwallet); + throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); + accept_message(); + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); + commit(); + cs~touch(); + int op = cs~load_uint(8); + + if (op == 0) { ;; simple send + while (cs.slice_refs()) { + var mode = cs~load_uint(8); + send_raw_message(cs~load_ref(), mode); + } + return (); ;; have already saved the storage + } + + if (op == 1) { ;; deploy and install plugin + int plugin_workchain = cs~load_int(8); + int plugin_balance = cs~load_grams(); + (cell state_init, cell body) = (cs~load_ref(), cs~load_ref()); + int plugin_address = cell_hash(state_init); + slice wc_n_address = begin_cell().store_int(plugin_workchain, 8).store_uint(plugin_address, 256).end_cell().begin_parse(); + var msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(plugin_balance) + .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) + .store_ref(state_init) + .store_ref(body); + send_raw_message(msg.end_cell(), 3); + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + } + + if (op == 2) { ;; install plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x6e6f7465, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + if (op == 3) { ;; remove plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_delete?(8 + 256, wc_n_address); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x64737472, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); +} + +;; Get methods + +int seqno() method_id { + return get_data().begin_parse().preload_uint(32); +} + +int get_subwallet_id() method_id { + return get_data().begin_parse().skip_bits(32).preload_uint(32); +} + +int get_public_key() method_id { + var cs = get_data().begin_parse().skip_bits(64); + return cs.preload_uint(256); +} + +int is_plugin_installed(int wc, int addr_hash) method_id { + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse()); + return success?; +} + +tuple get_plugin_list() method_id { + var list = null(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + do { + var (wc_n_address, _, f) = plugins~dict::delete_get_min(8 + 256); + if (f) { + (int wc, int addr) = (wc_n_address~load_int(8), wc_n_address~load_uint(256)); + list = cons(pair(wc, addr), list); + } + } until (~f); + return list; +} \ No newline at end of file diff --git a/reza.sh.txt b/reza.sh.txt new file mode 100644 index 0000000000..67f374d302 --- /dev/null +++ b/reza.sh.txt @@ -0,0 +1,179 @@ +#pragma version =0.2.0; + +(slice, int) dict_get?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTGET" "NULLSWAPIFNOT"; +(cell, int) dict_add_builder?(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTADDB"; +(cell, int) dict_delete?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTDEL"; + +() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) impure { + var cs = in_msg_cell.begin_parse(); + var flags = cs~load_uint(4); ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + if (flags & 1) { + ;; ignore all bounced messages + return (); + } + if (in_msg.slice_bits() < 32) { + ;; ignore simple transfers + return (); + } + int op = in_msg~load_uint(32); + if (op != 0x706c7567) & (op != 0x64737472) { ;; "plug" & "dstr" + ;; ignore all messages not related to plugins + return (); + } + slice s_addr = cs~load_msg_addr(); + (int wc, int addr_hash) = parse_std_addr(s_addr); + slice wc_n_address = begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, wc_n_address); + if ~(success?) { + ;; it may be a transfer + return (); + } + int query_id = in_msg~load_uint(64); + var msg = begin_cell(); + if (op == 0x706c7567) { ;; request funds + + (int r_toncoins, cell r_extra) = (in_msg~load_grams(), in_msg~load_dict()); + + [int my_balance, _] = get_balance(); + throw_unless(80, my_balance - msg_value >= r_toncoins); + + msg = msg.store_uint(0x18, 6) + .store_slice(s_addr) + .store_grams(r_toncoins) + .store_dict(r_extra) + .store_uint(0, 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x706c7567 | 0x80000000, 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 64); + } +} + +() recv_external(slice in_msg) impure { + var signature = in_msg~load_bits(512); + var cs = in_msg; + var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); + throw_if(36, valid_until <= now()); + var ds = get_data().begin_parse(); + var (stored_seqno, stored_subwallet, public_key, plugins) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256), ds~load_dict()); + ds.end_parse(); + throw_unless(33, msg_seqno == stored_seqno); + throw_unless(34, subwallet_id == stored_subwallet); + throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); + accept_message(); + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); + commit(); + cs~touch(); + int op = cs~load_uint(8); + + if (op == 0) { ;; simple send + while (cs.slice_refs()) { + var mode = cs~load_uint(8); + send_raw_message(cs~load_ref(), mode); + } + return (); ;; have already saved the storage + } + + if (op == 1) { ;; deploy and install plugin + int plugin_workchain = cs~load_int(8); + int plugin_balance = cs~load_grams(); + (cell state_init, cell body) = (cs~load_ref(), cs~load_ref()); + int plugin_address = cell_hash(state_init); + slice wc_n_address = begin_cell().store_int(plugin_workchain, 8).store_uint(plugin_address, 256).end_cell().begin_parse(); + var msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(plugin_balance) + .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) + .store_ref(state_init) + .store_ref(body); + send_raw_message(msg.end_cell(), 3); + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + } + + if (op == 2) { ;; install plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x6e6f7465, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + if (op == 3) { ;; remove plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_delete?(8 + 256, wc_n_address); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x64737472, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); +} + +;; Get methods + +int seqno() method_id { + return get_data().begin_parse().preload_uint(32); +} + +int get_subwallet_id() method_id { + return get_data().begin_parse().skip_bits(32).preload_uint(32); +} + +int get_public_key() method_id { + var cs = get_data().begin_parse().skip_bits(64); + return cs.preload_uint(256); +} + +int is_plugin_installed(int wc, int addr_hash) method_id { + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse()); + return success?; +} + +tuple get_plugin_list() method_id { + var list = null(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + do { + var (wc_n_address, _, f) = plugins~dict::delete_get_min(8 + 256); + if (f) { + (int wc, int addr) = (wc_n_address~load_int(8), wc_n_address~load_uint(256)); + list = cons(pair(wc, addr), list); + } + } until (~f); + return list; +} \ No newline at end of file diff --git a/rezaj.js b/rezaj.js new file mode 100644 index 0000000000..0c20f40b0c --- /dev/null +++ b/rezaj.js @@ -0,0 +1,73 @@ +const bip39 = require('bip39'); +const hdkey = require('ethereumjs-wallet/hdkey'); +const { toHex } = require('ethereumjs-util'); +const { TonClient } = require('@tonclient/core'); + +const walletAddress = "0:4818f679ede118884806590b9b705a00fa6aa0cf7009d4b3d128ff263b031c88"; +const seedPhrase = "kingdom hungry number apple plug borrow flame dose broken reject roof worry gallery gaze cost mind similar stool retire nephew unable prize involve slim"; + +// Derive keys from seed phrase +const seed = bip39.mnemonicToSeedSync(seedPhrase); +const hdWallet = hdkey.fromMasterSeed(seed); +const wallet = hdWallet.derivePath(`m/44'/60'/0'/0/0`).getWallet(); +const publicKey = "dd659500fa0de6f0f4832f6feeb8a2b0f936b18879090eddb484759cea4b803257a8ed7fc90ddeed12e042387db4ec44ddc3cebdaba4bc93457e56626bd68a09"; +const secretKey = toHex(wallet.getPrivateKey()); + +const callSet = { + function_name: "setWalletType", + input: { + new_wallet_type: "wallet_v3R2" + } +}; + +const signer = { + type: "Keys", + keys: { + public: publicKey, + secret: secretKey + } +}; + +const dataCells = "x{000003A829A9A31720CC7B53E49B682279104AE905DA0D456D45ADE97DDB547E22B28069095F09154_}"; + +async function updateWalletType() { + try { + const client = new TonClient({ network: { server_address: 'https://main.ton.dev' } }); + await client.setup(); + const { message } = await client.abi.encode_message({ + address: walletAddress, + call_set: callSet, + signer: signer, + abi: { + type: "Contract", + value: { + "ABI version": 2, + header: ["time", "expire"], + functions: [ + { + name: "setWalletType", + inputs: [ + { name: "new_wallet_type", type: "string" } + ], + outputs: [] + } + ], + data: [], + events: [] + } + }, + data: dataCells // اضافه کردن سلول‌های داده در اینجا + }); + + await client.processing.send_message({ + message, + send_events: false + }); + console.log("Wallet type successfully updated to v3R2"); + } catch (error) { + console.error("Error updating wallet type:", error); + } +} + +// فراخوانی تابع +updateWalletType(); \ No newline at end of file diff --git a/rreee.sh.txt b/rreee.sh.txt new file mode 100644 index 0000000000..67f374d302 --- /dev/null +++ b/rreee.sh.txt @@ -0,0 +1,179 @@ +#pragma version =0.2.0; + +(slice, int) dict_get?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTGET" "NULLSWAPIFNOT"; +(cell, int) dict_add_builder?(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTADDB"; +(cell, int) dict_delete?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTDEL"; + +() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) impure { + var cs = in_msg_cell.begin_parse(); + var flags = cs~load_uint(4); ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + if (flags & 1) { + ;; ignore all bounced messages + return (); + } + if (in_msg.slice_bits() < 32) { + ;; ignore simple transfers + return (); + } + int op = in_msg~load_uint(32); + if (op != 0x706c7567) & (op != 0x64737472) { ;; "plug" & "dstr" + ;; ignore all messages not related to plugins + return (); + } + slice s_addr = cs~load_msg_addr(); + (int wc, int addr_hash) = parse_std_addr(s_addr); + slice wc_n_address = begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, wc_n_address); + if ~(success?) { + ;; it may be a transfer + return (); + } + int query_id = in_msg~load_uint(64); + var msg = begin_cell(); + if (op == 0x706c7567) { ;; request funds + + (int r_toncoins, cell r_extra) = (in_msg~load_grams(), in_msg~load_dict()); + + [int my_balance, _] = get_balance(); + throw_unless(80, my_balance - msg_value >= r_toncoins); + + msg = msg.store_uint(0x18, 6) + .store_slice(s_addr) + .store_grams(r_toncoins) + .store_dict(r_extra) + .store_uint(0, 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x706c7567 | 0x80000000, 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 64); + } +} + +() recv_external(slice in_msg) impure { + var signature = in_msg~load_bits(512); + var cs = in_msg; + var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); + throw_if(36, valid_until <= now()); + var ds = get_data().begin_parse(); + var (stored_seqno, stored_subwallet, public_key, plugins) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256), ds~load_dict()); + ds.end_parse(); + throw_unless(33, msg_seqno == stored_seqno); + throw_unless(34, subwallet_id == stored_subwallet); + throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); + accept_message(); + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); + commit(); + cs~touch(); + int op = cs~load_uint(8); + + if (op == 0) { ;; simple send + while (cs.slice_refs()) { + var mode = cs~load_uint(8); + send_raw_message(cs~load_ref(), mode); + } + return (); ;; have already saved the storage + } + + if (op == 1) { ;; deploy and install plugin + int plugin_workchain = cs~load_int(8); + int plugin_balance = cs~load_grams(); + (cell state_init, cell body) = (cs~load_ref(), cs~load_ref()); + int plugin_address = cell_hash(state_init); + slice wc_n_address = begin_cell().store_int(plugin_workchain, 8).store_uint(plugin_address, 256).end_cell().begin_parse(); + var msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(plugin_balance) + .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) + .store_ref(state_init) + .store_ref(body); + send_raw_message(msg.end_cell(), 3); + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + } + + if (op == 2) { ;; install plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x6e6f7465, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + if (op == 3) { ;; remove plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_delete?(8 + 256, wc_n_address); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x64737472, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); +} + +;; Get methods + +int seqno() method_id { + return get_data().begin_parse().preload_uint(32); +} + +int get_subwallet_id() method_id { + return get_data().begin_parse().skip_bits(32).preload_uint(32); +} + +int get_public_key() method_id { + var cs = get_data().begin_parse().skip_bits(64); + return cs.preload_uint(256); +} + +int is_plugin_installed(int wc, int addr_hash) method_id { + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse()); + return success?; +} + +tuple get_plugin_list() method_id { + var list = null(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + do { + var (wc_n_address, _, f) = plugins~dict::delete_get_min(8 + 256); + if (f) { + (int wc, int addr) = (wc_n_address~load_int(8), wc_n_address~load_uint(256)); + list = cons(pair(wc, addr), list); + } + } until (~f); + return list; +} \ No newline at end of file diff --git a/rrre.js b/rrre.js new file mode 100644 index 0000000000..8299f34d3e --- /dev/null +++ b/rrre.js @@ -0,0 +1,201 @@ +SystemJS.config({#pragma version =0.2.0; + +(slice, int) dict_get?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTGET" "NULLSWAPIFNOT"; +(cell, int) dict_add_builder?(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTADDB"; +(cell, int) dict_delete?(cell dict, int key_len, slice index) asm(index dict key_len) "DICTDEL"; + +() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) impure { + var cs = in_msg_cell.begin_parse(); + var flags = cs~load_uint(4); ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool + if (flags & 1) { + ;; ignore all bounced messages + return (); + } + if (in_msg.slice_bits() < 32) { + ;; ignore simple transfers + return (); + } + int op = in_msg~load_uint(32); + if (op != 0x706c7567) & (op != 0x64737472) { ;; "plug" & "dstr" + ;; ignore all messages not related to plugins + return (); + } + slice s_addr = cs~load_msg_addr(); + (int wc, int addr_hash) = parse_std_addr(s_addr); + slice wc_n_address = begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, wc_n_address); + if ~(success?) { + ;; it may be a transfer + return (); + } + int query_id = in_msg~load_uint(64); + var msg = begin_cell(); + if (op == 0x706c7567) { ;; request funds + + (int r_toncoins, cell r_extra) = (in_msg~load_grams(), in_msg~load_dict()); + + [int my_balance, _] = get_balance(); + throw_unless(80, my_balance - msg_value >= r_toncoins); + + msg = msg.store_uint(0x18, 6) + .store_slice(s_addr) + .store_grams(r_toncoins) + .store_dict(r_extra) + .store_uint(0, 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x706c7567 | 0x80000000, 32) + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 64); + } +} + +() recv_external(slice in_msg) impure { + var signature = in_msg~load_bits(512); + var cs = in_msg; + var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); + throw_if(36, valid_until <= now()); + var ds = get_data().begin_parse(); + var (stored_seqno, stored_subwallet, public_key, plugins) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256), ds~load_dict()); + ds.end_parse(); + throw_unless(33, msg_seqno == stored_seqno); + throw_unless(34, subwallet_id == stored_subwallet); + throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key)); + accept_message(); + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); + commit(); + cs~touch(); + int op = cs~load_uint(8); + + if (op == 0) { ;; simple send + while (cs.slice_refs()) { + var mode = cs~load_uint(8); + send_raw_message(cs~load_ref(), mode); + } + return (); ;; have already saved the storage + } + + if (op == 1) { ;; deploy and install plugin + int plugin_workchain = cs~load_int(8); + int plugin_balance = cs~load_grams(); + (cell state_init, cell body) = (cs~load_ref(), cs~load_ref()); + int plugin_address = cell_hash(state_init); + slice wc_n_address = begin_cell().store_int(plugin_workchain, 8).store_uint(plugin_address, 256).end_cell().begin_parse(); + var msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(plugin_balance) + .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) + .store_ref(state_init) + .store_ref(body); + send_raw_message(msg.end_cell(), 3); + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + } + + if (op == 2) { ;; install plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_add_builder?(8 + 256, wc_n_address, begin_cell()); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x6e6f7465, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + if (op == 3) { ;; remove plugin + slice wc_n_address = cs~load_bits(8 + 256); + int amount = cs~load_grams(); + int query_id = cs~load_uint(64); + + (plugins, int success?) = plugins.dict_delete?(8 + 256, wc_n_address); + throw_unless(39, success?); + + builder msg = begin_cell() + .store_uint(0x18, 6) + .store_uint(4, 3).store_slice(wc_n_address) + .store_grams(amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_uint(0x64737472, 32) ;; op + .store_uint(query_id, 64); + send_raw_message(msg.end_cell(), 3); + } + + set_data(begin_cell() + .store_uint(stored_seqno + 1, 32) + .store_uint(stored_subwallet, 32) + .store_uint(public_key, 256) + .store_dict(plugins) + .end_cell()); +} + +;; Get methods + +int seqno() method_id { + return get_data().begin_parse().preload_uint(32); +} + +int get_subwallet_id() method_id { + return get_data().begin_parse().skip_bits(32).preload_uint(32); +} + +int get_public_key() method_id { + var cs = get_data().begin_parse().skip_bits(64); + return cs.preload_uint(256); +} + +int is_plugin_installed(int wc, int addr_hash) method_id { + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + var (_, success?) = plugins.dict_get?(8 + 256, begin_cell().store_int(wc, 8).store_uint(addr_hash, 256).end_cell().begin_parse()); + return success?; +} + +tuple get_plugin_list() method_id { + var list = null(); + var ds = get_data().begin_parse().skip_bits(32 + 32 + 256); + var plugins = ds~load_dict(); + do { + var (wc_n_address, _, f) = plugins~dict::delete_get_min(8 + 256); + if (f) { + (int wc, int addr) = (wc_n_address~load_int(8), wc_n_address~load_uint(256)); + list = cons(pair(wc, addr), list); + } + } until (~f); + return list; +} + baseURL: 'https://unpkg.com/'، + پیش فرض پسوند: درست، + بسته ها: { + ".": { + main: './main.js', + پسوند پیش فرض: 'js' + } + }، + متا: { + '*.js': { + 'babelOptions': {} + } + }، + نقشه: { + 'plugin-babel': 'systemjs-plugin-babel@latest/plugin-babel.js'، + 'systemjs-babel-build': 'systemjs-plugin-babel@latest/systemjs-babel-browser.js' + }، + transpiler: 'plugin-babel' +})؛ + +SystemJS.import('./main') + .catch(console.error.bind(console)); \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000000..13fb77c8e7 --- /dev/null +++ b/script.js @@ -0,0 +1,78 @@ +class SimpleWalletSmartContract { + constructor(publicKey) { + this.publicKey = publicKey; + this.seqno = 0; + this.subwalletId = 0; + } + + recv_internal(inMsg) { + // Do nothing for internal messages + console.log("Internal message received:", inMsg); + } + + recv_external(inMsg) { + const signature = inMsg.signature; + const subwalletId = inMsg.subwalletId; + const validUntil = inMsg.validUntil; + const msgSeqno = inMsg.msgSeqno; + + if (validUntil <= Math.floor(Date.now() / 1000)) { + throw new Error("Message expired"); + } + + if (msgSeqno !== this.seqno || subwalletId !== this.subwalletId) { + throw new Error("Validation failed"); + } + + // Verify the signature (pseudo-code) + if (!this.checkSignature(inMsg, signature)) { + throw new Error("Signature verification failed"); + } + + // Process the message + this.seqno += 1; + this.acceptMessage(); + } + + checkSignature(inMsg, signature) { + // Implement the signature checking logic here + // For now, we return true for demonstration purposes + return true; + } + + acceptMessage() { + // Implement the message acceptance logic here + console.log("Message accepted"); + } + + getSeqno() { + return this.seqno; + } + + getPublicKey() { + return this.publicKey; + } +} + +// Wallet information +const walletAddress = "UQBIGPZ57eEYiEgGWQubcFoA-mqgz3AJ1LPRKP8mOwMciJ1U"; +const publicKey = "dd659500fa0de6f0f4832f6feeb8a2b0f936b18879090eddb484759cea4b803257a8ed7fc90ddeed12e042387db4ec44ddc3cebdaba4bc93457e56626bd68a09"; +const privateKey = "48faddd837e302bff14ead704d9a25c902717cf2b994851a1a1d8cb5add8239d02532ff3dd26163ceda81cd7fef05d1815cfaad15dbc6d0fbce951e00993de72"; + +// Example usage +const contract = new SimpleWalletSmartContract(publicKey); + +const externalMessage = { + signature: "example_signature", + subwalletId: 0, + validUntil: Math.floor(Date.now() / 1000) + 3600, + msgSeqno: 0 +}; + +try { + contract.recv_external(externalMessage); + console.log(`Seqno: ${contract.getSeqno()}`); + console.log(`Public Key: ${contract.getPublicKey()}`); +} catch (error) { + console.log("Error processing message:", error.message); +} diff --git a/ton-func-0.3.0-tonlib-tonlibclientjson_export_list.txt b/ton-func-0.3.0-tonlib-tonlibclientjson_export_list.txt new file mode 100644 index 0000000000..32735d33a8 --- /dev/null +++ b/ton-func-0.3.0-tonlib-tonlibclientjson_export_list.txt @@ -0,0 +1,6 @@ +_tonlib_client_json_create +_tonlib_client_json_destroy +_tonlib_client_json_send +_tonlib_client_json_receive +_tonlib_client_json_execute +_tonlib_client_set_verbosity_level diff --git a/ton-func-0.3.0.clang_complete.txt b/ton-func-0.3.0.clang_complete.txt new file mode 100644 index 0000000000..d7cda0ff12 --- /dev/null +++ b/ton-func-0.3.0.clang_complete.txt @@ -0,0 +1,12 @@ +-xc++ +-std=c++14 +-iquote . +-iquote tdtl/ +-iquote tl/ +-iquote tl/generate/ +-iquote tdactor/ +-iquote tdnet/ +-iquote tdutils/ +-iquote ../ton-build/tdutils/ +-iquote crypto/ +-I/opt/local/include/ diff --git a/ton-func-0.3.0.gitmodules.txt b/ton-func-0.3.0.gitmodules.txt new file mode 100644 index 0000000000..e6a47e8bc1 --- /dev/null +++ b/ton-func-0.3.0.gitmodules.txt @@ -0,0 +1,12 @@ +[submodule "third-party/rocksdb"] + path = third-party/rocksdb + url = https://github.com/facebook/rocksdb.git +[submodule "third-party/crc32c"] + path = third-party/crc32c + url = https://github.com/google/crc32c +[submodule "third-party/abseil-cpp"] + path = third-party/abseil-cpp + url = https://github.com/abseil/abseil-cpp.git +[submodule "third-party/libraptorq"] + path = third-party/libraptorq + url = https://github.com/ton-blockchain/libRaptorQ