Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions derod-main/pages/dvm/smart-contract-fundamentals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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
```

<Callout type="warning">
**`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.
</Callout>

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:
Expand Down
2 changes: 1 addition & 1 deletion derod-main/pages/rpc-api/wallet-rpc-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<Callout type="warning" emoji="⚠️">
If this address is not registered on the blockchain, you will get this error:
Expand Down
Loading