From 1a6b8ecb1316f9f6b9f44db6d4cdf377b83007de Mon Sep 17 00:00:00 2001 From: Maxnflaxl <63856008+Maxnflaxl@users.noreply.github.com> Date: Thu, 6 Nov 2025 17:00:58 +0100 Subject: [PATCH 01/11] upd --- ...figuring-atomic-swaps-in-desktop-wallet.md | 115 +----------------- atomic-swaps/electrum-atomic-swaps.md | 19 +++ atomic-swaps/ethereum-atomic-swaps.md | 58 +++++++++ atomic-swaps/rpc-full-node-atomic-swaps.md | 38 ++++++ 4 files changed, 118 insertions(+), 112 deletions(-) create mode 100644 atomic-swaps/electrum-atomic-swaps.md create mode 100644 atomic-swaps/ethereum-atomic-swaps.md create mode 100644 atomic-swaps/rpc-full-node-atomic-swaps.md diff --git a/atomic-swaps/configuring-atomic-swaps-in-desktop-wallet.md b/atomic-swaps/configuring-atomic-swaps-in-desktop-wallet.md index 48ef052..fb61641 100644 --- a/atomic-swaps/configuring-atomic-swaps-in-desktop-wallet.md +++ b/atomic-swaps/configuring-atomic-swaps-in-desktop-wallet.md @@ -8,117 +8,8 @@ https://www.youtube.com/watch?v=_SOgPybgi8Y&t=504s Configure your Beam wallet to enable Atomic Swaps by connecting to the node and wallet of the currency you wish to swap. Each currency can link with your Beam wallet via RPC full node or an Electrum wallet. -## **Connecting to Full Node via Litecoin** +For detailed instructions on connecting via RPC full node, refer to [RPC Full Node Atomic Swaps Configuration](rpc-full-node-atomic-swaps.md). -To connect Litecoin with your Beam wallet via full node, follow the steps below: +For detailed instructions on connecting with an Electrum wallet, refer to [Electrum Atomic Swaps Configuration](electrum-atomic-swaps.md). -### **Edit Litecoin Configuration File** - -Using a text editor, open the `Litecoin.conf` file and enter the following parameters to configure Litecoin to run with JSON RPC: - -``` -# server=1 tells Litecoin-QT to accept JSON-RPC commands. -server=1 - -rpcport=9432 - -# You must set rpcuser and rpcpassword to secure the JSON-RPC api -rpcuser=liteuser -rpcpassword=123 -``` - -Save your changes to `Litecoin.conf`. - -### Synch Litecoin Node with Beam Wallet - -Go to **Settings**. - -![](.gitbook/assets/Screenshot\_203.png) - -### Enter Litecoin Node Address - -Under the Litecoin tab, **enter the node ip:port address along with the RPC username and password**. The fee paid on the respective chain per Kb of transaction size can be left at the default value. - -**Click Apply > Connect.** - -A green light will appear next to **Litecoin Node,** indicating the connection was a success! - -![](<.gitbook/assets/Screen Shot 2021-05-15 at 2.05.52 PM.png>) - -## Connect with Electrum Wallet - -If you have an Electrum wallet, connecting to a remote node follows a similar yet more straightforward process: - -### Edit Electrum Wallet Settings - -1. **Settings****> toggle "Node" to "Electrum."** -2. Enter your Electrum address. -3. Enter an existing seed phrase or generate a new one (you can change wallets at any time). - -Once connected, you should be able to see the list of all wallet addresses in your Electrum wallet by clicking "Show wallet addresses."\ - - -![](.gitbook/assets/Screenshot\_206.png) - -Once you have optimized and synchronized your nodes in the settings tabs, you will now be able to accept Atomic Swap offers. - -![](.gitbook/assets/Screenshot\_207.png) - -## Connecting to Ethereum - -To link your Ethereum and Beam wallets together, you must have an Infura account as well as an Ethereum Metamask. - -[Infura](https://infura.io/) is the API service that broadcasts information from the Ethereum blockchain, and [Metamask](https://metamask.io/) is a browser-based Ethereum wallet. - -Note: [infura.io](https://www.infura.io) requires specific parameters from your Beam wallet as well as valid email address verification. - - -Before attempting to create an Ethereum <> Beam Atomic Swap make sure your wallet balance has enough Ethereum to cover mining fees. - - -## To connect to Ethereum - -1. **Launch** [infura.io.](http://www.infura.io) -2. Go to **Settings > "keys" > Copy Project ID.** -3. **Launch** your Beam wallet. -4. Go to **Settings****> "Connectivity" > "Ethereum" > Paste Project ID.** -5. **Click "Generate Seed Phrase"** to generate the seed phrase you will import to your Metamask. You can also use an existing seed phrase. -6. **Copy seed phrase > "apply changes" > "Connect to node."** -7. **Launch** **Metamask > click "import using account seed phrase."** -8. Enter your seed phrase and create a strong wallet password. - -If you have successfully linked your accounts, a green light will appear next to the Ethereum node indicating the connection was a success! - -## **How it looks in your wallet** - -### Infura.io - -Copy this project ID string. - -![](.gitbook/assets/Screenshot\_172.png) - -### Beam wallet settings - -Paste your Infura Preject ID under "Ethereum." - -![](.gitbook/assets/Screenshot\_173.png) - -### Generate a new seed phrase - -Click "apply changes" after you have copied your seed phrase. - -![](.gitbook/assets/Screenshot\_174.png) - -### Connect to Ethereum - -![](.gitbook/assets/Screenshot\_175.png) - -### Import Ethereum seed phrase - -The next step is to import the Ethereum seed phrase into a Metamask wallet. At the bottom of your Metamask browser extension, click "Import using account seed phrase." Enter your seed phrase and create a password. - -![](.gitbook/assets/Screenshot\_176.png) - -### Atomic Swaps screen - -![](.gitbook/assets/Screenshot\_179.png) +For detailed instructions on connecting to Ethereum, refer to [Ethereum Atomic Swaps Configuration](ethereum-atomic-swaps.md). diff --git a/atomic-swaps/electrum-atomic-swaps.md b/atomic-swaps/electrum-atomic-swaps.md new file mode 100644 index 0000000..cd0db40 --- /dev/null +++ b/atomic-swaps/electrum-atomic-swaps.md @@ -0,0 +1,19 @@ +# Electrum Atomic Swaps Configuration + +## Connect with Electrum Wallet + +If you have an Electrum wallet, connecting to a remote node follows a similar yet more straightforward process: + +### Edit Electrum Wallet Settings + +1. **Settings****> toggle "Node" to "Electrum."** +2. Enter your Electrum address. +3. Enter an existing seed phrase or generate a new one (you can change wallets at any time). + +Once connected, you should be able to see the list of all wallet addresses in your Electrum wallet by clicking "Show wallet addresses." + +![](.gitbook/assets/Screenshot_206.png) + +Once you have optimized and synchronized your nodes in the settings tabs, you will now be able to accept Atomic Swap offers. + +![](.gitbook/assets/Screenshot_207.png) diff --git a/atomic-swaps/ethereum-atomic-swaps.md b/atomic-swaps/ethereum-atomic-swaps.md new file mode 100644 index 0000000..705c32a --- /dev/null +++ b/atomic-swaps/ethereum-atomic-swaps.md @@ -0,0 +1,58 @@ +# Ethereum Atomic Swaps Configuration + +## Connecting to Ethereum + +To link your Ethereum and Beam wallets together, you must have an Infura account as well as an Ethereum Metamask. + +[Infura](https://infura.io/) is the API service that broadcasts information from the Ethereum blockchain, and [Metamask](https://metamask.io/) is a browser-based Ethereum wallet. + +Note: [infura.io](https://www.infura.io) requires specific parameters from your Beam wallet as well as valid email address verification. + +Before attempting to create an Ethereum <> Beam Atomic Swap make sure your wallet balance has enough Ethereum to cover mining fees. + +## To connect to Ethereum + +1. **Launch** [infura.io.](http://www.infura.io) +2. Go to **Settings > "keys" > Copy Project ID.** +3. **Launch** your Beam wallet. +4. Go to **Settings****> "Connectivity" > "Ethereum" > Paste Project ID.** +5. **Click "Generate Seed Phrase"** to generate the seed phrase you will import to your Metamask. You can also use an existing seed phrase. +6. **Copy seed phrase > "apply changes" > "Connect to node."** +7. **Launch** **Metamask > click "import using account seed phrase."** +8. Enter your seed phrase and create a strong wallet password. + +If you have successfully linked your accounts, a green light will appear next to the Ethereum node indicating the connection was a success! + +## How it looks in your wallet + +### Infura.io + +Copy this project ID string. + +![](.gitbook/assets/Screenshot_172.png) + +### Beam wallet settings + +Paste your Infura Project ID under "Ethereum." + +![](.gitbook/assets/Screenshot_173.png) + +### Generate a new seed phrase + +Click "apply changes" after you have copied your seed phrase. + +![](.gitbook/assets/Screenshot_174.png) + +### Connect to Ethereum + +![](.gitbook/assets/Screenshot_175.png) + +### Import Ethereum seed phrase + +The next step is to import the Ethereum seed phrase into a Metamask wallet. At the bottom of your Metamask browser extension, click "Import using account seed phrase." Enter your seed phrase and create a password. + +![](.gitbook/assets/Screenshot_176.png) + +### Atomic Swaps screen + +![](.gitbook/assets/Screenshot_179.png) diff --git a/atomic-swaps/rpc-full-node-atomic-swaps.md b/atomic-swaps/rpc-full-node-atomic-swaps.md new file mode 100644 index 0000000..1d6417e --- /dev/null +++ b/atomic-swaps/rpc-full-node-atomic-swaps.md @@ -0,0 +1,38 @@ +# RPC Full Node Atomic Swaps Configuration + +## Connecting to Full Node via Litecoin + +To connect Litecoin with your Beam wallet via full node, follow the steps below: + +### Edit Litecoin Configuration File + +Using a text editor, open the `Litecoin.conf` file and enter the following parameters to configure Litecoin to run with JSON RPC: + +``` +# server=1 tells Litecoin-QT to accept JSON-RPC commands. +server=1 + +rpcport=9432 + +# You must set rpcuser and rpcpassword to secure the JSON-RPC api +rpcuser=liteuser +rpcpassword=123 +``` + +Save your changes to `Litecoin.conf`. + +### Synch Litecoin Node with Beam Wallet + +Go to **Settings**. + +![](.gitbook/assets/Screenshot_203.png) + +### Enter Litecoin Node Address + +Under the Litecoin tab, **enter the node ip:port address along with the RPC username and password**. The fee paid on the respective chain per Kb of transaction size can be left at the default value. + +**Click Apply > Connect.** + +A green light will appear next to **Litecoin Node,** indicating the connection was a success! + +![](<.gitbook/assets/Screen Shot 2021-05-15 at 2.05.52 PM.png>) From 86637a7499963d03f73076a6e9516f5a13dd32fb Mon Sep 17 00:00:00 2001 From: Maxnflaxl <63856008+Maxnflaxl@users.noreply.github.com> Date: Thu, 6 Nov 2025 17:01:20 +0100 Subject: [PATCH 02/11] upd --- hardware-wallet/Ledger.md | 82 +++++++++++++++++++++ hardware-wallet/README.md | 150 ++++++++++++-------------------------- hardware-wallet/Trezor.md | 86 ++++++++++++++++++++++ 3 files changed, 213 insertions(+), 105 deletions(-) create mode 100644 hardware-wallet/Ledger.md create mode 100644 hardware-wallet/Trezor.md diff --git a/hardware-wallet/Ledger.md b/hardware-wallet/Ledger.md new file mode 100644 index 0000000..61e2540 --- /dev/null +++ b/hardware-wallet/Ledger.md @@ -0,0 +1,82 @@ +--- +description: Ledger Hardware Wallet support +--- + +# Ledger + +We currently do not support smart contract transactions for the Hardware Wallets. + +## Ledger + +Ledger allows for 3rd-party developers to develop embedded apps that support custom coins. The app should be submitted for official review, and once they find it compliant to their safety standards - it will become available for installation via their official software (Ledger Live). + +Our app is submitted, and is waiting for the review. However, given the complexity of Beam, it looks unlikely to see Beam accepted anytime soon (as of 2023-01). + +Meanwhile our app can be installed as unofficial release. This is called sideloading. Some (but not all!) Ledger devices support this. + +#### Ledger Nano S +This device is outdated (discontinued), but we support it. However its very weak performance may impact user experience. It may take minutes (!!) to sign a transaction. Please be patient with it. + +#### Ledger Nano S Plus +This is the recommended device. Relatively inexpensive, yet powerful enough. Fully supports our functionality. + +#### Ledger Nano X +Unfortunately this device does not support sideloading. Will have to wait until Ledger officially accepts our app. + +#### Ledger Stax +No development environment available yet for this device. + + +# Instructions for the host machine + +We support Linux, Windows and Mac, i.e. all the platforms on which the Beam Wallet is already supported. No additional tools/prerequisites are required. Just plug the HW wallet, it should be detected by our desktop wallet automatically. + + +# Installation instructions + +Once the Beam app will be officially accepted by Ledger, it'll be possible to install it on the Ledger secure device using the official software (Ledger Live). +Until then our unofficial release should be installed. + +The best and easiest way to do this is using our CLI wallet. It contains the embedded apps for all the supported devices, and allows to install it on any supported device. Just run the following command line: + +`beam-wallet hid_install` + +It will automatically find the connected supported device, and install the appropriate app on it. This also ensure the embedded app version is fully compatible with the desktop wallet version. + +Nevertheless there's an option to download and sideload the app manually, as described in the next section. + +## Alternative installation method + +Overall the process of side-loading is documented [here](https://docs.radixdlt.com/main/user-applications/ledger-app-sideload.html). In essence the user should download python, and use the specified command line (included in our releases) to load the Beam application on the device. + +### Note for Linux users +On Linux, however, the Beam desktop wallet should have appropriate permissions to connect to the HW wallet. + +Desktop wallet can be run with elevated privileges (`sudo`) but this is not recommended. Instead it's possible to enable device access for all the users in the system. +To allow this the following file should be downloaded, and copied `/etc/udev/rules.d` into directory. After the device is re-plugged the new permissions should be in effect. +* [ledger-hid.zip](https://github.com/BeamMW/app-beam/files/10475866/ledger-hid.zip) +(unzip it before copying into target directory) + +#### Stable releases + +| Release Date| Commit | Api Ver | Nano S | Nano S Plus | Remarks | +|---|---|---|---|---|---| +| 2023-01-23| 58704c5cf328c47e8bde59a165c3c1d93d6c7244 | 3 | [download](https://github.com/BeamMW/app-beam/files/10475776/58704c5-nanos.zip) | [download](https://github.com/BeamMW/app-beam/files/10475779/58704c5-nanosp.zip) | | +| 2023-01-29| bc7585a346d15061b42d7706f39b68b9b395c573 | 3 | [download](https://github.com/BeamMW/app-beam/files/10529521/bc7585a-nanos.zip) | [download](https://github.com/BeamMW/app-beam/files/10529522/bc7585a-nanosp.zip) | | +| 2023-02-03| d00f0fecc7df294986104af3dd57cf38725b44e0 | 3 | [download](https://github.com/BeamMW/app-beam/files/10576697/d00f0fe-nanos.zip) | [download](https://github.com/BeamMW/app-beam/files/10576696/d00f0fe-nanosplus.zip) | Fixed incorrect endpoint for shielded txs | +| | | | | | | + +# Usage + +## Implications of device auto-lock + +HW wallets usually auto-lock if idle for some time. This makes sense of course (otherwise, if left unlocked and unattended, it could be used by any stranger or intruder to steal your funds). + +However in Beam the HW wallet is used not only to send funds, but also to receive. Hence the desktop wallet won't be able to receive funds while the device is locked. Our desktop wallet (both CLI and UI) gives an appropriate message if it can't access the HW wallet, and if/when the user unlocks it - the transaction will proceed. But if the user is not around then there will be no one to unlock the device, and all transactions will end stuck. + +At the moment we recommend the following options: + +Receiver: if you don't expect to receive eventual transactions, then we recommend keeping the auto-lock feature. If, however, you prefer to be able to receive transactions constantly, then consider disabling the auto-lock feature. + +Sender: If you expect the receiver to be online, then send transactions as usual. Otherwise it's always possible to use offline transactions types (public offline, or max privacy), since those are non-interactive transactions, and the receiver is not involved. + diff --git a/hardware-wallet/README.md b/hardware-wallet/README.md index 3e6074f..398df04 100644 --- a/hardware-wallet/README.md +++ b/hardware-wallet/README.md @@ -1,132 +1,72 @@ --- -description: Hardware Wallet support +description: Hardware Wallet Support Overview --- -# Hardware wallets +# Hardware Wallets -We currently do not support smart contract transactions for the Hardware Wallets. +Beam supports integration with popular **hardware wallets** to enhance security and protect private keys from exposure on your host machine. +This section provides an overview of hardware wallet support, installation, and usage. -## Ledger +Currently, Beam supports **Ledger** and **Trezor** devices with varying levels of functionality. -Ledger allows for 3rd-party developers to develop embedded apps that support custom coins. The app should be submitted for official review, and once they find it compliant to their safety standards - it will become available for installation via their official software (Ledger Live). +> ⚠️ Smart contract transactions are **not yet supported** for hardware wallets. -Our app is submitted, and is waiting for the review. However, given the complexity of Beam, it looks unlikely to see Beam accepted anytime soon (as of 2023-01). - -Meanwhile our app can be installed as unofficial release. This is called sideloading. Some (but not all!) Ledger devices support this. - -#### Ledger Nano S -This device is outdated (discontinued), but we support it. However its very weak performance may impact user experience. It may take minutes (!!) to sign a transaction. Please be patient with it. - -#### Ledger Nano S Plus -This is the recommended device. Relatively inexpensive, yet powerful enough. Fully supports our functionality. - -#### Ledger Nano X -Unfortunately this device does not support sideloading. Will have to wait until Ledger officially accepts our app. - -#### Ledger Stax -No development environment available yet for this device. - -### Trezor - -According to Trezor they don't consider accepting new coins (not clones of existing ones) to their official release. -Currently we investigate the possibility to add our app to an unofficial release. - -# Instructions for the host machine - -We support Linux, Windows and Mac, i.e. all the platforms on which the Beam Wallet is already supported. No additional tools/prerequisites are required. Just plug the HW wallet, it should be detected by our desktop wallet automatically. - -### Note for Linux users -On Linux, however, the Beam desktop wallet should have appropriate permissions to connect to the HW wallet. - -Desktop wallet can be run with elevated privileges (`sudo`) but this is not recommended. Instead it's possible to enable device access for all the users in the system. -To allow this the following file should be downloaded, and copied `/etc/udev/rules.d` into directory. After the device is re-plugged the new permissions should be in effect. -* [ledger-hid.zip](https://github.com/BeamMW/app-beam/files/10475866/ledger-hid.zip) -(unzip it before copying into target directory) - -# Installation instructions - -Once the Beam app will be officially accepted by Ledger, it'll be possible to install it on the Ledger secure device using the official software (Ledger Live). -Until then our unofficial release should be installed. - -The best and easiest way to do this is using our CLI wallet. It contains the embedded apps for all the supported devices, and allows to install it on any supported device. Just run the following command line: - -`beam-wallet hid_install` - -It will automatically find the connected supported device, and install the appropriate app on it. This also ensure the embedded app version is fully compatible with the desktop wallet version. - -Nevertheless there's an option to download and sideload the app manually, as described in the next section. - -## Alternative installation method - -Overall the process of side-loading is documented [here](https://docs.radixdlt.com/main/user-applications/ledger-app-sideload.html). In essence the user should download python, and use the specified command line (included in our releases) to load the Beam application on the device. +--- -#### Stable releases +## Supported Devices -| Release Date| Commit | Api Ver | Nano S | Nano S Plus | Remarks | -|---|---|---|---|---|---| -| 2023-01-23| 58704c5cf328c47e8bde59a165c3c1d93d6c7244 | 3 | [download](https://github.com/BeamMW/app-beam/files/10475776/58704c5-nanos.zip) | [download](https://github.com/BeamMW/app-beam/files/10475779/58704c5-nanosp.zip) | | -| 2023-01-29| bc7585a346d15061b42d7706f39b68b9b395c573 | 3 | [download](https://github.com/BeamMW/app-beam/files/10529521/bc7585a-nanos.zip) | [download](https://github.com/BeamMW/app-beam/files/10529522/bc7585a-nanosp.zip) | | -| 2023-02-03| d00f0fecc7df294986104af3dd57cf38725b44e0 | 3 | [download](https://github.com/BeamMW/app-beam/files/10576697/d00f0fe-nanos.zip) | [download](https://github.com/BeamMW/app-beam/files/10576696/d00f0fe-nanosplus.zip) | Fixed incorrect endpoint for shielded txs | -| | | | | | | +| Manufacturer | Model | Support Status | Notes | +|---------------|--------|----------------|-------| +| **Ledger** | Nano S | ✅⚠️ Supported (slow performance) | Discontinued but compatible | +| | Nano S Plus | ✅ Recommended | Full support and stable performance | +| | Nano X | 🚧 Not supported | No sideloading support until official approval | +| | Stax | 🚧 Not supported | No development environment available | +| **Trezor** | Model One / Model T | 🧩 Experimental | Under investigation for unofficial release | -# Usage +--- -## Implications of device auto-lock +## Getting Started -HW wallets usually auto-lock if idle for some time. This makes sense of course (otherwise, if left unlocked and unattended, it could be used by any stranger or intruder to steal your funds). +To use a hardware wallet with Beam: -However in Beam the HW wallet is used not only to send funds, but also to receive. Hence the desktop wallet won't be able to receive funds while the device is locked. Our desktop wallet (both CLI and UI) gives an appropriate message if it can't access the HW wallet, and if/when the user unlocks it - the transaction will proceed. But if the user is not around then there will be no one to unlock the device, and all transactions will end stuck. +1. Make sure you have the **latest version** of the Beam Desktop or CLI wallet installed. +2. Connect your hardware device to your computer. +3. The Beam wallet should automatically detect and communicate with it — no extra configuration is required on **Windows**, **macOS**, or **Linux**. -At the moment we recommend the following options: +> 🐧 **Linux users:** You may need to set appropriate USB permissions to allow Beam access to your hardware wallet. +> Follow the [Linux setup instructions](https://github.com/BeamMW/app-beam/files/10475866/ledger-hid.zip) to install the necessary udev rules. -Receiver: if you don't expect to receive eventual transactions, then we recommend keeping the auto-lock feature. If, however, you prefer to be able to receive transactions constantly, then consider disabling the auto-lock feature. +--- -Sender: If you expect the receiver to be online, then send transactions as usual. Otherwise it's always possible to use offline transactions types (public offline, or max privacy), since those are non-interactive transactions, and the receiver is not involved. +## Installation & Setup Guides +- [**Ledger Setup Guide →**](./Ledger.md) + Learn how to install the Beam app on Ledger devices, including sideloading instructions and device-specific notes. -### Installation - Trezor +- [**Trezor Setup Guide →**](./Trezor.md) + Step-by-step guide to preparing and using Trezor devices with Beam. +--- -### Install **Git** and **Python3** (with pip3) -- Debain/Ubuntu: `sudo apt-get -y install git python3 python3-pip` -- Windows/MacOS: download from https://www.python.org/downloads +## Usage Notes -### Install Trezor Bridge -Go to https://wallet.trezor.io/#/bridge, download and install. +Hardware wallets are used in Beam not only for **sending**, but also for **receiving** transactions. +If your hardware device **auto-locks**, Beam will not be able to process incoming transactions until you unlock it. -### Install Protobuf Compiler -Go to https://github.com/protocolbuffers/protobuf/releases and download the latest `protoc` for your OS. -Extract it and add `/bin` path to the system `PATH`: `export PATH=$PATH://bin`. +### Recommendations +- **Receiver:** + If you expect to receive transactions continuously, consider disabling auto-lock temporarily. + Otherwise, keep it enabled for security. -### Build Firmware Loader -Run the following commands (don't use `sudo` prefix on Windows): -``` -git clone https://github.com/BeamMW/python-trezor.git -cd python-trezor -git checkout beam -git submodule update --init --recursive --force +- **Sender:** + Use standard transactions when the receiver is online. + If not, use **offline** or **max privacy** transaction types — these are non-interactive and do not require the receiver’s participation. -sudo pip3 install protobuf click requests mnemonic construct ecdsa pyblake2 typing_extensions -python3 setup.py prebuild -``` +--- -## Install the firmware -- Wipe your Trezor device using `python3 ./trezorctl wipe-device` command. -- Go to https://github.com/BeamMW/trezor_beam_minimal_wallet/releases and download the latest `firmware.bin`. -- Restart the device to enter bootloader mode (video how to do it https://www.youtube.com/watch?v=xVBiSFTx0qQ). -- Call `python3 ./trezorctl firmware-update -f /firmware.bin` to install firmware. -### Windows -- Install `trezorctl` https://wiki.trezor.io/Installing_trezorctl_on_Windows . -- Restart the device to enter bootloader mode (video how to do it https://www.youtube.com/watch?v=xVBiSFTx0qQ). -- Call `trezorctl firmware-update -f /firmware.bin` to install firmware. +## Learn More -## Test Beam with Trezor -- Go to https://builds.beam.mw/#trezor_build and download/install the latest build. -- Connect your device, go to https://trezor.io/start, create a new wallet or recover with your seed phrase. -- Run installed **Beam Wallet** and push `create new Trezor wallet` button. -- Agree with generating **Owner Key** on Trezor device and wait, it usually takes about 15 sec. -![image](https://user-images.githubusercontent.com/1101448/65770926-c5d87f80-e13f-11e9-9095-a9fbac692917.png) -- Remember generated password from the `Key Password` page and enter it in the Beam Wallet. -![image](https://user-images.githubusercontent.com/1101448/65770789-7e51f380-e13f-11e9-899e-33dc09d96787.png) -- Hurray, the wallet is initialized, now try to send/receive beams to test how it works... +- [Beam Wallet Downloads](https://beam.mw/downloads) +- [Beam GitHub Organization](https://github.com/BeamMW) +- [Telegram](https://t.me/BeamPrivacy) diff --git a/hardware-wallet/Trezor.md b/hardware-wallet/Trezor.md new file mode 100644 index 0000000..798d61f --- /dev/null +++ b/hardware-wallet/Trezor.md @@ -0,0 +1,86 @@ +--- +description: Trezor Hardware Wallet support +--- + +# Trezor + +We currently do not support smart contract transactions for the Hardware Wallets. + + +### Trezor + +According to Trezor they don't consider accepting new coins (not clones of existing ones) to their official release. +Currently we investigate the possibility to add our app to an unofficial release. + +# Instructions for the host machine + +We support Linux, Windows and Mac, i.e. all the platforms on which the Beam Wallet is already supported. No additional tools/prerequisites are required. Just plug the HW wallet, it should be detected by our desktop wallet automatically. + +### Note for Linux users +On Linux, however, the Beam desktop wallet should have appropriate permissions to connect to the HW wallet. + +Desktop wallet can be run with elevated privileges (`sudo`) but this is not recommended. Instead it's possible to enable device access for all the users in the system. +To allow this the following file should be downloaded, and copied `/etc/udev/rules.d` into directory. After the device is re-plugged the new permissions should be in effect. + + +### Installation + + +### Install **Git** and **Python3** (with pip3) +- Debain/Ubuntu: `sudo apt-get -y install git python3 python3-pip` +- Windows/MacOS: download from https://www.python.org/downloads + +### Install Trezor Bridge +Go to https://wallet.trezor.io/#/bridge, download and install. + +### Install Protobuf Compiler +Go to https://github.com/protocolbuffers/protobuf/releases and download the latest `protoc` for your OS. +Extract it and add `/bin` path to the system `PATH`: `export PATH=$PATH://bin`. + + +### Build Firmware Loader +Run the following commands (don't use `sudo` prefix on Windows): +``` +git clone https://github.com/BeamMW/python-trezor.git +cd python-trezor +git checkout beam +git submodule update --init --recursive --force + +sudo pip3 install protobuf click requests mnemonic construct ecdsa pyblake2 typing_extensions +python3 setup.py prebuild +``` + +## Install the firmware +- Wipe your Trezor device using `python3 ./trezorctl wipe-device` command. +- Go to https://github.com/BeamMW/trezor_beam_minimal_wallet/releases and download the latest `firmware.bin`. +- Restart the device to enter bootloader mode (video how to do it https://www.youtube.com/watch?v=xVBiSFTx0qQ). +- Call `python3 ./trezorctl firmware-update -f /firmware.bin` to install firmware. +### Windows +- Install `trezorctl` https://wiki.trezor.io/Installing_trezorctl_on_Windows . +- Restart the device to enter bootloader mode (video how to do it https://www.youtube.com/watch?v=xVBiSFTx0qQ). +- Call `trezorctl firmware-update -f /firmware.bin` to install firmware. + +## Test Beam with Trezor +- Go to https://builds.beam.mw/#trezor_build and download/install the latest build. +- Connect your device, go to https://trezor.io/start, create a new wallet or recover with your seed phrase. +- Run installed **Beam Wallet** and push `create new Trezor wallet` button. +- Agree with generating **Owner Key** on Trezor device and wait, it usually takes about 15 sec. +![image](https://user-images.githubusercontent.com/1101448/65770926-c5d87f80-e13f-11e9-9095-a9fbac692917.png) +- Remember generated password from the `Key Password` page and enter it in the Beam Wallet. +![image](https://user-images.githubusercontent.com/1101448/65770789-7e51f380-e13f-11e9-899e-33dc09d96787.png) +- Hurray, the wallet is initialized, now try to send/receive beams to test how it works... + + +# Usage + +## Implications of device auto-lock + +HW wallets usually auto-lock if idle for some time. This makes sense of course (otherwise, if left unlocked and unattended, it could be used by any stranger or intruder to steal your funds). + +However in Beam the HW wallet is used not only to send funds, but also to receive. Hence the desktop wallet won't be able to receive funds while the device is locked. Our desktop wallet (both CLI and UI) gives an appropriate message if it can't access the HW wallet, and if/when the user unlocks it - the transaction will proceed. But if the user is not around then there will be no one to unlock the device, and all transactions will end stuck. + +At the moment we recommend the following options: + +Receiver: if you don't expect to receive eventual transactions, then we recommend keeping the auto-lock feature. If, however, you prefer to be able to receive transactions constantly, then consider disabling the auto-lock feature. + +Sender: If you expect the receiver to be online, then send transactions as usual. Otherwise it's always possible to use offline transactions types (public offline, or max privacy), since those are non-interactive transactions, and the receiver is not involved. \ No newline at end of file From e0064e230bd7666a158b9691cc0636b2af2e966c Mon Sep 17 00:00:00 2001 From: Maxnflaxl <63856008+Maxnflaxl@users.noreply.github.com> Date: Thu, 6 Nov 2025 17:58:01 +0100 Subject: [PATCH 03/11] upd mining --- mining/pool-mining-beam.md | 19 +++++++------------ mining/solo-mining-beam.md | 6 +++--- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/mining/pool-mining-beam.md b/mining/pool-mining-beam.md index 68d9d26..fa35956 100644 --- a/mining/pool-mining-beam.md +++ b/mining/pool-mining-beam.md @@ -1,6 +1,6 @@ # Pool Mining Beam -If you decide to participate in a Beam mining pool, you will need to select a mining pool (you can find a complete list on our [website](/mining)) and determine which mining pool best suits your needs. When selecting your pool, it is essential to consider the geographic locations, fee, hash rate, and user experience. +If you decide to participate in a Beam mining pool, you will need to select a mining [pool](https://miningpoolstats.stream/beam) and determine which mining pool best suits your needs. When selecting your pool, it is essential to consider the geographic locations, fee, hash rate, and user experience. https://www.youtube.com/watch?v=sM0SCGw8Puo @@ -9,20 +9,15 @@ https://www.youtube.com/watch?v=sM0SCGw8Puo * Mining rig containing at least one GPU with a minimum of 3GB RAM. * Basic knowledge of command line (CMD terminal) functions. * High-speed internet connection. -* A [mining](/mining) pool. -* [Mining](pool-mining-beam.md#mining-software) software. +* A mining [pool](https://miningpoolstats.stream/beam). +* Mining software, e.g., [lolMiner](https://github.com/Lolliedieb/lolMiner-releases). -Launch a CMD Prompt (Windows) or Terminal Window (Linux and macOS) on your mining rig to get your miner running. Each mining software will contain specific operational commands for the Command Line. Choose the mining software that best suits your needs. ## Mining Software -Available 3rd Party Mining Software and configuration guides for Beam: +Download [lolMiner](https://github.com/Lolliedieb/lolMiner-releases) -* [lolMiner](https://github.com/Lolliedieb/lolMiner-releases) -* [MiniZ](https://miniz.ch/) -* [Gminer](https://gminer.ac/en/home/) -* [Bminer](https://www.bminer.me/) - - -The miner software listed and linked above is used at your discretion and risk. Beam accepts no liability for any misuse or error caused by the above mining software. Users must do their research before deciding on which 3rd party software to use for mining. +You can find a ``mine_beam.bat`` for Windows and a ``mine-beam.sh`` for Linux in the lolMiner download. +Make sure to use a SBBS address for mining and have your Beam Wallet open when the mining pool sends the rewards. +The miner software listed and linked above is used at your discretion and risk. Beam accepts no liability for any misuse or error caused by the above mining software. Users must do their research on the 3rd party software they use for mining. diff --git a/mining/solo-mining-beam.md b/mining/solo-mining-beam.md index 035d1c2..cb9d3e2 100644 --- a/mining/solo-mining-beam.md +++ b/mining/solo-mining-beam.md @@ -13,7 +13,7 @@ Mining Beam coins is the best way to support Beam! Miners strengthen the securit ## **Part one: installation** -Download `Beam-Wallet-CLI` and `Beam-Node` files directly from our main [website](/downloads). +Download `Command Line Interface` and `Node` files directly from our main [website](/downloads). ‌Extract these files in a separate folder on your 'always-on PC' (or whichever device is running your Node) and label the folder as `beam-mining`. @@ -87,7 +87,7 @@ Add the following parameters (one per line) to your `beam-node.cfg` file: port=10000 log_level=verbose file_log_level=verbose -peer=eu-nodes.mainnet.beam.mw:8100,us-nodes.mainnet.beam.mw:8100,ap-nodes.mainnet.beam.mw:8100,ap-hk-nodes.mainnet.beam.mw:8100,shanghai-node.mainnet.beam.mw:8100 +peer=eu-nodes.mainnet.beam.mw:8100,us-nodes.mainnet.beam.mw:8100 stratum_port=3333 stratum_secrets_path=. ``` @@ -119,7 +119,7 @@ Your mining rig can use your node's IP address and stratum port to begin solo mi Using [lolMiner](https://github.com/Lolliedieb/lolMiner-releases) as an example, the command output is similar to the following: ``` -./lolMiner --coin BEAM --pool 127.0.0.1:3333 --user yourwalletaddress +./lolMiner --coin BEAM --pool 127.0.0.1:3333 --user your-SBBS-address ``` After you mine a block, your block rewards will show up in your wallet summary. From addccfbd7aadd9517bd86e7b834e463c28fc83d1 Mon Sep 17 00:00:00 2001 From: Maxnflaxl Date: Fri, 17 Apr 2026 03:04:20 +0200 Subject: [PATCH 04/11] overhaul core docs --- .../.gitbook/assets/SimpleTransactionFlow.png | Bin 42288 -> 0 bytes core-tech/.gitbook/assets/dmmr1.png | Bin 8058 -> 0 bytes core-tech/.gitignore | 1 + core-tech/AVX.md | 8 - ...ing-support-for-Beam-Confidential-Asset.md | 294 -- core-tech/Addresses-in-Beam.md | 259 -- core-tech/Atomic-swap-token.md | 41 - core-tech/Atomic-swap.md | 149 - ...ion-control-and-signatures-in-contracts.md | 131 - core-tech/BEAM-IPFS-Support.md | 189 +- core-tech/BEAM-Mining.md | 2 +- core-tech/Beam-Cpp-Style-And-Conventions.md | 389 +++ core-tech/Beam-Equihash-specification.md | 15 - core-tech/Beam-Node-Explorer-API.md | 243 -- core-tech/Beam-Technical-Specifications.md | 2 - core-tech/Beam-Wallet-Database.md | 100 - core-tech/Beam-Web-Wallet-Starter-Kit.md | 2 - core-tech/Beam-news-channels.md | 150 +- core-tech/Beam-signature-schemes.md | 102 - .../Beam-wallet-protocol-SWAP-API-(BETA).md | 413 --- ...Concept,-relevant-structures-and-values.md | 95 - ...Cold-wallet-implementation-(DEPRECATED).md | 71 - core-tech/Confidential-assets-(historical).md | 74 - core-tech/Confidential-assets.md | 321 --- core-tech/Contribution-Guidelines.md | 32 +- core-tech/Core-transaction-elements.md | 138 - core-tech/Cryptographic-primitives.md | 90 - core-tech/DMMR-internal-layout.md | 49 - core-tech/Exchange-Pool-integration-guide.md | 2 +- core-tech/Folder-and-file-locations.md | 3 + ...HW-wallet-requirements----DEPRECATED---.md | 165 -- core-tech/Hi-Frequency-transactions.md | 30 - core-tech/Home.md | 158 ++ core-tech/How-to-build(old).md | 278 -- core-tech/How-to-build.md | 25 +- ...he-Desktop-Wallet-files-in-a-manual-way.md | 28 - .../How-to-test-Beam-with-Trezor-wallet.md | 2 +- .../Instructions-for-Command-Line-Node.md | 143 - .../Instructions-for-Command-Line-Wallet.md | 101 - core-tech/Laser-BEAM-commands.md | 69 - core-tech/Lelantus-CLI.md | 93 - core-tech/Lelantus-MW.md | 200 -- core-tech/Lightning-Network.md | 307 -- ...in-wallet-entities-and-their-attributes.md | 94 - core-tech/Merkle-trees.md | 99 - core-tech/Mining-Difficulty.md | 30 - core-tech/New-address-types-support.md | 285 -- ...de-initial-synchronization-(DEPRECATED).md | 61 - ...One-side-payments-(take-2)---DEPRECATED.md | 24 - .../Programming-Beam-Terms-and-Concepts.md | 63 - .../Programming-Beam-Wallet-Transactions.md | 93 - core-tech/Programming-Beam-Wallet.md | 31 - core-tech/Programming-Beam.md | 15 - core-tech/Proposal-for-I-O-layer-and-P2P.md | 53 - core-tech/README.md | 75 - .../Secure-bulletin-board-system-(SBBS).md | 72 - core-tech/System-state-in-depth.md | 63 - ...Testing-Beam-Hard-Fork-on-Local-Testnet.md | 12 - core-tech/Transaction-creation-protocol.md | 135 - core-tech/Transaction-graph-obfuscation.md | 77 - .../UTXO-set,-horizons-and-cut-through.md | 156 -- core-tech/WASM-wallet-client.md | 72 +- core-tech/_Sidebar.md | 68 + core-tech/api/Beam-Node-Explorer-API.md | 557 ++++ .../Beam-mining-protocol-API-(Stratum).md | 0 core-tech/api/Beam-wallet-api-versioning.md | 163 ++ .../Beam-wallet-protocol-API-v6.0.md | 0 .../Beam-wallet-protocol-API-v6.1.md | 0 .../Beam-wallet-protocol-API-v6.2.md | 0 .../Beam-wallet-protocol-API-v7.0.md | 0 .../Beam-wallet-protocol-API-v7.1.md | 0 .../Beam-wallet-protocol-API-v7.2.md | 0 .../Beam-wallet-protocol-API-v7.3.md | 65 + .../api/Beam-wallet-protocol-API-v7.4.md | 2493 +++++++++++++++++ .../{ => api}/Beam-wallet-protocol-API.md | 1 + core-tech/bvm/BVM-AddSig.md | 17 + core-tech/bvm/BVM-AssetCreate.md | 20 + core-tech/bvm/BVM-AssetDestroy.md | 19 + core-tech/bvm/BVM-AssetEmit.md | 23 + .../BVM-Beam-Confidential-DeFi-Platform.md | 135 + .../BVM-Beam-SDK-Tutorial-(in-progress).md | 224 ++ core-tech/bvm/BVM-Beam-Smart-Contracts.md | 175 ++ core-tech/bvm/BVM-Building-Beam-Shaders.md | 15 + core-tech/bvm/BVM-CallFar.md | 22 + core-tech/bvm/BVM-Comm_Listen.md | 20 + core-tech/bvm/BVM-Comm_Read.md | 22 + core-tech/bvm/BVM-Comm_Send.md | 20 + core-tech/bvm/BVM-Comm_WaitMsg.md | 18 + core-tech/bvm/BVM-DerivePk.md | 29 + core-tech/bvm/BVM-DocAddArray.md | 24 + core-tech/bvm/BVM-DocAddBlob.md | 29 + core-tech/bvm/BVM-DocAddGroup.md | 24 + core-tech/bvm/BVM-DocAddNum32.md | 25 + core-tech/bvm/BVM-DocAddNum64.md | 25 + core-tech/bvm/BVM-DocAddText.md | 25 + core-tech/bvm/BVM-DocCloseArray.md | 24 + core-tech/bvm/BVM-DocCloseGroup.md | 24 + core-tech/bvm/BVM-DocGetBlob.md | 35 + core-tech/bvm/BVM-DocGetNum32.md | 25 + core-tech/bvm/BVM-DocGetNum64.md | 25 + core-tech/bvm/BVM-DocGetText.md | 30 + core-tech/bvm/BVM-EVM-Integration.md | 248 ++ core-tech/bvm/BVM-EmitLog.md | 23 + core-tech/bvm/BVM-FundsChange.md | 27 + core-tech/bvm/BVM-FundsLock.md | 18 + core-tech/bvm/BVM-FundsUnlock.md | 18 + core-tech/bvm/BVM-GenerateKernel.md | 42 + core-tech/bvm/BVM-GenerateKernelAdvanced.md | 66 + core-tech/bvm/BVM-GenerateRandom.md | 19 + core-tech/bvm/BVM-Halt.md | 17 + core-tech/bvm/BVM-HashClone.md | 18 + core-tech/bvm/BVM-HashCreateBlake2b.md | 21 + core-tech/bvm/BVM-HashCreateKeccak.md | 19 + core-tech/bvm/BVM-HashCreateSha256.md | 19 + core-tech/bvm/BVM-HashFree.md | 19 + core-tech/bvm/BVM-HashGetValue.md | 22 + core-tech/bvm/BVM-HashWrite.md | 20 + core-tech/bvm/BVM-Heap_Alloc.md | 19 + core-tech/bvm/BVM-Heap_Free.md | 19 + core-tech/bvm/BVM-Internals.md | 428 +++ core-tech/bvm/BVM-KeyTag.md | 35 + core-tech/bvm/BVM-LoadVar.md | 22 + core-tech/bvm/BVM-LoadVarEx.md | 30 + core-tech/bvm/BVM-LogGetProof.md | 18 + core-tech/bvm/BVM-Logs_Close.md | 17 + core-tech/bvm/BVM-Logs_Enum.md | 22 + core-tech/bvm/BVM-Logs_MoveNext.md | 27 + core-tech/bvm/BVM-Memcmp.md | 21 + core-tech/bvm/BVM-Memcpy.md | 28 + core-tech/bvm/BVM-Memis0.md | 19 + core-tech/bvm/BVM-Memset.md | 19 + core-tech/bvm/BVM-RefAdd.md | 17 + core-tech/bvm/BVM-RefRelease.md | 17 + ...M-Running-Beam-Shaders-using-CLI-Wallet.md | 29 + core-tech/bvm/BVM-SaveVar.md | 24 + core-tech/bvm/BVM-Secp_Point_Export.md | 19 + core-tech/bvm/BVM-Secp_Point_Import.md | 20 + core-tech/bvm/BVM-Secp_Point_IsZero.md | 18 + core-tech/bvm/BVM-Secp_Point_add.md | 19 + core-tech/bvm/BVM-Secp_Point_alloc.md | 18 + core-tech/bvm/BVM-Secp_Point_free.md | 17 + core-tech/bvm/BVM-Secp_Point_mul.md | 19 + core-tech/bvm/BVM-Secp_Point_mul_G.md | 18 + core-tech/bvm/BVM-Secp_Point_mul_H.md | 19 + core-tech/bvm/BVM-Secp_Point_mul_J.md | 18 + core-tech/bvm/BVM-Secp_Point_neg.md | 18 + core-tech/bvm/BVM-Secp_Scalar_add.md | 19 + core-tech/bvm/BVM-Secp_Scalar_alloc.md | 18 + core-tech/bvm/BVM-Secp_Scalar_export.md | 18 + core-tech/bvm/BVM-Secp_Scalar_free.md | 17 + core-tech/bvm/BVM-Secp_Scalar_import.md | 19 + core-tech/bvm/BVM-Secp_Scalar_inv.md | 21 + core-tech/bvm/BVM-Secp_Scalar_mul.md | 19 + core-tech/bvm/BVM-Secp_Scalar_neg.md | 18 + core-tech/bvm/BVM-Secp_Scalar_set.md | 19 + core-tech/bvm/BVM-SelectContext.md | 18 + core-tech/bvm/BVM-Shader-Development.md | 594 ++++ core-tech/bvm/BVM-Shader-SDK-Index.md | 11 + core-tech/bvm/BVM-SigRequest.md | 18 + core-tech/bvm/BVM-SlotInit.md | 19 + core-tech/bvm/BVM-StackAlloc.md | 17 + core-tech/bvm/BVM-StackFree.md | 19 + core-tech/bvm/BVM-Strcmp.md | 21 + core-tech/bvm/BVM-Strlen.md | 17 + core-tech/bvm/BVM-Tutorial-README.md | 9 + core-tech/bvm/BVM-Tutorial-concepts.md | 47 + core-tech/bvm/BVM-Tutorial-write-app.md | 50 + core-tech/bvm/BVM-Tutorial-write-contract.md | 80 + core-tech/bvm/BVM-UpdateShader.md | 18 + core-tech/bvm/BVM-VarGetProof.md | 22 + core-tech/bvm/BVM-Vars_Close.md | 17 + core-tech/bvm/BVM-Vars_Enum.md | 20 + core-tech/bvm/BVM-Vars_MoveNext.md | 25 + core-tech/bvm/BVM-VerifyBeamHashIII.md | 24 + core-tech/bvm/BVM-Write.md | 22 + core-tech/bvm/BVM-functions-for-shaders.md | 260 ++ core-tech/bvm/BVM-get_BlindSk.md | 24 + core-tech/bvm/BVM-get_CallDepth.md | 17 + core-tech/bvm/BVM-get_CallerCid.md | 19 + core-tech/bvm/BVM-get_HdrFull.md | 18 + core-tech/bvm/BVM-get_HdrInfo.md | 18 + core-tech/bvm/BVM-get_Height.md | 17 + core-tech/bvm/BVM-get_Pk.md | 20 + core-tech/bvm/BVM-get_PkEx.md | 21 + core-tech/bvm/BVM-get_RulesCfg.md | 18 + core-tech/bvm/BVM-get_SlotImage.md | 19 + core-tech/bvm/BVM-get_SlotImageEx.md | 20 + .../consensus/Consensus-Beam-Warp-dPoS.md | 289 ++ core-tech/consensus/Consensus-BeamHash.md | 137 + core-tech/consensus/Consensus-Hard-Forks.md | 215 ++ core-tech/core/Core-Block-And-Chain-State.md | 409 +++ .../core/Core-Cryptographic-Primitives.md | 434 +++ core-tech/core/Core-Merkle-Structures.md | 228 ++ core-tech/core/Core-transaction-elements.md | 381 +++ ...0-Upgrade-Guide-for-pools-and-exchanges.md | 4 +- ...0-Upgrade-Guide-for-pools-and-exchanges.md | 4 +- .../{ => historical}/Beam-Position-Paper.md | 2 + .../{ => historical}/BeamX-Getting-Started.md | 5 +- .../Ethash-verification-in-contracts.md | 2 + .../Lelantus-CLI-(historical,-below-v6.0).md | 4 +- .../{ => historical}/One-side-payments.md | 2 + .../{ => historical}/Out-of-sync-wallets.md | 2 + .../Payment-confirmation-(proof).md | 2 + .../Proposal-for-I-O-layer-and-P2P.md | 52 + core-tech/{ => historical}/Rescan-offline.md | 2 + ...ting-up-read-only-wallet-for-monitoring.md | 1 + ...dia-cards-for-mining-using-OpenCL-miner.md | 2 + .../Testnet-Command-Line-Instructions.md | 2 + ...s-about-eliminating-transaction-kernels.md | 2 + ...n-ordering-and-front-running-protection.md | 2 + ...ocking-subsequent-outgoing-transactions.md | 2 +- ...g-BeamX-Faucet-contract-with-CLI-Wallet.md | 2 + ...BeamX-Roulette-contract-with-CLI-Wallet.md | 2 + ...ng-BeamX-Vault-contract-with-CLI-Wallet.md | 2 + .../Wallets-discovery-and-dialog-proposal.md | 2 + core-tech/node/Node-Architecture.md | 415 +++ core-tech/node/Node-Fly-Client-Protocol.md | 241 ++ core-tech/node/Node-Mining-Modes.md | 196 ++ core-tech/node/Node-P2P-Protocol.md | 423 +++ .../Node-standard-operation-mode.md | 0 .../transactions/Transactions-Assets-Swaps.md | 205 ++ .../transactions/Transactions-Atomic-Swaps.md | 259 ++ .../Transactions-Confidential-Assets.md | 499 ++++ .../Transactions-Creation-Protocol.md | 378 +++ .../transactions/Transactions-Hi-Frequency.md | 273 ++ .../Transactions-Laser-Channels.md | 566 ++++ .../Transactions-Lelantus-Shielded-Pool.md | 449 +++ ...s-with-Beam-Wallet-CLI-over-TOR-network.md | 0 .../Wallet-Addresses-And-Key-Derivation.md | 381 +++ core-tech/wallet/Wallet-Architecture.md | 298 ++ core-tech/wallet/Wallet-Database-Schema.md | 340 +++ core-tech/wallet/Wallet-Key-Keeper.md | 234 ++ core-tech/wallet/Wallet-SBBS.md | 322 +++ core-tech/{ => wallet}/Wallet-Service.md | 0 core-tech/{ => wallet}/Wallet-audit.md | 0 core-tech/{ => wallet}/Wallet-requirements.md | 0 236 files changed, 16286 insertions(+), 5618 deletions(-) delete mode 100644 core-tech/.gitbook/assets/SimpleTransactionFlow.png delete mode 100644 core-tech/.gitbook/assets/dmmr1.png delete mode 100644 core-tech/AVX.md delete mode 100644 core-tech/Adding-support-for-Beam-Confidential-Asset.md delete mode 100644 core-tech/Addresses-in-Beam.md delete mode 100644 core-tech/Atomic-swap-token.md delete mode 100644 core-tech/Atomic-swap.md delete mode 100644 core-tech/Authorization-control-and-signatures-in-contracts.md create mode 100644 core-tech/Beam-Cpp-Style-And-Conventions.md delete mode 100644 core-tech/Beam-Equihash-specification.md delete mode 100644 core-tech/Beam-Node-Explorer-API.md delete mode 100644 core-tech/Beam-Wallet-Database.md delete mode 100644 core-tech/Beam-signature-schemes.md delete mode 100644 core-tech/Beam-wallet-protocol-SWAP-API-(BETA).md delete mode 100644 core-tech/Blocks,-headers,-system-states.-Concept,-relevant-structures-and-values.md delete mode 100644 core-tech/Cold-wallet-implementation-(DEPRECATED).md delete mode 100644 core-tech/Confidential-assets-(historical).md delete mode 100644 core-tech/Confidential-assets.md delete mode 100644 core-tech/Core-transaction-elements.md delete mode 100644 core-tech/Cryptographic-primitives.md delete mode 100644 core-tech/DMMR-internal-layout.md delete mode 100644 core-tech/HW-wallet-requirements----DEPRECATED---.md delete mode 100644 core-tech/Hi-Frequency-transactions.md create mode 100644 core-tech/Home.md delete mode 100644 core-tech/How-to-build(old).md delete mode 100644 core-tech/How-to-remove-the-Desktop-Wallet-files-in-a-manual-way.md delete mode 100644 core-tech/Instructions-for-Command-Line-Node.md delete mode 100644 core-tech/Instructions-for-Command-Line-Wallet.md delete mode 100644 core-tech/Laser-BEAM-commands.md delete mode 100644 core-tech/Lelantus-CLI.md delete mode 100644 core-tech/Lelantus-MW.md delete mode 100644 core-tech/Lightning-Network.md delete mode 100644 core-tech/Main-wallet-entities-and-their-attributes.md delete mode 100644 core-tech/Merkle-trees.md delete mode 100644 core-tech/Mining-Difficulty.md delete mode 100644 core-tech/New-address-types-support.md delete mode 100644 core-tech/Node-initial-synchronization-(DEPRECATED).md delete mode 100644 core-tech/One-side-payments-(take-2)---DEPRECATED.md delete mode 100644 core-tech/Programming-Beam-Terms-and-Concepts.md delete mode 100644 core-tech/Programming-Beam-Wallet-Transactions.md delete mode 100644 core-tech/Programming-Beam-Wallet.md delete mode 100644 core-tech/Programming-Beam.md delete mode 100644 core-tech/Proposal-for-I-O-layer-and-P2P.md delete mode 100644 core-tech/README.md delete mode 100644 core-tech/Secure-bulletin-board-system-(SBBS).md delete mode 100644 core-tech/System-state-in-depth.md delete mode 100644 core-tech/Testing-Beam-Hard-Fork-on-Local-Testnet.md delete mode 100644 core-tech/Transaction-creation-protocol.md delete mode 100644 core-tech/Transaction-graph-obfuscation.md delete mode 100644 core-tech/UTXO-set,-horizons-and-cut-through.md create mode 100644 core-tech/_Sidebar.md create mode 100644 core-tech/api/Beam-Node-Explorer-API.md rename core-tech/{ => api}/Beam-mining-protocol-API-(Stratum).md (100%) create mode 100644 core-tech/api/Beam-wallet-api-versioning.md rename core-tech/{ => api}/Beam-wallet-protocol-API-v6.0.md (100%) rename core-tech/{ => api}/Beam-wallet-protocol-API-v6.1.md (100%) rename core-tech/{ => api}/Beam-wallet-protocol-API-v6.2.md (100%) rename core-tech/{ => api}/Beam-wallet-protocol-API-v7.0.md (100%) rename core-tech/{ => api}/Beam-wallet-protocol-API-v7.1.md (100%) rename core-tech/{ => api}/Beam-wallet-protocol-API-v7.2.md (100%) rename core-tech/{ => api}/Beam-wallet-protocol-API-v7.3.md (97%) create mode 100644 core-tech/api/Beam-wallet-protocol-API-v7.4.md rename core-tech/{ => api}/Beam-wallet-protocol-API.md (99%) create mode 100644 core-tech/bvm/BVM-AddSig.md create mode 100644 core-tech/bvm/BVM-AssetCreate.md create mode 100644 core-tech/bvm/BVM-AssetDestroy.md create mode 100644 core-tech/bvm/BVM-AssetEmit.md create mode 100644 core-tech/bvm/BVM-Beam-Confidential-DeFi-Platform.md create mode 100644 core-tech/bvm/BVM-Beam-SDK-Tutorial-(in-progress).md create mode 100644 core-tech/bvm/BVM-Beam-Smart-Contracts.md create mode 100644 core-tech/bvm/BVM-Building-Beam-Shaders.md create mode 100644 core-tech/bvm/BVM-CallFar.md create mode 100644 core-tech/bvm/BVM-Comm_Listen.md create mode 100644 core-tech/bvm/BVM-Comm_Read.md create mode 100644 core-tech/bvm/BVM-Comm_Send.md create mode 100644 core-tech/bvm/BVM-Comm_WaitMsg.md create mode 100644 core-tech/bvm/BVM-DerivePk.md create mode 100644 core-tech/bvm/BVM-DocAddArray.md create mode 100644 core-tech/bvm/BVM-DocAddBlob.md create mode 100644 core-tech/bvm/BVM-DocAddGroup.md create mode 100644 core-tech/bvm/BVM-DocAddNum32.md create mode 100644 core-tech/bvm/BVM-DocAddNum64.md create mode 100644 core-tech/bvm/BVM-DocAddText.md create mode 100644 core-tech/bvm/BVM-DocCloseArray.md create mode 100644 core-tech/bvm/BVM-DocCloseGroup.md create mode 100644 core-tech/bvm/BVM-DocGetBlob.md create mode 100644 core-tech/bvm/BVM-DocGetNum32.md create mode 100644 core-tech/bvm/BVM-DocGetNum64.md create mode 100644 core-tech/bvm/BVM-DocGetText.md create mode 100644 core-tech/bvm/BVM-EVM-Integration.md create mode 100644 core-tech/bvm/BVM-EmitLog.md create mode 100644 core-tech/bvm/BVM-FundsChange.md create mode 100644 core-tech/bvm/BVM-FundsLock.md create mode 100644 core-tech/bvm/BVM-FundsUnlock.md create mode 100644 core-tech/bvm/BVM-GenerateKernel.md create mode 100644 core-tech/bvm/BVM-GenerateKernelAdvanced.md create mode 100644 core-tech/bvm/BVM-GenerateRandom.md create mode 100644 core-tech/bvm/BVM-Halt.md create mode 100644 core-tech/bvm/BVM-HashClone.md create mode 100644 core-tech/bvm/BVM-HashCreateBlake2b.md create mode 100644 core-tech/bvm/BVM-HashCreateKeccak.md create mode 100644 core-tech/bvm/BVM-HashCreateSha256.md create mode 100644 core-tech/bvm/BVM-HashFree.md create mode 100644 core-tech/bvm/BVM-HashGetValue.md create mode 100644 core-tech/bvm/BVM-HashWrite.md create mode 100644 core-tech/bvm/BVM-Heap_Alloc.md create mode 100644 core-tech/bvm/BVM-Heap_Free.md create mode 100644 core-tech/bvm/BVM-Internals.md create mode 100644 core-tech/bvm/BVM-KeyTag.md create mode 100644 core-tech/bvm/BVM-LoadVar.md create mode 100644 core-tech/bvm/BVM-LoadVarEx.md create mode 100644 core-tech/bvm/BVM-LogGetProof.md create mode 100644 core-tech/bvm/BVM-Logs_Close.md create mode 100644 core-tech/bvm/BVM-Logs_Enum.md create mode 100644 core-tech/bvm/BVM-Logs_MoveNext.md create mode 100644 core-tech/bvm/BVM-Memcmp.md create mode 100644 core-tech/bvm/BVM-Memcpy.md create mode 100644 core-tech/bvm/BVM-Memis0.md create mode 100644 core-tech/bvm/BVM-Memset.md create mode 100644 core-tech/bvm/BVM-RefAdd.md create mode 100644 core-tech/bvm/BVM-RefRelease.md create mode 100644 core-tech/bvm/BVM-Running-Beam-Shaders-using-CLI-Wallet.md create mode 100644 core-tech/bvm/BVM-SaveVar.md create mode 100644 core-tech/bvm/BVM-Secp_Point_Export.md create mode 100644 core-tech/bvm/BVM-Secp_Point_Import.md create mode 100644 core-tech/bvm/BVM-Secp_Point_IsZero.md create mode 100644 core-tech/bvm/BVM-Secp_Point_add.md create mode 100644 core-tech/bvm/BVM-Secp_Point_alloc.md create mode 100644 core-tech/bvm/BVM-Secp_Point_free.md create mode 100644 core-tech/bvm/BVM-Secp_Point_mul.md create mode 100644 core-tech/bvm/BVM-Secp_Point_mul_G.md create mode 100644 core-tech/bvm/BVM-Secp_Point_mul_H.md create mode 100644 core-tech/bvm/BVM-Secp_Point_mul_J.md create mode 100644 core-tech/bvm/BVM-Secp_Point_neg.md create mode 100644 core-tech/bvm/BVM-Secp_Scalar_add.md create mode 100644 core-tech/bvm/BVM-Secp_Scalar_alloc.md create mode 100644 core-tech/bvm/BVM-Secp_Scalar_export.md create mode 100644 core-tech/bvm/BVM-Secp_Scalar_free.md create mode 100644 core-tech/bvm/BVM-Secp_Scalar_import.md create mode 100644 core-tech/bvm/BVM-Secp_Scalar_inv.md create mode 100644 core-tech/bvm/BVM-Secp_Scalar_mul.md create mode 100644 core-tech/bvm/BVM-Secp_Scalar_neg.md create mode 100644 core-tech/bvm/BVM-Secp_Scalar_set.md create mode 100644 core-tech/bvm/BVM-SelectContext.md create mode 100644 core-tech/bvm/BVM-Shader-Development.md create mode 100644 core-tech/bvm/BVM-Shader-SDK-Index.md create mode 100644 core-tech/bvm/BVM-SigRequest.md create mode 100644 core-tech/bvm/BVM-SlotInit.md create mode 100644 core-tech/bvm/BVM-StackAlloc.md create mode 100644 core-tech/bvm/BVM-StackFree.md create mode 100644 core-tech/bvm/BVM-Strcmp.md create mode 100644 core-tech/bvm/BVM-Strlen.md create mode 100644 core-tech/bvm/BVM-Tutorial-README.md create mode 100644 core-tech/bvm/BVM-Tutorial-concepts.md create mode 100644 core-tech/bvm/BVM-Tutorial-write-app.md create mode 100644 core-tech/bvm/BVM-Tutorial-write-contract.md create mode 100644 core-tech/bvm/BVM-UpdateShader.md create mode 100644 core-tech/bvm/BVM-VarGetProof.md create mode 100644 core-tech/bvm/BVM-Vars_Close.md create mode 100644 core-tech/bvm/BVM-Vars_Enum.md create mode 100644 core-tech/bvm/BVM-Vars_MoveNext.md create mode 100644 core-tech/bvm/BVM-VerifyBeamHashIII.md create mode 100644 core-tech/bvm/BVM-Write.md create mode 100644 core-tech/bvm/BVM-functions-for-shaders.md create mode 100644 core-tech/bvm/BVM-get_BlindSk.md create mode 100644 core-tech/bvm/BVM-get_CallDepth.md create mode 100644 core-tech/bvm/BVM-get_CallerCid.md create mode 100644 core-tech/bvm/BVM-get_HdrFull.md create mode 100644 core-tech/bvm/BVM-get_HdrInfo.md create mode 100644 core-tech/bvm/BVM-get_Height.md create mode 100644 core-tech/bvm/BVM-get_Pk.md create mode 100644 core-tech/bvm/BVM-get_PkEx.md create mode 100644 core-tech/bvm/BVM-get_RulesCfg.md create mode 100644 core-tech/bvm/BVM-get_SlotImage.md create mode 100644 core-tech/bvm/BVM-get_SlotImageEx.md create mode 100644 core-tech/consensus/Consensus-Beam-Warp-dPoS.md create mode 100644 core-tech/consensus/Consensus-BeamHash.md create mode 100644 core-tech/consensus/Consensus-Hard-Forks.md create mode 100644 core-tech/core/Core-Block-And-Chain-State.md create mode 100644 core-tech/core/Core-Cryptographic-Primitives.md create mode 100644 core-tech/core/Core-Merkle-Structures.md create mode 100644 core-tech/core/Core-transaction-elements.md rename core-tech/{ => historical}/Beam-Eager-Electron-5.0-Upgrade-Guide-for-pools-and-exchanges.md (79%) rename core-tech/{ => historical}/Beam-Fierce-Fermion-6.0-Upgrade-Guide-for-pools-and-exchanges.md (92%) rename core-tech/{ => historical}/Beam-Position-Paper.md (97%) rename core-tech/{ => historical}/BeamX-Getting-Started.md (93%) rename core-tech/{ => historical}/Ethash-verification-in-contracts.md (97%) rename core-tech/{ => historical}/Lelantus-CLI-(historical,-below-v6.0).md (93%) rename core-tech/{ => historical}/One-side-payments.md (96%) rename core-tech/{ => historical}/Out-of-sync-wallets.md (92%) rename core-tech/{ => historical}/Payment-confirmation-(proof).md (97%) create mode 100644 core-tech/historical/Proposal-for-I-O-layer-and-P2P.md rename core-tech/{ => historical}/Rescan-offline.md (87%) rename core-tech/{ => historical}/Setting-up-read-only-wallet-for-monitoring.md (93%) rename core-tech/{ => historical}/Supported-nVidia-cards-for-mining-using-OpenCL-miner.md (65%) rename core-tech/{ => historical}/Testnet-Command-Line-Instructions.md (98%) rename core-tech/{ => historical}/Thoughts-about-eliminating-transaction-kernels.md (96%) rename core-tech/{ => historical}/Transaction-ordering-and-front-running-protection.md (92%) rename core-tech/{ => historical}/Unblocking-subsequent-outgoing-transactions.md (94%) rename core-tech/{ => historical}/Using-BeamX-Faucet-contract-with-CLI-Wallet.md (97%) rename core-tech/{ => historical}/Using-BeamX-Roulette-contract-with-CLI-Wallet.md (91%) rename core-tech/{ => historical}/Using-BeamX-Vault-contract-with-CLI-Wallet.md (93%) rename core-tech/{ => historical}/Wallets-discovery-and-dialog-proposal.md (97%) create mode 100644 core-tech/node/Node-Architecture.md create mode 100644 core-tech/node/Node-Fly-Client-Protocol.md create mode 100644 core-tech/node/Node-Mining-Modes.md create mode 100644 core-tech/node/Node-P2P-Protocol.md rename core-tech/{ => node}/Node-standard-operation-mode.md (100%) create mode 100644 core-tech/transactions/Transactions-Assets-Swaps.md create mode 100644 core-tech/transactions/Transactions-Atomic-Swaps.md create mode 100644 core-tech/transactions/Transactions-Confidential-Assets.md create mode 100644 core-tech/transactions/Transactions-Creation-Protocol.md create mode 100644 core-tech/transactions/Transactions-Hi-Frequency.md create mode 100644 core-tech/transactions/Transactions-Laser-Channels.md create mode 100644 core-tech/transactions/Transactions-Lelantus-Shielded-Pool.md rename core-tech/{ => transactions}/Transactions-with-Beam-Wallet-CLI-over-TOR-network.md (100%) create mode 100644 core-tech/wallet/Wallet-Addresses-And-Key-Derivation.md create mode 100644 core-tech/wallet/Wallet-Architecture.md create mode 100644 core-tech/wallet/Wallet-Database-Schema.md create mode 100644 core-tech/wallet/Wallet-Key-Keeper.md create mode 100644 core-tech/wallet/Wallet-SBBS.md rename core-tech/{ => wallet}/Wallet-Service.md (100%) rename core-tech/{ => wallet}/Wallet-audit.md (100%) rename core-tech/{ => wallet}/Wallet-requirements.md (100%) diff --git a/core-tech/.gitbook/assets/SimpleTransactionFlow.png b/core-tech/.gitbook/assets/SimpleTransactionFlow.png deleted file mode 100644 index aa9555fe97a3fe2fd8eb42e49f3cfa8ede0cdb72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42288 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 U8h10wxqlYw%Gyew6f9r=A5j7+y#N3J diff --git a/core-tech/.gitbook/assets/dmmr1.png b/core-tech/.gitbook/assets/dmmr1.png deleted file mode 100644 index 8ef38c0a2880324479b1ced2cd4f08fe43b69734..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8058 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 WR~Vq&X(8eMiPuqv+C`eSVgCaw1j)(( diff --git a/core-tech/.gitignore b/core-tech/.gitignore index e69de29..b13ebc3 100644 --- a/core-tech/.gitignore +++ b/core-tech/.gitignore @@ -0,0 +1 @@ +.claude/ \ No newline at end of file diff --git a/core-tech/AVX.md b/core-tech/AVX.md deleted file mode 100644 index c8e5d52..0000000 --- a/core-tech/AVX.md +++ /dev/null @@ -1,8 +0,0 @@ -Advanced Vector Extensions (AVX, also known as Sandy Bridge New Extensions) are extensions to the x86 instruction set architecture for microprocessors from Intel and AMD proposed by Intel in March 2008 and first supported by Intel with the Sandy Bridge processor shipping in Q1 2011 and later on by AMD with the Bulldozer processor shipping in Q3 2011. AVX provides new features, new instructions and a new coding scheme. - -For now we separate our builds in two categories: -* with AVX instructions set -* without AVX instructions set - -If you are not sure is the AVX support at your PC please check description of your processor. -[Example](https://prntscr.com/llj7mj) \ No newline at end of file diff --git a/core-tech/Adding-support-for-Beam-Confidential-Asset.md b/core-tech/Adding-support-for-Beam-Confidential-Asset.md deleted file mode 100644 index 7ed82f4..0000000 --- a/core-tech/Adding-support-for-Beam-Confidential-Asset.md +++ /dev/null @@ -1,294 +0,0 @@ -# Adding support for Beam Confidential Asset - -## TLDR; - -1. In version 6.0 Beam supports Confidential Assets -1. Each asset has an `asset_id`, 0 is for Beam and 1,2,3... for new Assets. -1. A complete list of existing assets is [here](https://explorer.beam.mw/assets) -1. To enable assets add the following line to the `wallet-api` config file - - ``` - enable_assets=true - ``` -1. The following API calls have been updated to support assets: - * `wallet_status` - * `tx_send` - * `tx_split` -1. New API methods have been added - * `tx_asset_issue` - * `tx_asset_consume` - * `tx_asset_info` - * `get_asset_info` - * `calc_change` - -## Confidential Assets - -Confidential Assets (CA) are tokens mint on the Beam blockchain. Beam supports Confidential Assets since hard fork 2, but this feature had limited ability to be used in real life applications. Starting from the version 6.0 Beam Wallet adds ability to create smart contracts which make CA more usable and very important feature in Beam infrastructure. We already have [API](https://github.com/BeamMW/beam/wiki/Beam-wallet-protocol-API#assets-support) to work with CA, but it was disabled by default. If you wish to accept and create transactions with CA you should enable this feature in the wallet API and update your codebase to handle CA correctly. - -### Enable CA support - -* run new binary with `--enable_assets`. With this flag your wallet starts to accept transactions with Confidential Assets - - ``` - ./wallet-api --enable_assets -n - ``` - or specify it in config file - ``` - enable_assets=true - ``` -* to retrieve info about assets use `wallet_status` method, it will return an array of the info about assets in the wallet, including BEAM - - `-->` - ```json - { - "jsonrpc":"2.0", - "id": 6, - "method":"wallet_status" - } - ``` - - `<--` - ```json - { - "id": 1236, - "jsonrpc": "2.0", - "result": { - "current_height": 112, - "current_state_hash": "b9e8b868de60f28e553a1499a569f481991e4cff9fe2191d09d71a03c7708296", - "difficulty": 378.36236572265625, - "prev_state_hash": "3f84da0b0390deaca908603b6061867def987575a1af9311248ffb01503a0f02", - "available": 303000000000, - "receiving": 123, - "sending": 0, - "maturing": 8000000000, - "locked": 30, - "totals": [ - { - "asset_id": 0, - "available": 303000000000, - "available_str": "303000000000", - "maturing": 8000000000, - "maturing_str": "8000000000", - "receiving": 123, - "receiving_str": "123", - "sending": 0, - "sending_str": "0" - }, - { - "asset_id": 1, // <--------------- this could be used to send/split CA or to retrieve extended info - "available": 2000000000, - "available_str": "2000000000", - "maturing": 0, - "maturing_str": "0", - "receiving": 0, - "receiving_str": "0", - "sending": 0, - "sending_str": "0" - } - ] - } - } - ``` - -* if you want to send or split CA you should specify `"asset_id"` in parameters - - `-->` - ```json - { - "jsonrpc":"2.0", - "id": 2, - "method":"tx_send", - "params": - { - "value": 12342342, - "fee": 2, - "from": "472e17b0419055ffee3b3813b98ae671579b0ac0dcd6f1a23b11a75ab148cc67", - "address": "472e17b0419055ffee3b3813b98ae671579b0ac0dcd6f1a23b11a75ab148cc67", - "comment": "thank you!", - "asset_id": 1 <------------------ NEW - } - } - ``` - -* if you want to get info about CA use - - `-->` - ```json - { - "jsonrpc":"2.0", - "id": 2, - "method": "tx_asset_info", - "params": - { - "asset_id": 1 - } - } - ``` - `<--` - ```json - { - "jsonrpc":"2.0", - "id": 2, - "result": - { - "txId" : "10c4b760c842433cb58339a0fafef3db" - } - } - ``` -* after this transaction become completed, you can read CA info from the local database - - `-->` - ```json - { - "jsonrpc":"2.0", - "id": 6, - "method": "get_asset_info", - "params" : - { - "asset_id": 1 - } - } - ``` - - * `asset_id` asset id to retrieve info about. Can be used for any asset even if you don't own it. - - `<--` - ```json - { - "id": 1236, - "jsonrpc": "2.0", - "result": - { - "asset_id": 1, - "emission": 2000000000, - "emission_str": "2000000000", - "isOwned": 1, - "lockHeight": 39, - "metadata": "STD:N=NAME;SN=SNM;UN=UNIT;NTHUN=NTHUNIT", - "ownerId": "0ae08a49e018e98177774294107dc033790b87538e54a20e99c6b98f1dbd39ce", - "refreshHeight": 927 - } - } - ``` - Returns full asset info or [error code](#Errors). - - * `asset_id` asset id - * `metadata` asset metadata - * `emission` & `emission_str` total asset emission. Maximum asset emission is 2128-1. To ensure compatibility with JavaScript raw number returned only if it is less than or equal to `Number.MAX_SAFE_INTEGER` (253-1). If asset emission is greater than `Number.MAX_SAFE_INTEGER` only corresponding string representation is returned. - * `isOwned` is 1 if you own this asset - * `lockHeight` last block when asset emission turned to/from 0. - * `refreshHeight` block at which asset information has been received. Please note, that all returned fields are valid only for this and previous blocks. In next blocks emission might change, asset become unregistered &c. Use [tx_asset_info](#tx_asset_info) to retrieve the most recent info. - -* For minting new asset coins use `tx_asset_issue`. You must own the asset and info about the asset should be in a local database. `tx_asset_info` to retrieve the latest asset info if necessary. Asset minting is free. You need to pay only regular transaction fee. - - `-->` - ```json - { - "jsonrpc": "2.0", - "id": 2, - "method": "tx_asset_issue", - "params": - { - "value": 6, - "asset_id": 1 - } - } - ``` - - * `value` how much asset to mint, in asset groth. - * `fee` transaction fee in BEAM groth. Omit to use default fee. - * `asset_id` asset id of the asset to mint. - * `txId` optional, provide your own transaction ID. - - `<--` - ```json - { - "jsonrpc": "2.0", - "id": 2, - "result": - { - "txId" : "10c4b760c842433cb58339a0fafef3db" - } - } - ``` - Returns transaction id or [error code](#Errors). - -* to burn existing asset coins use `tx_asset_consume`. You must own the asset itself as well as asset coins to burn them. You cannot burn asset coins that belong to another wallet. Info about the asset should be in a local database. - - `-->` - ```json - { - "jsonrpc":"2.0", - "id": 2, - "method":"tx_asset_consume", - "params": - { - "value": 6, - "asset_id": 1 - } - } - ``` - - * `value` how much asset to burn, in asset groth. - * `fee` transaction fee in BEAM groth, omit for a default fee. - * `asset_id` id of the asset to consume. - * `txId` optional, provide your own transaction ID - - - `<--` - ```json - { - "jsonrpc":"2.0", - "id": 2, - "result": - { - "txId" : "10c4b760c842433cb58339a0fafef3db" - } - } - ``` - Returns transaction id or [error code](#Errors). - -* if yoiu want to calculate the change amount for transaction use `calc_change`, it calculates the change value for given `amount` in for given `asset_id` - - `-->` - ```json - { - "jsonrpc":"2.0", - "id": 4, - "method":"calc_change", - "params": - { - "amount" : 1234, - "asset_id": 2, - "fee": 10000, - "is_push_transaction": true - } - } - ``` - - `<--` - ```json - { - "jsonrpc":"2.0", - "id": 4, - "result": - { - "asset_change": 12, - "asset_change_str": "12", - "change": 12, - "change_str": "12", - "explicit_fee": 1100000, - "explicit_fee_str": "1100000" - } - } - ``` - - where - - * `amount` is a requested amount we are going to send - * `asset_id` asset id of the requested amount - * `fee` explicit fee in GROTHs chosen by the user - * `asset_change` change amount for requested `asset_id` - * `change` change in for BEAM. `asset_change` and `change` are equal if `asset_id == 0`, i.e. BEAM - * `explicit_fee` the fee which should be used - * `is_push_transaction` `true` if we are going to push transaction output into the shielded pool. \ No newline at end of file diff --git a/core-tech/Addresses-in-Beam.md b/core-tech/Addresses-in-Beam.md deleted file mode 100644 index dad7b04..0000000 --- a/core-tech/Addresses-in-Beam.md +++ /dev/null @@ -1,259 +0,0 @@ - -![image](https://github.com/user-attachments/assets/110d645f-944f-43ea-a9e5-d51f7159da09) - - -There're (too) many different kinds of addresses in Beam: -* Regular (a.k.a. new-style) -* Legacy (BBS-only, a.k.a. old-style) -* Offline -* Max-privacy - -In addition to those kinds of addresses, there's more terminology: -* Payment _Tokens_, that consist of an address with the requested payment amount -* _Vouchers_ -* _Endpoints_ (alternatively called as _Signature_, or _Identity_) -* _Payment proof_ - -Some of the above things are permanent, some expire, and some are intended for single usage. -In addition to that, when the wallet is restored, the addresses are not preserved (new wallet instance generates new addresses). -All this is very confusing. Here we'll explain in details how things work, why historically so many kinds of addresses were implemented, and what is relevant today. - -# What are Beam addresses? - -First and foremost: -### there are no addresses on the Beam blockchain per se. -*** - -Beam is based on UTXO model (set of coins, in simple words). There're 2 types of UTXOs: -* MW (MimbleWimble) UTXOs. -* Shielded TXOs. Those are created and spent using in Lelantus-MW txs. - -Both kinds of UTXOs are opaque, and look like random data. No addresses that expose who owns them, and the value is concealed. - -Each UTXO has its secret key, which is needed to build a valid tx that spends it. Means whoever knows that secret key - actually owns the coin. - -## How the wallet manages its coins - -Each wallet has the _Master Key_ (initialized from the secret seed phrase). It is used to derive all the coin keys. When the coins are generated by the wallet, they're encoded such that they can re recognized by the corresponding _Owner Key_ (also derived from the Master Key). - -This means the following: -* All the coins belong to the wallet that generated it. They can be recognized by its _Owner Key_, and then spent in the future txs using its _Master Key_. -* Coins do **NOT** belong to addresses. -* Addresses are only used between the wallets to communicate and build txs (more about this later). After the tx is included in a block - addresses don't matter. - -# MW txs and old-style addresses - -Beam is based on MW, where transactions are built interactively. Means users must communicate to build a transaction. - -For this we developed an SBBS system, that allows wallets to exchange encrypted messages anonymously. Wallets can generate public/private key pairs, where the public key is used to encrypt messages, and private key can decrypt them. - -That's how **addresses** were born on Beam. Address in fact meant SBBS address, a public key to encode messages, that can only be decoded by the appropriate private key. - -Here're some notes regarding the SBBS encryption: -* All encrypted messages are opaque (look like random data), the sender/receiver of the message is also opaque, and the message is protected against tampering (using HMAC scheme). -* Using the SBBS address one can only encrypt messages, not decrypt. -* There's no feasible way to realize that a specific SBBS message was encoded by a given SBBS address. - * Means you can share your SBBS address to different users, they won't be able to see when you communicate with others. -* Users can generate as many SBBS addresses as they want. -* In order to receive the SBBS message, one tries to decrypt all the incoming SBBS traffic. Only the intended messages would be successfully decrypted and pass HMAC verification. -* If you listen to several active SBBS addresses - the wallet will try to decrypt each message by each address private key. - * The more active SBBS addresses - the harder the wallet works to receive the messages. - -## Address generation and expiration - -As we said, a wallet may generate multiple SBBS addreses. It may also _deactivate_ a specific address, which means it'd stop trying to decrypt incoming SBBS messages by its private key. - -Theoretically there was no good reason to have more than 1 SBBS address. User could just live fine with only a single SBBS address, and share it freely. As we've said, all the messages are completely opaque, and the communication is anonymous. - -There's only limited scenarios where a user may need more than 1 address. If the user wishes to provide several addresses that look like of different users (for example, have several accounts at an exchange, with different SBBS addresses for funds withdrawal). - -However, due to user habits and some misconceptions, users insisted on changing addresses regularly. That's why we implemented automatic SBBS address generation and expiration - -# Payment proof - -Unlike other blockchain designs, in Beam there're no addresses on the blockchain per se. -As a result, if Alice sends funds to Bob, there's no way to prove it later from the blockchain data (Bob has plausible deniability). - -To address this, we implemented a _Payment Proof_. It's a signature, signed by the recipient of the funds, that it indeed accepts the specific amount from the specific sender. It is signed by the receiver and verified by the sender during the transaction negotiation stage (all this happens off-chain). - -The _Payment Proof_ signature signed the following: -* Identity (pubkey) of the sender -* Identity (pubkey) of the receiver (the signature is signed by the corresponding private key). -* Amount and asset type being-received -* Transaction Kernel ID. If the tx was negotiated but not broadcasted and accepted in a block - the _Payment Proof_ is considered invalid (i.e. there was an intention of the tx, but it didn't take place actually). - -_Identities_ of both sender/receiver were in fact their SBBS addresses. That is, **the same key was used both for SBBS messages encryption, and to identify the owner of the funds**. - -# Hardware Wallet, and new-style addresses (a.k.a. Regular addresses) - -With the hardware wallet the things work differently. The _Master Key_ and all the coin keys are managed entirely in the HW wallet. The software wallet gets the _Owner Key_ that can recognize coins (but not spend them), and handles all the communication and blockchain state change logic. - -The SBBS address must be managed by the software wallet, it's too complex for the HW wallet to decrypt all the SBBS traffic. On the other hand, when the _Payment Proof_ is signed/verified - it must be done with the key that is managed by the HW wallet. - -This is where we decided to split the SBBS address and the user identity. The SBBS address is the address you're communicating with, and the _Identity_ is the public key of the final receiver/sender of the funds. For standard wallets both are managed by the wallet, but with the HW wallet they're managed in different places. - -To support this, we defined a new-style address (now called a Regular address). - -First, the address format was changed. The older SBBS address was just a hex-encoded pubkey. We decided to change it into an encoded collection of arbitrary number of parameters (to support possible future parameters for various address/token types). - -The Regular address consists of the following fields: -* SBBS address -* User Identity - -## Endpoint - -Historically we had several names for the above user identity: _Identity_, _HW Identity_, _Signature_, and etc. All that lead to confuses, so we decided to give a distinctive name to this: the _Endpoint_. - -The rationale behind this name is the following. Suppose Alice sends funds to Bob, both use HW wallet. Conceptually you may treat this situation as this: Alice's HW wallet is the ultimate sender of the funds, Bob's HW wallet is the ultimate receiver. And they negotiate the transaction with each other. -The software wallets of Alice and Bob are just intermediate entities, they're not part of the transaction negotiation. - -In other words, the _Endpoint_ is the final source/destination of the funds. - -# Lelantus-MW - -To address the inherent MW linkability problem, we extended Beam with the Lelantus-MW protocol. It's our proprietary modification of the Lelantus protocol, adjusted to fit and complement the MW. - -With it we added 2 new transaction elements: -* Shielded Output - add an opaque coin into the shielded pool -* Shielded Input - spend _some_ coin from the shielded pool. - -In MW transactions are interactive, when Bob receives funds from Alice, he creates his UTXO to accept the funds in advance (during negotiation stage) . And since Bob himself created his UTXO, he can recognize it using his _Owner Key_, and spend using his _Master Key_. - -In contrast to MW txs, Lelantus-MW txs are non-interactive. Means Alice creates the _Shielded Output_ tx element, without Bob being-involved. Yet she creates it in such a way that Bob will be able to recognize and spend it later. - -This means that Bob should give Alice an additional data, to allow her to send funds to Bob using Lelantus-MW. - -Technically each _Shielded Output_ comes with a _Ticket_. It's an opaque data object, but encoded such that it can be recognized by the funds recipient (Bob). Moreover, _Tickets_ must be unique, it's impossible to use the same ticket twice (this is related to double-spend prevention). - -So, basically there're 2 options here: -1. Bob gives Alice a source data, using which Alice may generate arbitrary number of Bob's tickets. -2. Bob generates arbitrary number of tickets, and gives them to Alice. - -Both methods have their pros and cons. And both are supported in terms of different address types. - -## Offline address - -This corresponds to the 1st method. The _Offline address_ in essence is a ticket generator. It also comes with the Bob's _Endpoint_, and is also signed by _Endpoint_'s signature (if Alice needs to prove that she sent funds to Bob - she can show that the corresponding ticket was generated by the generator signed by Bob). - -Once Alice has it, she can send arbitrary number of Lelantus-MW txs to Bob, which is a good thing. - -There's however a drawback. Alice knows the internal parameters of the ticket (since she actually generated it). One of them later will be used by Bob, when he'll spend this shielded coin. - -Means that the **sender will notice when the receiver will spend the shielded coin**. For the 3rd-party observers the shielded transactions are anonymous, but this specific kind is not anonymous w.r.t. the sender. Hence we call it _Offline_, but not truly private. - -**Note:** despite the above drawback, the above is perfectly fine if you receive shielded funds from a trusted sender. For instance, you may have several wallets (with different seed phrases). You may use _Offline_ address to transfer funds in a private way. As we've said, 3rd-party observers will see no link between the Shielded Output and the corresponding Shielded Input. - -## Max Privacy address - -This corresponds to the 2nd option. The _Max Privacy_ address consists of the following: -* Receiver _Endpoint_ -* Arbitrary number of _Vouchers_. - * Each _Voucher_ is actually a ticket, signed by Bob _Endpoint_ signature (to prove later that Bob is the receiver of the funds). -* Optional SBBS address to ask for more vouchers. - -This method doesn't have the drawback of the _Offline_ address. Alice may send funds to Bob, Bob later may spend those funds anonymously w.r.t. Alice. - -The obvious drawback is that there's a limited number of Vouchers/Tickets. Once they're all consumed - there's no way to send more txs. -This is where the SBBS address can be used. Once Alice runs out of Bob's vouchers (or getting low on them) - her wallet may request for more Bob's vouchers via SBBS. If/when Bob will be online - his wallet will respond, and provide Alice with more vouchers automatically. - -# Tokens - -As we've said, all the address types, except the "old-style", are represented as a collection of parameters. In addition to the address itself (whatever kind it is), it's possible to include more fields. - -Using this we've introduced a so-called payment _Tokens_, which are a way to request a specific payment. They consist of the address (any kind), and the requested Amount and asset type. - - -*** - -# Ideas for improvements - -So we've described what Beam addresses are, why it's not a big deal to loose them (i.e. coins don't belong to addresses, you don't loose coins). -We also explained why there're different kinds of addresses, and why they are necessary. The old-style address is actually obsolete, and even incompatible with the HW wallet (i.e. you can't even generate it with the HW wallet). But, unfortunately, we can't get rid of it completely, because some existing exchanges won't accept different addresses (they do a sort of a regular-expression check on the address). So they're still here. - -However, many things can and should be improved, mostly regarding user experience and the UX. - -The most important change can be expressed as this: - -*** -### It's all about Endpoints -*** - -In simple words, each address consists of two things: -* Who does it belong to, i.e. who is the supposed receiver of the funds. This is the _Endpoint_. -* What kind of tx would that be, and how to negotiate and build it. - -_Endpoint_, i.e. the identity of the sender/receiver - is the most important thing. It should be visible wherever applicable, and play a crucial role in the address book. -_Who_ am I paying, and _who_ payed me. This is arguably more important than _how_ is the payment done. - -## Address format - -Currently all address types (except legacy) are displayed as a Base58-encoded strings of a pairs, where key is an 1-byte identifier of the parameter. -As a result, the user has no way to see either the embedded arguments, or even the address type. A better option would be encoding the arguments in a human-readable way. - -For example, a Regular (online) address could be displayed as: - -`beam_Bk1azc8VtaYU1f6t7jiRGkxJDiAVui6Y5WvohjoU1yFA_bbs274b78587e1c9643e7472e221be1634b8efe06f747175d3d8c98ce1ef665b056d4a` - -It begins with `beam` (a common practice in some networks), then followed by a human-readable _Endpoint_, and then followed by the bbs address. - -### What if users tamper/modify address manually? - -The good news is that Beam addresses are generally resistant to tampering. If one modifies the address (either intentionally or not) - there is no risk of loss of funds. - -If one modifies the SBBS address, the communication with the receiver will fail. And if the _Endpoint_ is modified, the negotiation with the receiver will fail. - -Same applies to Max Privacy and Offline addresses. They contain pre-signed receiver signatures (that would be a part of the future payment proof). If one modifies some address fields - the address would become invalid. - -And, again, this all boils down to the _Endpoint_ of the address, i.e. **who** is the supposed recipient of the funds. If the sender verifies it and is confident that it's the intended one - there's no risk of funds loss, or the payment going into wrong hands. - -## Address book refactor - -Address book consists of several tabs. (My active addresses, My expired addresses, Contacts). -For the "Contacts" tab there is a list of all known addresses of other users. - -A more sane address book should look like this - -* There should be a list of known _Endpoints_, not addresses/tokens. Those are actually different contacts. Each can be annotated by a name. -* For each _Endpoint_ we can show the following information: - * Its SBBS address (if known) - * Do we have its Offline address (yes/no)? - * How many vouchers are left for Max Privacy txs? - * Optionally - a button to request more vouchers manually - -* For owned (my) _Endpoints_ the following information should be presented - * Internal number. That is, all the keys are generated using _Master Key_, from the provided key number. Normally they're picked at random, and not shown to the user. But we can show them. By such users will be able to re-generate the same addresses after the wallet is restored. - * Option to generate an address/token of any kind for this specific _Endpoint_. - * HW wallets: option to verify the _Endpoint_ on the HW wallet - -## Send screen - To - -Currently in the "To" field the user puts an address. The wallet parses the address, recognizes its type, and acts accordingly. For some addresses the wallet gives an option to modify the transaction type (Online, Offline, Max Privacy) if that token has enough information. - -Instead the wallet should recognize the _Endpoint_ from the given address, check if it's already in the address book, and realize all the possible ways of sending from what it already knows about it. Not only from the parameters of the provided address. - -Moreover, it should be possible to specify "To" the _Endpoint_ only. Or just the name that the user annotated to it in the address book. -The wallet should automatically find it in the address book, and allow tx types according to what is known about it. - -## Send screen - From - -Currently this doesn't exist at all. When funds are sent - the sending wallet always identifies itself as a random user with an ephemeral _Endpoint_. - -There should be an option to specify an **existing** _Endpoint_. By such the sender may make the receiver know who sent the funds. - -In the "From" field there should be a choice of the currently existing _Endpoints_ (i.e. active addresses), as well as previously used (perhaps no more active), or an "Anonymous", which means what it is today - a random _Endpoint_. - -## Transaction details - -The transaction details are loaded with lots of technical parameters (SBBS address of sender/receiver, signatures, etc.). They are mostly meaningless to the user. - -There should be the following parameters: -* For funds transfer transactions: - * _Endpoint_ of the sender/receiver. If they exist in the address book - this should be mentioned. - * Type of tx (Online, Offline, Max Privacy) - * Amount transferred and asset type - * Payment proof -* For other txs (coinswap, contract calls) - * _Endpoints_ and Payment proof are irrelevant. Don't show them. - * List of sent/received asset types and amounts - - diff --git a/core-tech/Atomic-swap-token.md b/core-tech/Atomic-swap-token.md deleted file mode 100644 index e816bb4..0000000 --- a/core-tech/Atomic-swap-token.md +++ /dev/null @@ -1,41 +0,0 @@ -# Atomic swap token -## Overview -Swap token is intended to allow users to exchange info about transactions(swap) via any side channels. -In general, token is serialized list of transaction parameters, presented as a base58 encoded byte buffer. - -## Description -Token has the following fields: - -`- flags // 1 byte` - -`- optional TxID // 1 or 17 bytes` - -`- list of parameters // not less than 34 byte since transaction should have at least one address parameter` - - -### flags -Flags is a 1-byte field where only the highest bit is defined the others are reserved. -0x80 means that this is a token. - - -### tx ID -This is an optional transaction ID. All swap transaction should have this value. It is optional for the cases if we will use the token structure for other types of transaction. -There are two possible values: - -`|0x01| 16 byte UUID|` - -or - -`|0x00| ` - -### Transaction parameters -Transaction parameter is a pair of the parameter key and value. -The key is 1 byte value and its meaning is defined by `TxParameterID `enum from [wallet/common.h](https://github.com/BeamMW/beam/blob/master/wallet/common.h) -The values are arrays of bytes and contain serialized values. -The value type and size is defined by the key meaning. All integer types are big-endian. - - - - - - diff --git a/core-tech/Atomic-swap.md b/core-tech/Atomic-swap.md deleted file mode 100644 index 5ac7eaf..0000000 --- a/core-tech/Atomic-swap.md +++ /dev/null @@ -1,149 +0,0 @@ -Atomic swap is performed between Beam and other cryptocurrency. Denote it BTC, but actually it can denote other network that supports the needed functionality. - -The swap is performed in a single transaction, which effectively transfers the ownership of the Beam UTXO in exchange for some secret, which is needed to claim the being-exchanged coin on the BTC network. - -# High-level design - -There are two parties: -* **A**lice. Owns the Beam, interested to trade it for the BTC -* **B**ob. Owns the BTC, interested to trade it for the Beam. - -There are 3 major phases of the atomic swap -1. Prerequesites - * The being-exchanged UTXOs are locked on both networks for a specific time period (in terms of blocks). - * Parties monitor both networks to ensure the source UTXOs are indeed locked. -2. Exchange - * Parties collaborate to create a transaction that transfers the locked Beam to **B** in exchange for the secret. - * **B** substitutes the secret to the transaction and finally broadcasts it to the network. - * Once transaction is visible - **A** learns the secret. - * **A** creates a BTC transaction to claim the BTC UTXO, and broadcasts it to the BTC network. -3. Rollback. In case the swap didn't take place (for whatever reason) - * Locked UTXOs on both network should remain intact until their lock timeout expires. - * After the timeout expiration parties broadcast transactions that transfers the locked UTXOs back to them. - -Note that **A** actually claims the BTC UTXO after sending the Beam UTXO. This means that the lock timeout of the BTC UTXO must be significantly bigger than that of the Beam UTXO, because **B** may broadcast the Beam transaction just before the timeout expires, the **A** should still have enough time to build and broadcast the BTC transaction. - -# Technical design - -The _unlock secret_ is the SHA-256 hash preimage (i.e. a 256-bit value which, after hashing, should be equal to a known 256-bit value). Supported on Beam, BTC, and, probably, many other networks. - -**Note**: The drawback of this scheme is a considerable privacy compromise. As we'll see, it's possible for the attacker to detect such an atomic swap, by looking for the matching hash preimages in both networks. - -There is a better option, where the _unlock secret_ is an EC scalar, i.e. private key. It's based on the so-called aggregate signatures. It's less generic, since it assumes both networks use the same EC equation and the Generator. - -So we'll review the scheme with the Hash-lock, but keep in mind that it can easily be modified to the one with the aggregate signature, and the rest of the argument, and the general flow are exactly the same. - -There are no scripts in Beam blockchain. However the following is supported in the transaction kernel: -* Timelock - minimum blockchain height for the kernel to be valid -* HashPreimage - -## UTXO lock on BTC network - -**B** broadcasts a BTC transaction, which creates an UTXO which can be spent under the following conditions: -1. Timeout + secret key chosen by **B** -1. Hash preimage chosen by **B** + secret key chosen by **A** - -## UTXO lock on Beam network - -This part is somewhat more complex, since there are no scripts in Beam. **A** and **B** collaborate to create a _shared_ UTXO, whose blinding factor is shared between them. - -1. **A** and **B** randomly choose their parts of the blinding factor for the shared UTXO -1. **A** and **B** first create the "rollback" transaction, which would transfer the shared UTXO back to **A** if the exchange didn't take place. - * This transaction kernel is Time-locked, i.e. transaction can only be broadcasted starting from specific blockchain height. - * **A** saves this transaction, but doesn't broadcast yet. -1. **A** and **B** create the transaction that spends **A**'s UTXO and creates the shared one. - * The tricky part is creating the Bulletproof for the shared UTXO. Takes 3 iterations. -1. They broadcast this transaction to the Beam network, to create the shared UTXO. - -## Exchange transaction - -At this point both Beam and BTC UTXOs are locked, both parties get confirmations for this. In addition **A** knows the _Image_ of the locked BTC UTXO. Now they collaborate to build a Beam transaction that transfers the shared (locked) Beam UTXO to **B** in exchange for revealing the _Hash Preimage_, which, after hashing, equals to the known _Image_. - -* **B** randomly chooses the blinding factor for the new UTXO -* **A** creates the Transaction Kernel, which is supposed to contain the _Hash Preimage_ (but doesn't contain yet), which corresponds to the knwo _Image_. -* **A** puts her part of the kernel multisig, which assumes the correct _Image_. -* Incomplete transaction is passed to **B**. -* **B** puts his part of the kernel multisig, which assumes the correct _Image_ (same as Alice). -* **B** substitutes the correct _Hash Preimage_ to make the transaction kernel valid. - * This is where the atomic swap actually occurs! -* **B** broadcasts the transaction to the Beam network. - -**A** monitors the Beam network. Once the exchange transaction kernel is visible: -* **A** realized that the exchange occurred. -* **A** learns the _Hash Preimage_. -* **A** creates and broadcasts the BTC transaction to claim her BTC UTXO. - -# In-depth flow diagram - -## Bob - -* Collaborate to lock the BTC UTXO - * Get `Pka` from **A** - her generated pubkey for some secret key `ska`. - * Generate the `hpi` - the _Hash Preimage_. - * `hi = Hash(hpi)` - the _Hash Image_. - * Generate and broadcast the transaction that creates a locked BTC UTXO. - * The created UTXO can be spent iff both `hpi` and `ska` are known. - * `hi` and `Pka` are revealed. - * Send **A** this transaction (so she'll be able to identify it in the BTC network). -* Collaborate to lock the Beam UTXO - * Generate `sfb` - the part of the blinding factor of the shared UTXO. - * Get `Pfa` - **A**'s part of the public blinding factor (of the shared UTXO). - * Collaborate to sign the kernel for the transaction that transfers the shared (non-existing yet) UTXO back to **A** - * The kernel must be time-locked - * **B**'s part of the signature accounts for the `sfb`. - * Collaborate to create the Bulletproof of the shared UTXO. - * requires 3 iteration cycles with **A** - * Collaborate to sign the kernel for the transaction that creates the shared UTXO - * **B**'s part of the signature accounts for the `sfb`. -* Wait until the mutual UTXO becomes visible -* Collaborate to build the exchange transaction - * Transaction kernel is supposed to (but doesn't yet) contain the `hpi`. - * Means - its signature signs the kernel contents, including `Hash(hpi) == hi`, whereas `hi` is known to both parties. - * Generate the new UTXO - * Pass it to **A** so that she creates such a kernel, and substitutes her part of the signature. - * Get the half-signed kernel from **A**, and verify it. - * **Important:** Ensure there is enough time left until the timelock of the shared UTXO expires! - * Finish the kernel signature. - * Substitute the `hpi` as the _Hash Preimage_. - * Complete the signature. - * Broadcast the transaction to the Beam network. -* Wait until the exchange transaction becomes visible, or until the BTC UTXO timelock expires. - * If the transaction is visible (and enough new blocks are generated above) - Congratulations! It's done. - * If the BTC UTXO timelock expired and it's still unspent - take it back (create and broadcast another BTC transaction). - -## Alice - -* Collaborate to lock the BTC UTXO - * Generate `ska` - private key on the BTC network. - * Send `Pka = G * ska` to **B**. - * Receive the BTC transaction details from **B**, and verify it - * Correct amount is locked. - * Can be spent using `ska`, and a _Preimage_ of `hi` (the preimage is not known yet). -* Collaborate to lock the Beam UTXO - * Select input(s) to build the transaction that creates the shared UTXO - * Generate `sfa` - the part of the blinding factor of the shared UTXO. - * Get `Pfb` - **B**'s part of the public blinding factor (of the shared UTXO). - * Collaborate with **B** to build: - * A time-locked rollback transaction that transfers the shared (non-existing yet) UTXO back to **A**. - * It must be created before the shared UTXO is actually created. - * Bulletproof for the shared UTXO - * Transaction that spends the selected inputs and creates the shared UTXO - * Send the transaction to create the shared UTXO to the network -* Wait until the locked BTC UTXO becomes visible in the BTC network -* Ensure the BTC timelock is significantly bigger than the Beam timelock -* Collaborate to build the exchange transaction - * Transaction kernel is supposed to (but doesn't yet) contain the `hpi`. - * **A** creates such a kernel, puts her part of the signature, which - * Corresponds to her part of the shared UTXO (compensates for `ska`). - * Would become valid only when the correct _Hash Preimage_ (`hpi`) will be substituted. - * Half-signed transaction is passed to **B** -* Wait until the exchange transaction becomes visible, or until the Beam UTXO timelock expires. - * Once the transaction is visible: - * **A** learns the `hpi` from the visible transaction kernel - * **A** Creates and broadcasts the BTC transaction to claim the BTC UTXO - * If the Beam UTXO timelock expired and it's still unspent - * Broadcast the rollback transaction to the network - * Wait until the transaction (either post-exchange or the rollback) becomes visible. - -## Swap diagram -![Atomic Swap Diagram](https://user-images.githubusercontent.com/2501619/60335463-abf39900-99a6-11e9-83ae-9494ea9e3577.png) \ No newline at end of file diff --git a/core-tech/Authorization-control-and-signatures-in-contracts.md b/core-tech/Authorization-control-and-signatures-in-contracts.md deleted file mode 100644 index 4258141..0000000 --- a/core-tech/Authorization-control-and-signatures-in-contracts.md +++ /dev/null @@ -1,131 +0,0 @@ -In the most common cases the contract method calls `Env::AddSig()` for each needed public key, and the app shader includes the key material for each key within the `SigRequest` structure, when it calls `Env::GenerateKernel()`. - -This is a preferred method to design a contract and its application, as it has the following advantages: - -* Performance: native signature is both compact and fast. -* Security: apps have no access to secret keys, they can only derive public keys. -* Simplicity. - -However there are more complex situations, where either several users are required to authorize a method call, or a custom signature scheme is required (such as m-out-of-n signature). - -Those may include: - -1. Explicit multisignatures. Several keys are verified (mutliple calls to `Env::AddSig()`), belonging to different users. -2. Seemless multisignatures. There is a single key, but it is a sum (or any linear combination) of several keys, belonging to different users. -3. Non-standard signature is needed (ring signatures and etc.). -4. Any combination of the above - -On the contract side those are supported. In addition to `Env::AddSig()` (which can be invoked arbitrary number of times) the contract has access to **Secp** primitives, using which it can implement custom cryptographic scheme verification. - -For apps, however, the default functionality is not enough. Creating a multisigned transaction that is supposed to invoke such a contract assumes that different wallets should cooperate and communicate on behalf of the apps. - -So we extended the BVM functionality to support all the variety of possible signature schemes. Though apps still don't get direct access to secret keys with the added functions, the risk is somewhat greater (more about this later), hence to use those extra functions the app needs an elevated privilege level (OFF by default). - -Technically those functions are: -* Nonce Slots management functions -* getting an image of a key or a slot, with either standard (**G**) or any custom generator -* getting a blinded key -* Communication support (via SBBS system) -* `Env::GenerateKernelAdvanced()` - with more specific signature control - -## Nonce slots and blinded keys - -(the idea of nonce slots is the same as in our HW wallet design) - -Generally our supported signatures follow this ritual: first a unique nonce is generated and its image is exposed (in some manner). Then, during the signing, a pseudo-random challenge is derived, and the prover should reveal a linear combination of the secret key and the nonce, a.k.a. blinded key. - -This scheme is applicable to Schnorr's signature, Ring signature, Groth's 1-out-of-many, and probably many others. -It's **critically** important to make sure the nonce is unique, i.e. not reused for the same secret key in different signatures. - -So we decided to add appropriate support functions for the apps: generate unique nonces, get their images, and get blinded keys: -* Generate unique nonce. - * BVM generates a nonce using system random and state mutation. - * optionally app can specify extra seed data to strengthen the nonce (i.e. less dependency on system random). -* Get nonce image (arbitrary number of times, with arbitrary generators). -* Get blinded key. - * The app supplies the needed key material (a.k.a. `KeyID`, `SigRequest`), arbitrary challenge (scalar) and the nonce slot number. - * Once the nonce is used - it's immediately wiped. - -By such apps are given opportunity to build complex signature schemes, without either direct access to the secret keys, or the feasible opportunity to extract them. - -# Building a custom signature scheme - -As we mentioned, an app can create a custom signature (such as Ring signature), include it in the contract method invocation arguments, then the contract shader may verify it by implementing the needed verification scheme (in terms of **Secp** primitives). - -Apps can generate such signatures by the provided functionality: obtaining nonce images, and getting blinded keys for the needed challenges. - -### Risk of signature _hijacking_ - -When using native signature (`SigRequest`/`AddSig()`), it's included in the kernel multi-signature, which also includes its blinding factor. Other users can't take it as-is and use in their transactions (it's not feasible to build a transaction with unknown blinding factor). - -In contrast, the custom signature is not automatically bound to the kernel blinding factor. Hence any other user that monitors transactions can build its own transaction that invokes the same method with exactly the same arguments. - -To mitigate this threat we recommend the following scheme: - -Normally challenges for signatures are derived using _Random Oracle Model_, which is initialized with the message being-signed, this binds the signature for this specific message. - -So we recommend deriving an arbitrary ephemeral (unique) key. Its image (pubKey) should be included in the method arguments, and initialize the _Oracle_ (challenges derivation), **AND** it also should be included in the native kernel signature (i.e. `Env::AddSig()`). - -So we recommend using a hybrid of a custom and native signatures. Instead of binding the signature to a message, we recommend binding it to an ephemeral key, whose signature in turn is bound to the kernel blidning factor. By such it's no more feasible to hijack the signature. - -# Building a mutli-signed transaction using native signature - -In simple scenario the app calls `Env::GenerateKernel()`, and supplies the info about how it should be signed (gives array of `SigRequest`), the signing itself is deferred until a later stage. Hence some kernel parameters may still vary: min/max height, fee. - -For multi-signed transactions this is different. All the kernel parameters must be decided in advance, so that all the challenges can be derived. -Those include: - -* Standard parameters: **contractID**, method number, args -* min/max heights -* kernel fee -* Funds balance -* Kernel blinding factor image - * together with Funds balance is used to derive kernel `Commitment` -* Total nonce image, which includes - * internal BVM nonce for the kernel blinding factor - * all the nonces the app uses for the keys used in the signature - * all the nonces the apps running in different wallets use for their keys - -From all this the challenges are derived. - -Then it's the apps's task to calculate the signature: the sum of all the needed blinded keys (its own, as well as of other users). - -Technically the flow goes like this: -* Decide auxiliary kernel parameters (heights, fee) -* get nonce images -* get the image of additional nonce, which would be used by the BVM to blind the kernel blinding factor -* for all the co-signers: - * co-signers send their (cumulative) nonces for their keys -* sum all the nonces -* Call Env::GenerateKernelAdvanced() for the 1st time to derive the challenges -* Extract the blinded keys, using the appropriate nonces and derived challenges -* for all the co-signers: - * Signer sends them the total nonce and the kernel blidning factor, so that they cal also derive the challenges - * co-Signers reply with the sum of their blinded keys -* sum those blinded keys to get a multi-signature -* Invoke Env::GenerateKernelAdvanced() for the 2nd time, to finally build the transaction. - -Some examples of this flow: -* **vault** app: example of a seamless multisignature, where a vault `PubKey` is actually a sum of the keys of 2 users. The contract code is unmodified (i.e. doesn't care if this is a multi-owned account). -* **upgradable2** contract and app: example of an explicit multisignature, where the contract demands authorization by multiple keys. -* more examples to come, to demonstrate custom signature schemes - -# Security considerations - -When app is invoked in the wallet, it's possible to define its _privilege level_, which may restrict its access to potentially dangerous functionality. - -* Level 0: apps have no access to any user-specific info, and no permission to create transactions. They can only interpret and display the blockchain status information. This is considered safe (though of course the info that app displays may be misleading). - -* Level 1 (default): Apps have an access to user's public keys (only those related to contracts), and can ask to create transactions. For the transactions the user sees the resulting balance (funds in/out), and they need user approval. There are 2 risks to consider: - * There is no reliable way to know it the funds are spent as supposed. A malicious app can steal those funds by sending them such that they won't be accessible by the user in the future. - * App may try to deanonymize the user. It may derive multiple public keys, which are normally intended for different contracts, and expose them in some transaction in a seamless way (a disguised parameter to some contract, recognized by the attacker). -* Level 2: Apps have access to blinded keys. - * A malicious app can sign **arbitrary** transaction to steal the user funds. - * Although such a risk already exists at privilege level 1, here it's somewhat greater, because the leaked signature may be used later, not necessarily during the app invocation. -* Level 3: Apps have access to inter-wallet communication. - * This somewhat increases the risk of disguised signature leakage: Rather than hiding the leaked signature for the attacker on-chain in the explicit tx, a malicious app can now communicate it directly to the attacker. - -## Conclusion -At any privilege level above 0 there is a risk of deanonymization and funds theft. So we strongly suggest using only trusted apps: either reviewed and built by the user, or signed by trusted 3rd-party developers. - -Anyway the deanonymization and theft risks are bounded by the contracts. Apps have no access to other wallet keys (UTXOs, shielded outputs, onwer key, and etc. diff --git a/core-tech/BEAM-IPFS-Support.md b/core-tech/BEAM-IPFS-Support.md index b78960e..9e62d92 100644 --- a/core-tech/BEAM-IPFS-Support.md +++ b/core-tech/BEAM-IPFS-Support.md @@ -1,121 +1,182 @@ -**THIS DOCUMENT DESCRIBES UPCOMING AND NOT YET RELEASED v6.3 IPFS SUPPORT. Subject to change without prior notice.** +# BEAM IPFS Support -As of v6.3 BEAM adds IPFS support and IPFS can be accessed via API. Refer [version 6.3 API](https://github.com/BeamMW/beam/wiki/Beam-wallet-protocol-API-v6.3) docs for details on supported IPFS calls. +Beam embeds a full [IPFS](https://ipfs.tech/) (InterPlanetary File System) node into the wallet process, enabling decentralized content-addressed storage for DApp user interfaces and other on-chain assets. -* in Desktop UI client IPFS is enabled by default. IPFS node is started when user launches any DApp granting full IPFS support to DApps. After IPFS node is started it continues to run until desktop client is closed. +## Why IPFS Is Embedded -* in wallet-api IPFS support is disabled by default, `--enable_ipfs=true` option should be specified to start IPFS node granting full IPFS support +Beam DApps are implemented as [shader pairs](BVM-Shader-Development): a contract shader running inside the BVM and an app shader that runs in the wallet and builds the UI. The UI assets — HTML, JavaScript, images — must be delivered to the wallet client without relying on a centralized server. IPFS provides content-addressed immutable storage, so a CID embedded in the shader's metadata permanently identifies the exact UI bundle. When a user opens a DApp the wallet fetches the bundle by CID from the IPFS network. -* in Mobile clients & WASM client limited IPFS support is enabled. No local IPFS node is started, write-only methods like ipfs_add/ipfs_pin would fail. Read-only methods like ipfs_get are enabled via HTTP calls to BEAM managed IPFS nodes. +Secondary use cases include NFT metadata storage and application-level content pinning from DApp shaders via the wallet API. -## BEAM IPFS Config +## Client Modes -BEAM IPFS repository is located in the `[wallet data folder]/ipfs-repo` until `--ipfs_repo=[path]` option is specified for API CLI or `[ipfsnode] ipfs_repo=[path]` in Desktop `settings.ini` file. When there is no initialized IPFS repository in the given path it would be automatically initialized with the default 'server' IPFS profile for API CLI and with the default (client) profile for Desktop Client except the following custom BEAM settings: +| Client type | IPFS node | Write operations | Read operations | +|---|---|---|---| +| Desktop wallet | Full local node (optional, starts on DApp launch by default) | `ipfs_add`, `ipfs_pin`, `ipfs_unpin`, `ipfs_gc` | `ipfs_get`, `ipfs_hash` | +| `wallet-api` CLI | Full local node (opt-in: `--enable_ipfs=true`) | All methods | All methods | +| Mobile / WASM clients | No local node | Not available (fail) | Via HTTP to BEAM-managed IPFS nodes | -* `Swarm.ConnMgr.LowWater` - is set to `100`. Can be changed using `--ipfs_low_water` option in API CLI and using `[ipfsnode] ipfs_low_water=` in Desktop client 'settings.ini' file. +The compile-time guard `BEAM_IPFS_SUPPORT` controls whether any of this code is included; builds without it expose none of the IPFS symbols. -* `Swarm.ConnMgr.HighWater` - `200` / `--ipfs_high_water`, `settings.ini -> [ipfsnode] ipfs_high_water=` +## Architecture -* Swarm.ConnMgr.GracePeriod - `20s` / `--ipfs_grace_period`, `settings.ini -> [ipfsnode] ipfs_grace_period=` as uint32 seconds +### Threading Model -* Bootstrap - default BEAM bootstrap node(s) / `--ipfs_bootstrap` (space separated [multiaddr](https://github.com/multiformats/multiaddr) list), `settings.ini -> [ipfsnode] ipfs_bootstrap=` +`IPFSService` (`wallet/ipfs/ipfs.h`) is the public interface. The underlying `asio_ipfs::node` runs on a dedicated **service thread** with its own `boost::asio::io_context`. All IPFS operations are non-blocking from the caller's perspective. -* Addresses.Swarm - custom `10100` listening port / `--ipfs_swarm_port`, `settings.ini -> [ipfsnode] ipfs_swarm_port=` +```cpp +struct IPFSService { + struct Handler { + // Called from the IPFS service thread — must dispatch back to the + // wallet's reactor thread, not execute work inline. + virtual void AnyThread_pushToClient(std::function&&) = 0; + virtual void AnyThread_onStatus(const std::string& error, uint32_t peercnt) = 0; + }; -* Addresses.API - custom `/ip4/127.0.0.1/tcp/6100` listening address for API / empty (API disabled) on Desktop / `--ipfs_api_addr`, `settings.ini -> [ipfsnode] ipfs_api_addr=` + static Ptr AnyThread_create(HandlerPtr); -* Addresses.Gateway - custom `/ip4/127.0.0.1/tcp/6200` listening address in API / empty (Gateway disabled) on Desktop / `--ipfs_gateway_addr`, `settings.ini -> [ipfsnode] ipfs_gateway_addr=` + // Calling thread becomes the service thread for this call + virtual void ServiceThread_start(asio_ipfs::config) = 0; + virtual void ServiceThread_stop() = 0; -* Swarm.EnableAutoRelay - false in API / `true` on Desktop / `--ipfs_auto_relay`, `settings.ini -> [ipfsnode] ipfs_auto_relay=` + virtual bool AnyThread_running() const = 0; + virtual std::string AnyThread_id() const = 0; -* Swarm.EnableRelayHop - `false` / `--ipfs_relay_hop`, `settings.ini -> [ipfsnode] ipfs_relay_hop=` + virtual void AnyThread_add (data, bool pin, timeout, res_cb, err_cb) = 0; + virtual void AnyThread_hash (data, timeout, res_cb, err_cb) = 0; + virtual void AnyThread_get (hash, timeout, res_cb, err_cb) = 0; + virtual void AnyThread_pin (hash, timeout, res_cb, err_cb) = 0; + virtual void AnyThread_unpin (hash, res_cb, err_cb) = 0; + virtual void AnyThread_gc (timeout, res_cb, err_cb) = 0; +}; +``` -* Swarm.Transports.Network.Relay - forced to `true` everywhere. Not adjustable at the moment. +Every method name prefixed `AnyThread_` is safe to call from any thread. Callbacks always arrive in the wallet's reactor thread via `Handler::AnyThread_pushToClient`, which posts through `PostToReactorThread` — an `io::AsyncEvent`-based cross-thread queue (`wallet/ipfs/ipfs_async.h`). -* AutoNAT.ServiceMode - `enabled` / `--ipfs_autonat`, `settings.ini -> [ipfsnode] ipfs_autonat=` as bool +### Startup Sequence -* AutoNAT.Throttle.GlobalLimit - `30` / `--ipfs_autonat_limit`, `settings.ini -> [ipfsnode] ipfs_autonat_limit=` +`ServiceThread_start` runs the `asio_ipfs::node::build` coroutine **synchronously** in the calling thread until the node is fully initialized (bootstrap connection established, swarm key accepted, peer ID derived). Only then does the dedicated service thread begin its event loop. This simplifies the startup flow at the cost of a potentially multi-second blocking call on first launch. -* AutoNAT.Throttle.PeerLimit - `3` / `--ipfs_autonat_peer_limit`, `settings.ini -> [ipfsnode] ipfs_autonat_peer_limit=` +## Configuration (`asio_ipfs::config`) -* Datastore.StorageMax - `20GB` in API CLI / `2GB` in Desktop client / `--ipfs_storage_max`, `settings.ini -> [ipfsnode] ipfs_storage_max=` +| Field | Desktop default | Server (`wallet-api`) default | CLI flag | `settings.ini` key | +|---|---|---|---|---| +| `repo_root` | `/ipfs-repo` | same | `--ipfs_repo` | `[ipfsnode] ipfs_repo` | +| `storage_max` | `2GB` | `20GB` | `--ipfs_storage_max` | `[ipfsnode] ipfs_storage_max` | +| `low_water` | `100` | `100` | `--ipfs_low_water` | `[ipfsnode] ipfs_low_water` | +| `high_water` | `200` | `200` | `--ipfs_high_water` | `[ipfsnode] ipfs_high_water` | +| `grace_period` | `20s` | `20s` | `--ipfs_grace_period` | `[ipfsnode] ipfs_grace_period` | +| `swarm_port` | `10100` | `10100` | `--ipfs_swarm_port` | `[ipfsnode] ipfs_swarm_port` | +| `api_address` | *(disabled)* | `/ip4/127.0.0.1/tcp/6100` | `--ipfs_api_addr` | `[ipfsnode] ipfs_api_addr` | +| `gateway_address` | *(disabled)* | `/ip4/127.0.0.1/tcp/6200` | `--ipfs_gateway_addr` | `[ipfsnode] ipfs_gateway_addr` | +| `routing_type` | `dht` | `dhtserver` | `--ipfs_routing_type` | `[ipfsnode] ipfs_routing_type` | +| `auto_relay` | `true` | `false` | `--ipfs_auto_relay` | `[ipfsnode] ipfs_auto_relay` | +| `relay_hop` | `false` | `false` | `--ipfs_relay_hop` | `[ipfsnode] ipfs_relay_hop` | +| `autonat` | `true` | `true` | `--ipfs_autonat` | `[ipfsnode] ipfs_autonat` | +| `autonat_limit` | `30` | `30` | `--ipfs_autonat_limit` | `[ipfsnode] ipfs_autonat_limit` | +| `autonat_peer_limit` | `3` | `3` | `--ipfs_autonat_peer_limit` | `[ipfsnode] ipfs_autonat_peer_limit` | +| `run_gc` | `true` | `false` | `--ipfs_run_gc` | `[ipfsnode] ipfs_run_gc` | +| `bootstrap` | network defaults | network defaults | `--ipfs_bootstrap` (space-separated multiaddr list) | `[ipfsnode] ipfs_bootstrap` | +| `peering` | network defaults | network defaults | — | — | +| `swarm_key` | network default | network default | `--ipfs_swarm_key` | `[ipfsnode] ipfs_swarm_key` | -* Routing.Type - `dhtserver` in API CLI / `dht` in Desktop client / `--ipfs_routing_type`, `settings.ini -> [ipfsnode] ipfs_routing_type=` +### Network-Specific Bootstrap and Swarm Keys -* swarm.key file is created to ensure connection to the BEAM private IPFS network / `--ipfs_swarm_key`, `settings.ini -> [ipfsnode] ipfs_swarm_key=` as string +Beam operates a **private IPFS swarm** — nodes with a wrong or missing swarm key cannot join. Bootstrap nodes and swarm keys are injected automatically based on `Rules::get().m_Network`: -* IPFS periodic GC is disabled in API CLI / launched in Desktop Client / `--ipfs_run_gc`, `settings.ini -> [ipfsnode] ipfs_run_gc=` as bool +| Network | Bootstrap peers | Swarm key prefix | +|---|---|---| +| `mainnet` | `eu-node01..04.mainnet.beam.mw:38041` | `1fabcf9e…` | +| `testnet` | `eu-node01..03.testnet.beam.mw:38041` | `1191aea7…` | +| `masternet` | `3.19.32.148:38041` | `18502580…` | +| `dappnet` | `3.16.160.95:38041` | `bf2f2063…` | -* sockets-based activation for "io.ipfs.api" and "io.ipfs.gateway" is disabled at the moment and is not planned in the future. Contact us if you need this feature. +All swarm keys use the PSK v1 format: `/key/swarm/psk/1.0.0/\n/base16/\n`. -* WebUI is not supported and disabled, will be supported in the future +If a custom `swarm_key` or `bootstrap` list is provided in config, the network defaults are ignored entirely for that field. -* fuse mounts for "/ipfs" and "/ipfs" are not supported and disabled, will be supported in the future +### `config.lock` — Preventing Config Overwrite -* remote pinning for MFS roots is not supported and disabled, will be supported in the future +On every startup Beam forcibly overwrites the BEAM-specific settings in `/config`. To suppress this (e.g., to preserve manual edits), create the file `/config.lock`. When this file is present, all BEAM-side config knobs — CLI flags, `wallet_api.cfg`, desktop settings — are ignored and the existing `config` file is used as-is. -There are no changes in default IPFS repo layout, all default config and data files are and you are able to manage the IPFS repo via default IPFS cli tool paired with the `IPFS_PATH` environment variable. Ensure that BEAM client that uses the repo is not launched when accessing it using IPFS cli. In case of Desktop client's IPFS repo `ipfs_node_api_port`/`Addresses.API` setting should be specified before running daemon or it would crash. go-ipfs is unable to launch without API support. +## Async API -### ipfs-repo/config.lock file +All six service methods follow the same pattern: submit a coroutine to the IPFS `io_context`, optionally attach a `boost::asio::steady_timer` for timeout enforcement, then marshal the result back to the wallet's reactor thread via `Handler::AnyThread_pushToClient`. -This section describes BEAM extension to IPFS repo & config handling. +| Method | Direction | Notes | +|---|---|---| +| `AnyThread_add(data, pin, timeout, res, err)` | local → IPFS network | Stores bytes; returns CID string. `pin=true` prevents GC from evicting the block. | +| `AnyThread_hash(data, timeout, res, err)` | local only | Computes CID without storing (`calc_cid` internally). No network I/O. | +| `AnyThread_get(hash, timeout, res, err)` | IPFS network → local | Fetches content by CID; returns raw bytes. | +| `AnyThread_pin(hash, timeout, res, err)` | local bookkeeping | Marks a CID as pinned so GC will not remove it. | +| `AnyThread_unpin(hash, res, err)` | local bookkeeping | Removes pin; timeout not applicable (local). | +| `AnyThread_gc(timeout, res, err)` | local | Removes all un-pinned blocks from the local store. | -On every start BEAM would force and overwrite the aforementioned BEAM custom settings in the `ipfs-repo/config` file. If you want to cancel this behavior, edit the `ipfs-repo/config` file manually or via cli and preserve your custom changes `ipfs-repo/config.lock` file should be created. +Timeout is in milliseconds; pass `0` to disable timeout enforcement (unpin always uses `0`). -If `ipfs-repo/config.lock` is present BEAM would not make any changes to the `ipfs-repo/config` file. All BEAM ways to change IPFS settings are immediately blocked and ignored including `--ipfs-xxx` CLI options, any IPFS options set in `wallet_api.cfg` file, any IPFS options set via desktop UI and any IPFS options set in desktop UI `settings.ini` file. +### Wallet API Methods -## Useful stuff +These operations are also exposed as JSON-RPC methods in the wallet API (since v6.3), all tagged `APPS_ALLOWED` so DApp shaders can call them: -### Access BEAM IPFS node using standard IPFS cli tool +| JSON-RPC method | Access level | Async | +|---|---|---| +| `ipfs_add` | write | yes | +| `ipfs_hash` | read | yes | +| `ipfs_get` | write | yes | +| `ipfs_pin` | write | yes | +| `ipfs_unpin` | write | yes | +| `ipfs_gc` | write | yes | -1. Start wallet api -2. Install go-ipfs -3. Create beam-ipfs bash script (do not forget to change your paths) +See the [Wallet API v7.0](api/Beam-wallet-protocol-API-v7.0) documentation for parameter schemas. -```bash -#/bin/bash -export IPFS_PATH=/home/ubuntu/beam-api/ipfs-repo/ -# uncomment the following line if you're using private IPFS network -# export LIBP2P_FORCE_PNET=1 -/home/ubuntu/go-ipfs-node/ipfs "$@" -``` +## Interaction with Shader Invocation -In desktop client IPFS node API is disabled by default. `ipfs_node_api_port` should be set in `settings.ini` or `Addresses.API` in `ipfs-repo/config` to access IPFS node API. +When a DApp is opened in the desktop wallet, the wallet: -4. Make it executable +1. Reads the shader's embedded metadata to find the app shader's IPFS CID. +2. Calls `AnyThread_get(cid, ...)` to fetch the UI bundle from IPFS. +3. Starts a local IPFS node on demand (if not already running) via `IWThread_startIPFSNode`. +4. Launches a sandboxed WebView pointing at the fetched bundle. -```bash -chmod +x ./beam_ipfs -``` +The app shader running inside the WebView can call `ipfs_add`, `ipfs_get`, etc., through the DApp API (`wallet/client/apps_api/apps_api.h`). The DApp API checks whether an IPFS node is available (`hasIPFSNode`) at DApp launch time and logs a warning if it is not; read operations from mobile/WASM clients fall back to HTTP calls to BEAM-managed gateway nodes. + +## Repository Layout -5. Execute usual ipfs commands via the script +The IPFS repo lives at `/ipfs-repo` by default and is a standard go-ipfs repository. The standard IPFS CLI can inspect it: ```bash -./beam-ipfs swarm peers +export IPFS_PATH=/path/to/beam/ipfs-repo +export LIBP2P_FORCE_PNET=1 # required for private swarm +ipfs swarm peers +ipfs pin ls ``` -### SystemD IPFS unit file +Ensure the Beam wallet is not running when using the IPFS CLI against the same repo — both processes cannot hold the repo lock simultaneously. -Example below if given for a standard go-ipfs binary. You can also use the same settings for running wallet API +**Desktop note:** The IPFS API (`Addresses.API`) is disabled in the desktop client's default repo config. Set `ipfs_node_api_port` in `settings.ini` or add `Addresses.API` manually to `ipfs-repo/config` before starting, otherwise `ipfs daemon` will abort. -``` -/etc/systemd/system/ipfs.service -``` +### SystemD Unit (wallet-api) -``` +```ini [Unit] -Description=GO IPFS Node +Description=Beam Wallet API with IPFS After=network.target [Service] Type=exec Restart=on-failure -Environment="IPFS_PATH=/home/ubuntu/go-ipfs-node/repo" -# uncomment if private IPFS network -# Environment="LIBP2P_FORCE_PNET=1" -WorkingDirectory=/home/ubuntu/go-ipfs-node -ExecStart=/home/ubuntu/go-ipfs-node/ipfs daemon +WorkingDirectory=/home/beam/wallet-api +ExecStart=/home/beam/wallet-api/wallet-api --enable_ipfs=true ... [Install] WantedBy=multi-user.target ``` + +## Current Limitations + +- **WebUI** is disabled and not planned. +- **FUSE mounts** (`/ipfs`, `/ipns`) are disabled and not planned. +- **Remote MFS-root pinning** is not supported. +- **Sockets-based activation** for `io.ipfs.api` / `io.ipfs.gateway` is not supported. +- The IPFS startup is **synchronous** (blocks the calling thread until the node is connected); async startup is a noted TODO in the implementation. +- Connect timeout lowering is also listed as a TODO; the initial peer connection may take several seconds on a cold start. diff --git a/core-tech/BEAM-Mining.md b/core-tech/BEAM-Mining.md index ded7049..f5e44a7 100644 --- a/core-tech/BEAM-Mining.md +++ b/core-tech/BEAM-Mining.md @@ -51,7 +51,7 @@ The external miner software is available for download [here](https://www.beam.mw # How can you help? * Want to help developing Beam mining infrastructure? Have GPU development skills or experience with mining pools? Write to us at mining@beam.mw. Fair compensation will be offered to qualified developers. -* Own a mining farm and want to mine Beam at launch? Join Beam Mining community on Telegram or contact us at mining@beam.mw. +* Own a mining farm and want to mine Beam? Join Beam Mining community on [Telegram](https://t.me/BeamMiners) or contact us at mining@beam.mw. diff --git a/core-tech/Beam-Cpp-Style-And-Conventions.md b/core-tech/Beam-Cpp-Style-And-Conventions.md new file mode 100644 index 0000000..9fdfff7 --- /dev/null +++ b/core-tech/Beam-Cpp-Style-And-Conventions.md @@ -0,0 +1,389 @@ +# Beam C++ Style and Conventions + +This page documents the C++ idioms, patterns, and conventions used throughout the Beam codebase. Its audience is contributors adding new code to `core/`, `node/`, `wallet/`, `bvm/`, or `utility/`. + +--- + +## C++ Standard and Compiler Support + +The baseline standard is **C++17** (`CMAKE_CXX_STANDARD 17`), enforced as required. An optional C++20 mode exists via the CMake flag `-DBEAM_CPP_20_STANDARD=ON`, but the vast majority of the codebase targets C++17. Avoid C++20-only features in new code unless explicitly building under that flag. + +Supported compilers: GCC, Clang, and MSVC. Platform guards use `#ifdef WIN32`, `#if defined(__clang__)`, `#if defined(__GNUC__)`. + +--- + +## Naming Conventions + +### Types and Classes + +All types use **PascalCase**: `NodeProcessor`, `TxKernel`, `WalletDB`, `HeightRange`, `Serializer`. + +Nested types follow the same rule: `NodeProcessor::Mapped::Utxo`, `Reactor::Object`, `Exc::Checkpoint`. + +### Data Members + +All data members carry an `m_` prefix: + +```cpp +Height m_Height = 0; +uint32_t m_Pos = 0; +ECC::Hash::Value m_Hash; +``` + +Pointer members additionally use a `p` suffix on the prefix: `m_pData`, `m_pExternal`, `m_pNext`. This signals non-owning raw pointer semantics. + +Static data members use `s_`: `s_pInstance`, `s_pTop`. + +### Free Functions and Methods + +Both free functions and member functions use **PascalCase**: `HeightAdd`, `ZeroObject`, `GetTime_ms`, `ExportNnz`, `FromPubKey`. Utility helpers outside the `beam` namespace (in `utility/helpers.h`) may use `lower_snake_case` (`format_timestamp`, `local_timestamp_msec`). + +### Macros + +All macros use `UPPER_SNAKE_CASE` with the `BEAM_` prefix for public-API macros: `BEAM_LOG_ERROR`, `BEAM_VERIFY`, `BEAM_LOG_INFO`. Internal codegen macros omit the prefix but still use upper snake case: `COMPARISON_VIA_CMP`, `IMPLEMENT_GET_PARENT_OBJ`, `SERIALIZE`, `BIND_THIS_MEMFN`. + +--- + +## Memory Ownership + +### The `Ptr` typedef + +Every class that participates in shared lifetime declares a `Ptr` member type alias: + +```cpp +// Shared ownership — services, long-lived objects +using Ptr = std::shared_ptr; // wallet/core/wallet.h +using Ptr = std::shared_ptr; // wallet/core/wallet_db.h +using Ptr = std::shared_ptr; // utility/io/reactor.h + +// Exclusive ownership — data objects with clear single owner +typedef std::unique_ptr Ptr; // core/block_crypt.h +typedef std::unique_ptr Ptr; +using Ptr = std::unique_ptr; // utility/io/timer.h +``` + +Callers use `ClassName::Ptr` rather than spelling out the smart pointer type, so ownership semantics are expressed once at the declaration site. + +### Guidelines + +| Scenario | Type | +|---|---| +| Object with a single, clear owner (kernel, input, output) | `std::unique_ptr` | +| Object shared between subsystems (wallet, reactor, DB) | `std::shared_ptr` | +| Non-owning reference / observer | raw pointer (`T*`) or raw reference (`T&`) | +| Optional pointer, not owned | raw pointer initialized to `nullptr` | + +`beam::Ptr<>` does not appear as a standalone alias in the codebase; ownership is expressed through the per-class `Ptr` typedef described above. + +--- + +## Error Handling + +### `beam::Exc` — Recoverable Exceptions + +The primary exception type is `beam::Exc`, derived from `std::runtime_error`: + +```cpp +struct Exc : public std::runtime_error { + uint32_t m_Type; + + static void Fail(); // throws with empty message + static void Fail(const char*); // throws with message + static void Test(bool b) { if (!b) Fail(); } +}; +``` + +`Exc::Test(cond)` is the preferred assertion-to-exception idiom: it reads like a guard clause and avoids `if (!cond) throw`. + +### `Exc::Checkpoint` — Contextual Breadcrumbs + +`Exc::Checkpoint` is a thread-local linked list of context objects that are dumped when an exception is thrown. Concrete implementations provide a `Dump(std::ostream&)` override. `CheckpointTxt` is the lightweight string variant: + +```cpp +Exc::CheckpointTxt cp("verifying kernel"); +// ... code that may throw ... +// On exception, "verifying kernel" appears in the error output +``` + +The logger integrates with checkpoints via `BEAM_LOG_MESSAGE << FlushAllCheckpoints{}`. + +### `beam::CorruptionException` — Non-Recoverable Errors + +`CorruptionException` is intentionally not derived from `std::exception`. It signals database or block corruption that cannot be recovered in-process and should not be caught at intermediate call sites. It propagates to the top-level handler, which shuts down the node cleanly. + +### Network Errors: `proto::NodeConnection::OnDisconnect` + +Network layer errors do not throw; they invoke the virtual callback: + +```cpp +virtual void OnDisconnect(const DisconnectReason&) {} +``` + +Subclasses override `OnDisconnect` to clean up connection state. The `DisconnectReason` carries an error code and a human-readable description. This pattern avoids exception propagation across async boundaries. + +--- + +## Serialization + +### YAS Binary Archive + +Beam uses the **YAS** (Yet Another Serialization) library for binary serialization, configured as: + +```cpp +constexpr int SERIALIZE_OPTIONS = + yas::binary | yas::no_header | yas::elittle | yas::compacted; +``` + +- `binary` — raw binary format, not JSON or text +- `no_header` — no version header in the byte stream +- `elittle` — explicit little-endian for all integers +- `compacted` — variable-length encoding for integers + +### The `SERIALIZE(...)` Macro + +Structs declare serialization inline using the `SERIALIZE` macro from `utility/serialize_fwd.h`: + +```cpp +struct HeightPos { + Height m_Height = 0; + uint32_t m_Pos = 0; + + template void serialize(Archive& ar) const { + ar & m_Height & m_Pos; + } + template void serialize(Archive& ar) { + ar & m_Height & m_Pos; + } +}; +// Equivalent — generated by: +SERIALIZE(m_Height, m_Pos) +``` + +The macro generates both const and non-const overloads. Use the macro for new structs; spell it out only when custom logic is needed inside `serialize`. + +### `Serializer` and `Deserializer` + +```cpp +// Write +beam::Serializer ser; +ser & myObject; +auto [ptr, size] = ser.buffer(); + +// Read +beam::Deserializer deser; +deser.reset(ptr, size); +deser & myObject; +``` + +For fixed-size on-stack buffers use `StaticBufferSerializer` (default 100 KB). For size estimation without storing data, use `SerializerSizeCounter`. + +--- + +## IO and Reactor Model + +### `io::Reactor` + +All async I/O runs through `io::Reactor`, a thin wrapper around **libuv**. A single reactor per thread owns the event loop: + +```cpp +auto reactor = io::Reactor::create(); // returns Reactor::Ptr +{ + io::Reactor::Scope scope(*reactor); // registers as thread-local current reactor + reactor->run(); // blocks until reactor->stop() is called +} +``` + +`Reactor::Scope` is an RAII guard that sets the thread-local current reactor. `Reactor::get_Current()` retrieves it from anywhere on that thread. + +### Timers + +```cpp +io::Timer::Ptr timer = io::Timer::create(*reactor); +timer->start(intervalMs, /*isPeriodic=*/true, [&]() { + // callback fires every intervalMs +}); +``` + +`Timer::Ptr` is `std::unique_ptr`. Destroying the `Ptr` cancels the timer. The callback is stored as `std::function`. + +### TCP Connections + +TCP connect/accept use `std::function` callbacks passed at connection time: + +```cpp +reactor->tcp_connect(address, tag, + [](uint64_t tag, std::unique_ptr&& stream, io::ErrorCode ec) { + if (ec != 0) { /* handle error */ return; } + // stream is ready + }, + timeoutMs +); +``` + +All network objects (`TcpStream`, `TcpServer`, `SslStream`) inherit from `Reactor::Object`, which owns a `uv_handle_t*` and a `Reactor::Ptr` back-reference. + +### `GracefulIntHandler` + +`Reactor::GracefulIntHandler` catches `SIGINT`/`SIGTERM` (or `Ctrl+C` on Windows) and calls `reactor->stop()`. Instantiate one per process to get clean shutdown behaviour: + +```cpp +io::Reactor::GracefulIntHandler intHandler(*reactor); +reactor->run(); +``` + +--- + +## RAII Scope Guards + +The `Scope` pattern recurs throughout Beam to set thread-local or global context for the lifetime of a block: + +| Class | What it sets | +|---|---| +| `io::Reactor::Scope` | Current reactor on this thread | +| `Executor::Scope` | Current parallel executor on this thread | +| `Rules::Scope` | Consensus parameters (used in tests to override fork heights) | +| `NodeDB::Transaction` | Database transaction | + +All follow the same pattern: constructor records the previous value, destructor restores it. + +--- + +## Common Macros + +### `IMPLEMENT_GET_PARENT_OBJ` + +Used when an inner struct needs access to its enclosing object without storing an explicit back-pointer. It computes the parent pointer arithmetically from `this` using offsetof-style arithmetic: + +```cpp +struct DB : public NodeDB { + void OnModified() override { get_ParentObj().OnModified(); } + IMPLEMENT_GET_PARENT_OBJ(NodeProcessor, m_DB) +} m_DB; +``` + +The generated `get_ParentObj()` returns a reference to the enclosing `NodeProcessor`. An `assert` in the macro validates the pointer computation in debug builds. + +### `COMPARISON_VIA_CMP` + +Generates all six comparison operators from a single `int cmp(const T&) const` method: + +```cpp +struct Blob { + int cmp(const Blob&) const; + COMPARISON_VIA_CMP +}; +``` + +### `BIND_THIS_MEMFN(M)` + +Wraps a member function pointer into a `std::function` lambda bound to `this`: + +```cpp +reactor->tcp_connect(addr, tag, BIND_THIS_MEMFN(OnConnected), timeout); +// equivalent to: +// std::bind_memfn(this, &ClassName::OnConnected) +``` + +### `BEAM_VERIFY(x)` + +Like `assert`, but preserves the expression in release builds as a void cast (side-effect safe, no check). Use for expressions that must be evaluated in release but whose failure is non-fatal in production. + +--- + +## X-Macro Pattern for Message Types + +The node-to-node protocol (`core/proto.h`) uses **X-macros** to declare all message types once and expand them into struct definitions, handler declarations, and dispatch tables: + +```cpp +// Declaration: each message lists its fields +#define BeamNodeMsg_NewTip(macro) \ + macro(Block::SystemState::Full, Description) + +// Expansion: generates struct NewTip { Block::SystemState::Full Description; }; +// and virtual void OnMsg(NewTip&&) {} in NodeConnection +``` + +The same macro set is used to generate serialization code and the handler virtual methods. Adding a new message type requires only a new `BeamNodeMsg_Foo(macro)` definition and adding `Foo` to the `BeamNodeMsgsAll` list. + +--- + +## Logging + +All logging goes through the `beam::Logger` singleton, accessed via macros: + +```cpp +BEAM_LOG_INFO() << "processing block " << height; +BEAM_LOG_WARNING() << "unexpected state: " << TRACE(value); +BEAM_LOG_ERROR() << "failed to apply tx: " << errorCode; +``` + +The macros check `Logger::will_log(level)` before constructing the `LogMessage` object, so disabled log levels cost nothing. In release builds (`NDEBUG`), `BEAM_LOG_DEBUG()` and `BEAM_LOG_VERBOSE()` expand to a no-op `LogMessageStub` that is optimized away entirely. + +`TRACE(var)` is a shorthand that emits `" var="` for quick variable printing. + +Logger instances are created as `std::shared_ptr` RAII objects; when all references are released the logger is flushed and torn down. + +--- + +## CMake Module Structure + +### Adding a New Library + +The standard pattern, illustrated by `core/CMakeLists.txt`: + +```cmake +set(MY_LIB_SRC + file1.cpp + file2.cpp +) +add_library(mylib STATIC ${MY_LIB_SRC}) +target_link_libraries(mylib + PUBLIC + utility # exposed in headers + Boost::boost + PRIVATE + secp256k1 # implementation detail only +) +``` + +- **`PUBLIC` dependencies** propagate to consumers of `mylib`. +- **`PRIVATE` dependencies** are hidden; consumers do not need them. + +### Test Subdirectories + +Unit tests live in `unittest/` subdirectories and are guarded by a CMake option: + +```cmake +if(BEAM_TESTS_ENABLED) + add_subdirectory(unittest) +endif() +``` + +This keeps test binaries out of production builds. Test targets are plain executables registered with `add_test()` via the `AddTest` module included at the top level. + +### Beam Interface Target + +A top-level `INTERFACE` target named `beam` carries the global include path and feature requirements: + +```cmake +add_library(beam INTERFACE IMPORTED GLOBAL) +target_include_directories(beam INTERFACE + ${PROJECT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR}/3rdparty) +target_compile_features(beam INTERFACE cxx_std_17) +``` + +All library targets link against `beam` to pick up the include path and standard requirement. + +--- + +## Unit Test Conventions + +Test files live in `unittest/` inside the relevant subsystem directory: + +- `core/unittest/ecc_test.cpp`, `core/unittest/storage_test.cpp` +- `node/unittests/` + +There is no single test framework dependency. Tests are standalone executables that `assert()` or call a lightweight `BEAM_VERIFY` helper. Each test file includes directly from its parent subsystem using relative paths (`../ecc_native.h`). + +Tests that need to manipulate consensus parameters use `Rules::Scope` to override fork heights, then restore the original state on exit. diff --git a/core-tech/Beam-Equihash-specification.md b/core-tech/Beam-Equihash-specification.md deleted file mode 100644 index 08eccab..0000000 --- a/core-tech/Beam-Equihash-specification.md +++ /dev/null @@ -1,15 +0,0 @@ -# Beam Equihash specification - -## Chosen parameters -`N = 150` -`K = 5` - -## Hash generation convention -Since 150 in not a multiple of 8 we pick 19 full bytes and clear lower 2 bits of 18th byte. -We can get only 3 hashes from 512-bit **blake2** output. -Expected blake2 hash output size is `3 * 19 = 57` bytes - - -## Implementation for CPU -Beam’s Equihash implementation for CPU is based on zcash’s version. -[https://github.com/BeamMW/beam/blob/master/3rdparty/crypto/equihash_impl.cpp](https://github.com/BeamMW/beam/blob/master/3rdparty/crypto/equihash_impl.cpp) \ No newline at end of file diff --git a/core-tech/Beam-Node-Explorer-API.md b/core-tech/Beam-Node-Explorer-API.md deleted file mode 100644 index 487327f..0000000 --- a/core-tech/Beam-Node-Explorer-API.md +++ /dev/null @@ -1,243 +0,0 @@ - - -# Beam Node Explorer API - -The Node Explorer provides information about current chain state and blocks. - -## How to use - -Find `explorer-node` binary in the `explorer` subdirectory and run with the following arguments: - -``` -Node explorer options: - -h [ --help ] list of all options - --peer arg (=172.104.249.212:8101) peer address - --port arg (=10000) port to start the local node on - --api_port arg (=8888) port to start the local api server on -``` - -`./explorer-node.exe --peer eu-node01.mainnet.beam.mw:8100 --api_port=8080` for example. -It may take some time (a few hours) on the first start to load all the info from chain. - -## API - -### status - -`GET http://x.x.x.x:port/status` - -_Description_: Gets current blockchain status. - -_Response_: -```json -{ - "chainwork": "0x38594101d0a0", - "hash": "7353b5e4ad29a2ffa5f7952749d1eb04acedd82215b1f4f01d75107165f4622b", - "height": 20531, - "low_horizon": 19090, - "timestamp": 1550158283, - "shielded_outputs_per_24h": 14, - "shielded_outputs_total": 16919, - "shielded_possible_ready_in_hours": 120 -} -``` -*** -### block - -`GET http://x.x.x.x:port/block?height={height}` -or -`GET http://x.x.x.x:port/block?hash={hash}` -or -`GET http://x.x.x.x:port/block?kernel={kernel}` - -_Description_: Gets block info for specified `height`, `hash` or `kernel`. - -_Response_: -```json -{ - "chainwork": "0x384fdc718a20", - "difficulty": 157.9972152709961, - "found": true, - "hash": "c2a7315b63b1de6106a185c1c79219001ef5e3a07c217db227b079bbb9dd9b64", - "height": 20516, - "inputs": [], - "kernels": [ - { - "excess": "0x60413b5a09858312403190721938463ca22d7d87981a024873ddfa204a399eec", - "fee": 0, - "id": "d72684dba6255b2fe8631be9df764ee3c984cb0c9f386a8cf71f566acebd197d", - "maxHeight": 18446744073709552000, - "minHeight": 20516 - } - ], - "outputs": [ - { - "coinbase": true, - "commitment": "0x75329071d041e7828a57cbf2f63fb8db21543f35c1c2291d5c26c20d9b11465a", - "incubation": 0, - "maturity": 20756 - } - ], - "prev": "4b9e35b467b416e0d307dd94bd2fdce6e720b6b3a029dca822ccab3ac57c6d22", - "subsidy": 8000000000, - "rate_btc": "0.00001551", - "rate_usd": "0.231282", - "timestamp": 1550157362 -} -``` -*** -### blocks - -`GET http://x.x.x.x:port/blocks?height={start}&n={count}` - -_Description_: Gets blocks info for specified range, where `count` should be <= 1500. - -_Response_: -```json -[ - { - "chainwork": "0x380b69b2d420", - "difficulty": 161.94402313232422, - "found": true, - "hash": "2107b173f174972c8ec7543ab731bf1905d24d101f45b42d5f0cd64853e4c38e", - "height": 20402, - "inputs": [], - "kernels": [ - { - "excess": "0x3829270cf74d473af83015501a83747b5b8c75c0d13303569a352bfe53b4ef4b", - "fee": 0, - "id": "3d0bed1e452c911f830351c671696f51e4a6a9086aeb7a059fc027a0db9c84a0", - "maxHeight": 18446744073709552000, - "minHeight": 20402 - } - ], - "outputs": [ - { - "coinbase": true, - "commitment": "0xb4261a4a7fabe181f6dd7e766410cf1aba8892fd2f41d3a7ff9378a4811521ff", - "incubation": 0, - "maturity": 20642 - } - ], - "prev": "09cf95acda1e9c3e8b1a45873fd9ef1d744d6645d16bd6b8c5e9ae8dfe2d0b1a", - "subsidy": 8000000000, - "rate_btc": "0.00001551", - "rate_usd": "0.231282", - "timestamp": 1550150788 - }, - { - "chainwork": "0x380ac7c128a0", - "difficulty": 162.0944366455078, - "found": true, - "hash": "09cf95acda1e9c3e8b1a45873fd9ef1d744d6645d16bd6b8c5e9ae8dfe2d0b1a", - "height": 20401, - "inputs": [], - "kernels": [ - { - "excess": "0x554a6ef457d33abddcb98169fcd7fe68a7aa94bc2145a40f39d07ace7b43c0de", - "fee": 0, - "id": "c68cddd64a07974a1d5ea73eb4333a9b732a5b9ac705546217fa66d2ba5e8dd8", - "maxHeight": 18446744073709552000, - "minHeight": 20401 - } - ], - "outputs": [ - { - "coinbase": true, - "commitment": "0x6fd9e1124f91a744c7043f2873716094e1a6cc3a8ae9ca5278a1a421a7622301", - "incubation": 0, - "maturity": 20641 - } - ], - "prev": "9a8053f05ed7b6575770e002100025fa58452e307cf73d3594cbcd861fa5035a", - "subsidy": 8000000000, - "rate_btc": "0.00001551", - "rate_usd": "0.231282", - "timestamp": 1550150719 - }, - { - "chainwork": "0x380a25a8fba0", - "difficulty": 161.4037857055664, - "found": true, - "hash": "9a8053f05ed7b6575770e002100025fa58452e307cf73d3594cbcd861fa5035a", - "height": 20400, - "inputs": [], - "kernels": [ - { - "excess": "0x7eef6fa3449e87dde801fec11cd6cec8b448a87f7bd1231cff668904ee6045d5", - "fee": 0, - "id": "bee59b34ea59a95e9fb415d34de3cc34416debcc1e14fd993f749b2aaee9b14d", - "maxHeight": 18446744073709552000, - "minHeight": 20400 - } - ], - "outputs": [ - { - "coinbase": true, - "commitment": "0x3b8a5d665b08119b8b8ee98c831089e0f7b3219ee92b3cf9d749777349ffd285", - "incubation": 0, - "maturity": 20640 - } - ], - "prev": "34ce853ef5d9b6878bb694b5eec0620217d2b5f68f36cfdfc9c3bd4f1ae67107", - "subsidy": 8000000000, - "rate_btc": "0.00001551", - "rate_usd": "0.231282", - "timestamp": 1550150667 - } -] -``` -*** -### swap totals - -`GET http://x.x.x.x:port/swap_totals` - -_Description_: Return total amounts for all swap offers. - -_Response_: -```json -{ - "beams_offered": "15", - "bicoin_cash_offered": "3", - "bitcoin_offered": "0", - "dash_offered": "0", - "dogecoin_offered": "0", - "litecoin_offered": "10", - "qtum_offered": "0", - "total_swaps_count": 2 -} -``` -*** -### swap offers - -`GET http://x.x.x.x:port/swap_offers` - -_Description_: Return swap offers from offer board. - -_Response_: -```json -[ - { - "beam_amount": "3", - "height_expired": 253126, - "min_height": 252406, - "status": 0, - "status_string": "pending", - "swap_amount": "3", - "swap_currency": "BCH", - "time_created": "2020.11.06 18:31:54", - "txId": "1b726d0adffe45c993b801c8bb46184e" - }, - { - "beam_amount": "12", - "height_expired": 253126, - "min_height": 252406, - "status": 0, - "status_string": "pending", - "swap_amount": "10", - "swap_currency": "LTC", - "time_created": "2020.11.06 18:31:39", - "txId": "1b837edae2904b658f95a7b5e84c7731" - } -] -``` -*** \ No newline at end of file diff --git a/core-tech/Beam-Technical-Specifications.md b/core-tech/Beam-Technical-Specifications.md index 360f8a7..2017962 100644 --- a/core-tech/Beam-Technical-Specifications.md +++ b/core-tech/Beam-Technical-Specifications.md @@ -6,7 +6,5 @@ BEAM implements the MW protocol (with some extensions), which is based on ellipt * [Core transaction elements](https://github.com/beam-mw/beam/wiki/Core-transaction-elements) * [Blocks, headers, System States: concept, relevant structures and values](https://github.com/beam-mw/beam/wiki/System-state,-header,-block) * [System State in-depth](https://github.com/beam-mw/beam/wiki/System-state-in-depth) -* Node - * [Initial synchronization](https://github.com/beam-mw/beam/wiki/Node-initial-synchronization) * [Secure bulletin board system (SBBS)](https://github.com/BeamMW/beam/wiki/Secure-bulletin-board-system-(SBBS)) * [Beam Equihash specification](https://github.com/BeamMW/beam/wiki/Beam-Equihash-specification) \ No newline at end of file diff --git a/core-tech/Beam-Wallet-Database.md b/core-tech/Beam-Wallet-Database.md deleted file mode 100644 index 50d649e..0000000 --- a/core-tech/Beam-Wallet-Database.md +++ /dev/null @@ -1,100 +0,0 @@ -Since in Mimblewimble only UTXO related information is available on chain, most of the Wallet state should be maintained locally and store in the Wallet Database, which is described in this chapter. - -Beam Wallet stores and tracks information about four key entities: -1. Coins -2. Addresses -3. Transactions -4. Blockchain State - -The interface for the database is specified in the [wallet_db.h](https://github.com/BeamMW/beam/blob/56e9cdd7be211649a576fa15d3f0a97922ae2acd/wallet/wallet_db.h#L164) file - -Beam currently uses sqlite relational database in the implementation - -# Coins - -We will start with the [definition](https://github.com/BeamMW/beam/blob/56e9cdd7be211649a576fa15d3f0a97922ae2acd/wallet/wallet_db.h#L41) of a Coin structure, which represents a UTXO as it is seen by the wallet. - -```c++ - - // Describes a UTXO in the context of the Wallet - struct Coin - { - // Status is not stored in the database but can be - // deduced from the current blockchain state - enum Status - { - Unavailable, // initial status of a new UTXO - Available, // UTXO is currently present in the chain and can be spent - Maturing, // UTXO is present in the chain has maturity higher than current height (i.e coinbase or treasury) - Outgoing, // Available and participates in outgoing transaction - Incoming, // Outputs of incoming transaction, currently unavailable - ChangeV0, // deprecated. - Spent, // UTXO that was spent. Stored in wallet database until reset or restore - - count - }; - - Coin(Amount amount = 0, Key::Type keyType = Key::Type::Regular); - bool operator==(const Coin&) const; - bool operator!=(const Coin&) const; - bool isReward() const; - std::string toStringID() const; - Amount getAmount() const; - - typedef Key::IDV ID; // unique identifier for the coin (including value), can be used to create blinding factor - ID m_ID; - - Status m_status; // current status of the coin - Height m_maturity; // coin can be spent only when chain is >= this value. Valid for confirmed coins (Available, Outgoing, Incoming, Change, Spent, Maturing). - - // The following fields are used to derive the status of the transaction - Height m_confirmHeight; // height at which the coin was confirmed (appeared in the chain) - Height m_spentHeight; // height at which the coin was spent - - boost::optional m_createTxId; // id of the transaction which created the UTXO - boost::optional m_spentTxId; // id of the transaction which spernt the UTXO - - uint64_t m_sessionId; // Used in the API to lock coins for specific session (see https://github.com/BeamMW/beam/wiki/Beam-wallet-protocol-API#tx_split) - - bool IsMaturityValid() const; // is/was the UTXO confirmed? - Height get_Maturity() const; // would return MaxHeight unless the UTXO was confirmed - - std::string getStatusString() const; - static boost::optional FromString(const std::string& str); - }; -``` - - ## Deducing Coin Status - -By monitoring the state of the blockchain, the wallet can always deduce the current status of each coin by tracking the m_confirmHeight height and m_spentHeight. This is done in the `void DeduceStatus(const IWalletDB&, Coin&, Height hTop);` method which calls the `Coin::Status GetCoinStatus(const IWalletDB&, const Coin&, Height hTop);` method that in turn returns the current status of the coin. - -```c++ - -Coin::Status GetCoinStatus(const IWalletDB& walletDB, const Coin& c, Height hTop) -{ - if (c.m_spentHeight != MaxHeight) - return Coin::Status::Spent; - - if (c.m_confirmHeight != MaxHeight) - { - if (c.m_maturity > hTop) - return Coin::Status::Maturing; - - if (IsOngoingTx(walletDB, c.m_spentTxId)) - return Coin::Status::Outgoing; - - return Coin::Status::Available; - } - - if (IsOngoingTx(walletDB, c.m_createTxId)) - return Coin::Status::Incoming; - - return Coin::Status::Unavailable; -} -``` - -## Selecting coins for a specified amount - -Implemented in the `std::vector selectCoins(Amount amount) override;` method. The purpose of the function is to select Coins matching a specific amount (for example in sending scenario). Selection method should minimize number of Coins and the change outputs and hence use greedy strategy with some additional heuristics. Specific strategies for coin selection are implemented in the `struct CoinSelector3` in honor of three attempts to write an effective selector for large amount of coins. - - \ No newline at end of file diff --git a/core-tech/Beam-Web-Wallet-Starter-Kit.md b/core-tech/Beam-Web-Wallet-Starter-Kit.md index 19fc46f..80f7915 100644 --- a/core-tech/Beam-Web-Wallet-Starter-Kit.md +++ b/core-tech/Beam-Web-Wallet-Starter-Kit.md @@ -1,5 +1,3 @@ - - # Beam Web Wallet Starter Kit [working draft] Web wallet starter allows you easily integrate Beam with your service, create a bunch of wallets and manage them... (TODO) diff --git a/core-tech/Beam-news-channels.md b/core-tech/Beam-news-channels.md index 50fe2b2..cbed970 100644 --- a/core-tech/Beam-news-channels.md +++ b/core-tech/Beam-news-channels.md @@ -1,62 +1,142 @@ -Beam able to provide actual news and exchange rates to wallet users. -This implemented using signed messages of different types transmitted over the Bulletin Board System (BBS). -Such messages make possible for instance to notify wallet user with popup on new wallet application version release. -Each message is broadcasted over the network to wallet applications. -Broadcasted messages has to be signed with apropriate key to verify publisher. Wallet applications have publisher key to check if messages are valid. +Beam delivers real-time news and exchange rates to wallet users through signed messages broadcast over the **Bulletin Board System (BBS)** — a private, encrypted message-passing layer built into the Beam network protocol. Messages are cryptographically signed so wallets can verify the publisher's identity before acting on the content. + +Each broadcast message is transmitted to a dedicated BBS channel, propagates through nodes, and is received by listening wallet applications. Messages remain available on the network for **12 hours**. ## Broadcaster utility -The utility is used for news message dispatching. -Also utility has ability to generate new random publisher key pair. Private key should be keept in secret and used to sign broadcasted messages. Public key has to be embedded to the wallet application and can be shared to anyone who want to listen broadcast messages. + +The `broadcaster` binary is a command-line tool for creating and dispatching signed broadcast messages. It can also generate a publisher key pair. + +**Mandatory options for all transmit operations:** + +| Option | Description | +|--------|-------------| +| `-n`, `--node_addr` | Node address used as network entry point (e.g. `eu-node02.masternet.beam.mw:8100`) | +| `--key`, `--private_key` | 64-character hex private key used to sign messages | +| `--msg_type` | Message type: `update`, `exchange`, or `averify` | + +**General options:** + +| Option | Description | +|--------|-------------| +| `--command` | Command to run: `generate_keys` or `transmit` (default: `transmit`) | +| `--node_poll_period` | Node poll interval in milliseconds (default: `0` = persistent connection) | +| `--log_cleanup_days` | Log file retention in days (default: `5`) | +| `--config` | Path to configuration file (default: `bbs.cfg`) | ## Commands -`--command` - option used to specify command: -`generate_keys` - used to generate new random publisher key pair +### generate_keys + +Generates a new publisher key pair. The private key signs outgoing messages; the public key is embedded in wallet applications to validate incoming messages. + +``` +./broadcaster --command generate_keys +``` + +Output: +``` +Private key: f70c36f2d8342b66e3081ea4d87543566d6ad242c6e61dbf926d57ff42de0c59 +Public key: db617cedb17543375b602036ab223b67b06f8648de2bb04de047f485e7a9daec +``` + +Keep the private key secret. Share the public key with anyone who should receive and trust your broadcast messages. + +### transmit + +Sends a signed broadcast message to the network. `--command transmit` can be omitted — transmit is the default action. + +The node address, private key, and message type are always required. Additional options depend on the message type. + +## Message types + +### update — wallet version notification + +Notifies wallets that a new version of a client application is available. -`transmit` - used to send broadcast message +| Option | Description | +|--------|-------------| +| `--upd_ver`, `--update_version` | New version string: `x.y.z` (mobile) or `x.y.z.r` (desktop, where `r` is UI revision) | +| `--upd_type`, `--update_type` | Application type: `desktop`, `android`, or `ios` | -Option `--command` can be omitted. In such case `transmit` is considered as default action. +_Example:_ announce desktop wallet v1.8.9: -## Transmit command -The utility needs the address of a node (to serve as an entry point for the message) and the publisher private key specified in hex-format (to sign the message) always to be specified. +``` +./broadcaster -n "eu-node02.masternet.beam.mw:8100" \ + --key "f70c36f2d8342b66e3081ea4d87543566d6ad242c6e61dbf926d57ff42de0c59" \ + --msg_type 'update' \ + --upd_ver '1.8.9' \ + --upd_type 'desktop' +``` -### Mandatory options -`-n` - address of node +### exchange — currency exchange rate -`--key` - 64 characters long private key in HEX format +Publishes an exchange rate for a currency pair. -`--msg_type` - message type (`'update'`, `'exchange'`) +| Option | Description | +|--------|-------------| +| `--exch_curr`, `--exchange_curr` | Source currency: `beam`, `btc`, `ltc`, `qtum`, `doge`, `dash`, `ethereum`, `dai`, `usdt`, `wbtc`, `bch` | +| `--exch_rate`, `--exchange_rate` | Rate in fixed-point format where `100000000` = 1 unit | +| `--exch_unit`, `--exchange_unit` | Target currency: `usd` (default) or `btc` | -_Example:_ `-n "eu-node02.masternet.beam.mw:8100" --key "f70c36f2d8342b66e3081ea4d87543566d6ad242c6e61dbf926d57ff42de0c59" --msg_type 'exchange'` +_Example 1:_ 1 BEAM = 7.89654123 USD: -Only messages signed with valid publisher keys are processed by wallet applications. +``` +./broadcaster -n "eu-node02.masternet.beam.mw:8100" \ + --key "f70c36f2d8342b66e3081ea4d87543566d6ad242c6e61dbf926d57ff42de0c59" \ + --msg_type 'exchange' \ + --exch_curr 'beam' \ + --exch_rate '789654123' +``` -### Options for specific message types -Specific options have to be passed for each message type. +_Example 2:_ 1 BEAM = 1.23456789 BTC: -**In case of the message notifying about new wallet application release:** +``` +./broadcaster -n "eu-node02.masternet.beam.mw:8100" \ + --key "f70c36f2d8342b66e3081ea4d87543566d6ad242c6e61dbf926d57ff42de0c59" \ + --msg_type 'exchange' \ + --exch_curr 'beam' \ + --exch_rate '123456789' \ + --exch_unit 'btc' +``` -`--msg_type 'update'` +### averify — confidential asset verification -`--upd_ver` - new application version in format [x.y.z] +Publishes verification metadata for a [Confidential Asset](Confidential-assets). Wallets use this to display verified asset status, icons, and color branding. -`--upd_type` - released application type ('desktop', 'android' or 'ios') +| Option | Description | +|--------|-------------| +| `--asset_id` | Asset ID (32-bit unsigned integer; cannot be `0`, which is reserved for BEAM) | +| `--verified` | Verification status: `true` or `false` | +| `--predefined_icon` | Icon identifier string | +| `--predefined_color` | Color identifier string | -_Example:_ `--msg_type 'update' --upd_ver '1.8.9' --upd_type 'desktop'` will say new desktop wallet release v1.8.9 is available +_Example:_ -**In case of message distributing some currency exchange rate:** +``` +./broadcaster -n "eu-node02.masternet.beam.mw:8100" \ + --key "f70c36f2d8342b66e3081ea4d87543566d6ad242c6e61dbf926d57ff42de0c59" \ + --msg_type 'averify' \ + --asset_id 1 \ + --verified true \ + --predefined_icon 'beam_logo' \ + --predefined_color 'green' +``` -`--msg_type 'exchange'` +## Security model -`--exch_curr` - currency name ('beam', 'btc', 'ltc', 'qtum') +Only messages signed by a known publisher key are accepted by wallet applications. The broadcaster signs each message using the ECC (Schnorr) scheme. The corresponding public key must be compiled into the wallet application; messages signed with unknown keys are silently discarded. -`--exch_rate` - exchange rate value in fixed point format (100,000,000 = 1 unit) +The private key must be passed in 64-character hexadecimal format. Guard it carefully — anyone with the private key can publish trusted messages to all wallets that trust the corresponding public key. -`--exch_unit` - second currency name which states unit of exchange rate value ('btc', 'usd' - default) +### Embedded publisher public keys (beam-ui) -_Example 1:_ `--msg_type 'exchange' --exch_curr 'beam' --exch_rate '789654123'` will say 1 Beam = 7.89654123 USD +The desktop wallet ([beam-ui](https://github.com/BeamMW/beam-ui)) embeds one publisher public key per network, resolved at compile time via `get_BroadcastValidatorPublicKey()` in `beam/wallet/core/common.cpp`: -_Example 2:_ `--msg_type 'exchange' --exch_curr 'beam' --exch_rate '123456789' --exch_unit 'btc'` will say 1 Beam = 1.23456789 BTC +| Network | Public key | +|---------|------------| +| Mainnet | `8ea783eced5d65139bbdf432814a6ed91ebefe8079395f63a13beed1dfce39da` | +| Testnet | `dc3df1d8cd489c3fe990eb8b4b8a58089a7706a5fc3b61b9c098047aac2c2812` | +| Masternet | `db617cedb17543375b602036ab223b67b06f8648de2bb04de047f485e7a9daec` | +| Dappnet | `4c5b0b58caf69542490d1bef077467010a396cd20a4d1bbba269c8dff41da44e` | -_Common example:_ -`./broadcaster.exe -n "eu-node02.masternet.beam.mw:8100" --key "f70c36f2d8342b66e3081ea4d87543566d6ad242c6e61dbf926d57ff42de0c59" --msg_type 'update' --upd_ver '1.8.9' --upd_type 'desktop'` +The `BroadcastMsgValidator` loads the appropriate key on startup and rejects any message whose signature does not verify against it. \ No newline at end of file diff --git a/core-tech/Beam-signature-schemes.md b/core-tech/Beam-signature-schemes.md deleted file mode 100644 index 6b29156..0000000 --- a/core-tech/Beam-signature-schemes.md +++ /dev/null @@ -1,102 +0,0 @@ -## Oracles -Oracles are objects used to generate challenges needed to construct/verify non-interactive proofs. They interpret exposed transcript data in a standard way, and produce the challenges in a deterministic way. - - oracle <-- exposed_data_1 - oracle --> challenge_1 - oracle --> challenge_2 - oracle <-- exposed_data_2 - oracle --> challenge_3 - oracle --> challenge_4 - // ... - -## Schnorr's signature -We use Schnorr's signatures throughout the code. We prefer the form `[N, k]`, whereas `N` is the "public nonce", because it's batch-verifications compatible. - -In addition to the standard Schnorr's signature we use the following variations: -1. Signatures within a specific context (transcript). Instead of signing a specific message the signature operates on the given Oracle, which means it signs a specific transcript. -2. Generalized Schnorr's signatures, i.e. argument of knowledge of the commitment opening in terms of several generators. -3. Schnorr's multi-signatures. For a number of signatures in terms of the same set of generators we use a scheme of the form `[N, k1, k2, ..., kn]`. That is, only a single `N`. For the verification n challenges are derived. The soundness of such a signature can be shown by the same "extractor" technique used for standard Schnorr's signature for each secret key in reverse order. - -Worth to note: we also use the (3) in the context of a more complex transcript, where a complex proof proves, among other things, knowledge of various secret keys (such as Lelantus spend proof). - -# Biased Sigma protocol. -prove the knowledge of opening of 1-out-of-N, after a _Bias_ is subtracted (methodically) from all the elements. - -Inputs: -* Bias (EC point) -* Set of N elements (EC points). - -The proof is similar to the standard Sigma protocol, as described by Jens Groth. The differences are the following: -1. It operates on Oracle. Means - it's a part of a specific transcript, and it's not possible to separate it or tamper with it. -2. For performance reasons the _Bias_ is not technically subtracted from the set. Instead its cumulative coefficient (multiplier) is calculated, so that the _Bias_ is added later to the equation. -3. Since because of (2) the set is not actually modified - the whole proof is very batch-friendly. So in a similar way the coefficients of the elements in the set are updated after each individual proof, but their multi-exponentiation is deferred. - -### Padding - -If there are not enough elements in the set we use zeroes (points at infinity). For original Sigma protocol that'd be insecure (opening of point at infinity is trivial), however for all our use-cases it's fine because of the Bias, since all our proofs are about validation of the Bias, showing that it's a legit commitment of G (blinding factor) and something else. Using the Bias that consists of blinding factor only makes no sense for the attacker. - -## Asset proof -Proves that a given blinded generator H' satisfies H' = k•G + Hi, whereas Hi is a legit generator defined as: -* i > 0: Hi = CreateGenerator("B.Asset.Gen.V1 | i); -* i = 0: Hi = H (standard H-generator used for Beams) - -The proof is based on the biased Sigma proof described above. The prover chooses the window containing its generator by specifying the window first element. The window size is fixed in the consensus rules. Padding is not applicable, since Hi is assumed to be infinite series. - -* The Sigma protocol's proof is in terms of `G`-generator only -* Bias := H' -* Witness data: `i`, `k` (the blinding factor of the generator) - -### Question -the H' currently is NOT exposed to the Oracle used in Biased Sigma protocol. Means - an attacker can theoretically craft a false Sigma proof, and then substitute an appropriate H' that would fit the needed equation and make the proof valid. - -However I can't see how the attacker can use such an H' generator. Since it comes-out as a random EC point, it has no direct relation to any other generator, and can't be used to conceal negative values, serial number or etc. - -Should we expose H' to the oracle? Is it "nice-to-have", or essential? - -## Lelantus spend proof - -Proves that a legit element is withdrawn from the shielded pool. - -Inputs: -* `SpendPk` - spend public key, from which the serial number `s` is derived in a deterministic way. -* Optional: blinded Asset generator `H'` and _Asset Proof_, which proves its validity. -* `Commitment` - commitment to the element being-withdrawn. -* Shielded pool window - the list of commitments (EC points). - -Proves the following: -* The spend is signed by the secret key, the pre-image of `SpendPk`. -* `Commitment` is a commitment of the form k•G + H'•v. The validity of `v` (i.e. rangeproof) is not necessary. -* Serial number `s` (derived from `SpendPk`) corresponds to an element in the specified window. -* `Commitment` commits to the same value and asset type (Hi, v). - -### Methodically - -* _Asset Proof_ is verified if specified. Otherwise the asset generator is assumed `H` (used for Beams). -* Generalized Schnorr's signature proves `Commitment` is indeed of the form k•G + H'•v. -* Serial number `s` is derived from `SpendPk` -* Biased Sigma protocol is used for the rest: - * The Bias is: `Commitment + s•J` - * The proof is in terms of `G`-generator only. - * Witness data is the blinding factor difference. - -### Technically - -Technically there are 2 Schnorr's proofs here: validity of `Commitment`, and knowledge of pre-image of `SpendPk`. They are compressed into a single generalized multi-signature, i.e. the prover knows the opening of both `Commitment` and `SpendPk` in terms of `G` and `H'`. - -Note: Normally the `SpendPk` must be of the form k•G, and in our scheme we weaken this by allowing additional generator `H'`. But there seems to be no problem here if someone decides to used `SpendPk` that contains also the asset generator used for this element. - -In addition the `Commitment` is used twice in the protocol: in the generalized Schnorr's signature, and as a part of the Bias for the Sigma protocol. So instead of using it twice we aggregate its coefficient, and is it once in the equation. - -Finally the transcript is the following: - -* oracle <-- Sigma parameters (`n`,`M`) -* oracle <-- `Commitment' -* oracle <-- `SpendPk' -* oracle <-- `N' (public nonce of the Schnorr's multi-signature) -* oracle --> Challenge for `Commitment` -* oracle --> Challenge for `SpendPk -* <-- Schnorr's multi-signature: `kG`, `kH` -* oracle <-- Sigma protocol part 1 (A, B, C, D, G-vector) -* oracle --> Challenge for Sigma protocol -* <-- Sigma protocol part 2 (a, c, r, f-vector) - diff --git a/core-tech/Beam-wallet-protocol-SWAP-API-(BETA).md b/core-tech/Beam-wallet-protocol-SWAP-API-(BETA).md deleted file mode 100644 index 3f347da..0000000 --- a/core-tech/Beam-wallet-protocol-SWAP-API-(BETA).md +++ /dev/null @@ -1,413 +0,0 @@ -Swap API extends [Beam wallet protocol API](https://github.com/BeamMW/beam/wiki/Beam-wallet-protocol-API) - -requires: configured swap settings in `wallet.db` (by CLI or UI) - -## API - -API will include the following methods: - -- [swap_offers_list](#swap_offers_list) -- [swap_offers_board](#swap_offers_board) -- [swap_create_offer](#swap_create_offer) -- [swap_offer_status](#swap_offer_status) -- [swap_decode_token](#swap_decode_token) -- [swap_publish_offer](#swap_publish_offer) -- [swap_accept_offer](#swap_accept_offer) -- [swap_cancel_offer](#swap_cancel_offer) -- [swap_get_balance](#swap_get_balance) -- [swap_recommended_fee_rate](#swap_recommended_fee_rate) - -## swap_offers_list -Get all own swap offers with specified `status` and `swapCoin`. if `filter` not specified return all own swap offers. - -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 1236, - "method": "swap_offers_list", - "params": {} -} -``` -`<--` -```json -{ - "id": 1236, - "jsonrpc": "2.0", - "result": [ - { - "height_expired": 140726, - "min_height": 140696, - "receive_amount": 2000000000, - "receive_currency": "BEAM", - "send_amount": 100000000, - "send_currency": "BTC", - "status": 4, - "status_string": "expired", - "time_created": "2020.03.16 17:22:12", - "txId": "b35fd69030694009b8bf849140d9319e" - }, - { - "height_expired": 136300, - "min_height": 136270, - "receive_amount": 2000000000, - "receive_currency": "BEAM", - "send_amount": 100000000, - "send_currency": "BTC", - "status": 4, - "status_string": "expired", - "time_created": "2020.03.13 15:16:07", - "txId": "0d36d9db06f14071b18e1fdf4c429a14" - }, - { - "height_expired": 133125, - "min_height": 133095, - "receive_amount": 2000000000, - "receive_currency": "BEAM", - "send_amount": 100000000, - "send_currency": "BTC", - "status": 4, - "status_string": "expired", - "time_created": "2020.03.11 10:14:16", - "txId": "f859fe65bd434522af16cfc7d31c43db" - }, - { - "height_expired": 123428, - "min_height": 123398, - "receive_amount": 200000000, - "receive_currency": "BEAM", - "send_amount": 100000000, - "send_currency": "BTC", - "status": 2, - "status_string": "completed", - "time_created": "2020.03.04 16:37:44", - "txId": "d218356770b34fe4aeab01fb12c6074c" - } - ] -} -``` -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 1236, - "method": "swap_offers_list", - "params": { - "filter" : { - "status" : 2 - } - } -} -``` -`<--` -```json -{ - "id": 1236, - "jsonrpc": "2.0", - "result": [ - { - "height_expired": 123428, - "min_height": 123398, - "receive_amount": 200000000, - "receive_currency": "BEAM", - "send_amount": 100000000, - "send_currency": "BTC", - "status": 2, - "status_string": "completed", - "time_created": "2020.03.04 16:37:44", - "txId": "d218356770b34fe4aeab01fb12c6074c" - } - ] -} -``` - -## swap_offers_board -Get all swap offers from offers board with specified `swapCoin`. if `swapCoin` not specified return all known swap offers. - - -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 1236, - "method": "swap_offers_board", - "params": {} -} -``` -`<--` -```json -{ - "id": 1236, - "jsonrpc": "2.0", - "result": [ - { - "is_my_offer": false, - "is_public": true, - "height_expired": 103173, - "min_height": 103143, - "receive_amount": 100000000, - "receive_currency": "BTC", - "send_amount": 1200000000, - "send_currency": "BEAM", - "status": 0, - "status_string": "pending", - "time_created": "2020.03.04 16:37:44", - "token": "6xfTV5NF6JWbcZLupbhTHNEQqnGjHQEL5L5VsT4XhAkMw9GqTzMowAVQVhpUWSAvg8cqtfV1s6BKSa75zk8vCMK7mVP7xNjATJ2pPCNcu3U8UYz4rce4gRuTBuYNDbyY7zFEEzMZL2RKKjGCtEN2bpCif8GuGUekzRc8hiL", - "txId": "f87b06cf752040cdaefbf99831bc3e80" - }, - - ] -} -``` - -## swap_create_offer -Creates swap offer that can be published on a board or sent directly to other side - -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 1236, - "method": "swap_create_offer", - "params": { - "send_amount": 44000000000, - "send_currency": "beam", - "receive_amount": 2000000000, - "receive_currency": "btc", - "beam_fee": 100, - "fee_rate": 90000, - "offer_expires": 30, - "comment": "API" - } -} -``` -`<--` -```json -{ - "id": 1236, - "jsonrpc": "2.0", - "result": { - "txId": "062757f5ea62448589d977aa05c5782f", - "token": "TJeBeBjF48BdyxTDJg8gjogn9eDKQUx1Nm18iHPw53YoFipxKKkutNUV5AkVnFyLohpSrWsrnFNLGyBakVGY4Y2URdSQ52cDACHGDuHjYVpjMz8KN7q6rJrWGEXah2wJXHxrARYbAh7dTizdtQxaNVj34dfr8wKkfPFC7vmk" - } -} -``` - -## swap_offer_status -Shows your offer status or swap transaction in which you are participating - -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 126, - "method": "swap_offer_status", - "params": { - "tx_id": "b35fd69030694009b8bf849140d9319e" - } -} -``` -`<--` -```json -{ - "id": 126, - "jsonrpc": "2.0", - "result": { - "height_expired": 140726, - "min_height": 140696, - "status": 4, - "status_string": "expired", - "time_created": "2020.03.16 17:22:12", - "tx_id": "b35fd69030694009b8bf849140d9319e" - } -} -``` - -## swap_decode_token -Decode swap token - -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 1236, - "method": "swap_decode_token", - "params": { - "token" : "6xfNAUemTbmp7KRCRydiGStMZe6oRh59LzS7uk1V4eTrUX1mKcCGY7jdtMtSs4XLt6Ug8jWnepMEZCrqSUw7PeKRDZ8yyVZu1WHXzootpybBjX3nVxxHRSdk4ncBGDh1cssmiJhswZC9PfsaJmRKqXJM3x9tcX7EZn5Vjg8" - } -} -``` -`<--` -```json -{ - "id": 1236, - "jsonrpc": "2.0", - "result": { - "height_expired": 123428, - "is_my_offer": false, - "is_public": false, - "min_height": 123398, - "receive_amount": 200000000, - "receive_currency": "BEAM", - "send_amount": 100000000, - "send_currency": "BTC", - "time_created": "2020.03.04 16:37:44", - "tx_id": "d218356770b34fe4aeab01fb12c6074c" - } -} -``` - -## swap_publish_offer -Publicates offer on a board - -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 126, - "method": "swap_publish_offer", - "params": { - "token": "TJeBeBjF48BdyxTDJg8gjogn9eDKQUx1Nm18iHPw53YoFipxKKkutNUV5AkVnFyLohpSrWsrnFNLGyBakVGY4Y2URdSQ52cDACHGDuHjYVpjMz8KN7q6rJrWGEXah2wJXHxrARYbAh7dTizdtQxaNVj34dfr8wKkfPFC7vmk" - } -} -``` -`<--` -```json -{ - "id": 126, - "jsonrpc": "2.0", - "result": { - "is_my_offer": true, - "is_public": true, - "height_expired": 103173, - "min_height": 103143 - "receive_amount": 2000000000, - "receive_currency": "BTC", - "send_amount": 44000000000, - "send_currency": "BEAM", - "status": 0, - "status_string": "pending", - "time_created": "2020.02.19 11:29:19", - "token": "TJeBeBjF48BdyxTDJg8gjogn9eDKQUx1Nm18iHPw53YoFipxKKkutNUV5AkVnFyLohpSrWsrnFNLGyBakVGY4Y2URdSQ52cDACHGDuHjYVpjMz8KN7q6rJrWGEXah2wJXHxrARYbAh7dTizdtQxaNVj34dfr8wKkfPFC7vmk", - "txId": "062757f5ea62448589d977aa05c5782f" - } -} -``` - -## swap_accept_offer -Starts the swap offer published on a board or received directly from other side - -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 1236, - "method": "swap_accept_offer", - "params": { - "beam_fee": 100, - "fee_rate": 90000, - "comment": "API-accept", - "token" : "6xfTV5NF6JWbcZLupbhTHNEQqnGjHQEL5L5VsT4XhAkMw9GqTzMowAVQVhpUWSAvg8cqtfV1s6BKSa75zk8vCMK7mVP7xNjATJ2pPCNcu3U8UYz4rce4gRuTBuYNDbyY7zFEEzMZL2RKKjGCtEN2bpCif8GuGUekzRc8hiL" - } -} -``` -`<--` -```json -{ - "id": 1236, - "jsonrpc": "2.0", - "result": { - "height_expired": 103173, - "min_height": 103143, - "receive_amount": 100000000, - "receive_currency": "BTC", - "send_amount": 1200000000, - "send_currency": "BEAM", - "status": 1, - "status_string": "in progress", - "time_created": "2020.02.19 11:20:50", - "txId": "f87b06cf752040cdaefbf99831bc3e80" - } -} -``` - -## swap_cancel_offer -Cancel swap offer (cancels running transaction, return true if successfully canceled or error with the reason) - -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 126, - "method": "swap_cancel_offer", - "params": { - "txId" : "a13525181c0d45b0a4c5c1a697c8a7b8" - } -} -``` -`<--` -```json -{ - "id": 126, - "jsonrpc": "2.0", - "result": true -} -``` - -## swap_get_balance - -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 126, - "method": "swap_get_balance", - "params": { - "coin": "btc" - } -} -``` -`<--` -```json -{ - "id": 126, - "jsonrpc": "2.0", - "result": { - "available": 129899985060 - } -} -``` - -## swap_recommended_fee_rate - -`-->` -```json -{ - "jsonrpc": "2.0", - "id": 127, - "method": "swap_recommended_fee_rate", - "params": { - "coin": "btc" - } -} -``` -`<--` -```json -{ - "id": 127, - "jsonrpc": "2.0", - "result": { - "feerate": 35123 - } -} -``` - -### Swap offers statuses description -``` -Pending (0) - waiting for someone accept your offer, or waiting when you accept offer -InProgress (1) - to indicate that swap transaction in progress, you should stay online -Completed (2) - a swap transaction is completed -Canceled (3) - "Cancelled" (by You) -Expired(4) - offer lifetime expired -Failed (5) - failed for some reason -``` \ No newline at end of file diff --git a/core-tech/Blocks,-headers,-system-states.-Concept,-relevant-structures-and-values.md b/core-tech/Blocks,-headers,-system-states.-Concept,-relevant-structures-and-values.md deleted file mode 100644 index 05fae0d..0000000 --- a/core-tech/Blocks,-headers,-system-states.-Concept,-relevant-structures-and-values.md +++ /dev/null @@ -1,95 +0,0 @@ -First let's define terminology. - -* System state - is a _valid_ state of the system, which is fully defined by all the existing data (more about this later) -* Block - is an information used to perform a _transition_ from one system state to another. - -To avoid ambiguity we refrain from saying "block hash" or "block height", because, strictly speaking, those are properties of the System state. OTOH blocks are just transactions, which may be combined. - -Each state has a header, and there are several structures related to it. - -### SystemState::ID - -Consists of: -* `Merkle::Hash m_Hash` -* `Height m_Height` - -Used to denote an existing known state. (Hash would be enough, but we decided to include the height as well) - -### SystemState::Full - -A full header bound to the system state. Consists of: -* `Height m_Height` - * Our convention: `m_Height = 0` - is for initial system state, no data and nothing is interpreted yet. The next state, which is achieved after interpreting the genesis block, has `m_Height = 1`. -* `Merkle::Hash m_Prev` - * explicit reference to prev -* `Difficulty::Raw m_ChainWork` - * Cumulative chainwork (sum of difficulties) including the difficulty of this state. -* `Merkle::Hash m_Definition` - * The Hash of the full system definition in this state (more about this later) -* `Timestamp m_TimeStamp` -* `PoW m_PoW` - * Proof-of-Work. An equihash solution. - * Contains the `Difficulty` of this specific state. - -The _System State Hash_ is calculated from all the header parameters, including PoW. Not to be confused with `m_Definition`, it's different. - -Note that when many such headers should be presented for consecutive states - there are 3 redundant elements: -* `m_Prev` - obviously equals to the Hash of the previous state -* `m_Height` - just increased by 1 -* `m_ChainWork` - can be calculated from previous header, after adding the difficulty of this one. - -So for those cases there are appropriate structures defined: `SystemState::Sequence::Prefix` and `SystemState::Sequence::Element`. And the `SystemState::Full` just inherits them both. - -### PoW - -BEAM uses equihash mining algorithm. It includes the following: -* `Difficulty m_Difficulty` -* `m_Nonce` - arbitrary 64-bit values -* `m_Indices` - the solution, array of sorted indexes. - -The input for the solver/verifier is constructed from all the Header fields, except the PoW solution itself. But it does include the `m_Nonce` and the `m_Difficulty`. So that the difficulty must be selected before the mining, and can't be adjusted a-posteriori, if the solution eventually could reach higher difficulty (reached a smaller target). - -**Note**: The whole PoW parameters, including the solution, are accounted for in calculating the System State Hash. This is an intentional design decision, which ensures it's not possible to construct the chain of the system state headers without actually mining them, and then be able to mine only some specific states on-demand. This assumption is essential for _FlyClient_ protocol. - -# System Definition Hash - -One of the most important parameters. The complete system state is constructed from the following data: -* All the existing non-spent UTXOs, stored with the relevant parameters in an `UtxoTree`, which is a variant of the `RadixTree`. -* All the existing Kernels, stored in the `RadixTree`. -* MMR of all the inherited system states. - -The System Definition Hash is defined as: - -`System-Definition-Hash = Hash [ InheritedStates.Root | Hash (UTXOs.Root | Kernels.Root) ]` - -After interpreting the appropriate block, the Full Node evaluates the actual System-Definition-Hash, and compares it with value in the State Header. - -Note also that it's actually a root hash of the Merkle tree, whose elements are another Merkle trees. Using this property it's possible to generate and verify Merkle proofs for: -* Existing UTXO in the current system state -* Existing Kernel -* Inherited System State - -All the Verifier needs is the proof, and the System Definition Hash. In addition to verifying the proof, the Verifier ensures the proof suffix is in accordance to the known part of the Merkle tree structure. Means: -* For UTXOs and Kernels the Verifier knows the hashing direction of the last 2 elements. -* For inherited System State the Verifier knows the whole Merkle path, hence all the hashing directions are deduced automatically. - -# History compression, Macroblocks - -BEAM fully supports the excellent MW feature of history compression with removal of the spent outputs. However unlike what was written in the original MW whitepaper (published by monsieur Tom Elvis Jedusor) - there is no need to provide Merkle proofs or other supplementary info. - -The "compressed history" in BEAM is actually just a one huge block, which we call a _Macroblock_, which contains a single huge transaction, which is interpreted (almost) as a regular block/transaction. And this is where the System Definition Hash is of critical importance. - -No matter how big the compressed history is, the only thing that matters is the final system state, and it's verified according to the expected System Definition Hash. This is how the authenticity of the compressed history is verified. - -# How Macroblocks are generated and used in BEAM - -There is an implementation of the merging two consequent (macro)blocks. It's a sort of a "merge sort" of all the transaction elements (which must be sorted both in input and the resulting blocks), with removal of spent elements. Using this implementation an arbitrary number of blocks may be merged by recursive halving. - -Our initial design was to generate and keep a _cascade_ of macroblocks. Means, the Node each time merges several blocks at the tail, and then they are iteratively merged to the last merged macroblock, only if they are of the same complexity. This means at any moment we have a list of macroblocks of decreasing size, overall O(log(Height)) such blocks. - -Then, to import a compressed history, the (other) Node downloads the most recent list of the consecutive macroblocks and interprets them according to their order. - -But later we abandoned this idea, mostly because of the hassles for the client to download a list of the macroblocks, especially given the fact they are constantly created and deleted by the generating Node. - -So currently the Node just creates a single macroblock once in a while (1 day by default), whereas the cascade-merge is used only internally by the Node to generate each time the new macroblock incrementally. -Worth to note that during the macroblock generation, which can be a time-consuming operation, the Node is not paralyzed, and works as usual. diff --git a/core-tech/Cold-wallet-implementation-(DEPRECATED).md b/core-tech/Cold-wallet-implementation-(DEPRECATED).md deleted file mode 100644 index 376f012..0000000 --- a/core-tech/Cold-wallet-implementation-(DEPRECATED).md +++ /dev/null @@ -1,71 +0,0 @@ -# Cold wallet implementation -## Definitions -### **cold** wallet - * can generate private keys, i.e. it has _master key_ generated from _seed phrase_ - * has no connection with internet, as a result, it cannot send transactions to the node, and it cannot get proofs and notifications from the node - -### **hot** wallet - * cannot generate any secrets from master key by the reason that it doesn't have it - * has internet connection and can send/get messages from the node - -## Design - -The goal of this design is to get cold wallet scenario with minimal changes in existing codebase. - -The main idea is to split wallet database (_wallet.db_) onto two parts: public (_wallet.db_) and private (_wallet.db.private_). The last one should hold master key generated from seed phrase. -"Cold" wallet has both of these files, "hot" has public data only. To be able to make tranasctions with this setup user have to constantly move public _wallet.db_ file between "cold" and "hot" wallets. Since we override _wallet.db_ we have to stop "hot" wallet before we copy _wallet.db_ file from/into its folder - -### Changes - -1. For "Cold" wallet we don't set up connection with the node. -2. "Cold" wallet stores all outgoing encrypted messages into public database (_wallet.db_), we subclass existing behavior with SBBS -3. Add a stage for processing stored incoming messages. -4. For "hot" wallet there is a need to add some checks if it has master key, also "hot" wallet has no ability to decrypt incoming SBBS messages, since it doesn't have private keys, so it has to store all incoming messages from the channel. - - -## Usage -To tell wallet that it works in "cold" mode you have to add `--cold_wallet` parameter - -### Initialization of "cold" wallet - -`beam-wallet init --cold_wallet` - -This command will create two databases: _wallet.db_ and _wallet.db.private_ - -### Sending from "cold" wallet - -Pre-conditions: -Make sure the cold wallet is synced. In order to do so, follow the next steps: -1. copy the _wallet.db_ file to the "hot" wallet's data folder. -2. launch the "hot" wallet and wait till it's synced. -3. stop the "hot" wallet, copy the _wallet.db_ file into the "cold" wallet folder. -4. launch the "cold" wallet for listening. -`beam-wallet listen --cold_wallet` - -Now as the "cold" wallet is synced, proceed with the next steps: -1. In the cold wallet run the command: -`beam-wallet send -a -r -f --cold_wallet` -Note: there is no need in node address in this case -2. copy _wallet.db_ file to "hot" wallet's data folder -3. launch "hot" wallet. It should send encrypted message to the node, also he may get encrypted message back. -4. stop "hot" wallet, copy _wallet.db_ file into "cold" wallet folder -5. launch "cold" wallet for listening -`beam-wallet listen --cold_wallet` -it should create a signed transaction kernel -6. copy _wallet.db_ from "cold" to "hot" -new transaction should go to the node and got confirmed -7. copy _wallet.db_ from "hot" to "cold" -"cold" wallet should have actual balance and transactions statuses - -### Receiving to "cold" wallet - -1. Generate new address in "cold" wallet and send it to the sender -2. copy _wallet.db_ to "hot" -3. launch "hot" wallet. Note there will be no new transactions, since "hot" wallet cannot decrypt incoming messages -4. stop "hot". copy _wallet.db_ from "hot" to "cold" -5. launch "cold" wallet for listening, it should get new transaction and accept it. -6. copy _wallet.db_ from "cold" to "hot" -7. launch "hot", wait until new transaction becomes completed -8. copy _wallet.db_ "hot" to "cold" balance and transactions statuses should be correct. - - diff --git a/core-tech/Confidential-assets-(historical).md b/core-tech/Confidential-assets-(historical).md deleted file mode 100644 index 6103e05..0000000 --- a/core-tech/Confidential-assets-(historical).md +++ /dev/null @@ -1,74 +0,0 @@ -Consult the [MW CLA](https://github.com/BeamMW/beam/wiki/MW-CLA) section for Confidential Assets implementation details - -Consult the [Confidential assets (BETA) -](https://github.com/BeamMW/beam/wiki/Confidential-assets-(BETA)) section for the Confidential Assets tutorial - -**THE TEXT BELOW IS KEPT FOR HISTORICAL REASONS** - -*** - -MW can be extended to allows encoding multiple types of assets to be traded on the same blockchain. And it will only need a slight modifications to actually allow this. -There are two types of assets that can be implemented: _predefined_ and _custom_. Each type has its advantages and limitations. - -## Basic idea - -The UTXO is an EC point, which is a linear combination of two nums (nothing-up-my-sleeve) generators: `G` and `H`, whereas `G` is multiplied by the secret key (blinding factor), and the `H` - by the value. - -To allow multiple types of assets it's sufficient to use different generators (one per asset type) instead of the single `H`. There may be different schemes to represent such UTXOs, but in any of them the following should be taken into consideration: - -* Those **must** be nums-generators, and the verifier should be able to verify this. -* The verifier should be able to verify the rangeproof. Means - the bulletproof should be adjusted accordingly. -* There should be a brief scheme for the emission of the assets. - -## Predefined asset types - -This idea belongs to Andrew Poelstra. Described [here](https://blockstream.com/2017/04/03/blockstream-releases-elements-confidential-assets.html). - -Each UTXO should carry a _tag_, which is an EC point, which defines the asset type. The great advantage of this scheme is that all the tags are **blinded**. Means - anyone can verify that this tag corresponds to one of the defined asset types, but not to which of them exactly. This is achieved by using Andrew Poelstra's Asset Surjection Proof, which has a modest size compared to the bulletproof for a reasonably-small set of asset types. - -The set of the asset types, as well as their emission schedule, must be defined for the blockchain. Any change to this will require a fork. - -### Another variant - -Another possible way to implement this is to encode all the asset types within a single UTXO. That is, each UTXO is presumably a linear combination of all the generators at once. In this design _tags_ are not needed. - -The drawback here is the increased complexity and size of the bulletproofs, which seem to be dramatic. So that the idea with _tags_, whereas an UTXO encodes only a single asset type - seems to be better. - -## Custom asset types - -In addition there is a possibility to allow _custom_ assets, which any user can emit and trade. As in the previous scheme, such UTXOs should carry a _tag_, which corresponds to the asset type. But this time those tags can't be blinded perfectly. All the user can do is present a set of tags, and prove that the used tag is one of them. - -So that custom tags should either be visible, or partially obfuscated. The encoded amount, naturally, is fully concealed. - -Now, since there are no predefined generators used for custom asset types, there should be a way for the verified to make sure each such a generator is actually a nums-generator. This is addressed by the following scheme. - -### Asset control - -To create a custom asset type the user generates a public/private key pair. The public key serves as an _Asset ID_, and the generator used for this asset type is derived from the ID via hashing, so that it may be considered as a sound nums-generator. - -The user controls the emission and collection of the asset. The user can _convert_ some amount of the master asset type (i.e. BEAM) into his/her type by a special instruction, which is signed by the corresponding **private** key. For convenience it can be embedded into the transaction kernel. - -**Note:** The conversion is only needed to prevent bloat. The user effectively _buys_ his/her coins, but they are refundable. Only the user is be able to trade the unspent assets back to collect the refund. If the bloat is not an issue - it's possible to allow the emission for free. - -# Final design - -The BEAM should support both the predefined and custom assets. - -There should be several predefined asset types, which are automatically emitted by every new block. Their difference is the emission schedule. There should be one with constant emission, one with capped emission. Possibly another one with declining but non-converging (e.i. not capped) emission. - -This is equivalent to having several coin types suitable for instant payment, store of value, and etc. - -Custom asset tags are not emitted automatically, they're explicitly traded for one of the predefined types. - -The modifications needed to support all this is considerable, but straightforward. The following should be modified: -* Tags should be added to UTXOs -* For predefined types: Assert Surjection proofs should be added to UTXOs -* For custom types: - * Assert Surjection proofs may optionally be used, in addition to a list of the possible asset types. - * Another possibility - they should not be blinded, and contain the _Asset ID_ explicitly. -* Transaction/Block verification: - * Bulletproof code should be modified to support custom generators (probably slight performance degradation) - * Custom type conversion instruction should be supported, but this is straightforward (only alters the summation to zero criteria) - * Block emission should be handled w.r.t. predefined types and their emission schedule. - - diff --git a/core-tech/Confidential-assets.md b/core-tech/Confidential-assets.md deleted file mode 100644 index 01dbecc..0000000 --- a/core-tech/Confidential-assets.md +++ /dev/null @@ -1,321 +0,0 @@ -This documents describes CLI Confidential Assets workflow. - -Consult the [MW CLA](https://github.com/BeamMW/beam/wiki/MW-CLA) section for Confidential Assets implementation details. - -Consult the [Beam wallet protocol API](https://github.com/BeamMW/beam/wiki/Beam-wallet-protocol-API) section for API calls description. N.B. assets can be registered only via CLI. - -# Overview - -**Assets Support** - -Confidential Assets (hereinafter СA) support requires `Fork2` and at least `v5.0` CLI/API. Any CA operation before `Fork2` would fail with the `AssetsDisabledFork2 (45)` error code. - -In `v5.0` CA support is disabled by default to avoid compatibility issues. In the GUI wallet CA support cannot be enabled at the moment. All incoming CA transactions would be rejected by the GUI wallet with the `AssetsDisabled (43)` error code. Rejected CA transactions are not displayed by the GUI wallet. Full GUI assets support is planned for v5.1. - -In the CLI and API `--enable_assets` flag should be specified to perform any CA transactions. Without this flag CA transactions would be rejected with the `AssetsDisabled (43)` error code. - -Information about Assets UTXOs/Shielded Coins/Assets Transactions/Assets Summary can be displayed using `--assets` or `--asset_id ID` parameters added to the corresponding commands. - -**Fees** - -All fees (transaction fees and registration deposit) are always paid in BEAM/Groth. It is not possible to pay any fees using assets. - -**Asset Owner** - -`Asset Owner` is the person (wallet) which registered the asset. Asset owner owns private key used for signing asset issue/consume/unreg operations. Only the asset owner can perform these operations. - -**Asset ID** - -`Asset ID` is an unsigned integer associated with the asset. Asset is known to the world by its asset id. Asset operations are performed using its asset id. Node assigns asset id during the asset registration process and uses the first id available. - -Technically there can be a situation when one asset is unregistered, asset id becomes available and the next registered asset takes the id that has been previously used. [`Lock period`](#lock) is introduced to ensure that asset receiver would never receive an unexpected (forged) asset. - -Asset ID of 0 is reserved and represents original BEAM. - -**Asset Info** - -`Asset info` is information about the asset. It includes asset metadata, total emission and lock height. Asset info is received by the wallet automatically during asset transactions or can be requested manually using [`asset_info`](#assetinfo) command. - -Some parts of the asset info are valid only at the height the asset info has been received (`refresh height`). In subsequent blocks total asset emission can change or the asset become unregistered. Unregistering the asset invalidates all the information associated with the particular asset id. - -**Limits** - -Maximum Asset emission is 2128-1 asset nth units. Maximum amount for a single asset transaction (issue, consume, send, receive &c.) is 264-1 asset nth units. - -**Lock period** - -Lock period is a timeframe when several asset operations are restricted for safety reasons. This ensures that asset is not changed during rollback and/or by the asset owner and that receiver of the asset would receive exactly the expected asset. - -Asset becomes locked every time when its total emission reaches 0 or leaves 0. Currently lock period duration is set to `1440` blocks (24 hours roughly). - -Restricted operations are the following: - -* Asset unreg -* Asset send/receive - -**Restore** - -General rules apply to the restore process. You can restore your UTXOs but not transactions. To restore shielded -UTXOs node used for the restore process should be running with your owner key. Asset info is not restored automatically. You would need to execute the `asset_info` command for each restored asset manually after the restore process is completed. - -# Working with assets - -## Asset registration - -Before asset can be used it should be registered on chain using the `asset_reg` command: - -``` -./beam-wallet asset_reg --pass 1 -n 127.0.0.1:10000 --asset_meta "STD:SCH_VER=1;N=Beam Coin;SN=BEAM;UN=Beam;NTHUN=Groth;CUSTOM1=VAL1;CUSTOM2=VAL2" --fee 100 --enable_assets -``` - -You must specify your wallet password, node address, asset meta, optional transaction fee and add `--enable_assets` flag. - -**Fees** - -There is a fixed fee for asset registration of 3000 BEAM. This fee is mandatory, cannot be changed and deduced from your wallet automatically. Registration fee ensures that the network would not be spammed with dummy assets. Registration fee is returned to the owner of the asset as soon as the asset is unregistered. So basically 3000 BEAM are locked for the asset lifetime. You must also pay regular transactions fees. The `--fee` param applies only to the transaction fee, not the registration fee. - -**Asset meta** - -Asset meta is a byte buffer associated with the asset and stored on chain. It is provided on asset registration and cannot be changed afterwards. Currently CLI expects UTF8 string with several mandatory `Key=Value` pairs. It is not possible to register an asset without meta. Please consult the [`Asset Descriptor`](https://github.com/BeamMW/beam/wiki/Asset-Descriptor-v1.0) document for more details. - -**Asset ID** - -After successful asset registration it is associated with the `Asset ID` issued by the node. Asset becomes known to the world by its ID. Asset id is used in any asset operations performed by any person. Asset owner can perform asset operations using as asset id or asset meta. Consult the [`Asset ID`](#assetid) section for more details. - -**Lock Period** - -Immediately after the asset registration it becomes locked for 24h hours. Consult the [`Lock period`](#lock) section for more details. - -**Privacy** - -Transaction kernel including all the asset meta becomes visible to the world. Node would know that you/your IP is the owner of the asset. - -**API Restriction** - -Asset registration can be performed only via CLI. There is no API call for asset registration for safety reasons. - -## Asset issue - -After asset registration its total emission is set to 0. Before performing any asset transactions the owner must mint (issue) asset coins using the `issue` command. Only asset owner can mint asset coins. - -``` -./beam-wallet issue --pass 1 --asset_id 1 -n 127.0.0.1:10000 --amount 10 --fee 100 --enable_assets -``` - -``` -./beam-wallet issue --pass 1 --asset_meta "STD:SCH_VER=1;N=Beam Coin;SN=BEAM;UN=Beam;NTHUN=Groth;CUSTOM1=VAL1;CUSTOM2=VAL2" -n 127.0.0.1:10000 --amount 10 --fee 100 --enable_assets -``` - -You must specify your wallet password, node address, asset id or asset meta, issue amount, optional transaction fee and add `--enable_assets` flag. - -**Coins availability** - -New Asset coins cannot be used until the issue transaction is completed. Please ensure that the minting process is completed and new coins are present in your wallet and marked as available before sending them. - -**Fees** - -Asset emission is absolutely free. You can mint as many coins as you want. You pay only regular transaction fee. - -**Limits** - -Maximum Asset emission is 2128-1 asset nth units. Maximum amount for a single issue transaction is 264-1 asset nth units. - -**Lock Period** - -If after the issue operation total asset emission leaves 0 asset becomes locked. Consult the [`Lock period`](#lock) section for more details. Asset issue can be performed even if asset is locked. Subsequent asset issue operations do not extend the lock period. - -**Privacy** - -Asset information is forcibly refreshed (received from node) during this operation. Operation fails if node doesn't confirm the asset. Transaction kernel including the issued asset amount and asset id becomes visible to the world. Node would know that you/your IP is the owner of the asset. - -## Asset consume - -Owner of the asset can consume (burn) asset coins. To burn the asset you must both be the owner of the asset and the owner of the particular coin/utxo. Asset can be consumed using the `consume` command. - -``` -./beam-wallet consume --pass 1 --asset_id 1 -n 127.0.0.1:10000 --amount 10 --fee 100 --enable_assets -``` - -``` -./beam-wallet consume --pass 1 --asset_meta "STD:SCH_VER=1;N=Beam Coin;SN=BEAM;UN=Beam;NTHUN=Groth;CUSTOM1=VAL1;CUSTOM2=VAL2" -n 127.0.0.1:10000 --amount 10 --fee 100 --enable_assets -``` - -You must specify your wallet password, node address, asset id or asset meta, consume amount, optional transaction fee and add `--enable_assets` flag. - -**Fees** - -Asset consuming is absolutely free. You pay only regular transaction fee. - -**Limits** - -Maximum amount for a single consume transaction is 264-1 asset nth units. - -**Lock Period** - -If after the consume operation total asset emission reaches 0 asset becomes locked. Consult the [`Lock period`](#lock) section for more details. - -**Privacy** - -Asset information is forcibly refreshed (received from node) during this operation. Operation fails if node doesn't confirm the asset. Transaction kernel including the consumed asset amount and asset id becomes visible to the world. Node would know that you/your IP is the owner of the asset. - -## Asset unreg - -Asset can be unregistered from chain by the owner. To unregister the asset its emission should be 0 and it should be not locked. Asset is unregistered using the `asset_unreg` command. - -``` -./beam-wallet asset_unreg --pass 1 -n 127.0.0.1:10000 --asset_meta "STD:SCH_VER=1;N=Beam Coin;SN=BEAM;UN=Beam;NTHUN=Groth;CUSTOM1=VAL1;CUSTOM2=VAL2" --fee 100 --enable_assets -``` - -``` -./beam-wallet asset_unreg --pass 1 -n 127.0.0.1:10000 --asset_id 1 --fee 100 --enable_assets -``` - -You must specify your wallet password, node address, asset meta or asset id, optional transaction fee and add `--enable_assets` flag. - -**Fees** - -Asset unregistration is free. You pay only regular transaction fee. This operation also returns 3000 BEAM locked during the asset registration. - -**Asset ID** - -Asset ID becomes free after this operation and can be reused by another asset. - -**Limits** - -Maximum amount for a single consume transaction is 264-1 asset nth units. - -**Privacy** - -Asset information is forcibly refreshed (received from node) during this operation. Operation fails if node doesn't confirm the asset. Transaction kernel which includes asset id becomes visible to the world. Node would know that you/your IP is the owner of the asset. - -**API Restriction** - -Asset unregistration can be performed only via CLI. There is no API call for asset unregistration for safety reasons. - -## Getting Asset Info - -Asset info can be received from node using `asset_info` command for any asset registered on chain. `asset_info` command stores the received info in a local database for future usage. - -``` -./beam-wallet asset_info --pass 1 -n 127.0.0.1:10000 --asset_id 1 --enable_assets -``` - -`asset_info` command always receives the latest information from node. To view locally stored information regular `info` command should be used with `--assets` or `--asset_id ID` parameters. - -Asset owner can query asset info using asset meta (`--asset_meta "STD:...."`) as well. Non-owners can use only asset id. - -**Fees** - -`asset_info` operation is free. You do not pay any fees. - -**Privacy** - -`asset_info` operation only communicates with the node and doesn't leave any traces in the blockchain. Node would know that particular IP has been interested in given asset. - -## Displaying Assets - -By default CLI wallet doesn't display any information about assets you own or have. To view assets info, assets UTXOs & assets transactions `--assets` (for all assets) or `--asset_id ID` (for a specific asset) params should be used. - -View asset info & asset UTXOs - -``` -./beam-wallet info --pass 1 --asset_id 1 -``` - -``` -./beam-wallet info --pass 1 --assets -``` - -View asset transactions - -``` -./beam-wallet info --pass 1 --asset_id 1 --tx_history -``` - -``` -./beam-wallet info --pass 1 --assets --tx_history -``` - -View shielded (Lelantus) asset UTXOs - -``` -./beam-wallet info --pass 1 --asset_id 1 --shielded_utxos -``` - -``` -./beam-wallet info --pass 1 --assets --shielded_utxos -``` - -View Shielded (Lelantus) Asset transactions - -``` -./beam-wallet info --pass 1 --asset_id 1 --shielded_tx_history -``` - -``` -./beam-wallet info --pass 1 --assets --shielded_tx_history -``` - -**Enable flag** - -Asset info can be displayed without the `--enable_assets` flag - -**Orphaned transactions** - -Asset transactions that do not include asset id would be displayed as `orphaned`. This can occur when transaction has been started with `--asset_meta` param and no valid asset id has been associated with the transaction while it was running. For example it can happen if you have tried to register an asset but there is not enough BEAM to pay the registration fee. - -## Sending assets - -Asset can be sent using regular `send` command. The only difference from regular BEAM transaction is the `--asset_id` and `--enable_assets` parameters. - -``` -./beam-wallet -n 127.0.0.1:10000 --pass 1 --command send -r 1ec08b72ea25cd471ec37f9088a1ae0dcb8f4526eff3b8ab38f8e23901e2adf48a2 --amount 5 --asset_id 1 --enable_assets -``` - -**Limits** - -Maximum amount for a single send transaction is 264-1 asset nth units. - -**Enable flag** - -Both sender and receiver should specify `--enable_assets` flag in command line otherwise transaction would fail with the `AssetsDisabled (43)` error code. - -**Lock period** - -Asset cannot be sent to non-owner during the lock period. Transaction would be rejected by the receiving party with the `AssetLocked (34)` error code. - -**Privacy** - -Send transaction doesn't refresh asset info. Asset ID is hidden during the send transaction though it is visible that the transaction is performed on some asset. General Mimblewimble rules apply to the transaction. Amount, sender and receiver are not disclosed. - -## Receiving assets - -Process of receiving assets is mostly identical to the receiving of regular BEAM. - -**Enable flag** - -CLI/API receives assets automatically if it is running (listens) with the `--assets_enable` option. If assets are not enabled all incoming asset transaction would be rejected with the `AssetsDisabled (43)` error code. - -**Lock period** - -Asset cannot be received by non-owner during the lock period. Transaction would be rejected by the receiving party with the `AssetLocked (34)` error code. - -**Privacy** - -Receive operation does not refresh asset info if there are any unspent UTXOs of the asset being received in the wallet. If there are no unspent UTXOs asset info might be refreshed if wallet doesn't have info about the asset (first receive) or info is older than the lock period duration. - -Asset ID is hidden during the receive transaction though it is visible that the transaction is performed on some asset. General Mimblewimble rules apply to the transaction. Amount, sender and receiver are not disclosed. - -## Lelantus & one-sided payments - -**N.B. As of v5.1 basic lelantus operations (pull & push) are removed. The info below applies only to the v5.0** - -Lelantus transactions fully support confidential assets. To insert to/extract asset from pool `--asset_id ID` option should be specified as well as `--enable_assets` flag. Refer [Lelantus CLI](https://github.com/BeamMW/beam/wiki/Lelantus-CLI) for details. - -**Lock Period** - -Lock period rules do not apply to Lelantus transactions. Assets can be inserted to the pool and extracted from the pool at any time. - -**Privacy** - -Asset info is never refreshed during Lelantus transactions. Amount and Asset ID is hidden though it is visible that the transaction is performed on some asset. \ No newline at end of file diff --git a/core-tech/Contribution-Guidelines.md b/core-tech/Contribution-Guidelines.md index 6783e23..2d9c1b8 100644 --- a/core-tech/Contribution-Guidelines.md +++ b/core-tech/Contribution-Guidelines.md @@ -2,11 +2,17 @@ ## Introduction -Beam is an open source project, and as such welcomes developers to contribute. In order to simplify and organize this process we have written this short contribution guide that explains the key principles of contributing to Beam project. +Beam is an open source project, and as such welcomes developers to contribute. +
+In order to simplify and organize this process we have written this short contribution guide that explains the key principles of contributing to Beam. For any questions you might have regarding the process please contact Beam CTO at alex at beam.mw or @bigromanov on Telegram or @BeamCTO on Twitter. -For more specific questions please contact developer team on Telegram: https://t.me/beamdevsupport +For more specific questions please contact the developer team on Telegram: https://t.me/beamdevsupport + +## Code Style + +Before contributing C++ code, please read the [Beam C++ Style and Conventions](Beam-Cpp-Style-And-Conventions) guide. It covers naming conventions, memory ownership, error handling, serialization, the IO/reactor model, logging, and CMake module structure used across `core/`, `node/`, `wallet/`, `bvm/`, and `utility/`. ## Projects overview @@ -23,26 +29,10 @@ To contribute to this project please follow the steps below: 1. Setup your dev environment, checkout and build the project using the [Building Instructions](https://github.com/BeamMW/beam-ui/wiki/How-to-build-Beam-desktop-UI) -2. Explore tasks in the currently active project on the [projects page](https://github.com/BeamMW/beam-ui/projects) ([Eager Electron 5.1](https://github.com/BeamMW/beam-ui/projects/1) at the time of the writing) +2. Explore tasks in the currently active project on the [projects page](https://github.com/BeamMW/beam-ui/issues). -3. Look for tasks marked with the 'help wanted' label. Of course you are also welcome to contribute to other tasks as well +3. Look for tasks marked with the ['help wanted' label](https://github.com/BeamMW/beam/labels/help%20wanted). Of course you are also welcome to contribute to other issues as well 4. Write a comment clarifying that you are starting to work on the task and providing a very rough estimate how much time you expect to spend on it. -5. If the task does not have a clearly assigned bounty in the task description please contact @bigromanov on Telegram, or email alex at beam.mw - -### Beam Web Wallet Extension - -Coming soon.... - - -## Coding guidelines - -### C++ - -Coming soon - -### JS / Angular - -Coming soon - +5. If the task does not have a clearly assigned bounty in the task description please contact @bigromanov on Telegram, or email alex at beam.mw \ No newline at end of file diff --git a/core-tech/Core-transaction-elements.md b/core-tech/Core-transaction-elements.md deleted file mode 100644 index f62b3d1..0000000 --- a/core-tech/Core-transaction-elements.md +++ /dev/null @@ -1,138 +0,0 @@ -# Core data types used in BEAM: -* `Height` - 64-bit unsigned integer -* `HeightRange` - a pair of `Height` -* `Timestamp` - 64-bit unsigned integer -* `Amount` - used to denote the value of a single UTXO. 64-bit unsigned integer -* `AmountBig` - used to denote the value of an arbitrary number of UTXOs. Consists of 2 64-bit unsigned integer (i.e. equivalent to 128-bit integer) -* `Difficulty` - 32-bit encoding of a floating-point number. 8 bits for order, 24 bits for mantissa. -* `Difficulty::Raw` - 256-bit unsigned integer. Represents an "unpacked" `Difficulty` on a linear scale. Used to represent the chainwork (sum of difficulties). - - -# Input UTXO - -Consists of the following: -* `ECC::Point m_Commitment` - * A commitment to the UTXO (which is supposed to exist in the system) -* `Height m_Maturity` - * Optional field to specify the maturity of the UTXO being-spent. - * Used only in _Macroblocks_ (compressed history block), more about this later. Illegal to use in transactions. - -# Output UTXO - -Consists of the following: -* `ECC::Point m_Commitment` - * A commitment to the UTXO (which is supposed to be created in a transaction) -* `Height m_Maturity` - * Optional field to specify the maturity of the created UTXO. - * Used only in _Macroblocks_ (compressed history block), more about this later. Illegal to use in transactions. -* `bool m_Coinbase` - * Must be set iff it's a coinbase UTXO. -* `Height m_Incubation` - * Optional field. If specified - the number of extra blocks (in addition to standard system rules) until the UTXO becomes mature. -* UTXO Signature. Must be one of the following: - * `ECC::RangeProof::Confidential` - a confidential signature (Bulletproof) - * `ECC::RangeProof::Public` - a public signature, with the Amount visible. - -### UTXO Signature - -* Coinbase UTXO must have a public signature (the Amount explicitly specified). -* Non-coinbase UTXO - depends on the system rules. In the current configuration all non-coinbase UTXOs are enforced to have a confidential signature, but may also be configured to allow public signatures. - -The confidential signature is implemented in terms of a Bulletproof. The public signature consists of the following: -* `Amount m_Value` - the explicit value -* `ECC::Signature m_Signature` - a Schnorr's signature for the UTXO blinding factor. - -**Note**: the `m_Incubation` field is accounted in the UTXO signature, to prevent tampering. - -# Transaction Kernel - -Consists of the following: -* `ECC::Point m_Excess` - * The transaction excess (public) -* `ECC::Signature m_Signature` - * The Schnorr's signature for the whole kernel body, signed with the transaction excess (secret) -* `Amount m_Fee` - * Transaction fee -* `uint64_t m_Multiplier` - * Optional field, used in a scheme where a kernel may be consumed (more about this later) -* `HeightRange m_Height` - * Optional: the transaction timelock parameters (min/max height for being valid in the block) -* `uintBig m_HashLock` - * Optional: a hashlock. An arbitrary 256-bit value which is hashed, and then accounted in the kernel signature -* `m_vNested` - * Optional: an array of _nested_ kernels. More about this later. - -## Kernel Signature - -The Hash of the kernel is evaluated, and then it's signed by the Schnorr's signature. The Hash evaluation formula is: - -> M = m_Fee | m_Height | m_Excess | m_Multiplier; -> if Hashlock specified -> M = M | true | Hash(Hashlock.Preimage); -> else -> M = M | false; -> -> For each Nested Kernel -> M = M | true | (Nested Kernel).ID; -> -> M = M | false -> -> KernelHash = Hash(M) - -The formula accounts for all the members except except the signature. It's also unambiguous (i.e. explicit separation for optional input fields). - -**Note**: The excess, which is a signature public key, is also included. This is an intentional design decision, to make the kernel's excess also immutable after it has been signed (otherwise any party could modify the excess and keep the signature correct). - -## Kernel ID - -According to the system rules every kernel has a unique ID (duplicate IDs are banned). Its value is identical to the `KernelHash`, except there are "forbidden" values, which are reserved for the internal system use. So if the kernel ID happens to be equal to a forbidden value (which is highly unlikely), its value is mutated. - -Currently the only forbidden value is 0. - -# Transaction -Consists of the following: - * Input UTXOs - * Output UTXOs - * Input Kernels - * This is the BEAM extension - kernels may also be consumed! More about this later. - * Output Kernels - * `ECC::Scalar m_Offset` - -## Context-free Transaction validation - -The following is validated: -* All the transaction elements (UTXOs, Kernels) must be specified in a well-defined order (there's a comparison function for each transaction element type). -* Each element must have a valid signature -* Timelocks of all the kernels must be valid for the current height - -Next, we define the Σ as a sum of all outputs minus all inputs: - -Σ = Σ(UTXO-Out.Commit) - Σ(UTXO-In.Commit) + Σ(Kernel-Out.Excess) - Σ(Kernel-In.Excess) + m_Offset · G - -In case of transaction validation there are transaction fees that are considered lost, i.e. they are implicit outputs. So, the validation formula is: - -Σ + Σ(Fees)·H = 0 - -# Block body -Contains all that is included in a transaction. In addition: -* `AmountBig m_Subsidy` - * explicit Amount created by this block (Coinbase and, possibly, other types of subsidy) -* `bool m_SubsidyClosing` - * If set - means from the next block only coinbase subsidy should be allowed - -Since blocks may be arbitrary large (when merged) - there are different underlying techniccal representations of the Block body. In a simple case it contains just arrays of all the transaction elements (like a Transaction object). But larger blocks don't keep all the data pre-loaded, instead it's read sequentially from files. - -There is an `Transaction::IReader` interface used to iterate sequentially over the transaction elements, and it's used by the context-free validation code, regardless to the actual data representation details. - - -## Context-free Block body validation - -The block body is validated similar to a transaction, keeping in mind however that this may be a _Macroblock_, i.e. a merged block for a specific height range (applicable to the Timelock validation of kernels). - -Then Σ is calculated. But in contrast to transaction the Fees should not be added, because they must have already been consumed by explicit output UTXO(s) (injected by the miner). Instead the explicit Subsidy must be accounted as an input. Hence the formula is: - -Σ - m_Subsidy·H = 0 - -In addition the Verifier must verify that the Coinbase UTXOs are properly tagged, and unspent unless the coinbase maturity is reached. -For a single block verification the sum of all Coinbase UTXO amount must be equal to the single block Coinbase emission as defined by the system rules. -For _Macroblock_ verification the Verifier should take into account that some Coinbase UTXOs may have already been spent. diff --git a/core-tech/Cryptographic-primitives.md b/core-tech/Cryptographic-primitives.md deleted file mode 100644 index e0575a9..0000000 --- a/core-tech/Cryptographic-primitives.md +++ /dev/null @@ -1,90 +0,0 @@ -Cryptographic primitives used by BEAM are based on the `secp256k1` library (the one that is used in bitcoin). Naturally it uses the same elliptic curve equation. The following primitives are used directly: - -* `secp256k1_gej` - Basic curve point arithmetics: point addition, doubling, negation, import/export to a platform-ndependent format. -* `secp256k1_scalar` - Scalar arithmetics: addition, multiplication, inverse -* `secp256k1_sha256_t` - SHA-256 hash -* Cryptographic nonce generation (`nonce_function_rfc6979`). -* `secp256k1_hmac_sha256_t` - HMAC (message authentication) - -The following cryptographic functions and schemes are built over them: - -* Point multiplication (by a scalar). - * There are different multiplication modes and scenarios: - * Secure/Fast - * Point may be either known in advance (a.k.a. Generator, prepared for multiplication) or "casual". - * Aggregation: when many points are multiplied by scalars and summed - an appropriate effective algorithm is used. - * The reason that this functionality is implemented in BEAM and not taken directly from `secp256k1` is the following: - * We'd like to have more low-level control of the primitives to implement advanced schemes - * We need more generators: Standard secp256k1 supports just two (`G,H`), whereas we need many more (131) - * No effective aggregation implementation - * Commitments (encoded amount with the blinding factor) - * Schnorr's signatures (including multi-sig) - * Bulletproofs (including multi-sig and batch verification) - * Secure communication channels - * Secure BBS messaging system - -In addition there's a `uintBig` - a "big integer" (arbitrary width), supports basic arithmetics and shift operations (not including division). The number is represented as an array of bytes in a big-endian byte order. Platform-independent, serialized as-is. -Implementation is very straight-forward, not for performance-critical tasks. - -## Hash - -The Hash refers to the SHA-256 hash, unless otherwise specified. Used in various schemes. When hashing some data, it's fed in a way that is both platform-independent and unambiguous. This is achieved by the following specifications: - -* 1-byte data is fed as-is -* Boolean values are encoded as a single byte with value either 0 or 1. -* Strings are fed as-is, including the 0-terminator (to prevent ambiguity for consequent strings). -* Numerical types (fixed-point) are stored as a variable-length byte sequence, with a special terminator mark. This ensures platform independence (integers may have varying width across different platforms). -* Non-primitive types are converted into the platform-independent binary format for hashing. - -The following objects are derived from hash (built over them) - -### Oracle - -Oracle is used in non-interactive cryptographic proofs, it's supposed to produce cryptographic challenges in a deterministic way, based on the visible transcript to the moment. - -In BEAM Oracle uses the Hash in a straightforward way. All the visible transcript is hashed. Once the challenge is needed - the hash value is finalized, the result is the challenge, and it's immediately re-fed to the Hash. So that the new challenge construction (if needed) is generated from the visible transcript, including the previous challenge. - -If there are restrictions for the challenge (such as it should be non-overflowing, non-zero scalar, or a valid x-coordinate of a curve point) - the Finalize-Re-feed is called in a loop, until the satisfying challenge is produced (i.e. accept/reject strategy is used). - -### Nonce Generator - -Also used in cryptographic proofs, but, unlike Oracle, the nonce generation involves secret data, and should not be possible to reconstruct by others. - -In BEAM Nonce generator is a combination of an Oracle, and the nonce function initialized by the secret data. That is, the Oracle accounts for all the visible transcript. When a nonce is needed - first it's received from the Oracle, and then passed as an input to the nonce function (implemented in (`secp256k1`), which also uses the secret data. - -The final nonce generation function implemented in `secp256k1` actually a modified HMAC-SHA-256 scheme. - -### KDF - Key derivation function - -All the private keys are generated via KDF. In BEAM it's implemented via the Nonce generator, which is initialized once by the master secret data. The requested key parameters (key index, type/subtype, etc.) are hashed and then the output is generated by the standard Nonce generator initialized with the master secret. - -## Schnorr's signature - -Implemented according to the standard, the "long" version, compatible with batch verification. Consists of a pair `[P,k]`, whereas `P` is an arbitrary EC point, and `k` is the blinded private key. Supports multisignature of course. - -Specifically the scheme is the following. Given a message hash `M`, private key `sk`, public key `pk = G * sk`: - -* Prover - * Generate a nonce `nk = Nonce(sk, M)`, whereas `Nonce()` is the standard nonce generating function. - * Calculate: `P = nk*G` - * Expose to Oracle: `P, M` - * Get the challenge `e` from Oracle. - * Calculate `k = - nk - e*sk` - * Signature: `[P, k]` -* Verifier - * Expose to Oracle: `P, M` - * Get the challenge `e` from Oracle. - * Verify: `k*G + e*Pk + P == 0` - -## Binary platform-independent representation of the ECC primitives - -The following are the primitives: - -* ECC Scalar - * 256-bits wide integer, representing the number in a big-endian format (via `uintBig`) - * Deserialization ensures the number is indeed a valid scalar, i.e. strictly less than modulo-prime, to prevent ambiguity -* ECC Point - * Represented as an X-coordinate, and a Y-parity flag (1 bit). - * The X-coordinate is serialized via `uintBig` (similar to scalar). - * To recover the Y-coordinate one must solve a quadratic equation, which, naturally has 2 solutions. This is where Y-parity flag is used. - * When serialized individually the data is padded to a byte boundary (means the Y-parity bit takes the whole byte). However in some complex data types those flags are merged and stored separately (Ex: Bulletproofs). diff --git a/core-tech/DMMR-internal-layout.md b/core-tech/DMMR-internal-layout.md deleted file mode 100644 index 8670cae..0000000 --- a/core-tech/DMMR-internal-layout.md +++ /dev/null @@ -1,49 +0,0 @@ -In Merkle trees there are leaf nodes that are added explicitly, and appropriate non-leaf nodes which are created on-demand. - -Our DMMR consists of _Elements_ of variable size, whereas each new element internally contains all the supposed non-leaf nodes. Technically element consists of: - -1. Hashes of the assumed non-leaf nodes -1. _Pointers_ to the elements that contain the siblings assumed by the above non-leaf nodes. - * By _pointers_ we mean the information used to access the element, not necessarily the memory pointer. -1. A pointer to the last element of the previous MMR peak. - - -For example, consider and MMR containing 10 items: - - * - / \ - / \ - / \ - / \ - / \ - / \ - / \ - / \ - / \ - / \ - / \ - * * - / \ / \ - / \ / \ - / \ / \ - / \ / \ - / \ / \ - * * * * * - / \ / \ / \ / \ / \ - / \ / \ / \ / \ / \ - 0 1 2 3 4 5 6 7 8 9 - -In our DMMR this is represented by the following data: - -[[/images/dmmr1.png]] - -There are 10 elements of varying size, denoted by different colors. Rectangles outline the data and the non-leaf hashes of which the elements comprise. Lines denote pointers to the parent elements. We see the following: - -* Elements with odd index contain extra hashes, denoted by asterisk (*). The number of hashes equals to the height of the formed peak. -* For every extra hash there is also a pointer to the last element of the appropriate sibling node. -* Most of the elements in addition have a pointer to the last element of the previous MMR peak, denoted by a curly line. - * The exceptions are elements at position 0, 1, 3, 7, because they are last elements of the only peak. - * This is obviously the property of elements at positions 2n-1. -* The only element that contains no data is the 1st, at position 0. - -It's easy to see that each element has access to all the parent elements and their datas. Hence it can be used as an effective MMR implementation with all the relevant functionality, such as calculating the root, and generating proofs. diff --git a/core-tech/Exchange-Pool-integration-guide.md b/core-tech/Exchange-Pool-integration-guide.md index 50036da..7f10b3f 100644 --- a/core-tech/Exchange-Pool-integration-guide.md +++ b/core-tech/Exchange-Pool-integration-guide.md @@ -6,7 +6,7 @@ ## Getting binaries First of all, define the network you'd like to "play" with: - `mainnet` - it's the latest released production version, working with real money and you can get binaries from the [official website](https://www.beam.mw/downloads), see [Github Releases](https://github.com/BeamMW/beam/releases) or build yourself from the sources of ([mainnet branch](https://github.com/BeamMW/beam/tree/mainnet)). -- `testnet` - to check the features will be released soon to production and you can get binaries from the [official website](/downloads/testnet) +- `testnet` - to check the features will be released soon to production and you can get binaries from the [official website](https://beam.mw/downloads/testnet) , see [Github Releases](https://github.com/BeamMW/beam/releases) or build from the [testnet branch](https://github.com/BeamMW/beam/tree/testnet). - `master` - to see the latest changes in development build the [master branch](https://github.com/BeamMW/beam/tree/master). diff --git a/core-tech/Folder-and-file-locations.md b/core-tech/Folder-and-file-locations.md index d7259d1..f4a64c0 100644 --- a/core-tech/Folder-and-file-locations.md +++ b/core-tech/Folder-and-file-locations.md @@ -1,5 +1,8 @@ # Desktop Wallet app +Please refer to: https://documentation.beam.mw/en/latest/rtd_pages/user_files_and_locations.html?highlight=location + + ## General points to mention: * The default location of the Desktop Wallet app can be modified during the installation process (Windows only). * The default Database location for the Desktop Wallet app can be changed setting the `appdata` parameter to `beam-wallet.cfg` (Windows only). diff --git a/core-tech/HW-wallet-requirements----DEPRECATED---.md b/core-tech/HW-wallet-requirements----DEPRECATED---.md deleted file mode 100644 index 6bc3fdf..0000000 --- a/core-tech/HW-wallet-requirements----DEPRECATED---.md +++ /dev/null @@ -1,165 +0,0 @@ -# -- DEPRECATED -- - -The HW wallet should support the following functionality -1. Deterministic key generation for key parameters -1. Export public keys -1. Participate in signing schemes: Schnorr's signature, Bulletproof. - * The latter in CPU-hungry, but most of the computations can be done without HW -1. Support multi-signatures - * This includes both: signing with multiple self keys, as well as the keys generated by the others. -1. Obviously secret keys must not be revealed. - -## Nonces and randomness - -Our signing protocols follow a ritual where the signer generates some _nonce(s)_, reveals its _image(s)_, gets a _challenge(s)_, and then should reveal the appropriate _preimage_. To guarantee (5) the signer must **never** answer to different _challenges_ for the same _nonce_. This is absolutely vital! - -In a regular signature protocol the _nonce_ can always be generated in a deterministic way from the visible transcript and the sercret key, the _challenge_ is derived from the visible transcript, and the whole signing process is atomic. - -This approach, however, is not compatible with (4). In the case of the multisignature the signing process is not atomic. And ability to create multisignatures is essential in MW. - -Hence, in order to sustain the requirements the HW should use another source of (pseudo)randomness. Moreover, the random _nonce_ generated for the signing process should be kept inside the HW for indefinite time, because signing may take considerable time, during which HW wallet should be able to operate normally. In addition each _nonce_ should be **erased** once the _preimage_ based on it is revealed. - -# Proposed design - -HW wallet should support the basic EC cryptography primitives for the parameters specified by the `secp256k1` standard (the one that is used in bitcoin). Means - 256-bit wide keys, the same EC equation, finite field parameters, same `G`-generator. - -The HW wallet should have non-volatile memory, represented by memory _slots_. There should be the following _slots_: - -1. Master secret. - * No direct access to the caller. - * Should be used as a secret for key generation. -1. Nonce source. - * No direct access to the caller. - * Should be initialized by true random either during production, or upon initialization of the Master secret. -1. Generated key. - * Contains the generated key. May be a single key or their sum/difference (more about this later). -1. Generated nonces. - -This low-level design may look weird, but it's needed to support all the MW functionality. The following functionality should be supported: - -### Nonce regeneration - -Parameters: -* `i` - the target slot index - -Result: the target slot should contain a unique nonce, derived from the Nonce source, and the Nonce source itself should be mutated immediately after that. - -* `n[i] = DeriveNonce(NonceSource)` -* `NonceSource = Mutate(NonceSource)` - -Important: all the nonce slots must be regenerated before (or immediately after) the Master secret is initialized. In simple words, there must be no situation where the HW is operational, yet there's a nonce slot which contains predictable (zero?) value. - -### Key slot reset (assign to zero) - -Result: the target slot should contain zero value: `k = 0` - -### Key generation -Parameters: -* `ID` - an opaque 256-bit data that identifies the key - -Result: the generated key should be added to the target slot: `k += KeyGenerate(MasterSecret, ID)` - -### Key split -The key should be split into 2 parts in a deterministic (yet opaque) way. - -Return value: `k2 = Muate(k)` - -Result: `k -= k2` - -### Image (public key) reveal -Parameters: -* `i` - the slot index. - -Return value: EC point (in whatever representation) equals to the `G`-generator multiplied by the value of this slot: `G * n[i]` - -Applicable for key and nonce slots - -### Sig1 (Schnorr) - -Parameters: -* `i` - the slot index -* `e` - challenge - -Return value: blinded _preimage_: `kb = n[i] + e*k` - -Result: used nonce is immediately regenerated: `Regenerate(i)` - -### Sig2 (Bulletproof) - -Parameters: -* `i1, i2` - 2 slot indexes -* `e`, `e2` - 2 challenges - -Return value: blinded _preimage_: `kb = n[i1] + e2*n[i2] + e*k` - -Result: used nonce is immediately regenerated: `Regenerate(i1)`, `Regenerate(i2)` - - -*** - -*** - -# API - -### Key generation -Inputs: -* `KIDV` for the needed key -Otputs: -* The public key (ECC point) - -Generate the key, and export its image (i.e. multiplies by `G`-generator) - -### Bulletproof generation -Inputs: -* `KIDV` for the needed key -Otputs: -* The Bulletproof - -### Nonce generation - -Inputs: -* Slot number -Otputs: -* The nonce image (ECC point) - -Generate the random nonce (ECC scalar), and export its image (i.e. multiplies by `G`-generator). - -### Transaction signature - -Inputs: -* List of `KIDV`s of input UTXOs -* List of `KIDV`s of output UTXOs -* Randomly generated offset (ECC scalar) -* Number of the nonce slot -* Challenge `e` (ECC scalar) // after discussion, it seems that it should be calculated on device, so we need kernel parameters - - Fee - - Commitment // total public excess - - minimal height - - maximum height - - Amount(m_AssetEmission) - - m_pHashLock; - - Public nonce of 2nd party (for multisig) - - Public excess of 2nd party (for multisig) - -Outputs: -* Signature (ECC scalar) - - -The HW wallet should do the following: -1. Request user's permission for the transaction. -1. Calculate the result. -1. Immediately overwrite the nonce slot with another randomly-generated value. - -The result is calculated by the following algorithm: -1. Generate all the keys (i.e. blinding factors), and calculate `sk` as sum of inputs minus outputs. - - `sk = Sum(input blinding factors) - Sum(output blinding factors) - offset` - - `offset` is generated randomly on caller side -1. Calculate multi signature public nonce: `PublicNonce = Nonce*G + PeerPublicNonce` -1. Calculate total blinding excess: `TotalExcess = sk * G + PeerPublicExcess` -1. Calculate Message for sign: hash kernel parameters see: TxKernel::get_Hash -1. Calculate challenge by: `e = H(PublicNonce|Message)` -1. Calculate the signature by: `Signature = sk * e + Nonce` -1. Re-generate `Nonce` (overwrite the contents of the slot) -1. Reveal `Signature` diff --git a/core-tech/Hi-Frequency-transactions.md b/core-tech/Hi-Frequency-transactions.md deleted file mode 100644 index b598990..0000000 --- a/core-tech/Hi-Frequency-transactions.md +++ /dev/null @@ -1,30 +0,0 @@ -## Standard transaction handling - -Standard Beam transactions are considered independent. After they are broadcast to the network (in the _fluff_ phase) they are kept in a _Transaction pool_ in each node, until they either expire or included in a block. Miners select the transactions according to their Fee/Size ratio, to maximize the reward. - -The transaction lifespan (e.i. _height range_) is controlled by its creator, but usually order of several hours. Once the transaction is broadcast, the wallet monitors the new blocks, until either it notices the transaction is included in a block (succeeded), or expires (failed). - - -## DeFi - -While the above scheme is OK for normal transactions, smart contracts demand a different design, because transactions are potentially dependent, their order and block height may have consequences for users, or even render some of them invalid. - -So we designed a concept of _dependent_ transactions. Those that insist to be included in a specified block and at the specified position, or not included at all. -In contrast to normal transactions, that are stored in a _flat_ transaction pool, dependent transactions are stored in a special tree. Then in order to assemble a block, the miner picks the branch with maximum total fees, and includes all the appropriate transactions in this exact order. - -When working in the HFT mode, the wallet not only gets notifications about new blocks, but also about the changes in the dependent transactions tree. Then, in order to build a transaction, it does the following: -* Gets the information about the current transaction branch with the maximum total fee (the one that is most likely to be selected by the miner) -* Specifies this branch ID when querying the appropriate contract information. By such it can foresee the effects of all the preceding transactions in the branch, and build a new transactions accordingly. -* When ready, broadcast this transaction to the node, with the branch ID that defines uniquely the position where this transaction should be included. -* Even before the new block is mined, the wallet gets notification about the transaction tree updates. If for some reason the current transaction is unlikely to be mined (another competing branch has more total fee) - the wallet may rebuild and resend transaction according to the new context. -* Optionally this may be repeated continuously, until the transaction is mined. - -By such we achieve the following goals: -1. Strict transaction inclusion rule. Protect the user from unexpected side effects (a.k.a. front running attack). -2. Give users prompt pseudo-confirmation for their transactions. -3. Give opportunity for several users to see effects of other's transactions, hence include otherwise conflicting transactions in the same block. - -# Technical design - -(in progress) - diff --git a/core-tech/Home.md b/core-tech/Home.md new file mode 100644 index 0000000..3d13345 --- /dev/null +++ b/core-tech/Home.md @@ -0,0 +1,158 @@ + +# Current version: Groovy Gluon 7.5.13840 + +Download latest binaries here: https://www.beam.mw/downloads + +## IMPORTANT +[Upgrade guide for pools and exchanges](https://github.com/BeamMW/beam/wiki/Beam-Fierce-Fermion-6.0-Upgrade-Guide-for-pools-and-exchanges) + + +In case you encounter any problem, please open a GitHub ticket at https://github.com/BeamMW/beam/issues or email us at support@beam.mw + +For effective investigation please attach the following items for every issue: +* Logs, compressed into a single archive +* Configuration file +* Command line parameters of the executed binary + +# Beam Confidential DeFi Platform + +[BVM Internals](https://github.com/BeamMW/beam/wiki/bvm/BVM-Internals) + +[BVM Host Functions Reference](https://github.com/BeamMW/beam/wiki/bvm/BVM-functions-for-shaders) + +[Web wallet client](https://github.com/BeamMW/beam/wiki/WASM-wallet-client) + +# Documentation + +[User Guides](https://beam.mw/docs) + +[Exchange Integration Guide](https://github.com/BeamMW/beam/wiki/Exchange-Pool-integration-guide) + +[How To Build](https://github.com/BeamMW/beam/wiki/How-to-build) + +--- + +## Core — Cryptography, Transactions, Block Structure + +Reference documentation for Beam's cryptographic primitives, transaction anatomy, block format, and chain state structures. + +* [Beam Technical Specifications](https://github.com/BeamMW/beam/wiki/Beam-Technical-Specifications) +* [Cryptographic Primitives](https://github.com/BeamMW/beam/wiki/core/Core-Cryptographic-Primitives) +* [Core Transaction Elements](https://github.com/BeamMW/beam/wiki/core/Core-transaction-elements) +* [Merkle Structures](https://github.com/BeamMW/beam/wiki/core/Core-Merkle-Structures) +* [Block and Chain State](https://github.com/BeamMW/beam/wiki/core/Core-Block-And-Chain-State) + +## Node — Architecture, P2P, Mining, Sync + +Full-node internals: block processing, transaction pool, peer-to-peer protocol, proof-of-work, and synchronization. + +* [Node Architecture](https://github.com/BeamMW/beam/wiki/node/Node-Architecture) +* [P2P Network Protocol](https://github.com/BeamMW/beam/wiki/node/Node-P2P-Protocol) +* [Fly Client Protocol (SPV)](https://github.com/BeamMW/beam/wiki/node/Node-Fly-Client-Protocol) +* [Beam Mining](https://github.com/BeamMW/beam/wiki/BEAM-Mining) + * [Mining Modes](https://github.com/BeamMW/beam/wiki/node/Node-Mining-Modes) + * [AVX Optimization](https://github.com/BeamMW/beam/wiki/AVX) + * [Supported nVidia Cards (OpenCL)](https://github.com/BeamMW/beam/wiki/Supported-nVidia-cards-for-mining-using-OpenCL-miner) + +## Wallet — Engine, DB, Addresses, Key Management + +Wallet architecture, database schema, key derivation, address formats, SBBS messaging, and hardware wallet support. + +* [Wallet Architecture](https://github.com/BeamMW/beam/wiki/wallet/Wallet-Architecture) +* [Wallet Database Schema](https://github.com/BeamMW/beam/wiki/wallet/Wallet-Database-Schema) + * [Payment Confirmation](https://github.com/BeamMW/beam/wiki/Payment-confirmation-(proof)) + * [One-Side Payment](https://github.com/BeamMW/beam/wiki/One-side-payments) + * [Transactions over TOR](https://github.com/BeamMW/beam/wiki/transactions/Transactions-with-Beam-Wallet-CLI-over-TOR-network) +* [Addresses and Key Derivation](https://github.com/BeamMW/beam/wiki/wallet/Wallet-Addresses-And-Key-Derivation) +* [Secure Bulletin Board System (SBBS)](https://github.com/BeamMW/beam/wiki/wallet/Wallet-SBBS) +* [WASM Wallet Client](https://github.com/BeamMW/beam/wiki/WASM-wallet-client) +* [Wallet Audit (Read-Only)](https://github.com/BeamMW/beam/wiki/wallet/Wallet-audit) + * [Setting Up Read-Only Wallet](https://github.com/BeamMW/beam/wiki/Setting-up-read-only-wallet-for-monitoring) +* [Key Keeper and Hardware Wallet Support](https://github.com/BeamMW/beam/wiki/wallet/Wallet-Key-Keeper) + * [Hardware Wallet Design](https://github.com/BeamMW/beam/wiki/HW-wallet-design) + * [How to Test with Trezor T](https://github.com/BeamMW/beam/wiki/How-to-test-Beam-with-Trezor-wallet) +* [Beam URI Scheme](https://github.com/BeamMW/beam/wiki/Beam-URI-scheme) + +## Transactions — Simple, Assets, Shielded, Swaps, Channels + +Transaction types and creation protocols: plain BEAM transfers, Confidential Assets, Lelantus shielded pool, atomic swaps, hi-frequency transactions, and payment channels. + +* [Transaction Creation Protocol](https://github.com/BeamMW/beam/wiki/transactions/Transactions-Creation-Protocol) + * [Token Format](https://github.com/BeamMW/beam/wiki/Atomic-swap-token) +* [Simple Transactions and Confidential Assets](https://github.com/BeamMW/beam/wiki/transactions/Transactions-Confidential-Assets) + * [Asset Descriptor v1.0](https://github.com/BeamMW/beam/wiki/Asset-Descriptor-v1.0) +* [Lelantus-MW Shielded Pool](https://github.com/BeamMW/beam/wiki/transactions/Transactions-Lelantus-Shielded-Pool) + * [Confidential Lelantus Assets (MW-CLA)](https://github.com/BeamMW/beam/wiki/MW-CLA) +* [Hi-Frequency Transactions (HFTX)](https://github.com/BeamMW/beam/wiki/transactions/Transactions-Hi-Frequency) +* [Atomic Swaps](https://github.com/BeamMW/beam/wiki/transactions/Transactions-Atomic-Swaps) +* [Asset Swaps / DEX](https://github.com/BeamMW/beam/wiki/transactions/Transactions-Assets-Swaps) +* [Laser Channels (Payment Channels)](https://github.com/BeamMW/beam/wiki/transactions/Transactions-Laser-Channels) + * [Laser Beam Commands](https://github.com/BeamMW/beam/wiki/Laser-BEAM-commands) +* [Transaction Ordering and Front-Running Protection](https://github.com/BeamMW/beam/wiki/historical/Transaction-ordering-and-front-running-protection) + +## BVM — Smart Contracts, Shaders, IPFS + +Beam Virtual Machine internals, shader (smart contract) development SDK, IPFS integration, and EVM compatibility. + +* [BVM Internals](https://github.com/BeamMW/beam/wiki/bvm/BVM-Internals) +* [Smart Contracts Overview](https://github.com/BeamMW/beam/wiki/bvm/BVM-Beam-Smart-Contracts) +* [BVM Host Functions Reference](https://github.com/BeamMW/beam/wiki/bvm/BVM-functions-for-shaders) +* [Building Beam Shaders](https://github.com/BeamMW/beam/wiki/bvm/BVM-Building-Beam-Shaders) +* [Running Shaders with CLI Wallet](https://github.com/BeamMW/beam/wiki/bvm/BVM-Running-Beam-Shaders-using-CLI-Wallet) +* [Shader SDK Index](https://github.com/BeamMW/beam/wiki/bvm/BVM-Shader-SDK-Index) +* [Ethash Verification in Contracts](https://github.com/BeamMW/beam/wiki/Ethash-verification-in-contracts) +* [BEAM IPFS Support](https://github.com/BeamMW/beam/wiki/BEAM-IPFS-Support) + +**BeamX Contract Examples** +* [BeamX Getting Started](https://github.com/BeamMW/beam/wiki/BeamX-Getting-Started) +* [Using BeamX Faucet with CLI Wallet](https://github.com/BeamMW/beam/wiki/Using-BeamX-Faucet-contract-with-CLI-Wallet) +* [Using BeamX Vault with CLI Wallet](https://github.com/BeamMW/beam/wiki/Using-BeamX-Vault-contract-with-CLI-Wallet) +* [Using BeamX Roulette with CLI Wallet](https://github.com/BeamMW/beam/wiki/Using-BeamX-Roulette-contract-with-CLI-Wallet) + +## Consensus — Hard Forks, BeamHash, Upgrade Guides + +Consensus parameter evolution, proof-of-work algorithm history, and network upgrade guides for pools and exchanges. + +* [Hard Forks — Rules, Heights, and Consensus Changes](https://github.com/BeamMW/beam/wiki/consensus/Consensus-Hard-Forks) +* [BeamHash PoW Algorithm](https://github.com/BeamMW/beam/wiki/consensus/Consensus-BeamHash) +* [Beam Warp: dPoS / PBFT Consensus](https://github.com/BeamMW/beam/wiki/consensus/Consensus-Beam-Warp-dPoS) +* [Upgrade Guide: Eager Electron 5.0](https://github.com/BeamMW/beam/wiki/Beam-Eager-Electron-5.0-Upgrade-Guide-for-pools-and-exchanges) +* [Upgrade Guide: Fierce Fermion 6.0](https://github.com/BeamMW/beam/wiki/Beam-Fierce-Fermion-6.0-Upgrade-Guide-for-pools-and-exchanges) +* [Testing Hard Forks on Local Testnet](https://github.com/BeamMW/beam/wiki/Testing-Beam-Hard-Fork-on-Local-Testnet) + +## API — Wallet, Explorer, Stratum + +JSON-RPC and protocol API references for wallet integration, blockchain data access, and mining pool operation. + +* [Beam Wallet API](https://github.com/BeamMW/beam/wiki/api/Beam-wallet-protocol-API) + * [v6.0](https://github.com/BeamMW/beam/wiki/api/Beam-wallet-protocol-API-v6.0) + * [v6.1](https://github.com/BeamMW/beam/wiki/api/Beam-wallet-protocol-API-v6.1) + * [v6.2](https://github.com/BeamMW/beam/wiki/api/Beam-wallet-protocol-API-v6.2) + * [v7.0](https://github.com/BeamMW/beam/wiki/api/Beam-wallet-protocol-API-v7.0) + * [v7.1](https://github.com/BeamMW/beam/wiki/api/Beam-wallet-protocol-API-v7.1) + * [v7.2](https://github.com/BeamMW/beam/wiki/api/Beam-wallet-protocol-API-v7.2) + * [v7.3](https://github.com/BeamMW/beam/wiki/api/Beam-wallet-protocol-API-v7.3) + * [v7.4](https://github.com/BeamMW/beam/wiki/api/Beam-wallet-protocol-API-v7.4) +* [Beam Node Explorer API](https://github.com/BeamMW/beam/wiki/api/Beam-Node-Explorer-API) +* [Beam Mining API (Stratum)](https://github.com/BeamMW/beam/wiki/api/Beam-mining-protocol-API-(Stratum)) + +## Contributing — C++ Conventions and Codebase Guide + +Conventions, idioms, and patterns used throughout the Beam C++ codebase. + +* [C++ Style and Conventions](https://github.com/BeamMW/beam/wiki/Beam-Cpp-Style-And-Conventions) +* [How To Build](https://github.com/BeamMW/beam/wiki/How-to-build) +* [Contribution Guidelines](https://github.com/BeamMW/beam/wiki/Contribution-Guidelines) + +--- + +# Research and Historical Proposals + +Design proposals and research documents preserved for historical reference. These were not fully implemented in their described form. + +* [Eliminating Transaction Kernels](https://github.com/BeamMW/beam/wiki/historical/Thoughts-about-eliminating-transaction-kernels) +* [Wallets Discovery and Dialog Proposal](https://github.com/BeamMW/beam/wiki/historical/Wallets-discovery-and-dialog-proposal) +* [Proposal for I/O Layer and P2P](https://github.com/BeamMW/beam/wiki/historical/Proposal-for-I-O-layer-and-P2P) +* [Mimblewimble Whitepaper (June 2016)](https://github.com/BeamMW/beam/wiki/Mimblewimble-Whitepaper-(June-2016)) +* [Beam Position Paper](https://github.com/BeamMW/beam/wiki/historical/Beam-Position-Paper) +* [News Channels](https://github.com/BeamMW/beam/wiki/Beam-news-channels) diff --git a/core-tech/How-to-build(old).md b/core-tech/How-to-build(old).md deleted file mode 100644 index 6d42966..0000000 --- a/core-tech/How-to-build(old).md +++ /dev/null @@ -1,278 +0,0 @@ -# Windows -1. Install Visual Studio >= 2017 with CMake support. -1. Download and install Boost prebuilt binaries https://sourceforge.net/projects/boost/files/boost-binaries/1.68.0/boost_1_68_0-msvc-14.1-64.exe, also add `BOOST_ROOT` to the _Environment Variables_. -1. Download and install OpenSSL prebuilt binaries https://slproweb.com/products/Win32OpenSSL.html (`Win64 OpenSSL v1.1.0h` for example) and add `OPENSSL_ROOT_DIR` to the _Environment Variables_. -1. Download and install QT 5.11 http://master.qt.io/new_archive/qt/5.11/5.11.0/qt-opensource-windows-x86-5.11.0.exe and add `QT5_ROOT_DIR` to the _Environment Variables_ (usually it looks like `.../5.11.0/msvc2017_64`), also add `QML_IMPORT_PATH` (it should look like `%QT5_ROOT_DIR%\qml`). BTW disabling system antivirus on Windows makes QT installing process much faster. -1. Add `.../qt511/5.11.1/msvc2017_64/bin` and `.../boost_1_68_0/lib64-msvc-14.1` to the _System Path_. -1. Open project folder in Visual Studio, select your target (`Release-x64` for example, if you downloaded 64bit Boost and OpenSSL) and select `CMake -> Build All`. -1. Go to `CMake -> Cache -> Open Cache Folder -> beam` (you'll find binaries in `beam/...`, `wallet/...`, `ui/...`, `explorer/...` subfolders). - -# Linux - -**Please read carefully the points below** - -**1.** After finishing your build you'll find the the `beam-node` binary (node) in the `beam/beam` folder, `beam-wallet` (cli wallet) in the `beam/wallet` folder and `BeamWallet` (GUI wallet) in the `beam/ui` folder. - -**2.** You need to clone beam sources before building -``` -git clone https://github.com/BeamMW/beam.git -``` -The command above checks out the latest master branch where all the development happens. Usually it is not what you want to build. Choose an appropriate branch [here](https://github.com/BeamMW/beam/branches) and check out it after you have the main repository cloned. For example the command below checks out the Double Doppler 4.0 release branch -``` -cd beam -git checkout double_doppler_4.0RC -``` - -**3.** By default instructions produce masternet builds (development version, development blockchain). To be able to build testnet (testing) or mainnet (real-world blockchain) you need to edit the `beam/CMakeLists.txt` file lines 151-157. Uncomment (remove the '#' sign) respective definitions. -``` -# uncomment next line for testnet -#set(BEAM_TESTNET TRUE) -# uncomment next line for mainnet -#set(BEAM_MAINNET TRUE) - -# uncomment next line for swap mainnet -#set(SWAP_MAINNET TRUE) -``` - -**4.** Server instructions result only in a valid build and enable you running all the CLI tools. They are not intended to ensure that you would be able to run the UI. Desktop build instructions include additional steps to ensure that the UI can be launched. - -**5.** At the moment building the UI can take a lot of time (a few hours) due to the bug in QT: [QTBUG-27936](https://bugreports.qt.io/browse/QTBUG-27936). To skip building the UI pass `-DBEAM_NO_QT_UI_WALLET=On` to cmake. You can also omit all Qt5 dependencies in this case. - -## Ubuntu 18.04 Desktop - -Instructions below are valid for a clean default Ubuntu 18.04.03 Desktop LTS install. If your're building on an aged system please check that steps 1, 2 & 4 do not overwrite/conflict with more recent versions of cmake and boost that might have been installed before. You can omit cmake/boost installation if you already have more recent versions. - -1. Install dependencies - ``` - sudo add-apt-repository ppa:beineri/opt-qt-5.11.0-bionic - sudo add-apt-repository ppa:mhier/libboost-latest - sudo apt-get update && sudo apt-get upgrade - sudo apt-get install g++-8 libssl-dev curl wget git make - sudo apt-get install libgl1-mesa-dev zlib1g-dev libboost1.67-dev - sudo apt-get install qt511base qt511declarative qt511svg qt511tools - ``` - -1. Install cmake - ``` - wget https://cmake.org/files/v3.13/cmake-3.13.0-Linux-x86_64.sh - sudo sh ./cmake-3.13.0-Linux-x86_64.sh --skip-license --prefix=/usr - ``` - -1. Go to the Beam project folder and start the release build - ``` - export PATH=/opt/qt511/bin:$PATH && export CC=gcc-8 && export CXX=g++-8 - cmake -DCMAKE_BUILD_TYPE=Release && make -j4 - ``` - -1. To be able to run the UI (BeamWallet) install additional dependencies - ``` - sudo apt-get install qt511quick* qt511graphicaleffects - ``` - -## Ubuntu 18.04 Server - -Instructions below are valid for a clean default Ubuntu 18.04.03 Server LTS with all the updates applied during install. If your're building on an aged system please check that steps 1 & 2 do not overwrite/conflict with more recent versions of cmake and boost that might have been installed before. You can omit cmake/boost installation if you already have more recent versions. - -1. Install dependencies - ``` - sudo add-apt-repository ppa:beineri/opt-qt-5.11.0-bionic - sudo add-apt-repository ppa:mhier/libboost-latest - sudo apt-get update && sudo apt-get upgrade - sudo apt-get install g++-8 libssl-dev curl wget git make - sudo apt-get install libgl1-mesa-dev zlib1g-dev libboost1.67-dev - sudo apt-get install qt511base qt511declarative qt511svg qt511tools - ``` - -1. Install cmake - ``` - wget https://cmake.org/files/v3.13/cmake-3.13.0-Linux-x86_64.sh - sudo sh ./cmake-3.13.0-Linux-x86_64.sh --skip-license --prefix=/usr - ``` - -1. Go to the Beam project folder and start the release build - ``` - export PATH=/opt/qt511/bin:$PATH && export CC=gcc-8 && export CXX=g++-8 - cmake -DCMAKE_BUILD_TYPE=Release && make -j4 - ``` - -## Ubuntu 19.10 Server - -Instructions below are valid for a default Ubuntu 19.10 Server install with updates applied during install. - -1. Install dependencies - ``` - sudo apt-get update && sudo apt-get upgrade - sudo apt-get install g++ git make cmake libboost-all-dev zlib1g-dev - sudo apt-get install libssl-dev qtbase5-dev qtdeclarative5-dev - sudo apt-get install libqt5svg5-dev qttools5-dev qt5-default - ``` - -1. Go to the Beam project folder and start the release build - ``` - cmake -DCMAKE_BUILD_TYPE=Release . && make -j4 - ``` - -## Ubuntu 19.10 Desktop - -Instructions below are valid for a minimal Ubuntu 19.10 Desktop install with 'update during install' option enabled. - -1. Install dependencies - ``` - sudo apt-get install g++ git make cmake libboost-all-dev zlib1g-dev - sudo apt-get install libssl-dev qtbase5-dev qtdeclarative5-dev - sudo apt-get install libqt5svg5-dev qttools5-dev qt5-default - ``` - -1. Go to the Beam project folder and start the release build - ``` - cmake -DCMAKE_BUILD_TYPE=Release . && make -j4 - ``` - -1. To be able not only to build but also to run the UI (BeamWallet) you need to install additional dependencies - - ``` - sudo apt-get install qml-module-qt* - ``` - -## Centos 7.7 - -Instructions below are valid for a clean CentOS 7.0-1908 minimal install. If your're building on an aged system please check that steps 2 & 3 do not overwrite more recent versions of cmake and boost that might have been installed before. - -N.B. These build instruction provide only commandline tools including node but no GUI wallet. Use newer operating system with more up to date Qt libraries (5.11+) to effortlessly build the UI. - -1. Install dependencies - ``` - sudo yum update && shutdown -r now - sudo yum install centos-release-scl yum-utils - sudo yum-config-manager --enable rhel-server-rhscl-8-rpms - sudo yum install devtoolset-8-gcc* - scl enable devtoolset-8 bash - sudo yum install git make wget openssl-devel - ``` - -1. Build & install boost. This step could take considerable amount of time - ``` - wget https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz - tar xzvf boost_1_66_0.tar.gz - cd boost_1_66_0 && ./bootstrap.sh && sudo ./b2 install && cd ~ - ``` - -1. Install cmake - ``` - wget https://cmake.org/files/v3.13/cmake-3.13.0-Linux-x86_64.sh - sudo sh ./cmake-3.13.0-Linux-x86_64.sh --skip-license --prefix=/usr - ``` - -1. Go to the beam sources folder and start the release build - ``` - cmake -DCMAKE_BUILD_TYPE=Release -DBEAM_NO_QT_UI_WALLET=On . && make -j4 - ``` - -## CentOS 8 - -Instructions below are valid for a clean CentOS 8.0-1905 minimal install. If your're building on an aged install please check that step 2 does not overwrite more recent version of cmake that might have been installed before. - -1. Install dependencies - ``` - sudo dnf update - sudo dnf config-manager --set-enabled PowerTools - sudo dnf install git make cmake gcc-c++ libstdc++-static boost-devel - sudo dnf install openssl-devel tar wget qt5-qtbase-devel qt5-linguist - sudo dnf install qt5-qtsvg-devel qt5-qtdeclarative-devel - ``` - -1. Install cmake - ``` - wget https://cmake.org/files/v3.13/cmake-3.13.0-Linux-x86_64.sh - sudo sh ./cmake-3.13.0-Linux-x86_64.sh --skip-license --prefix=/usr - ``` - -1. Go to the beam sources folder and start the release build - ``` - export PATH=${PATH}:/usr/lib64/qt5/bin - cmake -DCMAKE_BUILD_TYPE=Release . && make -j4 - ``` - -## Fedora 31 Workstation - -Instructions below are valid for a default Fedora 31-1.9 Workstation install. - -1. Install dependencies - ``` - sudo dnf update && shutdown -r now - sudo dnf install git make cmake gcc-c++ libstdc++-static boost-devel - sudo dnf install zlib-devel openssl-devel tar qt5-qtbase-devel qt5-linguist - sudo dnf install qt5-qtsvg-devel qt5-qtdeclarative-devel - ``` - -1. Go to the Beam project folder and start the release build - ``` - cmake -DCMAKE_BUILD_TYPE=Release . && make -j4 - ``` - -1. To be able to run the UI (BeamWallet) install additional dependencies - ``` - sudo dnf install qt5-qtquickcontrols qt5-qtquickcontrols2 - ``` - -## Fedora 31 Server - -Instructions below are valid for a default Fedora 31-1.9 Headless Server install. - -1. Install dependencies - ``` - sudo dnf update && shutdown -r now - sudo dnf install git make cmake gcc-c++ libstdc++-static boost-devel - sudo dnf install zlib-devel openssl-devel tar qt5-qtbase-devel qt5-linguist - sudo dnf install qt5-qtsvg-devel qt5-qtdeclarative-devel - ``` - -1. Go to the Beam project folder and start the release build - ``` - cmake -DCMAKE_BUILD_TYPE=Release . && make -j4 - ``` - -# Mac -1. Download the source code by using: - ``` - git clone https://github.com/BeamMW/beam.git - ``` - this will give you a master branch which is developer's version of Beam. To get _mainnet_ or _testnet_ use - ``` - git clone --branch mainnet https://github.com/BeamMW/beam.git - ``` - or - ``` - git clone --branch testnet https://github.com/BeamMW/beam.git - ``` - -1. Install Brew Package Manager. -1. Install necessary packages using: - ``` - brew install openssl cmake - ``` -1. Remove any existing brew installations of qt and boost: - ``` - brew uninstall --ignore-dependencies qt boost - ``` -1. Download and install a compatible version of boost: - ``` - curl -O https://raw.githubusercontent.com/Homebrew/homebrew-core/5da5895add2f6b9320d654dd844d4827f6876c8b/Formula/boost.rb - brew install ./boost.rb - ``` -1. Download and install QT5.11 from the official website http://master.qt.io/new_archive/qt/5.11/5.11.0/qt-opensource-mac-x64-5.11.0.dmg -1. Set your Environment Variables by using the following: - ``` - - export OPENSSL_ROOT_DIR="/usr/local/opt/openssl@1.1" - - export PATH=/Users//Qt5.11.0/5.11.0/clang_64/bin:$PATH - - export QT5_ROOT_DIR=/Users//Qt5.11.0/5.11.0/ - - export QML_IMPORT_PATH="/Users//Qt5.11.0/5.11.0/qml" - ``` -1. Go to Beam project folder and call - ``` - cmake -DCMAKE_BUILD_TYPE=Release . && make -j4 - ``` -1. Use `cpack` to get .dmg file -1. You'll find binaries in `beam/wallet`, `beam/ui`, and `beam/explorer` subfolders. - -If you don't want to build UI don't install QT5 and add `-DBEAM_NO_QT_UI_WALLET=On` command line parameter when you are calling `cmake`. diff --git a/core-tech/How-to-build.md b/core-tech/How-to-build.md index aa3ce0c..2db238d 100644 --- a/core-tech/How-to-build.md +++ b/core-tech/How-to-build.md @@ -24,14 +24,8 @@ For earlier versions, build instructions are located [here](https://github.com/B git submodule update --init --recursive ``` -## Branch convention -1. We use `master` branch for development. -1. To be able to connect to `testnet` you have to checkout `testnet` branch -1. To be able to connect to `mainnet` you have to checkout `mainnet` branch - - ## CMake options -Beam uses CMake to generate a build. Beam has several options to say how to build the project, which feature to turn ON/OFF. T +Beam uses CMake to generate a build. Beam has several options to say how to build the project, which feature to turn ON/OFF. Please, look reference to root `CMakeLists.txt` file. # Windows @@ -80,7 +74,7 @@ git checkout double_doppler_4.0RC ## Ubuntu 18.04 Desktop -Instructions below are valid for a clean default Ubuntu 18.04.03 Desktop LTS install. If your're building on an aged system please check that steps 1, 2 & 4 do not overwrite/conflict with more recent versions of cmake and boost that might have been installed before. You can omit cmake/boost installation if you already have more recent versions. +Instructions below are valid for a clean default Ubuntu 18.04.03 Desktop LTS install. If you're building on an aged system please check that steps 1, 2 & 4 do not overwrite/conflict with more recent versions of cmake and boost that might have been installed before. You can omit cmake/boost installation if you already have more recent versions. 1. Install dependencies ``` @@ -249,16 +243,9 @@ Instructions below are valid for a default Fedora 31-1.9 Headless Server install ``` git clone https://github.com/BeamMW/beam.git ``` - this will give you a master branch which is developer's version of Beam. To get _mainnet_ or _testnet_ use - ``` - git clone --branch mainnet https://github.com/BeamMW/beam.git - ``` - or - ``` - git clone --branch testnet https://github.com/BeamMW/beam.git - ``` 1. Install Brew Package Manager. + 1. Install necessary packages using: ``` brew install openssl cmake @@ -269,12 +256,12 @@ Instructions below are valid for a default Fedora 31-1.9 Headless Server install ``` 1. Download and install a compatible version of boost: ``` - curl -O https://raw.githubusercontent.com/Homebrew/homebrew-core/5da5895add2f6b9320d654dd844d4827f6876c8b/Formula/boost.rb - brew install ./boost.rb + brew install boost@1.76 + brew link --force --overwrite boost@1.76 ``` 1. Set your Environment Variables by using the following: ``` - - export OPENSSL_ROOT_DIR="/usr/local/opt/openssl@1.1" + - export OPENSSL_ROOT_DIR="/usr/local/opt/openssl@3" ``` 1. Go to Beam project folder and call ``` diff --git a/core-tech/How-to-remove-the-Desktop-Wallet-files-in-a-manual-way.md b/core-tech/How-to-remove-the-Desktop-Wallet-files-in-a-manual-way.md deleted file mode 100644 index 4b64eaf..0000000 --- a/core-tech/How-to-remove-the-Desktop-Wallet-files-in-a-manual-way.md +++ /dev/null @@ -1,28 +0,0 @@ -Since the current versions of the Desktop Wallet are not backward compatible, it is required to remove the files manually before upgrading to the next major version. - -Points to mention: -* On Mac and Windows the wallet files reside in directories which are not shown by default, yet they can be accessed via a command line interface (see the examples below). -* On Mac and Windows the wallet files reside (by default) in a home directory of the user. In the examples below the user name is `alice` on all the platforms. -* The suggested commands will unconditionally remove the files, an action which cannot be undone. - -### On Windows -* Push windows button+R, the Run window will appear. Type cmd and click OK. -* In the window that appears, paste the following command and click enter: - -``` sh -RD /s /q "C:\Users\alice\AppData\Local\Beam Wallet" -``` - -### On Mac -* Open the Terminal app, paste the following command and click enter: - -``` sh -rm -R "/Users/alice/Library/Application Support/Beam Wallet" -``` - -### On Linux -* Run the following command in terminal: - -``` sh -rm -R ".local/share/Beam Wallet" -``` diff --git a/core-tech/How-to-test-Beam-with-Trezor-wallet.md b/core-tech/How-to-test-Beam-with-Trezor-wallet.md index bdb219c..f2d7510 100644 --- a/core-tech/How-to-test-Beam-with-Trezor-wallet.md +++ b/core-tech/How-to-test-Beam-with-Trezor-wallet.md @@ -34,7 +34,7 @@ python3 setup.py prebuild - Call `trezorctl firmware-update -f /firmware.bin` to install firmware. ## Test Beam with Trezor -- Go to https://builds.beam-mw.com/trezor_build and download/install the latest build. +- Go to https://builds.beam.mw/#trezor_build and download/install the latest build. - Connect your device, go to https://trezor.io/start, create a new wallet or recover with your seed phrase. - Run installed **Beam Wallet** and push `create new Trezor wallet` button. - Agree with generating **Owner Key** on Trezor device and wait, it usually takes about 15 sec. diff --git a/core-tech/Instructions-for-Command-Line-Node.md b/core-tech/Instructions-for-Command-Line-Node.md deleted file mode 100644 index 056d72d..0000000 --- a/core-tech/Instructions-for-Command-Line-Node.md +++ /dev/null @@ -1,143 +0,0 @@ -# This documentation is obsolete - -Please refer to [Beam Node User Guide](https://beam-docs.readthedocs.io/en/latest/rtd_pages/user_beam_node_guide.html) - -# Running a node - -* [Node source code](https://github.com/BeamMW/beam/tree/master/beam) -* Node binaries for Windows, Mac and Linux can be downloaded from the Beam website (http://beam.mw/downloads) or GitHub (https://github.com/BeamMW/beam/releases). -* Node parameters can be either passed through command line or specified in the configuration file called `beam-node.cfg` and located in the same folder the node resides in. -* For every parameter, the value in the command line prevails over configuration file. -* The log files are located in the `logs` folder, which in turn resides in the node folder. -* Once started, the node will create a `node.db` file in the same folder it is located. This file will store an internal state of the node. -* Upon the first launch, the node will download current blockchain history in batch mode as a single large macroblock. After the initial sync is complete, the node will continue to sync blocks and individual transactions from the current blockchain Tip (height) and onwards. This can be seen in the log entry: `My Tip: 24704-f2ab414ba6430d85`. - -# Command line execution example: - -``` sh -./beam-node --peer 104.248.159.154:8100 --mining_threads 1 --file_log_level debug --key_mine=Ipte/cVRHvS72U4h66KIDDILwtIhpsRugTWycwnDUqwOqFq+qmcVEuWhjPJ2OwBn6ZkxKKpLX0W9PvHhGIUVPz8d6CL5CSB8fjt4kA== --key_view=xj7uVZh7kWaY2U4h66KIDDILwtIhpsRugTWycwnDUqwOqFq+qmcVEuVqiydGxomYaF2lQcc92Rzm3HBqsvk9LrFZlrksacvpDgteNLqxQJ4DUD+iKiDYvXy+VLCui125Rw69lO+8gxnxMM5j1rk= --pass=123 -``` - -## Node command line parameters explained: -| Name | Description | -|------|-------------| -| `peer` | Specifies a comma-separated list of peers the node will initially connect to. After the connection is established, the node will get an updated list of peers from other nodes, along with peer ratings and from that moment the node will manage its connections on its own. | -| `key_mine` | A password-protected secret key, exported by the wallet, that should be used for standalone mining (when the owner wallet is offline). If not specified - mining would be possible only when the owner wallet is online | -| `key_view` | A semicolon-separated list of password-protected viewer keys, exported by the wallet, that should be monitored by the node. The wallet master viewer key is also needed for node-wallet authentication. The `key_mine`, if set, is also included implicitly | -| `pass` | A password that should be used to access they encoded keys. | -| `mining_treads` | Specifies the number of CPU cores utilized for mining. If set to 0, node acts as a validating node only. | -| `file_log_level` | Allows to raise the debug level when a deeper investigation is required. | - -# Config file example: - -``` sh -# port to start server on -port=10000 - -# secret key for mining. -key_mine=Ipte/cVRHvS72U4h66KIDDILwtIhpsRugTWycwnDUqwOqFq+qmcVEuWhjPJ2OwBn6ZkxKKpLX0W9PvHhGIUVPz8d6CL5CSB8fjt4kA== - -# All the viewer keys. ---key_view=xj7uVZh7kWaY2U4h66KIDDILwtIhpsRugTWycwnDUqwOqFq+qmcVEuVqiydGxomYaF2lQcc92Rzm3HBqsvk9LrFZlrksacvpDgteNLqxQJ4DUD+iKiDYvXy+VLCui125Rw69lO+8gxnxMM5j1rk= - -# Password. If required (at least 1 key specified) and not set - will be asked after launch. ---pass=123 - -# number of mining threads(there is no mining if 0) -mining_threads=1 - -# peers -peer=104.248.159.154:8100 - -# miner type -miner_type=cpu -``` - -# The full list of options supported by the node - -## General options: - -| Name | Description | -|------|-------------| -| `h` or `help`| list of all options | -| `p arg` or `port arg (=10000)` | port to start the server on | -| `log_level arg` | log level `[info/debug/verbose]` | -| `file_log_level arg` | file log level `[info/debug/verbose]` | -| `v` or `version` | return project version | -| `git_commit_hash` | return commit hash | - -## Node options: -| Name | Description | -|------|-------------| -| `storage arg (=node.db)` | node storage path | -| `history_dir arg (=./)` | directory for compressed history | -| `temp_dir arg (=/tmp/)` | temp directory for compressed history, must be on the same volume | -| `miner_type arg (=cpu)` | miner type [cpu/gpu] | -| `mining_threads arg (=0)` | number of mining threads(there is no mining if 0) | -| `verification_threads arg (=-1)` | number of threads for cryptographic verifications (0 = single thread, -1 = auto) | -| `miner_id arg (=0)` | seed for miner nonce generation | -| `peer arg` | nodes to connect to | -| `import arg (=0)` | specify the blockchain height to import, the compressed history is assumed to be downloaded to the specified directory | - -## Rules configuration: - -| Name | Description | -|------|-------------| -| `CoinbaseEmission arg (=80000000)` | coinbase emission in a single block | -| `MaturityCoinbase arg (=60)` | Number of blocks before coinbase UTXO can be spent | -| `MaturityStd arg (=0)` | Number of blocks before non-coinbase UTXO can be spent | -| `MaxBodySize arg (=1048576)` | Max block body size in `[bytes]` | -| `DesiredRate_s arg (=60)` | Desired rate of generated blocks in `[seconds]` | -| `DifficultyReviewCycle arg (=1440)` | Number of blocks after which the mining difficulty can be adjusted | -| `MaxDifficultyChange arg (=2)` | Max difficulty change after each cycle (each step is roughly x2 complexity) | -| `TimestampAheadThreshold_s arg (=7200)` | Block timestamp tolerance in `[seconds]` | -| `WindowForMedian arg (=25)` | How many blocks are considered in calculating the timestamp median | -| `AllowPublicUtxos arg (=0)` | Set to allow regular (non-coinbase) UTXO to have non-confidential signature | -| `FakePoW arg (=0)`| Don't verify PoW. Mining is simulated by the timer. For tests only | - -# Running Beam Node with Stratum Server - -* Beam node implements Stratum protocol for connecting external miner clients. Clients open a TCP connection to the node though which they receive jobs to mine blocks using Equihash mining protocol. - -# Command line execution example - -``` sh -./beam-node --port {NODE_PORT} --peer {PEER_IP} --stratum_port {STRATUM_PORT} --stratum_secrets_path {DIRECTORY} ----key_view=xj7uVZh7kWaY2U4h66KIDDILwtIhpsRugTWycwnDUqwOqFq+qmcVEuVqiydGxomYaF2lQcc92Rzm3HBqsvk9LrFZlrksacvpDgteNLqxQJ4DUD+" -``` - -## Command line parameters - -| Name | Description | -|------|-------------| -| `port` | port to start the node server on | -| `peer` | nodes to connect to (in example remote node from masternet) | -| `stratum_port` | stratum server port (should be >0) | -| `stratum_secrets_path` | folder where configuration files are located | - -## Configuration files - -| Name | Description | -|------|-------------| -| `stratum.crt` | TLS certificate | -| `stratum.key` | private key for TLS | -| `stratum.api.keys` | file with allowed api keys | - -For testing purposes ONLY `stratum.crt` and `stratum.key` can be downloaded from: - -* https://github.com/BeamMW/beam/blob/master/utility/unittest/test.crt -* https://github.com/BeamMW/beam/blob/master/utility/unittest/test.key - -The stratum.api.keys file (which you create by yourself) should contain any number of strings at least 7 symbols long without spaces each: - -``` -12345678 -sfdskjhfdksk -984398349834 -``` - -If there is no `stratum.api.keys`, ACL will be switched off. - -Please note that `stratum.api.key` file is reloaded by the server every 5 seconds, if you want to add/delete/edit key you shouldn't restart `beam-node`, just edit file `stratum.api.keys` file. - -# Known limitations -* CPU without SSE3 instruction set are not supported diff --git a/core-tech/Instructions-for-Command-Line-Wallet.md b/core-tech/Instructions-for-Command-Line-Wallet.md deleted file mode 100644 index cb60e7e..0000000 --- a/core-tech/Instructions-for-Command-Line-Wallet.md +++ /dev/null @@ -1,101 +0,0 @@ -# This documentation is obsolete -Please refer to [Command Line User Guide](https://beam-docs.readthedocs.io/en/latest/rtd_pages/user_cli_wallet_guide.html) - - -# Running a command line wallet - -* After extracting the wallet binary to a folder, we need to initialize the wallet by executing the following command: -``` sh -./beam-wallet --command init -``` -* You will be prompted to provide wallet password and then the secret phrase, which would be used to initialize the master secret. Make sure to write down the secret phrase, to be able to restore wallet contents in case of emergency. - - -# Printing wallet information - -* To get the information about the current status of the wallet, execute: -``` sh -./beam-wallet --command info -n 127.0.0.1:10000 -``` - - -# Receiving Beams - -* To receive beams start the wallet in a listening mode by running: -``` sh -./beam-wallet --command listen -n 127.0.0.1:10000 -``` -* After entering the password, the wallet will print out the line similar to: `WalletID 4a0e54b24d5fdf06891a8eaa57b4b3ac16731e932a64da8ec768083495d624f1 subscribes to BBS channel 9` -* This shows the SBBS address the wallet is listening on. This address can be copied and sent to Sender. -* If you want to create new SBBS address use the following command: -``` sh -./beam-wallet --command=new_addr --listen -n 127.0.0.1:10000 -``` - -# Exporting keys for standalone Node(s) - -The Node(s) that belongs to the wallet should be given appropriate keys for the following purpose: -* Node-Wallet authentication -* Standalone mining (when the wallet is offline) -* Monitoring wallet activity, supporting recovery and etc. - -It's possible to export the master wallet key, as well as a _child_ key, which is derived from the master key (but not vice versa!). -In addition every key can be exported as a full key, or as a _viewer_ key, which is suitable for Node authentication and monitoring activity, but not for generating and spending the UTXOs. - -Keeping in mind that the wallet may own several nodes, we recommend providing each node a different child key for mining, so that in case it gets hacked - the attacker won't be able to steal what's been mined by other nodes. Anyway when the owner wallet connects the Node prefers to involve the wallet in mining, so that key won't be used either. -Obviously it's not recommended to export the master secret key ever. - -In addition to mining, one or more viewer keys should be exported and provided to the nodes. To be able to communicate with the wallet, each Node must have its master viewer key. In addition to this, every node should have all the viewer child keys that are used for mining, to be able to detect/restore all the mined UTXOs. - -* To export a child key -``` sh -./beam-wallet --command=key_export --subkey=N -``` -whereas `N` is the child index. Specifying `0` means the master key. - -# Sending Beams - -* To sending beams use the following command -``` sh -./beam-wallet --command=send -n 127.0.0.1:10000 -r 77de6bd3de40bc58ab7e4fb68d5e0596fd1e72f3c4fb3eb3d106082d89264909 -a 11.3 -f 0.2 -``` -* The send-related command line parameters of the wallet: - -| Name | Description | -|------|-------------| -| `r` | SBBS address of the receiver node | -| `a` | amount of beams to send | -| `f` | transaction fee | - - -# The Full list of wallet command line options - -## General options: -| Name | Description | -|------|-------------| -| `h` or `help` | list of all options | -| `p` or `port arg (=10000)` | port to start the server on | -| `log_level arg` | log level `[info|debug|verbose]` | -| `file_log_level arg` | file log level `[info|debug|verbose]` | -| `v` or `version` | return project version | -| `git_commit_hash` | return commit hash | - -## Wallet options: - -| Name | Description | -|------|-------------| -| `seed_phrase arg` | phrase to initialize master secret, according to BIP-39 | -| `pass arg` | password for the wallet | -| `a` or `amount arg` | amount to send (in Beams, 1 Beam = 1000000 chattle) | -| `f` or `fee arg (=0)` | fee (in Beams, 1 Beam = 1000000 chattle) | -| `r` or `receiver_addr arg` | address of receiver | -| `n` or `node_addr arg` | address of node | -| `wallet_path arg (=wallet.db)` | path to wallet file | -| `bbs_keystore_path arg (=bbs_keys.db)` | path to file with bbs keys | -| `tx_history` | print transactions' history in info command | -| `command arg` | command to execute `[send|receive|listen|init|info]` - - - -# Known limitations -* CPUs without SSE3 instruction set are not supported diff --git a/core-tech/Laser-BEAM-commands.md b/core-tech/Laser-BEAM-commands.md deleted file mode 100644 index 3774f46..0000000 --- a/core-tech/Laser-BEAM-commands.md +++ /dev/null @@ -1,69 +0,0 @@ -1) show laser channels - -`./beam-wallet-masternet laser --laser_channels_list` - -2) wait incoming laser connection (will generate address) - -`./beam-wallet-masternet laser --laser_receive --laser_my_locked_amount --laser_remote_locked_amount --laser_fee ` - -Example: - -`./beam-wallet-masternet laser --laser_receive --laser_my_locked_amount 1.1 --laser_remote_locked_amount 1.1 --laser_fee 100` - -3) connect with laser - -`./beam-wallet-masternet laser --laser_open --laser_address
--laser_my_locked_amount --laser_remote_locked_amount --laser_fee ` - -Example: - -`./beam-wallet-masternet laser --laser_open --laser_address 285a776d78e6e0ee285a196282e61768b87c7c108a7d8cf7622a094555d2cfeb80e --laser_my_locked_amount 0.9 --laser_remote_locked_amount 1.1 --laser_fee 100` - -4) listen laser channels - -`./beam-wallet-masternet laser --laser_listen [channel id 1,channel id 2, ... channel id N]` - -Example: - -`./beam-wallet-masternet laser --laser_listen` - -`./beam-wallet-masternet laser --laser_listen 4bd5ee31b264f6102709dc145cf37b55` - -`./beam-wallet-masternet laser --laser_listen 4bd5ee31b264f6102709dc145cf37b55,73e5af986eb3ea165f71bbb54ebfad37` - -5) send coins - -`./beam-wallet-masternet laser --laser_send --laser_channel ` - -Example: - -`./beam-wallet-masternet laser --laser_send 0.1 --laser_channel 4bd5ee31b264f6102709dc145cf37b55` - -6) close laser channels. after lock time is up or if other side is offline - -`./beam-wallet-masternet laser --laser_drop ` - -Example: - -`./beam-wallet-masternet laser --laser_drop 4bd5ee31b264f6102709dc145cf37b55` - -`./beam-wallet-masternet laser --laser_drop 4bd5ee31b264f6102709dc145cf37b55,73e5af986eb3ea165f71bbb54ebfad37` - -7) close laser channels. before lock time is up, only if other side is online - -`./beam-wallet-masternet laser --laser_close ` - -Example: - -`./beam-wallet-masternet laser --laser_close 4bd5ee31b264f6102709dc145cf37b55` - -`./beam-wallet-masternet laser --laser_close 4bd5ee31b264f6102709dc145cf37b55,73e5af986eb3ea165f71bbb54ebfad37` - -8) delete laser channels from DB, only for closed channels - -`./beam-wallet-masternet laser --laser_delete ` - -Example: - -`./beam-wallet-masternet laser --laser_delete 4bd5ee31b264f6102709dc145cf37b55` - -`./beam-wallet-masternet laser --laser_delete 4bd5ee31b264f6102709dc145cf37b55,73e5af986eb3ea165f71bbb54ebfad37` \ No newline at end of file diff --git a/core-tech/Lelantus-CLI.md b/core-tech/Lelantus-CLI.md deleted file mode 100644 index 873d017..0000000 --- a/core-tech/Lelantus-CLI.md +++ /dev/null @@ -1,93 +0,0 @@ -## V6.0 Changes - -Starting from v6.0 - -* CLI `get_address --offline` switch is renamed to `--offline_count` -* default address generated by the UI is an offline address that includes 1 offline voucher (enables 1 offline payment). This address is equivalent to the `get_address --ofline_count 1` in CLI -* all `offline` addresses by default trigger an online regular transaction if used in CLI `send` without the `--offline` switch -* to make an offline payment via the `send` command with the `offline` address the `--offline` switch should be added - -Text below includes the changes described in this section. For CLI instructions before v6.0 refer the [Lelantus CLI Historical](https://github.com/BeamMW/beam/wiki/Lelantus-CLI-(v6.0-)) page. - -## Overview -Conceptually, Lelantus is a mean which allows to avoid UXTO linkability in transactions graph. To make UTXOs unlinked user should insert regular BEAM UTXO into _shielded pool_, converting these UTXOs into _shielded UTXOs_ and then, after some time extract them back as _unlinked_ UTXOs. _Shielded UTXO_ belonging to the wallet could be detected by the node with owner key (as regular utxo), and the user can use this info to extract these coins back. -We are trying to hide the details of this process from the user, extracting from the _shielded pool_ is performed automatically when user sends beams, it influences the fee, but the user shouldn't think about unlinking. - -To send BEAMs through Lelantus we introduced three types of addresses: - -* offline -* max privacy -* public offline - -All of these addresses could be used with `send` command and should be passed via `-r` parameter - -### Offline address -It allows sending BEAMs without interactions with the receiver. It is a very long base58 string, which contains embedded information for 10 payments(in UI), also it has SBBS address of the receiver, so, in the case when the receiver becomes online, the sender could get info for more payments. - -To generate this type of address with 10 embedded payments use - -``` -./beam-wallet get_address --offline_count=10 -``` - -### Max privacy address -This address allows to make only one payment, there is no ability to get more payments, and there is a guaranty that shielded coins received by sending on this address will be extracted in the correct moment to achieve the max privacy effect. -To generate a new max privacy address use - -``` -./beam-wallet get_address --max_privacy -``` - -### Public offline address -This type of address is intended to be used to receive donations. It is permanent, relatively short, and provides less privacy comparing with others, the sender has an ability to detect if the sent shielded coin has been spent. -This type of address could be obtained with the following command: - -``` -./beam-wallet get_address --public_offline -``` - -## Offline payments -With Lelantus we are able to without need to be online, this is also known as one-side payments. To make them we need to accomplish the following steps: - -### Receiver -1. Receiver have to generate a token with the needed quantity of vouchers (allowed number of payments) - - ``` - ./beam-wallet get_address --offline_count=3 - ``` - -1. Send this token to the sender, and go offline - -### Sender -1. Sender can use the received token with the `--offline` switch to make payments as many times as many vouchers this token has. If the `--ofline` switch is not specified, regular online transaction would be executed - - ``` - ./beam_wallet send -r --offline -n -a -f - ``` - -### Receiver -1. Receiver after a while should check if he has _shielded UTXOs_ - - ``` - ./beam_wallet info - ``` - - the shielded coins has type `shld` - - ``` - | ID | BEAM | GROTH | Maturity | Status | Type | - 14724 34 0 95849 [Spent] shld - 14725 7 0 95873 [Spent] shld - ``` - -1. Also a new transaction record should appear with status `received max privacy`, `received offline` or `received public offline`, depending od what address type was used - - ``` - ./beam_wallet info --tx_history - ``` - ``` - 2020.11.14 12:52:22 incoming 5 received offline c714875164c8444cb12f90c4353fa1f6 - 2020.10.30 18:13:22 incoming 1 received max privacy 7a6dbf11fa6649e39992c41c349ab6ad - 2020.10.30 17:57:22 incoming 4 received max privacy d5f1b5acee474b4cb187321431040306 - 2020.10.30 11:15:22 incoming 2 received public offline - ``` \ No newline at end of file diff --git a/core-tech/Lelantus-MW.md b/core-tech/Lelantus-MW.md deleted file mode 100644 index faef31a..0000000 --- a/core-tech/Lelantus-MW.md +++ /dev/null @@ -1,200 +0,0 @@ -Linkability is the Achilles' heel of MW. - -Beam has several [improvements](https://github.com/BeamMW/beam/wiki/Transaction-graph-obfuscation) to the original MW to obfuscate the transaction graph. Now we're building a hybrid, of MW and Lelantus, which should be a huge step forward in this direction. - -## Disclaimer - -The [Lelantus protocol](https://lelantus.io/) is the work of Zcoin's cryptographer Aram Jivanyan as part of its research to improve its privacy protocol. - -Our design and implementation are based on the publicly-available Lelantus scientific paper. All our code was developed from scratch based on this paper alone. - -# Our design - -To fit our needs and utilize the full power of MW we made several modifications to the original protocol. - -1. Instead of focusing on transaction types described in the paper (Mint, Spend, Joint-Split) we implement this in terms of _primitives_, which can be combined and used in various transaction types. -1. Minted/spent values are never revealed. -1. We use other technique to prove the transaction balance. We removed the balance proof from the original Lelantus protocol, hence it's now closer to the original Sigma protocol by Jens Groth. - -MW blockchain consists of the following objects (primitives): -1. Inputs - references to existing UTXOs, that are being spent -1. Outputs -1. Transaction kernels - -Our design, which we call Lelantus-MW, keeps this structure, and the Balance-to-zero principle also holds. -All those 3 object types, however, are modified to support Lelantus. - -We use the following notation in the code: -* **G** - generator (nothing-up-my-sleeve EC point) multiplied by UTXO blinding factor -* **H** - generator multiplied by UTXO Value -* **J** - generator multiplied by UTXO 2nd blinding factor (i.e. double-blinded commitment). - - - -## Outputs - -Normal MW output consists of a Pedersen commitment (EC point) and the Bulletproof signature. After validation it's added to the UTXO set, and later can be referenced as inputs in consequent blocks/transactions. - -The modified output, used in Lelantus, is called _Shielded_ output. Unlike normal output, shielded output is double-blinded, hence its bulletproof is (slightly) extended. - -After validation it's added to the Shielded pool (rather than UTXO set). - -## Kernels - -As we said, shielded outputs are double-blinded. Hence, in order to keep the balance-to-zero principle, transaction kernels can optionally contain the 2nd blinding factor excess as well. So that transactions are allowed to have excess of both blinding factors, but not the value (obviously). - -Such kernels are signed by generalized Schnorr's signature (rather than normal Schnorr's signature), to prove that their revealed commitment is indeed of the form `k*G + s*J` - -Note: the generalized Schnorr's signature does not reveal which part of the kernel commitment is due to each of the blinding factors. I.e. the attacker can't split it into `k*G` and `s*J`. This is important, as the 2nd blinding factor (a.k.a. serial number) eventually gets revealed, there is still no way to identify its corresponding transaction kernel. - -## Inputs - -Normal inputs are just commitments (EC points) that correspond to previous outputs that must be in the current UTXO set. - -Shielded inputs, in addition to the commitment, have the Spend Proof, which proves that: -* A valid shielded element is being-spent -* No double-spend -* The specified input commitment encodes the value equal to the one being spent (with different blinding factor though). - -# Spend Proof - -In the original Lelantus paper the proof idea is the following: -* Convert the revealed public Spend Key into serial number `s` -* Subtract (methodically) `s*J` from each commitment in the referenced anonymity set (a.k.a. cmList) -* Prove the knowledge of the opening of one of the elements in the form of `k*G + v*H`, i.e. without the serial number -* Additionally prove that the revealed being-extracted value corresponds to the value of that element - * For this the original Sigma protocol was modified - -We modified it into the following: -* Convert the revealed public Spend Key into serial number `s` -* Prove that the revealed commitment `C` is of the form `k*G + v*H`, i.e. does not conceal additional serial number -* Subtract (methodically) `s*J + C` from each commitment in the referenced anonymity set -* Prove the knowledge of the opening of one of the elements in the form of `k*G` only, i.e. without the serial number or additional value - -In such a scheme there is no need to provide additional balance proof, since the value of extracted commitment should be the same as of the element being-spent. Because of this there is also no need to prove the value is non-negative (by bulletproof), as it was already proven when the element was added to the shielded pool. - -So, the whole Spend proof, in addition to the commitment being-extracted, contains the following: -* Generalized Schnorr's proof that this commitment is of the form `k*G + v*H` -* Public spend key, and the whole spend proof is signed by the appropriate private key -* Standard 1-out-of-N Sigma protocol in terms of a single `G`-generator only. - -## Compared to original Lelantus paper - -What is similar: -* Shielded outputs are double-blinded, with the appropriate (extended) bulletproof signature -* To spend a shielded element the public Spend Key must be revealed, and the Spend Proof must be signed by the appropriate private key -* Spend proof is also based on the 1-out-of-N Sigma protocol (by Jens Groth) - - -What is different: -* Rather than specifying transactions, Lelantus-MW is formulated in terms of inputs and outputs (i.e. MW-style). Hence: - * Just a single type of shielded input and output primitive is enough - * Transactions are easily merged (as usual) - * Despite better size and verification time, we don't implement multi-input spend proofs. - * Limiting all the inputs to the same anonymity set seems to be practically restricting - * This also potentially reveals their linkability -* Added/spent values are never revealed -* Separate balance proof is not required: it's an inherent part of each MW block/transaction. -* Spend proof is improved - * Implemented in terms of classical (unmodified) Sigma protocol - * Significantly smaller size - * Better verification time - * Significant in batch mode, when all the proofs refer to the same anonymity set - -# Direct anonymous payments - -In classical MW payments are interactive, and this is unavoidable: payment means creating an UTXO for someone else, however in order to create such an UTXO and its bulletproof the creator needs its blinding factor, hence it owns it, means it must be the payee. - -We [designed](https://github.com/BeamMW/beam/wiki/One-side-payments) a mechanism to allow one-side payments after initial setup (currently fully supported in Node, but not in the wallet), however it's less anonymous, and the functionality is limited. - -Lelantus doesn't have this limitation. It's possible to create a shielded output, such that the creator itself can't spend (thanks to the idea with Spend pubkey). What's remaining is the "coloring" scheme of the shielded output, i.e. how to make it distinguishable to the payee only, but not to others, including those that pay to the same payee. - -## Standard bulletproof coloring scheme - -(based on the coloring scheme used by secp256k1 library) - -Our standard UTXO coloring scheme allows to embed an arbitrary 255-bits long description. In practice we use 24-byte description, which we call _Coin ID_. - -During bulletproof construction various nonces are generated. Those nonces are generated in a deterministic way from the public (visible) UTXO commitment, and a secret _coloring seed_ (not necessarily the one used to generate the blinding factor). - -In particular the following is performed -* α - generated nonce -* ρ - generated nonce -* x - challenge -* Revealed: `μ = α + ρ*x` - -In order to embed meta-data into UTXO, the creator converts it into a scalar `β` (possible for every 255-bit data), and adds it to the originally-generated nonce `α`. - -So, the revealed `μ` is calculated as: `μ = α + β + ρ*x`. - -In order to recognize such an UTXO one needs the same secret _coloring seed_. It generates the same `α`, `ρ`, and then recovers `β` and the embedded parameters: - -The recognition process goes as following: - -* Generate `α`, `ρ` from the UTXO commitment and the _coloring seed_ -* Calculate the challenge `x` (from the revealed bulletproof transcript) -* Calculate `β = μ - α - ρ*x` -* Decode the _Coin ID_, see if this makes sense (in particular it may have only 24 trailing non-zero bytes) -* Recreate the UTXO commitment from the master secret and the extracted _Coin ID_ -* Check if the obtained commitment is correct - -## Advanced coloring - -So far the above scheme is suitable for coloring the shielded double-blind UTXO, but it's not anonymous: anyone with the same _coloring seed_ can identify such an UTXO - -To overcome this limitation we use an additional step. We'll encode the embedded meta-data using the Diffie-Hellman encoding scheme. - -The payee creates a private/public key pair, which we call _encoding key_. The _encoding pubkey_ is given to the payer, along with the _coloring seed_. - -During the bulletproof construction, among other things, the creator reveals the `T1` commitment, which is used to hide the blinding factors. In case of double-blinded bulletproof it's calculated as: -* `T1 = n1 * G + n2 * J` -* `n1`, `n2` - nonces, generated deterministically from the UTXO commitment and the _coloring seed_ - -Now we'll add another nonce to this: -* `T1 = (n1 + n3) * G + n2 + J` -* `n3` - **random** nonce, i.e. can't be recovered from the _coloring seed_ - -So, using the _coloring seed_ it's not possible to recover `n3`, but it's possible to obtain `n3 * G`. - -Finally, both payer and payee calculate the same secret: -* Payer: - * `n3` * _encoding pubkey_ -* Payee: - * `n3 * G` * _encoding private key_ - -Finally the scheme goes as following: - -Payer: -* Generate random nonce `n3` -* Calculate shared secret point `S = n3 * encoding pubkey` -* Convert X-coordinate of `S` to a scalar `γ` - * If it's too large and can't be converted (highly unlikely) - retry with different nonce -* Add `γ` to the encoded meta-data `β` -* Add `n3` to `n1` for the rest of the protocol -* The rest is straight-forward - -Payee: -* Generate the nonces `n1`, `n2` -* Calculate the "unmodified" `T1` -* Subtract it from the revealed `T1` to obtain `n3 * G` -* Calculate shared secret point `n3 * G * encoding private key` -* Convert X-coordinate of `S` to a scalar `γ` - * If it's too large - skip the rest -* Recover encoded meta-data `β` (as usual) -* Subtract `γ` from `β` -* The rest is straight-forward - -### What about shielded inputs? - -They are identified by the revealed Spend pubkey. The payee should track all the Spend pubkeys for shielded outputs it detected, and realize the spending once it sees the shielded input from the same Spend pubkey. - -### Payee address - -So far the payer needs the _coloring seed_ and the _encoding pubkey_. But they don't have to be different: a payee can provide the _encoding pubkey_, and the _coloring seed_ may be generated from it in a deterministic way. -Moreover, since the _encoding pubkey_ is fully controlled by the payee - it can always make sure its `Y`-coordinate is odd/even (by just negating the private key), hence providing only X-coordinate (32 bytes) is enough. - -### Multiple address? - -Although in the above scheme a payer can not identify payments of others to the same payee, it may still be necessary to have multiple addresses. For instance, if payers share information, it may be necessary to conceal the fact that they pay to the same payee. - -The above scheme is possible to extend to multiple addresses, they payee can generate arbitrary number of addresses. However there is no unified way for the payee to identify the payments: it needs to scan all the shielded outputs by all its generated addresses. diff --git a/core-tech/Lightning-Network.md b/core-tech/Lightning-Network.md deleted file mode 100644 index 7b41126..0000000 --- a/core-tech/Lightning-Network.md +++ /dev/null @@ -1,307 +0,0 @@ -## a.k.a. Laser Beam - -# What is Lightning Network -As in traditional blockchains (btc-alike), in Beam lightning network two (or more) users lock some funds, and then effectively transfer them _off-chain_. This has the following advantages: -* Instant. No need to wait for transaction confirmation (after initial setup). -* No transaction fee. -* Hidden. The information about intermediate transactions is never broadcasted. The number of off-chain transactions, frequency and amounts are never revealed. - -All the transfers are performed in the context of the _Lightning channel_. Its lifetime consists of the following: -1. Channel Open - * Users prepare and broadcast the transaction that consumes their inputs, and create a multi-signed output, which can be spent collectively. - * At this point each user already has a refund transaction, which can be used to get the funds back. -2. Off-chain funds transfers (arbitrary number of times). - * Users agree on another partition of the locked funds, and generate newer refund transactions, with appropriate amounts to each, which is effectively equivalent to the funds transfer. - * Older refund transactions are revoked (more about this later). Nothing is broadcasted to the network. -3. Channel close. - * Each user any moment can broadcast the most recent refund transaction, to get the funds back. - * All the users notice this, and the channel is considered closed. - * In case the users cooperate and perform a _graceful_ channel closure - it'd be faster, and with less fee (more about this later). - -# Implementation in Beam - -Since there are no scripts in MW, all the relevant functionality is implemented within the context of the transaction negotiation. This is called _scriptless scripts_. - -The actual negotiation flow is somewhat complex, but logically it can be split into separate _building blocks_. - -### MultiSig - multisigned UTXO -An UTXO created by several users, whose blinding factor consists of their blinding factor. Such an UTXO looks indistinguishable from others. The following operations can only be done collectively by all the users: -* Creating the UTXO (commitment + bulletproof) -* Transaction that creates it (has as an output) -* Transaction that spends it (has as an input) - -### Relative timelock -This feature enables to create 2 dependent transactions, whereas the second one becomes valid only after the first one is already accepted in a block, and the block is mature enough. Means - there is a minimum enforced delay between the transactions. -It requires a special processing on the node side, and will be available after the planned Hard Fork 1. - -Technically each kernel may optionally contain the Relative Lock info, which consists of: -* Kernel ID (hash) being referenced -* Minimum maturity (height difference) - -When such a kernel is encountered the node verifies if indeed the referenced kernel exists in the blockchain, and is mature enough. - -### Refund procedure -Refund procedure consists of 2 transactions, which consume the locked funds and create the agreed user outputs. -1. MultiSig.0 -> MultiSig.N -1. MultiSig.N -> Outputs.N - * Relatively time-locked w.r.t. transaction (1). - -whereas `MultiSig.0` represents the funds locked in the channel, `MultiSig.N` is an intermediate multisigned UTXO, and `Outputs.N` are all the outputs that users are supposed to get by the refund. - -The transaction (2) is time-locked w.r.t. transaction (1). Means, after (1) was broadcasted, the `MultiSig.N` becomes visible in the blockchain, but the transaction (2) can't be used immediately. -As we'll see this is important. In case a malicious user would try to use not the most recently agreed refund procedure, it gives a time window for the affected user to respond. - -### Refund revocation -As we said, there is a way to revoke the refund procedure. This should prevent malicious users from trying to use an older refund procedure after a newer agreement was set. - -In Beam in order to revoke the N-th refund procedure, the user **reveals its blinding factor** that was used for `MultiSig.N`. - -Once the blinding factor was revealed the user won't be able to use the refund procedure. If it does, then after transaction (1) the `MultiSig.N` becomes visible in the blockchain, and the peer can consume it immediately, because it knows the overall blinding factor. Just build and broadcast a transaction immediately that takes it as an input, and creates an output that belongs solely to it, i.e. punish. - -This is why relative timelock is important. - -### Multi-user Refund procedure -Now let's see how 2 users (A)lice and (B)ob build and use their refund procedures. We'll study the case for 2 users, but it can easily be generalized for arbitrary number of users. - -To build N-th refund procedure (A) and (B) negotiate to build the following transactions: -* Refund.N.A.1 - * MultiSig.0 -> MultiSig.N.A -* Refund.N.A.2 - * MultiSig.N.A -> Outputs.N -* Refund.N.B.1 - * MultiSig.0 -> MultiSig.N.B -* Refund.N.B.2 - * MultiSig.B.A -> Outputs.N - -So there are 4 transactions overall, all of them are built collectively. At the end each user has its own refund procedure, with different intermediate `MultiSig.N.X`, but the final `Outputs.N` are the same. - -Note the following: -* The transaction (1) of each refund procedure is kept **private**. Means - only (A) has the Refund.N.A.1, and only (B) has the Refund.N.B.1 -* The transaction (2) of each refund procedure is **public**. Means - both (A) and (B) have Refund.N.A.2 and Refund.N.B.2 -* The order of transaction building is important. Both (A) and (B) should **NOT** complete their parts of transaction (1) for the peer, before they have the appropriate transaction (2). - * Otherwise a malicious user can just use the transaction (1) to lock the funds permanently. - -So, the idea is that (A) and (B) have their own refund procedures, partly kept private. This separation is important, since in case they come to another agreement and create a newer refund procedures - they will need to revoke the older ones, which means the appropriate blinding factors of `MultiSig.N.A` and `MultiSig.N.B` must be revealed. As we already mentioned, using a compromised transaction (1) would lead to loss of funds. But, importantly, we must also guarantee that user that gets the revealed blinding factor can't initiate the compromised path on its own. This is the reason why the appropriate transactions (1) are private. - -# Lightning channel from the building blocks. - -Conceptually the lightning channel operates the following way: - -### Channel open -1. Users agree on how much funds each of them locks. -1. Create the `MultiSig.0` -1. Build `Refund.1` -1. Create a transaction `Inputs` -> `MultiSig.0` + `Changes` -1. Wait for confirmation - -Of course the order is important. Users should not make (4) available before they have (3). - -### Off-chain funds transfer -1. Users agree on newer partition of the locked funds. -2. Negotiate to build `Refund.N` -3. Revoke the previous `Refund.N-1` - -### Graceful channel closure. -1. Users agree to close the channel gracefully. -1. Create a transaction `MultiSig.0` -> `Outputs.N` - -This scheme makes the withdrawal immediate. No timelocks are needed. - -### One-side channel closure. -1. User decides to invoke its refund procedure (in case there's no cooperation) -1. User uses its latest refund procedure (all the others are revoked). - -### Blockchain status monitoring (a.k.a. watch towers) -In addition to the voluntary actions, all the users should monitor the blockchain to detect if/when any of them made one-side actions. -Depends on the agreed timelock (which is applied in all the relative locks of all the refund procedures) - the monitoring doesn't have to be for each new block. It can be once in many blocks as well. - -Once a new block arrives and the user decides to check the status: -* Does `MultiSig.0` present? - * Yes - channel is open. No further actions. - * No - * Was the channel open already? - * No - we're still opening it (waiting for the 1st tx). - * Yes - the channel is being closed! - * Find one of he `MultiSig.N` that was created for the refund procedures. - * Does it belong to the revoked refund? - * Yes - cheat attempt detected!!! - * Claim all the funds immediately. - * No - valid withdrawal triggered - * Wait until the timelock expires - * Broadcast the appropriate transaction (2) - -## Code design - Minimizing the number of negotiation roundtrips. - -As we saw, each operation on the Lightning channel requires to prepare many different _building blocks_, with dependencies. Some are literally dependent on each other (some of their results are needed by others), whereas for some there are artificial order restrictions to prevent malicious users from doing harm. - -Nevertheless, many such negotiations may run in parallel. At least partially, up to the point where their dependencies come into play. - -To allow this Beam code infrastructure allows the negotiations in terms of _primitives_, each is responsible for a well-defined functionality (such as creating a MultiSig, or a transaction), each has an interface to load/store the parameters and transfer the data to the peer. -When those primitives are aggregated to create a more complex negotiation scheme - their inputs/outputs are "re-routed", to reflect their dependency. - -By such the code remains relatively not too complex (readable), the dependencies are visible and can be verified, whereas on the other hand the negotiations effectively run in parallel, and each action is performed in a minimum number of negotiation roundtrips. - -# How typical negotiations look - -Below are the real negotiations produced by our code. - -### MultiSig - A -> B 115 bytes - Partial Commitment - Bulletproof T1,T2 - B -> A 155 bytes - Partial Commitment - Bulletproof T1,T2 - Bulletproof TauX - B done - A done - -Overall 1 roundtrip, assuming both users get the commitment, but only A has the valid bulletproof - -### Refund, one-sided - - A -> B 279 bytes - MultiSig.Partial Commitment - MultiSig.Bulletproof T1,T2 - Tx-TLock.Excess Commitment - Tx-TLock.Nonce Commitment - Tx-Final.Excess Commitment - Tx-Final.Nonce Commitment - B -> A 1158 bytes - MultiSig.Partial Commitment - MultiSig.Bulletproof T1,T2 - MultiSig.Bulletproof TauX - Tx-TLock.Excess Commitment - Tx-TLock.Nonce Commitment - Tx-TLock.Partial Kernel Signature - Tx-Final.Excess Commitment - Tx-Final.Nonce Commitment - Tx-Final.Partial Kernel Signature - Tx-Final.Partial Transaction - A -> B 925 bytes - Tx-Final.Partial Transaction - B -> A 52 bytes - Tx-TLock.Partial Transaction - B done - A done -Overall 2 roundtrips. Note that B delays the completion of `Tx-TLock` for A until it gets and validates the `Tx-Final` from it. - - -Now let's see how the Lightning channel operations are negotiated. - -## Lightning channel open - A -> B 591 bytes - MultiSig.Partial Commitment - MultiSig.Bulletproof T1,T2 - Tx-Open.Excess Commitment - Tx-Open.Nonce Commitment - Exit-A.MultiSig.Partial Commitment - Exit-A.MultiSig.Bulletproof T1,T2 - Exit-A.Tx-TLock.Excess Commitment - Exit-A.Tx-TLock.Nonce Commitment - Exit-A.Tx-Final.Excess Commitment - Exit-A.Tx-Final.Nonce Commitment - Exit-B.MultiSig.Partial Commitment - Exit-B.MultiSig.Bulletproof T1,T2 - B -> A 1754 bytes - MultiSig.Partial Commitment - MultiSig.Bulletproof T1,T2 - MultiSig.Bulletproof TauX - Tx-Open.Excess Commitment - Tx-Open.Nonce Commitment - Tx-Open.Partial Kernel Signature - Exit-A.MultiSig.Partial Commitment - Exit-A.MultiSig.Bulletproof T1,T2 - Exit-A.MultiSig.Bulletproof TauX - Exit-A.Tx-TLock.Excess Commitment - Exit-A.Tx-TLock.Nonce Commitment - Exit-A.Tx-TLock.Partial Kernel Signature - Exit-A.Tx-Final.Excess Commitment - Exit-A.Tx-Final.Nonce Commitment - Exit-A.Tx-Final.Partial Kernel Signature - Exit-A.Tx-Final.Partial Transaction - Exit-B.MultiSig.Partial Commitment - Exit-B.MultiSig.Bulletproof T1,T2 - Exit-B.MultiSig.Bulletproof TauX - Exit-B.Tx-TLock.Excess Commitment - Exit-B.Tx-TLock.Nonce Commitment - Exit-B.Tx-Final.Excess Commitment - Exit-B.Tx-Final.Nonce Commitment - A -> B 1968 bytes - Exit-A.Tx-Final.Partial Transaction - Exit-B.MultiSig.Bulletproof TauX - Exit-B.Tx-TLock.Excess Commitment - Exit-B.Tx-TLock.Nonce Commitment - Exit-B.Tx-TLock.Partial Kernel Signature - Exit-B.Tx-Final.Excess Commitment - Exit-B.Tx-Final.Nonce Commitment - Exit-B.Tx-Final.Partial Kernel Signature - Exit-B.Tx-Final.Partial Transaction - B -> A 977 bytes - Exit-A.Tx-TLock.Partial Transaction - Exit-B.Tx-Final.Partial Transaction - A -> B 52 bytes - Exit-B.Tx-TLock.Partial Transaction - B -> A 85 bytes - Tx-Open.Partial Transaction - B done - A done - -## Lightning channel update (funds transfer) - A -> B 394 bytes - Exit-A.MultiSig.Partial Commitment - Exit-A.MultiSig.Bulletproof T1,T2 - Exit-A.Tx-TLock.Excess Commitment - Exit-A.Tx-TLock.Nonce Commitment - Exit-A.Tx-Final.Excess Commitment - Exit-A.Tx-Final.Nonce Commitment - Exit-B.MultiSig.Partial Commitment - Exit-B.MultiSig.Bulletproof T1,T2 - B -> A 1477 bytes - Exit-A.MultiSig.Partial Commitment - Exit-A.MultiSig.Bulletproof T1,T2 - Exit-A.MultiSig.Bulletproof TauX - Exit-A.Tx-TLock.Excess Commitment - Exit-A.Tx-TLock.Nonce Commitment - Exit-A.Tx-TLock.Partial Kernel Signature - Exit-A.Tx-Final.Excess Commitment - Exit-A.Tx-Final.Nonce Commitment - Exit-A.Tx-Final.Partial Kernel Signature - Exit-A.Tx-Final.Partial Transaction - Exit-B.MultiSig.Partial Commitment - Exit-B.MultiSig.Bulletproof T1,T2 - Exit-B.MultiSig.Bulletproof TauX - Exit-B.Tx-TLock.Excess Commitment - Exit-B.Tx-TLock.Nonce Commitment - Exit-B.Tx-Final.Excess Commitment - Exit-B.Tx-Final.Nonce Commitment - A -> B 1968 bytes - Exit-A.Tx-Final.Partial Transaction - Exit-B.MultiSig.Bulletproof TauX - Exit-B.Tx-TLock.Excess Commitment - Exit-B.Tx-TLock.Nonce Commitment - Exit-B.Tx-TLock.Partial Kernel Signature - Exit-B.Tx-Final.Excess Commitment - Exit-B.Tx-Final.Nonce Commitment - Exit-B.Tx-Final.Partial Kernel Signature - Exit-B.Tx-Final.Partial Transaction - B -> A 977 bytes - Exit-A.Tx-TLock.Partial Transaction - Exit-B.Tx-Final.Partial Transaction - A -> B 92 bytes - Reveal Previous Blinding Factor - Exit-B.Tx-TLock.Partial Transaction - B -> A 40 bytes - Reveal Previous Blinding Factor - B done - A done - -So, both channel open and funds transfer negotiations are completed in 3 full roundtrips, whereas all the dependencies are observed. - -# Demo - -There's a working demo of the Lightning channel in our codebase here: `beam/node/laser_beam_demo` - -Various scenarios are emulated, such as graceful channel opening and closure, one-side channel closure and appropriate user responses, and the cheat attempt and punishing. - -The node used in the demo is the standard Beam node (no hacks, workarounds, or other tricks specifically for the demo), configured to generate fake PoW. All the broadcasted transactions and timelocks are fully validated. diff --git a/core-tech/Main-wallet-entities-and-their-attributes.md b/core-tech/Main-wallet-entities-and-their-attributes.md deleted file mode 100644 index 4586bde..0000000 --- a/core-tech/Main-wallet-entities-and-their-attributes.md +++ /dev/null @@ -1,94 +0,0 @@ -# User info -* Address (can be many): Unique ID money can be sent to/from. Each user/wallet can create and use any number of addresses. Address is assigned to one or more address categories (each category is denoted by name and color). -* Name: Meaningful name is kept for semantic identification only (in a separate Directory service, should not be unique). -* Avatar: Small and nice picture for the further identification. - -# Address -* a list of categories it is assigned to -* a textual description (optional) -* additional attributes such as: single use (won't be valid after the transaction is completed or failed) or time expiration (won't be valid once expired) - -# Balance -* Amounts, aggregated by transaction states: - * Available: always shown, with LARGE font - * In progress: Sending, Receiving, Change etc: shown when applicable (Alexandra Shelenkova do we need it?) - * Locked: shown separately when applicable (sub-cases: "maturing" etc) -* currency is: - * BEAM - * GROTH (1*10^-8 of BEAM) - * Consider estimated amount in BTC/ETH later on - -# UTXO details -* ID -* Amount -* Transactions it had participated in - * As output UTXO for incoming transaction, "earned" time is specified - * As input UTXO for outgoing transaction, "spent" time is specified -* Coin type - * Regular: just a regular coin, can receive most of the statuses (see below) - * Regular (received): received upon a successful completion of an incoming transaction - * Regular (change): received by the sender when his UTXO is split during a successfully accomplished outgoing transaction - * Transaction fee: paid by the user, is always created with "Maturing" status - * Coinbase: mined when miner closed the block, is always created with "Maturing" status - * Treasury: generated for maintenance and development of the project -* Status - * Available: not in the transaction, can be spent - * In progress, can have the following sub-cases: - * Incoming (draft) or Incoming: the amount is locked because of the ongoing incoming transaction - * Example: - * Alice has single UTXO of 100 BEAM and wants to send it fully to Bob (zero transaction fee for clarity) - * Bob sees 100 BEAM as "Incoming (draft)" before that UTXO was registered in the node/blockchain - * Bob sees 100 BEAM as "Incoming" when that UTXO was recognized registered in the node/blockchain - * Outgoing: the amount is locked because of the ongoing outgoing transaction, new UTXO will be generated as a change once the transaction will be competed - * Example: - * Alice has single UTXO of 100 BEAM and wants to send 20 BEAM to Bob (zero transaction fee for clarity) - * Alice sees 100 BEAM are "outgoing (locked)" at first - * Alice sees 80 BEAM as "incoming (change)" and Bob sees 20 BEAM "incoming" - * Alice sees 80 BEAM as "Available" and Bob sees 20 BEAM "Available" - * Maturing - * Reserved till