diff --git a/contracts/collectible.yaml.template b/contracts/collectible.yaml.template index 3ac661b..6c9a120 100644 --- a/contracts/collectible.yaml.template +++ b/contracts/collectible.yaml.template @@ -3,7 +3,7 @@ testnet: true issuer: codexId: qg8TdlRF-~RGz7bI-pceS960-evWjLKg-NcWTNWy-D9pIYBA version: 0 - api: r~mUOw + checksum: r~mUOw name: OtherToken method: issue timestamp: "2024-12-18T10:32:00-02:00" diff --git a/contracts/usdt.yaml.template b/contracts/usdt.yaml.template index 596f93a..cbf6269 100644 --- a/contracts/usdt.yaml.template +++ b/contracts/usdt.yaml.template @@ -1,9 +1,9 @@ consensus: bitcoin testnet: true issuer: - codexId: y6L7YTlM-5_v4LWy-oQsj5hV-I2imvxD-zRu0JBo-yaguhrY + codexId: 7C15w3W1-L0T~zXw-Aeh5~kV-Zquz729-HXQFKQW-_5lX9O8 version: 0 - api: rLosfg + checksum: AYkSrg name: USDT method: issue timestamp: "2024-12-18T10:32:00-02:00" diff --git a/demo-analysis-en.md b/demo-analysis-en.md new file mode 100644 index 0000000..a91f56e --- /dev/null +++ b/demo-analysis-en.md @@ -0,0 +1,637 @@ +# RGB Demo.sh Execution Analysis Report + +## πŸ“‹ Table of Contents +1. [Script Overview](#script-overview) +2. [Core Components](#core-components) +3. [Execution Flow Details](#execution-flow-details) +4. [Sequence Diagrams](#sequence-diagrams) +5. [Scenario Descriptions](#scenario-descriptions) +6. [Key Function Analysis](#key-function-analysis) + +--- + +## Script Overview + +`demo.sh` is a complete RGB protocol testing sandbox script that demonstrates the issuance and transfer flow of RGB smart contracts on the Bitcoin network. + +### Main Features +- 🏦 Issue two types of RGB assets: USDT (RGB20) and Collectible (RGB25) +- πŸ’Έ Perform multiple asset transfers between three wallets +- βœ… Verify the correctness of all transfers +- πŸ”„ Support two wallet types: wpkh and tapret-key-only + +### Technology Stack +- **Language**: Bash 4.0+ +- **Blockchain**: Bitcoin Regtest +- **Wallets**: bp-wallet, rgb-wallet +- **Indexer**: Electrum (default) / Esplora +- **Containers**: Docker Compose + +--- + +## Core Components + +### 1. Variable Configuration +``` +CONTRACT_DIR="contracts" # Contract files directory +NETWORK="regtest" # Bitcoin test network +WALLET_PATH="wallets" # Wallet path +SATS=800 # Satoshis per transfer +FEE=260 # Transaction fee +``` + +### 2. RGB Wallet Types +- **wpkh**: Traditional SegWit wallet (BIP84) +- **tapret-key-only**: Taproot wallet (BIP86) + +### 3. Indexer Configuration +- **Electrum**: Port 50001 +- **Esplora**: HTTP API on port 8094 + +### 4. Contract Mapping +``` +CONTRACT_NAME_MAP["usdt"] = USDT +CONTRACT_NAME_MAP["collectible"] = OtherToken +``` + +--- + +## Execution Flow Details + +### Phase 1: Initial Setup + +```mermaid +sequenceDiagram + participant S as Script + participant D as Docker Services + + S->>S: Check Bash version (needs 4.0+) + S->>S: Check required tools (cargo, docker, jq, etc.) + S->>S: Install Rust crates + Note over S: bp-wallet v0.12.0-rc.1 + Note over S: rgb-wallet v0.12.0-rc.3 + S->>D: Start Docker services + activate D + D->>D: Start bitcoind + D->>D: Start electrum/esplora + D->>D: Create miner wallet + D->>D: Mine 103 blocks (get available balance) + deactivate D +``` + +**Key Steps**: +1. βœ… `check_tools()`: Verify all dependency tools +2. πŸ”§ `install_rust_crate()`: Install bp-wallet and rgb-wallet +3. 🐳 `start_services()`: Start Docker containers +4. ⛏️ `prepare_btc_wallet()`: Mine to get initial funds + +--- + +### Phase 2: Wallet Preparation + +```mermaid +sequenceDiagram + participant S as Script + participant W0 as Wallet_0 + participant W1 as Wallet_1 + participant W2 as Wallet_2 + + S->>W0: prepare_rgb_wallet(wallet_0, wpkh) + activate W0 + W0->>W0: Generate seed + W0->>W0: Derive keys + W0->>W0: Initialize RGB wallet + W0->>W0: Create descriptor + deactivate W0 + + S->>W1: prepare_rgb_wallet(wallet_1, wpkh) + activate W1 + W1->>W1: Same initialization flow + deactivate W1 + + S->>W2: prepare_rgb_wallet(wallet_2, wpkh) + activate W2 + W2->>W2: Same initialization flow + deactivate W2 +``` + +**Each wallet initialization includes**: +1. πŸ“ Create seed file (`bp-hot seed`) +2. πŸ”‘ Derive key pairs (`bp-hot derive`) +3. 🎨 Initialize RGB storage (`rgb init`) +4. πŸ’Ό Create wallet instance (`rgb create`) + +--- + +### Phase 3: Contract Issuance + +```mermaid +sequenceDiagram + participant S as Script + participant W0 as Wallet_0 + participant D as Docker/Bitcoin + participant BC as Blockchain + + S->>W0: get_issue_utxo() + W0->>D: Request funding address + D->>W0: Return address + D->>BC: sendtoaddress (1 BTC) + BC->>BC: Mine 1 block for confirmation + W0->>W0: Sync wallet + + S->>W0: issue_contract(usdt) + activate W0 + W0->>W0: Read contract template (usdt.yaml.template) + W0->>W0: Replace parameters (supply: 2000) + W0->>W0: Import issuer file + W0->>W0: Execute issuance (rgb issue) + W0->>W0: Record contract_id + Note over W0: USDT contract ID generated + deactivate W0 + + S->>W0: issue_contract(collectible) + activate W0 + W0->>W0: Same flow to issue Collectible + Note over W0: Collectible contract ID generated + deactivate W0 +``` + +**Contract Parameters**: +- **Supply**: 2000 units +- **Binding**: Specific UTXO (txid:vout) +- **Types**: NIA (RGB20) and CFA (RGB25) + +--- + +### Phase 4: Contract Distribution + +```mermaid +sequenceDiagram + participant S as Script + participant W0 as Wallet_0 + participant W1 as Wallet_1 + participant W2 as Wallet_2 + participant FS as File System + + S->>W0: export_contract(usdt) + W0->>FS: Copy contract file to contracts/ + + S->>FS: import_contract(usdt, wallet_1) + FS->>W1: Copy contract file to data1/ + + S->>FS: import_contract(usdt, wallet_2) + FS->>W2: Copy contract file to data2/ + + Note over W0,W2: Repeat same flow for Collectible +``` + +**Notes**: +- RGB contracts are shared via file system +- Each wallet needs to import the contract definition to receive that asset + +--- + +### Phase 5: Asset Transfers + +This is the most complex part. Let me show a complete transfer flow in detail: + +```mermaid +sequenceDiagram + participant Sender as Wallet_0 (Sender) + participant Recipient as Wallet_1 (Recipient) + participant Bitcoin as Bitcoin Network + participant Indexer as Indexer (Electrum) + + Note over Sender,Recipient: Transfer 100 USDT: Wallet_0 -> Wallet_1 + + rect rgb(230, 240, 255) + Note over Sender,Recipient: 1. Preparation Phase + Sender->>Sender: check_balance(2000 USDT) + Recipient->>Recipient: check_balance(0 USDT) + end + + rect rgb(255, 240, 230) + Note over Sender,Recipient: 2. Invoice Generation + Recipient->>Bitcoin: Request new address/UTXO + Bitcoin-->>Recipient: Return UTXO + Recipient->>Recipient: rgb invoice (100 USDT) + Recipient-->>Sender: Invoice string + end + + rect rgb(240, 255, 240) + Note over Sender,Recipient: 3. Create Transfer + Sender->>Sender: rgb pay (process invoice) + Sender->>Sender: Generate PSBT (Partially Signed Bitcoin Transaction) + Sender->>Sender: Generate Consignment (RGB proof) + Sender-->>Recipient: Copy consignment file + end + + rect rgb(255, 255, 230) + Note over Sender,Recipient: 4. Validate and Accept + Recipient->>Recipient: rgb accept (validate consignment) + Recipient->>Recipient: Verify state transition validity + Recipient->>Recipient: Update local state + end + + rect rgb(255, 230, 255) + Note over Sender,Recipient: 5. Sign and Broadcast + Sender->>Sender: bp-hot sign (sign PSBT) + Sender->>Sender: rgb finalize (finalize transaction) + Sender->>Bitcoin: broadcast (broadcast transaction) + Bitcoin->>Bitcoin: Mine 1 block for confirmation + end + + rect rgb(230, 255, 255) + Note over Sender,Recipient: 6. Sync and Verify + Sender->>Indexer: sync wallet + Recipient->>Indexer: sync wallet + Sender->>Sender: check_balance(1900 USDT) + Recipient->>Recipient: check_balance(100 USDT) + end +``` + +#### Transfer Type Descriptions + +**Transfers included in Scenario 0 (default)**: + +| # | Asset | Sender | Recipient | Amount | Type | Description | +|---|-------|--------|-----------|--------|------|-------------| +| 0 | USDT | wallet_0 | wallet_1 | 100 | Aborted | Aborted transfer | +| 1 | USDT | wallet_0 | wallet_1 | 100 | Normal | Retry success | +| 2 | Collectible | wallet_0 | wallet_1 | 200 | Normal | CFA asset | +| 3 | USDT | wallet_0 | wallet_1 | 200 | Witness | Using witness output | +| 4 | USDT | wallet_1 | wallet_2 | 250 | Normal | Spend multiple allocations | +| 5 | Collectible | wallet_1 | wallet_2 | 100 | Normal | CFA asset | +| 6 | USDT | wallet_2 | wallet_0 | 100 | Witness | Close loop, return to issuer | +| 7 | Collectible | wallet_2 | wallet_0 | 50 | Witness | CFA close loop | +| 8 | USDT | wallet_0 | wallet_1 | 50 | Normal | Spend returned assets | +| 9 | Collectible | wallet_0 | wallet_1 | 25 | Normal | CFA re-transfer | +| 10 | USDT | wallet_1 | wallet_2 | 100 | Normal | Spend all (no change) | +| 11 | USDT | wallet_2 | wallet_0 | 250 | Witness | Return all | + +--- + +### Phase 6: Final Verification + +```mermaid +sequenceDiagram + participant S as Script + participant W0 as Wallet_0 + participant W1 as Wallet_1 + participant W2 as Wallet_2 + + S->>W0: check_balance(usdt) + W0-->>S: 2000 βœ… + S->>W1: check_balance(usdt) + W1-->>S: 0 βœ… + S->>W2: check_balance(usdt) + W2-->>S: 0 βœ… + + S->>W0: check_balance(collectible) + W0-->>S: 1825 βœ… + S->>W1: check_balance(collectible) + W1-->>S: 125 βœ… + S->>W2: check_balance(collectible) + W2-->>S: 50 βœ… + + Note over S: All balance verifications passed! +``` + +--- + +### Phase 7: Cleanup + +```mermaid +sequenceDiagram + participant S as Script + participant D as Docker Services + participant FS as File System + + S->>D: Stop all services + D->>D: Gracefully stop electrs/socat + D->>D: docker compose down + S->>FS: Delete data directories + Note over FS: data0, data1, data2
datacore, dataindex +``` + +--- + +## Scenario Descriptions + +The script supports 4 predefined scenarios: + +### scenario_0 (default) +- **Wallet Type**: wpkh (SegWit) +- **Includes**: Aborted transfer test +- **Number of Transfers**: 12 +- **Test Points**: + - βœ… Normal transfers + - βœ… Aborted/retry transfers + - βœ… Witness output transfers + - βœ… Spend multiple allocations + - βœ… No-change transfers + +### scenario_1 +- **Wallet Type**: tapret-key-only (Taproot) +- **Other**: Same as scenario_0 + +### scenario_10 +- **Wallet Type**: wpkh +- **Excludes**: Aborted transfer test +- **Number of Transfers**: 11 + +### scenario_11 +- **Wallet Type**: tapret-key-only +- **Excludes**: Aborted transfer test +- **Number of Transfers**: 11 + +--- + +## Key Function Analysis + +### 1. transfer_assets() +The most important function that handles the complete asset transfer flow. + +**Parameters**: +```bash +transfer_assets wallet_0/wallet_1 2000/0 100 1900/100 0 0 usdt + ↑ ↑ ↑ ↑ ↑ ↑ ↑ + sender/recipient initial amt final wit reuse contract +``` + +**Internal Flow**: +1. `transfer_create()`: Create transfer (generate PSBT and consignment) +2. `transfer_complete()`: Complete transfer (validate, sign, broadcast) + +### 2. prepare_rgb_wallet() +Initialize RGB wallet. + +**Steps**: +1. Generate BIP39 seed +2. Derive HD keys (BIP84 or BIP86) +3. Create RGB wallet +4. Set descriptor mapping + +### 3. issue_contract() +Issue RGB contract. + +**Steps**: +1. Read YAML template +2. Replace parameters (supply, UTXO) +3. Import issuer file +4. Execute issue command +5. Record contract_id + +### 4. check_balance() +Verify wallet balance. + +**Verification Logic**: +1. List all unspent outputs (UTXOs) +2. Get RGB allocations for each UTXO +3. Sum up total balance +4. Compare with expected value + +--- + +## Execution Time Estimation + +| Phase | Time | Notes | +|-------|------|-------| +| Initial Setup | ~30-60s | First run requires Rust compilation | +| Wallet Preparation | ~10s Γ— 3 | Per wallet | +| Contract Issuance | ~5s Γ— 2 | Per contract | +| Single Transfer | ~10-15s | Including mining and sync | +| **Total** | **~5-10 minutes** | Full run of scenario_0 | + +--- + +## Data Flow Diagram + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ demo.sh Execution Flow β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ 1. Environment Check and Init β”‚ + β”‚ - Bash version β‰₯ 4.0 β”‚ + β”‚ - Tool dependencies (cargo, docker...)β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ 2. Install Rust Crates β”‚ + β”‚ - bp-wallet v0.12.0-rc.1 β”‚ + β”‚ - rgb-wallet v0.12.0-rc.3 β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ 3. Start Docker Services β”‚ + β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ + β”‚ β”‚ bitcoind (regtest) β”‚ β”‚ + β”‚ β”‚ electrum / esplora β”‚ β”‚ + β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ 4. Prepare Bitcoin Wallet β”‚ + β”‚ - Create miner wallet β”‚ + β”‚ - Mine 103 blocks (get funds) β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ 5. Prepare RGB Wallets (0/1/2) β”‚ + β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ + β”‚ β”‚ Generate seed β”‚ β”‚ + β”‚ β”‚ Derive keys (BIP84/BIP86) β”‚ β”‚ + β”‚ β”‚ Initialize RGB storage β”‚ β”‚ + β”‚ β”‚ Create wallet instance β”‚ β”‚ + β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ 6. Issue RGB Contracts β”‚ + β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ + β”‚ β”‚ USDT (RGB20): 2000 units β”‚ β”‚ + β”‚ β”‚ Collectible (RGB25): 2000 units β”‚ β”‚ + β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ 7. Export/Import Contracts β”‚ + β”‚ wallet_0 ──export──> contracts/ β”‚ + β”‚ contracts/ ──import──> wallet_1/2 β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ 8. Asset Transfer Loop (multiple) β”‚ + β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ + β”‚ β”‚ Recipient generates invoice β”‚ β”‚ + β”‚ β”‚ Sender creates transfer (PSBT) β”‚ β”‚ + β”‚ β”‚ Recipient validates consignment β”‚ β”‚ + β”‚ β”‚ Sender signs and broadcasts β”‚ β”‚ + β”‚ β”‚ Mine for confirmation β”‚ β”‚ + β”‚ β”‚ Both parties sync wallets β”‚ β”‚ + β”‚ β”‚ Verify balances β”‚ β”‚ + β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ 9. Final Balance Verification β”‚ + β”‚ βœ… wallet_0: 2000 USDT, 1825 CFA β”‚ + β”‚ βœ… wallet_1: 0 USDT, 125 CFA β”‚ + β”‚ βœ… wallet_2: 0 USDT, 50 CFA β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ 10. Cleanup β”‚ + β”‚ - Stop Docker services β”‚ + β”‚ - Delete data directories β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +--- + +## Technical Highlights + +### RGB Protocol Key Concepts + +1. **Client-side Validation**: RGB state is validated off-chain +2. **Consignment**: Data package containing state transition proofs +3. **PSBT**: Partially Signed Bitcoin Transaction +4. **Seal**: Mechanism to bind RGB state to UTXO + +### Two Commitment Methods + +1. **OP_RETURN (opret)**: Uses OP_RETURN output +2. **Tapret**: Uses Taproot output (more private) + +### Transfer Modes + +1. **Blinded UTXO**: Recipient provides specific UTXO +2. **Witness Output (wout)**: Sender creates new witness output + +--- + +## Troubleshooting + +### 1. Bash Version Error +```bash +ERROR: This script requires Bash 4.0 or higher +``` +**Solution**: Install newer bash on macOS +```bash +brew install bash +/opt/homebrew/bin/bash demo.sh +``` + +### 2. Docker Port Conflict +```bash +ERROR: port 50001 is already bound +``` +**Solution**: Stop services occupying the port +```bash +./demo.sh --stop +``` + +### 3. Missing Tools +```bash +ERROR: could not find required tool "jq" +``` +**Solution**: Install missing tools +```bash +brew install jq +``` + +--- + +## Command Line Arguments + +```bash +./demo.sh [options] + +Options: + -h, --help Display help information + -l, --list List available scenarios + -s, --scenario Run specified scenario (default: 0) + -v, --verbose Enable verbose output + -r, --recompile Force recompile + --esplora Use esplora indexer (default: electrum) + -u, --skip-stop Don't stop Docker containers after completion + --stop Stop Docker containers +``` + +### Usage Examples + +```bash +# Run default scenario (wpkh, includes abort test) +./demo.sh + +# Run Taproot scenario +./demo.sh -s 1 + +# Use Esplora indexer +./demo.sh --esplora + +# Verbose mode + don't stop services +./demo.sh -v -u + +# List all scenarios +./demo.sh -l +``` + +--- + +## Summary + +`demo.sh` is a comprehensive RGB protocol testing script that demonstrates: + +βœ… **Complete Lifecycle**: From wallet creation to asset issuance, to multiple transfers +βœ… **Multiple Scenarios**: Support different wallet types and transfer modes +βœ… **Strict Validation**: Balance and state checks at every step +βœ… **Automation**: One-click run for the entire test flow +βœ… **Cleanup Mechanism**: Automatically clean up environment and data + +This is an excellent starting point for learning and testing the RGB protocol! + +--- + +## Appendix: Key File Structure + +``` +rgb-sandbox/ +β”œβ”€β”€ demo.sh # Main script +β”œβ”€β”€ contracts/ # Contract files directory +β”‚ β”œβ”€β”€ usdt.yaml.template # USDT contract template +β”‚ └── collectible.yaml.template # Collectible contract template +β”œβ”€β”€ issuers/ # Issuer definitions +β”‚ β”œβ”€β”€ RGB20-Simplest-v0-*.issuer +β”‚ └── RGB25-UniquelyFungible-v0-*.issuer +β”œβ”€β”€ wallets/ # Wallet files +β”‚ β”œβ”€β”€ wallet_*.seed # Seed files +β”‚ └── wallet_*.derive # Derived keys +β”œβ”€β”€ data0/ # wallet_0's RGB data +β”œβ”€β”€ data1/ # wallet_1's RGB data +β”œβ”€β”€ data2/ # wallet_2's RGB data +β”œβ”€β”€ bp-wallet/ # bp-wallet binaries +β”‚ └── bin/ +β”‚ β”œβ”€β”€ bp +β”‚ └── bp-hot +└── rgb-wallet/ # rgb-wallet binaries + └── bin/ + └── rgb +``` + +--- + +**Generated**: 2026-02-03 +**Script Version**: demo.sh (RGB v0.12) diff --git a/demo.sh b/demo.sh index 5fc070c..b0360b0 100755 --- a/demo.sh +++ b/demo.sh @@ -1,5 +1,18 @@ #!/usr/bin/env bash +# Check bash version (need 4.0+ for associative arrays) +if [ "${BASH_VERSINFO[0]}" -lt 4 ]; then + echo "ERROR: This script requires Bash 4.0 or higher (you have ${BASH_VERSION})" + echo "" + echo "On macOS, install a newer bash with:" + echo " brew install bash" + echo "" + echo "Then run the script explicitly with the newer bash:" + echo " /opt/homebrew/bin/bash demo.sh # for Apple Silicon" + echo " /usr/local/bin/bash demo.sh # for Intel Mac" + exit 1 +fi + # variables CONTRACT_DIR="contracts" DEBUG=0 @@ -19,7 +32,7 @@ export SEED_PASSWORD="seed test password" BP_WALLET_FEATURES="--features=cli,hot" BP_WALLET_VER="0.12.0-rc.1" RGB_WALLET_FEATURES="" -RGB_WALLET_VER="0.12.0-rc.1.1" +RGB_WALLET_VER="0.12.0-rc.3" # RGB wallet types WALLET_TYPES=("wpkh" "tapret-key-only") @@ -117,7 +130,7 @@ _wait_indexers_sync() { electrum_json="{\"jsonrpc\": \"2.0\", \"wallet_type\": \"blockchain.block.header\", \"params\": [$block_count], \"id\": 0}" while :; do electrum_res="$(echo "$electrum_json" \ - | netcat -w1 localhost $ELECTRUM_PORT \ + | nc -w1 localhost $ELECTRUM_PORT \ | jq '.result')" [ -n "$electrum_res" ] && break echo -n "." @@ -198,12 +211,16 @@ _show_state() { # helper functions check_tools() { _subtit "checking required tools" - local required_tools="awk base64 cargo cut docker grep head jq netcat sha256sum tr" + local required_tools="awk base64 cargo cut docker grep head jq sha256sum tr" for tool in $required_tools; do if ! which "$tool" >/dev/null; then - _die "could not find reruired tool \"$tool\", please install it and try again" + _die "could not find required tool \"$tool\", please install it and try again" fi done + # Check for netcat (can be 'nc' or 'netcat' depending on system) + if ! which nc >/dev/null && ! which netcat >/dev/null; then + _die "could not find required tool \"netcat\" (or \"nc\"), please install it and try again" + fi if ! docker compose >/dev/null; then _die "could not call docker compose (hint: install docker compose plugin)" fi @@ -225,6 +242,16 @@ install_rust_crate() { local features opts local debug="" local force="" + + # Check if binary already exists and skip if not forcing recompile + if [ -d "./$crate/bin" ] && [ $RECOMPILE != 1 ]; then + local bin_count=$(ls "./$crate/bin" 2>/dev/null | wc -l) + if [ "$bin_count" -gt 0 ]; then + _subtit "skipping $crate installation (binary already exists)" + return 0 + fi + fi + if [ -n "$3" ]; then read -r -a features <<< "$3" fi @@ -263,9 +290,9 @@ set_aliases() { stop_services() { _subtit "stopping services" # cleanly stop esplora - if $COMPOSE ps |grep -q esplora; then + if docker compose ps |grep -q esplora; then for SRV in socat electrs; do - $COMPOSE exec esplora bash -c "sv -w 60 force-stop /etc/service/$SRV" + docker compose exec esplora bash -c "sv -w 60 force-stop /etc/service/$SRV" done fi @@ -277,7 +304,8 @@ start_services() { _subtit "checking data directories" for data_dir in data0 data1 data2; do if [ -d "$data_dir" ]; then - if [ "$(stat -c %u $data_dir)" = "0" ]; then + # macOS uses 'stat -f %u' instead of 'stat -c %u' + if [ "$(stat -f %u $data_dir 2>/dev/null || stat -c %u $data_dir 2>/dev/null)" = "0" ]; then echo "existing data directory \"$data_dir\" found, owned by root" echo "please remove it and try again (e.g. 'sudo rm -r $data_dir')" _die "cannot continue" @@ -293,7 +321,7 @@ start_services() { [ "$PROFILE" = "electrum" ] && EXPOSED_PORTS=(50001) [ "$PROFILE" = "esplora" ] && EXPOSED_PORTS=(8094) for port in "${EXPOSED_PORTS[@]}"; do - if netcat -z localhost "$port"; then + if nc -z localhost "$port"; then _die "port $port is already bound, services can't be started" fi done @@ -421,8 +449,9 @@ issue_contract() { -e "s/txid/$TXID_ISSUE/" \ -e "s/vout/$VOUT_ISSUE/" \ "$contract_tmpl" > "$contract_yaml" - _subtit "issuing" - _trace "${RGB[@]}" -d "data${wallet_id}" import issuers/* + _subtit "importing issuer files (contract type definitions)" + _trace "${RGB[@]}" -d "data${wallet_id}" import issuers/*.issuer + _subtit "issuing contract from YAML" _trace "${RGB[@]}" -d "data${wallet_id}" issue -w "$wallet" "$contract_yaml" \ >$TRACE_OUT 2>&1 issuance="$(cat $TRACE_OUT)" @@ -459,7 +488,7 @@ prepare_rgb_wallet() { _trace "${BPHOT[@]}" seed "$WALLET_PATH/$wallet.seed" _trace "${BPHOT[@]}" derive -N -s $der_scheme \ "$WALLET_PATH/$wallet.seed" "$WALLET_PATH/$wallet.derive" >$TRACE_OUT - account="$(cat $TRACE_OUT | awk '/Account/ {print $NF}')" + account="$(cat $TRACE_OUT | awk '/Account:/ {print $2}')" DESC_MAP[$wallet]="$account/<0;1>/*" [ $DEBUG = 1 ] && echo "descriptor: ${DESC_MAP[$wallet]}" WALLETS+=("$wallet") @@ -468,8 +497,13 @@ prepare_rgb_wallet() { # RGB setup _subtit "creating RGB wallet $wallet" wallet_id=${WLT_ID_MAP[$wallet]} - _trace "${RGB[@]}" -d "data${wallet_id}" init -q + _trace "${RGB[@]}" -d "data${wallet_id}" init _trace "${RGB[@]}" -d "data${wallet_id}" create --"$wallet_type" "$wallet" "${DESC_MAP[$wallet]}" + # RGB v0.12 stores wallets as NAME.wallet directories, but accepts NAME in commands + # Rename the directory if needed for compatibility + if [ -d "data${wallet_id}/bitcoin.testnet/$wallet" ] && [ ! -d "data${wallet_id}/bitcoin.testnet/$wallet.wallet" ]; then + mv "data${wallet_id}/bitcoin.testnet/$wallet" "data${wallet_id}/bitcoin.testnet/$wallet.wallet" + fi } sign_and_broadcast() { @@ -573,7 +607,7 @@ transfer_create() { local fee=() [ -n "$SATS" ] && sats=(--sats "$SATS") [ -n "$FEE" ] && fee=(--fee "$FEE") - _trace "${RGB[@]}" -d "$send_data" pay -w "$SEND_WLT" \ + _trace "${RGB[@]}" -d "$send_data" pay "$INDEXER_CLI" -w "$SEND_WLT" \ "${sats[@]}" "${fee[@]}" --force \ "$INVOICE" "$send_data/$CONSIGNMENT" "$send_data/$PSBT" if ! ls "$send_data/$CONSIGNMENT" >/dev/null 2>&1; then @@ -728,8 +762,8 @@ set_aliases trap cleanup EXIT # install crates -install_rust_crate "bp-wallet" "$BP_WALLET_VER" "$BP_WALLET_FEATURES" "--git https://github.com/BP-WG/bp-wallet --branch v0.12" # commit 0d439062 -install_rust_crate "rgb-wallet" "$RGB_WALLET_VER" "$RGB_WALLET_FEATURES" "--git https://github.com/RGB-WG/rgb --branch v0.12" # commit 9ffff7fb +install_rust_crate "bp-wallet" "$BP_WALLET_VER" "$BP_WALLET_FEATURES" "--git https://github.com/BP-WG/bp-wallet --branch v0.12" +install_rust_crate "rgb-wallet" "$RGB_WALLET_VER" "$RGB_WALLET_FEATURES" "--git https://github.com/RGB-WG/rgb --rev b8c85817c8f1e3336c25dff7e328dff0121722fe" mkdir "$CONTRACT_DIR" diff --git a/docker-compose.yml b/docker-compose.yml index 9eb6bda..45455a2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,22 +1,30 @@ services: bitcoind: profiles: [electrum] - image: registry.gitlab.com/hashbeam/docker/bitcoind:27.1 + image: registry.gitlab.com/hashbeam/docker/bitcoind:28.1 command: "-fallbackfee=0.0002" volumes: - ./datacore:/srv/app/.bitcoin + healthcheck: + test: ["CMD-SHELL", "su -c 'bitcoin-cli -regtest getblockchaininfo' blits"] + interval: 5s + timeout: 5s + retries: 30 + start_period: 10s electrs: profiles: [electrum] - image: registry.gitlab.com/hashbeam/docker/electrs:0.10.0 + image: registry.gitlab.com/hashbeam/docker/electrs:0.10.9 depends_on: - - bitcoind + bitcoind: + condition: service_healthy ports: - 50001:50001 volumes: - ./dataelectrs:/srv/app/db + restart: unless-stopped esplora: profiles: [esplora] - image: blockstream/esplora:956c74f42eb6ad803d8aedc272ba83d3aa6dcf5c + image: blockstream/esplora:latest command: /srv/explorer/run.sh bitcoin-regtest explorer environment: DEBUG: verbose diff --git a/issuers/RGB20-Simplest-v0-rLosfg.issuer b/issuers/RGB20-Simplest-v0-rLosfg.issuer index 408e7ff..222f34c 100644 Binary files a/issuers/RGB20-Simplest-v0-rLosfg.issuer and b/issuers/RGB20-Simplest-v0-rLosfg.issuer differ diff --git a/rgb-schemata b/rgb-schemata new file mode 160000 index 0000000..7a66a9b --- /dev/null +++ b/rgb-schemata @@ -0,0 +1 @@ +Subproject commit 7a66a9b02a3a36d3f121cbc5833fe876caf9f1f2