From 9014ba3d9c5e100535e3cf3dc8195428f950b0f1 Mon Sep 17 00:00:00 2001
From: DHEBP <152355273+DHEBP@users.noreply.github.com>
Date: Sun, 7 Jun 2026 21:39:18 -0400
Subject: [PATCH 1/2] docs(dvm): clarify Initialize vs InitializePrivate
semantics
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add a focused subsection to smart-contract-fundamentals explaining that
InitializePrivate flips a single metadata byte (SC_META_DATA.Type 0->1)
and selects the install entrypoint — nothing more. It does NOT hide
contract code, encrypt state, or change STORE/LOAD/GetSC behavior; for
both types, code and stored variables are world-readable. "Private smart
contract" refers to tokens becoming encrypted balances in user wallets,
not to the contract itself.
Grounded in daemon source (dvm/sc.go:38, transaction_execute.go:325-326,
:336-337) and cross-linked to the existing private-smart-contracts page.
---
.../pages/dvm/smart-contract-fundamentals.mdx | 46 +++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/derod-main/pages/dvm/smart-contract-fundamentals.mdx b/derod-main/pages/dvm/smart-contract-fundamentals.mdx
index 522cad3..e5b5fee 100644
--- a/derod-main/pages/dvm/smart-contract-fundamentals.mdx
+++ b/derod-main/pages/dvm/smart-contract-fundamentals.mdx
@@ -77,6 +77,52 @@ This looks primitive, but it's **by design**. There is no hidden control flow. Y
---
+## `Initialize` vs `InitializePrivate`
+
+Every contract has exactly one initializer that runs **once**, at install time. It is named **either** `Initialize` **or** `InitializePrivate` — and which name you choose is the *only* difference between the two contract types DERO recognizes.
+
+```basic
+// Type 0 — "Open" contract
+Function Initialize() Uint64
+ 10 STORE("owner", SIGNER())
+ 20 RETURN 0
+End Function
+
+// Type 1 — "Private" contract: identical body, different name
+Function InitializePrivate() Uint64
+ 10 STORE("owner", SIGNER())
+ 20 RETURN 0
+End Function
+```
+
+At deploy, the daemon checks the function name and sets a single metadata byte:
+
+```go
+// blockchain/transaction_execute.go:325-326
+if _, ok := sc.Functions["InitializePrivate"]; ok {
+ meta.Type = 1 // present -> Private (Type 1); absent -> Open (Type 0)
+}
+// ...then the matching name is used as the install entrypoint:
+// transaction_execute.go:336-337 if meta.Type == 1 { entrypoint = "InitializePrivate" }
+```
+
+That byte is the whole distinction:
+
+```go
+// dvm/sc.go:38
+Type byte // 0 = Open, 1 = Private
+```
+
+
+**`InitializePrivate` does NOT hide your contract.** It does not encrypt code, does not encrypt state, and does not change how `STORE`/`LOAD` or `DERO.GetSC` behave. For **both** types the contract code is public and every stored variable is world-readable — `DERO.GetSC` serves Type 0 and Type 1 state identically, with no privacy gate.
+
+
+So what is "private" about a private smart contract? **The tokens it issues**, not the contract itself. When a contract sends an asset with `SEND_ASSET_TO_ADDRESS`, that balance lands **encrypted in the recipient's wallet** and moves wallet-to-wallet with homomorphic encryption afterward — the contract never tracks who holds what. The Type 1 marker is what tells the chain to treat the contract as a private-asset issuer. (See [Private Smart Contracts](/privacy/private-smart-contracts) for the token model in full.)
+
+**Practical guidance:** if your contract issues tokens/assets, use `InitializePrivate`. If it is a pure logic or storage contract, either name works — but never rely on either one to keep state secret. Anything that must be confidential has to be encrypted by your app **before** it is stored on-chain.
+
+---
+
## The Core Primitives
Everything in DVM-BASIC is built from a handful of building blocks:
From 35a72c82231f72586850ebb2db6627245947520e Mon Sep 17 00:00:00 2001
From: DHEBP <152355273+DHEBP@users.noreply.github.com>
Date: Mon, 8 Jun 2026 17:28:32 -0400
Subject: [PATCH 2/2] docs(wallet-rpc): note payload-bearing transfers need a
non-zero amount
Extends the transfer 'amount' NOTE: a zero-amount transfer creates no output
for the recipient's wallet to detect, so an attached payload_rpc (comment,
destination port, or app data) never arrives even though the tx is valid and
mined. Use >= 1 atomic unit. Applies to any use of a transfer as a data carrier,
not just payments. Confirmed against the DeroMessage mainnet reference (Amount=1).
---
derod-main/pages/rpc-api/wallet-rpc-api.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/derod-main/pages/rpc-api/wallet-rpc-api.mdx b/derod-main/pages/rpc-api/wallet-rpc-api.mdx
index 9173705..51777bc 100644
--- a/derod-main/pages/rpc-api/wallet-rpc-api.mdx
+++ b/derod-main/pages/rpc-api/wallet-rpc-api.mdx
@@ -182,7 +182,7 @@ curl -X POST \
}
```
-**NOTE:** The amount is in atomic format. As a reminder, 10^5 (=100000) is equivalent to 1 DERO.
+**NOTE:** The amount is in atomic format. As a reminder, 10^5 (=100000) is equivalent to 1 DERO. When using a transfer to carry a payload (a comment, destination port, or app data) rather than to send value, the amount must still be at least **1 atomic unit** (`0.00001 DERO`): a zero-amount transfer creates no output for the recipient's wallet to detect, so its attached `payload_rpc` never reaches them even though the transaction is valid and mined. This applies to any use of a transfer as a data carrier, not just payments.
If this address is not registered on the blockchain, you will get this error: