Skip to content
Open
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
67 changes: 67 additions & 0 deletions acknacki/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
namespace-identifier: acknacki
title: Acki Nacki Blockchain
author: Mitja Goroshevsky (@Futurizt)
status: Draft
type: Informational
created: 2026-04-07
---

# Namespace for Acki Nacki Blockchain

Acki Nacki is a Rust implementation of a probabilistic proof-of-stake
consensus protocol optimized for fast finality, while allowing for high
throughputs via execution parallelization. It achieves higher Byzantine
fault tolerance than Nakamoto, BFT (including Hotstuff and AptosBFT),
Solana, and other modern consensus protocols. The protocol reaches
consensus in two communication steps and exchanges a total number of
messages per consensus round that is subquadratic in the number of nodes.

Acki Nacki runs AVM (Advanced Virtual Machine) supporting both Ton Virtual
Machine (TVM) and WASM execution environments. It features a DApp ID system for gasless
internal transactions, ECC (Extra Currency Collection) token transfers,
and native support for AI agent operations.

## Rationale

The `acknacki` namespace (8 characters, the CAIP-2 maximum) identifies
the Acki Nacki blockchain family. The reference field uses the
`global_id` integer from the block header, which uniquely identifies
each network (mainnet, shellnet/testnet).

A separate namespace from `tvm` is necessary because:
- Acki Nacki runs AVM supporting TVM and WASM, evolving beyond TVM
- The DApp ID threading model is unique to Acki Nacki
- The consensus mechanism is specific to Acki Nacki
- Address format uses DApp ID routing, not workchain IDs

## Governance

