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

# Deploy a custom QRC-compatible contract

> Use Path B — compile your own Solidity, deploy bytecode through Qustody, and call functions with ABI-encoded data.

<Note>
  This guide describes a flow that **works today**. Path B reuses the existing transaction endpoints (`POST /v1/transactions` with `CONTRACT_CALL`) and the Qustody approval + post-quantum signing pipeline.
</Note>

You will compile a QRC-compatible Solidity contract, deploy it through Qustody, and call a function on the deployed contract.

## Prerequisites

* A Solidity toolchain (`solc`, Foundry, or Hardhat).
* A Qustody tenant and an API key with `transactions:create` permission.
* A vault account with native currency for gas.
* An [approval policy](/concepts/policies) that requires approval for `CONTRACT_CALL` deployments.

## Step 1 — Compile Solidity

```bash theme={null}
solc --abi --bin contracts/MyToken.sol -o build/
```

You now have `build/MyToken.bin` (deployment bytecode) and `build/MyToken.abi` (ABI).

## Step 2 — Prepare the deployment payload

```bash theme={null}
DEPLOY_BYTECODE="0x$(cat build/MyToken.bin)"
```

If your constructor takes arguments, ABI-encode them and append to the bytecode. For example, with `ethers.js`:

```js theme={null}
import { Interface } from "ethers";
const iface = new Interface(abi);
const args  = iface.encodeDeploy(["My Token", "MTK", 18]);
const payload = "0x" + bytecode.slice(2) + args.slice(2);
```

## Step 3 — Submit the deployment transaction

```http theme={null}
POST /v1/transactions
Idempotency-Key: deploy-mytoken-2026-04-27

{
  "operationType": "CONTRACT_CALL",
  "from": { "type": "vaultAccountId", "vaultAccountId": "vault_123" },
  "to": null,
  "data": "0x60806040…",
  "value": "0",
  "feeStrategy": "MEDIUM"
}
```

Qustody returns a transaction in `PENDING_AUTHORIZATION`.

## Step 4 — Approve

An `approver` calls:

```http theme={null}
POST /v1/transactions/{id}/approve
```

The transaction enters `PENDING_SIGNATURE`.

## Step 5 — Post-quantum signing

If your signer is configured to sign automatically (gRPC or remote modes), the transaction continues. Otherwise, fetch the signing payload and submit the signature:

```http theme={null}
GET  /v1/transactions/{id}/signing_payload
POST /v1/transactions/{id}/signature
```

See [external signing](/guides/external-signing).

## Step 6 — Read the contract address

After confirmation:

```http theme={null}
GET /v1/transactions/{id}
```

The response includes `receipt.contractAddress`. Save it for later calls.

## Step 7 — Call a function

ABI-encode the call data and submit a contract call:

```js theme={null}
const data = iface.encodeFunctionData("transfer", ["0x9a8e…", "1000000000000000000"]);
```

```http theme={null}
POST /v1/transactions
Idempotency-Key: transfer-2026-04-27-001

{
  "operationType": "CONTRACT_CALL",
  "from": { "type": "vaultAccountId", "vaultAccountId": "vault_123" },
  "to": "0x9a8e5e21f0c27d2c5c14b6e9bd8e4a0f9c9b4d12",
  "data": "0xa9059cbb000000000000000000000000…",
  "value": "0",
  "feeStrategy": "MEDIUM"
}
```

## Step 8 — Verify state via RPC

Use Quantum Chain RPC to read state:

```bash theme={null}
curl -X POST $RPC_URL -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x9a8e…","data":"0x70a08231000000000000000000000000…"},"latest"],"id":1}'
```

## Caveats

* The QVM **removes** the `ecrecover` precompile. Solidity that depends on it will revert. Use the post-quantum precompile at `0x0b` instead — see [QVM vs EVM](/quantum-chain/qvm-vs-evm).
* BIP-32 / BIP-44 derivation is not applicable to post-quantum keys.
* Treat upgrades as deployments — the upgrade transaction is its own privileged operation.

## Related

* [Advanced contracts](/qustody/token-management/advanced-contracts)
* [RPC and bytecode](/qustody/token-management/rpc-and-bytecode)
* [QVM vs EVM](/quantum-chain/qvm-vs-evm)
* [External signing](/guides/external-signing)
