> ## Documentation Index
> Fetch the complete documentation index at: https://kit.near.tools/llms.txt
> Use this file to discover all available pages before exploring further.

# Global Contracts

On NEAR, typically every smart contract account holds its own copy of the Wasm bytecode. This means if you deploy the same Token contract to 1,000 accounts, you are paying for that storage 1,000 times.

**Global Contracts** allow you to publish the Wasm bytecode **once** to a global registry. You can then deploy instances of that contract by simply referencing its hash.

## Use Cases

* **Factories:** If you are building a "DAO Factory" or "Token Factory" that deploys new contracts for users, this reduces the deployment cost from \~4 NEAR (storage) to less than 0.1 NEAR.
* **Standard Libraries:** Publish a standard implementation (like a multisig) that everyone trusts and uses.

## 1. Publishing Code

Publishing requires a storage deposit proportional to the size of your Wasm file (approx 1 NEAR per 100KB).

### Updatable Contracts (Default)

By default, published contracts are identified by **your account ID**. This allows you to update the code later by publishing again. All users who deployed referencing your account will automatically use the latest version you published.

```typescript theme={null}
import { readFileSync } from "fs"

const wasm = readFileSync("./my-token.wasm")

// Publish updatable contract (identified by your account)
await near.transaction("factory.near").publishContract(wasm).send()

// Later, you can update it:
const updatedWasm = readFileSync("./my-token-v2.wasm")
await near
  .transaction("factory.near")
  .publishContract(updatedWasm) // Overwrites previous version
  .send()
```

Users deploying with `{ accountId: "factory.near" }` will always get your latest published version.

### Immutable Contracts (Trustless)

For trustless protocols or when you want guaranteed immutability, publish the code identified by its **SHA-256 hash**. It can never be changed.

```typescript theme={null}
import { readFileSync } from "fs"
import { createHash } from "crypto" // Standard Node.js module

const wasm = readFileSync("./my-token.wasm")

// 1. Calculate the hash locally
const codeHash = createHash("sha256").update(wasm).digest()

// 2. Publish as immutable (identified by hash)
await near
  .transaction("deployer.near")
  .publishContract(wasm, { identifiedBy: "hash" })
  .send()

console.log("Immutable contract published!")
console.log("Hash:", codeHash.toString("base64"))
```

## 2. Deploying by Reference

To deploy, use `deployFromPublished` instead of `deployContract`. This action is extremely cheap because it uses almost no bandwidth or new storage.

### Deploying from Account (Updatable)

This deploys whatever code `factory.near` has currently published. If they update the contract later, you'll automatically get the latest version.

```typescript theme={null}
await near
  .transaction("user.near")
  .createAccount("dao.user.near")
  .transfer("dao.user.near", "1 NEAR") // Storage for state, not code!
  .deployFromPublished({ accountId: "factory.near" })
  .functionCall("dao.user.near", "init", {})
  .send()
```

### Deploying from Hash (Immutable)

For contracts published with `identifiedBy: "hash"`, reference them by their SHA-256 hash:

```typescript theme={null}
const codeHash = "5FzD8..." // Base58-encoded hash from publishing

await near
  .transaction("user.near")
  .createAccount("token.user.near")
  .transfer("token.user.near", "1 NEAR")
  .deployFromPublished({ codeHash })
  .functionCall("token.user.near", "init", { supply: "1000" })
  .send()
```

## 3. Querying Published Code

You can check what's in the global registry without deploying anything. `getGlobalContract` accepts the same reference shape as `deployFromPublished` and returns the published WASM together with its current SHA-256 hash:

```typescript theme={null}
// Current code published by a factory (updatable)
const { code, hash } = await near.getGlobalContract({
  accountId: "factory.near",
})
console.log(`factory.near publishes ${code.length} bytes, hash ${hash}`)

// Immutable contract by its code hash
const published = await near.getGlobalContract({ codeHash: "5FzD8..." })
```

For updatable contracts, the returned `hash` is the hash of the **current** version — compare it against a locally computed hash to detect when the publisher has updated the code.

To just check existence (for example before `deployFromPublished`):

```typescript theme={null}
if (await near.globalContractExists({ accountId: "factory.near" })) {
  // safe to deploy by reference
}
```

If the identifier has no published code, `getGlobalContract` throws a `GlobalContractNotFoundError`:

```typescript theme={null}
import { GlobalContractNotFoundError } from "near-kit"

try {
  await near.getGlobalContract({ accountId: "not-a-publisher.near" })
} catch (error) {
  if (error instanceof GlobalContractNotFoundError) {
    console.log("Nothing published under", error.identifier)
  }
}
```

There's also a matching `near.getContractCode("contract.near")` for reading the code deployed on a regular account. Note that all of these queries download the full WASM — if you only need a regular contract's code hash, `near.getAccount()` is cheaper.

## 4. Deterministic Account IDs (NEP-616)

**NEP-616** enables deploying contracts to deterministic addresses (starting with `0s`) derived from their initialization state. Perfect for sharded contract designs where you deploy many instances of the same contract.

### Deploying with StateInit

```typescript theme={null}
import { deriveAccountId } from "near-kit"

const encoder = new TextEncoder();

// Deploy to deterministic address (auto-derived from state)
await near
  .transaction("alice.near")
  .stateInit({
    code: { accountId: "publisher.near" },
    data: new Map([
      [encoder.encode("owner"), encoder.encode("alice.near")]
    ]),
    deposit: "1 NEAR",
  })
  .send()

// If already deployed, deposit is refunded automatically
```

The account ID is derived as: `"0s" + hex(keccak256(borsh(state_init))[12..32])`

### Computing Addresses

```typescript theme={null}
const encoder = new TextEncoder();

// Derive the address without deploying
const accountId = deriveAccountId({
  code: { accountId: "publisher.near" },
  data: new Map([
    [encoder.encode("owner"), encoder.encode("alice.near")]
  ]),
})
// => "0s1234567890abcdef1234567890abcdef12345678"

// Check if an account is deterministic
isDeterministicAccountId("0s123...") // true
isDeterministicAccountId("alice.near") // false
```

### Why Use This?

* **Anyone can deploy:** Since addresses are deterministic, anyone can pay to deploy if it doesn't exist
* **Sharded contracts:** Deploy many instances with predictable addresses
* **Code verification:** Verify that another contract is running specific code

<Info title="Learn More">
  See [NEP-616](https://github.com/near/NEPs/blob/master/neps/nep-0616) for the full specification.
</Info>