Acki Nacki core protocol developer is [GOSH](https://gosh.sh). Protocol
specifications and node software are open source at
[github.com/ackinacki/ackinacki][github]. Network updates are performed
bitcoin-style — node owners update their nodes to a newest version at
will. There is no DAO, foundation or governance body.

The consensus protocol is formally described in a peer-reviewed
publication at [ACNS 2024 (Springer)][springer].

## References

- [Acki Nacki Documentation][docs] - Official documentation
- [Acki Nacki Developer Portal][dev] - Developer guides and API reference
- [Acki Nacki GitHub][github] - Node software and smart contracts
- [Consensus Paper (Springer)][springer] - "Acki Nacki: A Probabilistic
Proof-of-Stake Consensus Protocol with Fast Finality and
Parallelisation" (ACNS 2024)
- [Block Explorer][explorer] - Mainnet block explorer

[docs]: https://docs.ackinacki.com
[dev]: https://dev.ackinacki.com
[github]: https://github.com/ackinacki/ackinacki
[springer]: https://doi.org/10.1007/978-3-031-61486-6_4
[explorer]: https://mainnet.ackinacki.org

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
176 changes: 176 additions & 0 deletions acknacki/caip10.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
---
namespace-identifier: acknacki-caip10
title: Acki Nacki Blockchain - Account ID Specification
author: Mitja Goroshevsky (@Futurizt)
discussions-to: https://github.com/ChainAgnostic/namespaces/pull/XXX
status: Draft
type: Standard
created: 2026-04-07
requires: CAIP-2, CAIP-10
---

# CAIP-10

*For context, see the [CAIP-10][] specification.*

## Introduction

Acki Nacki uses a two-part account addressing scheme. Each account is
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little unclear on what an AccountID means by itself. An "Externally owned account", for example, like a metamask on EVM: does that work by itself? Can a P2P transfer with no smart contracts involved work from a bare accountID to a bare accountID, and if so, who pays the gas?

Regardless of whether all this is inherited from "vanilla" TVM, I would spell it out, because as-is it sounds like the only actors on Acki Nacki are what EVM calls "onchain accounts" (controlled/mediated via a deployed contract).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — this is a genuine source of confusion for EVM-familiar readers. Added an "Account Model" subsection to caip10.md in 40434a1 spelling out:

  • Acki Nacki uses an account-based model where every account is itself a smart contract; there are no EVM-style EOAs.
  • A private key is not an actor on its own — it can only sign external messages addressed to an already-deployed contract whose code chooses whether to accept the signature and execute. A "user wallet" is therefore a deployed contract (typically a multisig).
  • P2P value transfers always flow contract-to-contract:
    • Inside a DApp ID — gas is drawn from the shared DappConfig pool via gosh.mintshell() (gasless internal txs).
    • From outside (external message) — the receiving contract pays gas from its own balance. A bare AccountID with no deployed contract is uninitialized; incoming messages either bounce or, when accompanied by a stateInit, deploy the contract at that address.
    • Cross-DApp — native VMSHELL is zeroed at the protocol level; ECC tokens (e.g. SHELL) can cross.
  • A bare AccountID is meaningful only as a destination address — it cannot originate a transaction until a contract has been deployed at it.

identified by a **DApp ID** (256 bits) and an **Account ID** (256 bits),
forming a 512-bit composite address called `AccountRouting`.

The DApp ID groups contracts into a logical application. All contracts
within the same DApp ID share ONE (1) gas pool (defined in DappConfig) and
can transact internally without gas costs. The Account ID uniquely identifies
the contract within its DApp.

When a contract is deployed by an external message, its DApp ID equals
its own Account ID (self-originating). When deployed by an internal
message from another contract, it inherits the sender's DApp ID.

### Account Model

Acki Nacki uses an account-based model in which **every account is itself a
smart contract**; there are no EVM-style externally owned accounts (EOAs). A
private key is not an actor on its own — it can only sign external messages
addressed to an already-deployed contract whose code chooses whether to
accept the signature and execute. A "user wallet" on Acki Nacki is therefore
a deployed contract (typically a multisig).

Peer-to-peer value transfers always flow contract-to-contract:

- **Inside a DApp ID** — internal messages are gasless: gas is drawn from
the shared `DappConfig` pool via `gosh.mintshell()`.
- **From outside (external message)** — the receiving contract pays gas
from its own balance. A bare AccountID with no deployed contract is
*uninitialized*: incoming messages either bounce or, when accompanied by
a `stateInit`, deploy the contract at that address.
- **Cross-DApp transfers** — the native VMSHELL token is zeroed at the
protocol level when crossing DApp boundaries; ECC tokens (e.g. SHELL)
can cross.

A bare AccountID is therefore meaningful only as a destination address —
it cannot originate a transaction until a contract has been deployed at it.

## Specification

### Semantics

An Acki Nacki account address consists of:
- **DApp ID**: 256-bit identifier (32 bytes, 64 hex chars)
- **Account ID**: 256-bit identifier (32 bytes, 64 hex chars)

Together they form an `AccountRouting` — the full address used for
message routing and thread assignment in the Acki Nacki network.

### Syntax

The CAIP-10 account address is the concatenation of the lowercase
hex-encoded DApp ID and Account ID, separated by a period:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can tell from the examples below that hex-encoded DOESN'T use the 0x prefix common in other blockchains, but you might want to explicitly call that out here for the lazy EVM-familiar skimmer who doesn't check the examples confronted with this ambiguity!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an explicit line in the Syntax section in 40434a1: "Hex encoding is lowercase and does not include the 0x prefix used in EVM-style addresses; both DApp ID and Account ID are exactly 64 hex characters with no separator."


```
acknacki:<chain_id>:<dapp_id>.<account_id>
```

Where:
- `<chain_id>` is the CAIP-2 reference (e.g. `0` for mainnet)
- `<dapp_id>` is the 64-character lowercase hex DApp ID
- `<account_id>` is the 64-character lowercase hex Account ID

Hex encoding is lowercase and does **not** include the `0x` prefix used in
EVM-style addresses; both DApp ID and Account ID are exactly 64 hex
characters with no separator.

For self-originating contracts (deployed via external message),
`dapp_id == account_id`.

Validation regex for the account address portion:

```
[0-9a-f]{64}\.[0-9a-f]{64}
```

Total CAIP-10 validation:

```
acknacki:[-]?[0-9]{1,10}:[0-9a-f]{64}\.[0-9a-f]{64}
```

### Resolution Mechanics

An account can be queried via the GraphQL API using only the Account ID
portion (prefixed with `0:` for legacy compatibility):

```graphql
query {
blockchain {
account(address: "0:<account_id_hex>") {
info {
balance
}
}
}
}
```

The DApp ID of a deployed contract can be determined from the deployment
transaction: if deployed externally, `dapp_id = account_id`; if deployed
internally, `dapp_id` is inherited from the sender.

## Rationale

The two-part address reflects Acki Nacki's unique DApp ID architecture.
Unlike workchain-based addressing used in other chains, the DApp ID
is a logical grouping mechanism that determines gas routing and thread
assignment. Including both parts in the CAIP-10 address preserves the full
routing information needed for cross-DApp operations.

The period separator (`.`) is used instead of colon (`:`) to avoid
ambiguity with the CAIP-10 namespace:chain_id:address format.

### Backwards Compatibility

This is the initial specification. No legacy identifiers exist.

## Test Cases

```
# Self-originating contract on mainnet (dapp_id == account_id)
acknacki:0:03079cdd1f5c3044fb3f7993becb2f581ffc1e3d128db4afc411e7870af883c3.03079cdd1f5c3044fb3f7993becb2f581ffc1e3d128db4afc411e7870af883c3

# Child contract deployed within a DApp on mainnet
# (dapp_id = SwarmRoot address, account_id = child wallet address)
acknacki:0:afdfe5f15a73a966f38de23bd38436a6a0a0f02a4b81f53d30d6eab94b374610.5fcf27147706876b13be473280ca6fa3ce9e5babf3d288926d929ca37998a505

# Contract on shellnet
acknacki:1:03079cdd1f5c3044fb3f7993becb2f581ffc1e3d128db4afc411e7870af883c3.03079cdd1f5c3044fb3f7993becb2f581ffc1e3d128db4afc411e7870af883c3
```

## Additional Considerations

The DApp ID system is fundamental to Acki Nacki's gasless transaction
model. Contracts within the same DApp ID share a gas pool via DappConfig,
enabling internal transactions without explicit gas payment. Cross-DApp
transfers of the native VMSHELL token are zeroed at the protocol level,
while ECC tokens (SHELL) can cross DApp boundaries.

Future protocol upgrades may introduce additional addressing components
(e.g., thread identifiers) that could extend this specification.

## References

- [Acki Nacki Documentation][docs] - Official documentation
- [Acki Nacki Accounts][accounts] - Account and DApp ID documentation
- [DApp ID Guide][dappid] - Full guide on DApp ID creation and fees
- [CAIP-2 Profile][] - Acki Nacki chain identification

[docs]: https://docs.ackinacki.com
[accounts]: https://docs.ackinacki.com/for-developers/accounts
[dappid]: https://dev.ackinacki.com/dapp-id-full-guide-creation-fees-centralized-replenishment
[CAIP-2 Profile]: ./caip2.md
[CAIP-2]: https://chainagnostic.org/CAIPs/caip-2
[CAIP-10]: https://chainagnostic.org/CAIPs/caip-10

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
130 changes: 130 additions & 0 deletions acknacki/caip2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
namespace-identifier: acknacki-caip2
title: Acki Nacki Blockchain - Chain ID Specification
author: Mitja Goroshevsky (@Futurizt)
discussions-to: https://github.com/ChainAgnostic/namespaces/pull/XXX
status: Draft
type: Standard
created: 2026-04-07
requires: CAIP-2
---

# CAIP-2

*For context, see the [CAIP-2][] specification.*

## Introduction

Acki Nacki is a layer-1 blockchain identified by a `global_id` integer stored
in every block header. Each network (mainnet, shellnet) has a unique
`global_id` assigned at genesis.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assigned by whom?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no assigning authority — Acki Nacki is permissionless and decentralized. global_id is fixed at genesis and remains constant for the lifetime of the network. The public mainnet (0) and shellnet (1) values are conventionally reserved; anyone bootstrapping a private network selects their own value at genesis. Clarified in the Semantics section in 40434a1.


## Specification

### Semantics

Each Acki Nacki network is uniquely identified by its `global_id`, a signed
32-bit integer present in every block. This value is fixed at genesis and
remains constant for the lifetime of the network. The public mainnet
(`global_id = 0`) and shellnet (`global_id = 1`) values are conventionally
reserved; anyone bootstrapping a private Acki Nacki network selects their
own `global_id` at genesis.

### Syntax

The `global_id` is used directly as the CAIP-2 reference:

```
acknacki:<global_id>
```

The reference is the decimal string representation of `global_id`.

Validation regex:

```
acknacki:[-]?[0-9]{1,10}
```

### Resolution Mechanics

The `global_id` can be retrieved from any block via the GraphQL API:

```graphql
query {
blocks(limit: 1) {
global_id
}
}
```

**Mainnet endpoint:** `https://mainnet.ackinacki.org/graphql`
**Shellnet endpoint:** `https://shellnet.ackinacki.org/graphql`

Example response:

```json
{
"data": {
"blocks": [
{ "global_id": 0 }
]
}
}
```

The returned `global_id` value is the CAIP-2 reference for that network.

## Rationale

Using `global_id` from the block header follows the same pattern as the `tvm`
namespace (which uses the identical field for Everscale and TON). This provides
a simple, deterministic, on-chain verifiable identifier that requires no
external registry.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if a new chain is started that "reuses" a chainId already in use? Or if a malicious network starts returning a different chainId over time when queried by the above method? Good to explain this stuff (and link to further reading if "it's complicated") for first-timers, who are the target audience of this document.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a "Verification and Trust Model" subsection in 40434a1 covering both:

(a) protocol-level verification — global_id is embedded in every block header, so a client can cross-check the value against multiple Block Keepers rather than trusting a single GraphQL endpoint. Acki Nacki is permissionless, so no central registry can prevent two unrelated private networks from picking the same global_id; applications needing stronger guarantees should additionally fingerprint the chain (genesis block hash, well-known system contract addresses).

(b) for outside observers requiring cryptographic assurance of the chain history itself, Acki Nacki includes a network-history proof system based on zero-knowledge proofs that lets an external verifier validate the chain witness without trusting any single node. The proof system is currently under test and is planned for activation on mainnet to harden the witness for light clients and cross-chain verifiers.


### Verification and Trust Model

Because `global_id` is embedded in every block header, the resolution method
above is protocol-level verifiable: a client can cross-check the value against
multiple Block Keepers rather than trusting a single GraphQL endpoint. Acki
Nacki is permissionless, so there is no central registry that can prevent two
unrelated private networks from picking the same `global_id`; applications
that need stronger guarantees should additionally fingerprint the chain
(genesis block hash, well-known system contract addresses).

For outside observers requiring cryptographic assurance of the chain history
itself, Acki Nacki includes a network-history proof system based on
zero-knowledge proofs that lets an external verifier validate the chain's
witness without trusting any single node. The proof system is currently
under test and is planned for activation on mainnet to harden the witness
for light clients and cross-chain verifiers.

### Backwards Compatibility

This is the initial specification. No legacy identifiers exist.

## Test Cases

```
# Acki Nacki Mainnet (global_id = 0)
acknacki:0

# Acki Nacki Shellnet / Testnet (global_id = 1)
acknacki:1
```

## References

- [Acki Nacki Documentation][docs] - Official documentation
- [Acki Nacki Developer Portal][dev] - Developer guides, GraphQL API
- [Acki Nacki GitHub][github] - Node software and contracts
- [CAIP-2][] - Blockchain ID Specification

[docs]: https://docs.ackinacki.com
[dev]: https://dev.ackinacki.com
[github]: https://github.com/ackinacki/ackinacki
[CAIP-2]: https://chainagnostic.org/CAIPs/caip-2

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).