# Work with smart contracts

You can deploy and call smart contracts on ledgers with smart contract support.

For more information, see [Supported blockchain ledgers](/products/custody/v1.19/support/supported-ledgers).

All of the information needed for the smart contract is encoded in the application binary interface (ABI) data.

Tip!
You can also deploy smart contracts as ABI data in JSON format associated with an endpoint. For more information, see [Register endpoints](/products/custody/v1.19/api/accounting-entities/endpoint/register).

## Deploy a smart contract on an EVM ledger

You can deploy new smart contracts on EVM ledgers.

### Prerequisites

To deploy a smart contract on an EVM ledger, you need the following:

| Prerequisite | Additional information |
|  --- | --- |
| An account on an EVM ledger from which to deploy the contract | [View account details](/products/custody/v1.19/api/accounting-entities/account/view) |
| Enough funds in the account to cover the transaction fees and the amount | [Check account balances](/products/custody/v1.19/api/accounting-entities/account/balances#check-account-balances) |
| The ABI data for the contract, in bytecode format |  |
| The following new IDs, in a standard UUID format:A transaction order IDAn intent ID |  |


### Deploy the smart contract

System change process
All new requests to change the system state follow the same process. To familiarize yourself with this process first, follow the [Request a change with an intent](/products/custody/v1.19/resources/tutorials/intent) tutorial.

To deploy a smart contract, follow the steps in [Request a change with an intent](/products/custody/v1.19/resources/tutorials/intent), with a payload similar to the following example.

#### Payload example


```json
{    
    "payload": {
        "id": "a67365ca-ce15-4b22-bb37-72aed5f93657",
        "accountId": "bc9a3d6d-a6e5-4c1c-9058-40ba7ee9ead0",
        "parameters": {
            "destination": null,
            "data": "0x...",
            "amount": "0",
            "feeStrategy": {
                "type": "Priority",
                "priority": "Medium"
            },
            "maximumFee": "2187025000000000",
            "type": "Ethereum"
        },
        "type": "v0_CreateTransactionOrder"
    },
}
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | Internal account ID of an existing Ethereum account in Ripple Custody. |
| `parameters.destination` | Destination address of the smart contract. This is a standard address on the blockchain, so set this field to `null`. |
| `parameters.data` | ABI data of the smart contract in EVM bytecode format. The data can include multiple smart contracts. |
| `parameters.amount` | If the constructor is `payable`, you can specify an amount, in Wei, to deduct from the account specified in `accountId` to be used to fund the balance of the smart contract. |
| `parameters.feeStrategy` | The fee strategy to use for the transaction. For more information, see [Fee strategy and maximum fee](/products/custody/v1.19/overview/blockchain/transactions/transaction-fees#fee-strategy-and-maximum-fee). |
| `parameters.maximumFee` | The maximum fee, in Wei. For more information, see [Fee strategy and maximum fee](/products/custody/v1.19/overview/blockchain/transactions/transaction-fees#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Ethereum`. |
| `type` | `v0_CreateTransactionOrder` |


When the transaction order is successfully approved, Ripple Custody does the following:

- Creates a transaction, to broadcast the details and register the smart contract on the blockchain.
- Creates one or more transfers, to represent the separate amounts associated with the transaction, such as the cryptocurrency amount and the fees.


### View the smart contract details

To view the smart contract details:

1. Get details of the transaction entity created for the transaction order, as described in [View transactions for a transaction order](/products/custody/v1.19/api/accounting/transactions/view#view-transactions-for-a-transaction-order).
2. Check the transaction entity, as described in [Check the entity](/products/custody/v1.19/api/get-started/key-operations/update/check#check-the-entity).


The response body returned is similar to the following example:


```json
{
    "id": "a4614cce-80e1-453a-a064-c092b27d89ee",
    "ledgerId": "ethereum-testnet",
    "orderReference": {
        "id": "137bc5db-b88d-43c2-a54f-2d7780e5bcd9",
        "domainId": "f457833d-d734-4ef2-b185-a7f2c795b3d6"
    },
    "relatedAccounts": [
        {
            "id": "bc9a3d6d-a6e5-4c1c-9058-40ba7ee9ead0",
            "domainId": "f457833d-d734-4ef2-b185-a7f2c795b3d6",
            "sender": true
        }
    ],
    "processing": {
        "status": "Completed"
    },
    "registeredAt": "2023-03-15T13:49:25.606Z",
    "ledgerTransactionData": {
        "ledgerStatus": "Confirmed",
        "failure": null,
        "ledgerTransactionId": "0x6b12478f131ad3e851aa58c95c7a3abb151b6cc32dd0d90dd1d76d622d549dce",
        "rawTransaction": "0x02f920e305...",
        "statusLastUpdatedAt": "2023-03-15T14:14:50.623Z",
        "ledgerData": {
            "logs": [],
            "createdContractAddresses": [
                "0x7a09ce2981fb6a056b4b51c679e6457b2119bc4a"
            ],
            "type": "Ethereum"
        }
    }
}
```

The `ledgerTransactionData` block includes the following fields:

- `ledgerData.createdContractAddresses`: A list of created contract addresses.
- `ledgerData.deletedContractAddresses`: A list of deleted contract addresses.


## Call an EVM smart contract

You can call an EVM smart contract to trigger the specific action encoded in the contract, such as transfer of an asset.

### Prerequisites

To call a smart contract on an Ethereum ledger, you need the following:

| Prerequisite | Additional information |
|  --- | --- |
| An account on an Ethereum ledger from which to call the contract | [View account details](/products/custody/v1.19/api/accounting-entities/account/view) |
| Enough funds in the account to cover the transaction fees and the amount | [Check account balances](/products/custody/v1.19/api/accounting-entities/account/balances#check-account-balances) |
| The contract address | [View the smart contract details](#view-the-smart-contract-details) |
| The ABI data of the contract | [View the smart contract details](#view-the-smart-contract-details) |
| The following new IDs, in a standard UUID format:A transaction order IDAn intent ID |  |


### Call the smart contract

System change process
All new requests to change the system state follow the same process. To familiarize yourself with this process first, follow the [Request a change with an intent](/products/custody/v1.19/resources/tutorials/intent) tutorial.

To call an Ethereum smart contract, follow the steps in [Request a change with an intent](/products/custody/v1.19/resources/tutorials/intent), with a payload similar to the following example.

#### Payload example


```json
{
    "payload": {
        "id": "a67365ca-ce15-4b22-bb37-72aed5f93657",
        "accountId": "bc9a3d6d-a6e5-4c1c-9058-40ba7ee9ead0",
        "parameters": {
            "destination": {
                "address": "0x9983f755bbd60d1886cbfe103c98c272aa0f03d6",
                "type": "Address"
            },
            "amount": "0",
            "feeStrategy": {
                "priority": "Medium",
                "type": "Priority"
            },
            "maximumFee": "2187025000000000",
            "data": "0x...",
            "type": "Ethereum"
}
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | Internal account ID of an existing Ethereum account in Ripple Custody. |
| `parameters.destination` | Details of the destination to be used by the smart contract. |
| `parameters.data` | ABI data to interact with the smart contract, in EVM bytecode format. |
| `parameters.amount` | If the constructor is `payable`, you can specify an amount, in Wei, to deduct from the account specified in `accountId` to be used to fund the balance of the smart contract. |
| `parameters.feeStrategy` | The fee strategy to use for the transaction. For more information, see [Fee strategy and maximum fee](/products/custody/v1.19/overview/blockchain/transactions/transaction-fees#fee-strategy-and-maximum-fee). |
| `parameters.maximumFee` | The maximum fee, in Wei. For more information, see [Fee strategy and maximum fee](/products/custody/v1.19/overview/blockchain/transactions/transaction-fees#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Ethereum`. |
| `type` | `v0_CreateTransactionOrder` |


When the transaction order is successfully approved, Ripple Custody does the following:

- Creates a transaction, to broadcast the details on the blockchain.
- Creates one or more transfers, to represent the separate amounts associated with the transaction, such as the cryptocurrency amount and the fees.


## Query an EVM smart contract

You can query an EVM smart contract in read-only mode. You do not need to authenticate or pay a fee for this call.

### Prerequisites

To query a smart contract on an EVM ledger, you need the following:

| Prerequisite | Additional information |
|  --- | --- |
| An account on an Ethereum ledger from which to call the contract | [View account details](/products/custody/v1.19/api/accounting-entities/account/view) |
| The contract address | [View the smart contract details](#view-the-smart-contract-details) |
| The ABI data needed to interact with the contract, in bytecode format |  |


### Query the smart contract

To query the smart contract, call the [Process contract call](/products/custody/v1.19/api/reference/openapi/ledgers/processethereumcontractcall) operation, with a payload similar to the following example.

#### Payload example


```json
{
    "contractAddress": "0xb2F701a94D864b131Fd47c9cf4563e6298AFDBfC",
    "from": {
        "address": "0xd0fe99113224600b369be3bd4a2e8b4a901ea1be",
        "type": "Address"
    },
    "value": "0",
    "data": "0x70a08231000000000000000000000000d6afa2cd61297abf4763aab4cfd2bed30f7c5a2a"
}
```

This ABI data includes a call to the `balanceOf` method. This produces the following response, which is the balance amount in hexadecimal format:


```
"0x0000000000000000000000000000000000000000000000036b5e854dc150800c"
```

## Call a Tezos smart contract

You can call a Tezos smart contract to trigger the specific action encoded in the contract, such as transfer of an asset.

### Prerequisites

To call a smart contract on a Tezos ledger, you need the following:

| Prerequisite | Additional information |
|  --- | --- |
| An account on a Tezos ledger from which to call the contract | [View account details](/products/custody/v1.19/api/accounting-entities/account/view) |
| Enough funds in the account to cover the transaction fees and the amount | [Check account balances](/products/custody/v1.19/api/accounting-entities/account/balances#check-account-balances) |
| The contract address | [View the smart contract details](#view-the-smart-contract-details) |
| The data needed to interact with the contract |  |
| The following new IDs, in a standard UUID format:A transaction order IDAn intent ID |  |


### Call the smart contract

System change process
All new requests to change the system state follow the same process. To familiarize yourself with this process first, follow the [Request a change with an intent](/products/custody/v1.19/resources/tutorials/intent) tutorial.

To call a Tezos smart contract, follow the steps in [Request a change with an intent](/products/custody/v1.19/resources/tutorials/intent), with a payload similar to the following example.

#### Payload example


```json
"payload": {
    "id": "953d75b2-e384-46e9-8a72-a1ce753a50e2",
    "accountId": "0bb0b283-da9e-4789-b134-cb5edde472a8",
    "parameters": {
        "operation": {
            "destination": {
                "address": "KT1Nf5LibLx8pod61a1476sefSWyddiwLkPg",
                "type": "Address"
                    },
            "amount": "0",
            "contractParameters": {
                "value": "ff05726573657400000002030b",
                "type": "Raw"
            },
            "type": "Transaction"
                },
        "feeStrategy": {
            "priority": "Low",
            "type": "Priority"
        },
        "maximumFee": "10000",
        "type": "Tezos"
    },
    "type": "v0_CreateTransactionOrder"
}
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | Internal account ID of an existing Ethereum account in Ripple Custody. |
| `parameters.operation.destination` | Details of the destination to be used by the smart contract. |
| `parameters.operation.contractParameters` | A string to call the smart contract. |
| `parameters.maximumFee` | The maximum fee, in micro tez. For more information, see [Fee strategy and maximum fee](/products/custody/v1.19/overview/blockchain/transactions/transaction-fees#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Tezos`. |
| `type` | `v0_CreateTransactionOrder` |


When the transaction order is successfully approved, Ripple Custody does the following:

- Creates a transaction, to broadcast the details on the blockchain.
- Creates one or more transfers, to represent the separate amounts associated with the transaction, such as the cryptocurrency amount and the fees.