> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ethereum/go-ethereum/llms.txt
> Use this file to discover all available pages before exploring further.

# accounts/abi and keystore

> ABI encoding and decoding, and encrypted key management in Go.

Two packages handle the account layer in go-ethereum:

* **`accounts/abi`** — encode method calls, decode return values, and parse event logs.
* **`accounts/keystore`** — create, import, unlock, and sign with password-encrypted key files.

## accounts/abi

```
import "github.com/ethereum/go-ethereum/accounts/abi"
```

### The ABI type

```go theme={null}
type ABI struct {
    Constructor Method
    Methods     map[string]Method
    Events      map[string]Event
    Errors      map[string]Error
    Fallback    Method
    Receive     Method
}
```

### Parsing an ABI

```go theme={null}
func JSON(reader io.Reader) (ABI, error)
```

```go theme={null}
parsedABI, err := abi.JSON(strings.NewReader(abiJSON))
if err != nil {
    log.Fatal(err)
}
```

### Encoding a method call

`Pack` prepends the 4-byte selector and ABI-encodes all arguments:

```go theme={null}
func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error)
```

```go theme={null}
toAddr := common.HexToAddress("0xRecipient")
amount := big.NewInt(1e18)

calldata, err := parsedABI.Pack("transfer", toAddr, amount)
if err != nil {
    log.Fatal(err)
}
// calldata = [selector (4 bytes)] + [ABI-encoded args]
```

Pass an empty name to encode constructor arguments only (no selector):

```go theme={null}
calldata, err := parsedABI.Pack("", constructorArg1, constructorArg2)
```

### Decoding return values

`Unpack` returns `[]interface{}`; `UnpackIntoInterface` maps values into a struct or slice:

```go theme={null}
func (abi ABI) Unpack(name string, data []byte) ([]interface{}, error)
func (abi ABI) UnpackIntoInterface(v interface{}, name string, data []byte) error
func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) error
```

```go theme={null}
// Using UnpackIntoInterface — v must be a pointer
var balance *big.Int
if err := parsedABI.UnpackIntoInterface(&balance, "balanceOf", returnData); err != nil {
    log.Fatal(err)
}
fmt.Println("balance:", balance)
```

```go theme={null}
// Using Unpack — returns []interface{}
results, err := parsedABI.Unpack("balanceOf", returnData)
if err != nil {
    log.Fatal(err)
}
balance := results[0].(*big.Int)
```

### Parsing event logs

Events are accessed through `abi.Events`:

```go theme={null}
// Get the event definition
transferEvent := parsedABI.Events["Transfer"]

// The first topic is always the event ID (keccak256 of the signature)
fmt.Println(transferEvent.ID.Hex())

// Unpack non-indexed data from log.Data
values, err := transferEvent.Inputs.UnpackValues(log.Data)
if err != nil {
    log.Fatal(err)
}
```

<Note>
  Indexed event parameters are packed into `log.Topics` (32 bytes each), **not** into `log.Data`. Non-indexed parameters are ABI-encoded in `log.Data`.
</Note>

### Looking up methods and events by selector

```go theme={null}
func (abi *ABI) MethodById(sigdata []byte) (*Method, error)
func (abi *ABI) EventByID(topic common.Hash) (*Event, error)
func (abi *ABI) ErrorByID(sigdata [4]byte) (*Error, error)
```

### Decoding revert reasons

```go theme={null}
func UnpackRevert(data []byte) (string, error)
```

Passes raw revert data (from `CallContract` errors or receipt logs) and returns the human-readable reason string from a Solidity `revert("...")` or a panic code description.

### Full example — call + decode

```go theme={null}
package main

import (
    "context"
    "fmt"
    "log"
    "math/big"
    "strings"

    "github.com/ethereum/go-ethereum"
    "github.com/ethereum/go-ethereum/accounts/abi"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/ethclient"
)

const erc20ABI = `[{"inputs":[{"name":"account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]`

func main() {
    client, err := ethclient.Dial("https://mainnet.infura.io/v3/<key>")
    if err != nil {
        log.Fatal(err)
    }

    parsedABI, err := abi.JSON(strings.NewReader(erc20ABI))
    if err != nil {
        log.Fatal(err)
    }

    token := common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48") // USDC
    account := common.HexToAddress("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")

    calldata, err := parsedABI.Pack("balanceOf", account)
    if err != nil {
        log.Fatal(err)
    }

    result, err := client.CallContract(context.Background(), ethereum.CallMsg{
        To:   &token,
        Data: calldata,
    }, nil)
    if err != nil {
        log.Fatal(err)
    }

    var balance *big.Int
    if err := parsedABI.UnpackIntoInterface(&balance, "balanceOf", result); err != nil {
        log.Fatal(err)
    }
    fmt.Println("USDC balance (units):", balance)
}
```

***

## accounts/keystore

```
import "github.com/ethereum/go-ethereum/accounts/keystore"
```

Keys are stored as encrypted JSON files using the [Web3 Secret Storage](https://ethereum.org/en/developers/docs/data-structures-and-encoding/web3-secret-storage/) specification.

### Scrypt parameters

Two predefined cost settings trade security for speed:

| Constant                              | N      | P | Use                   |
| ------------------------------------- | ------ | - | --------------------- |
| `StandardScryptN` / `StandardScryptP` | 262144 | 1 | Production            |
| `LightScryptN` / `LightScryptP`       | 4096   | 6 | Development / testing |

### Creating a keystore

```go theme={null}
func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore
```

```go theme={null}
ks := keystore.NewKeyStore("/path/to/keystore", keystore.StandardScryptN, keystore.StandardScryptP)
```

### Creating an account

```go theme={null}
func (ks *KeyStore) NewAccount(passphrase string) (accounts.Account, error)
```

```go theme={null}
account, err := ks.NewAccount("my-passphrase")
if err != nil {
    log.Fatal(err)
}
fmt.Println("address:", account.Address.Hex())
```

### Importing a raw private key

```go theme={null}
func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error)
```

```go theme={null}
privKey, err := crypto.HexToECDSA("<hex-private-key>")
if err != nil {
    log.Fatal(err)
}
account, err := ks.ImportECDSA(privKey, "my-passphrase")
```

### Unlocking and signing a transaction

```go theme={null}
// Unlock indefinitely (timeout = 0)
func (ks *KeyStore) Unlock(a accounts.Account, passphrase string) error

// Unlock for a fixed duration
func (ks *KeyStore) TimedUnlock(a accounts.Account, passphrase string, timeout time.Duration) error

// Sign a transaction with the unlocked key
func (ks *KeyStore) SignTx(a accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)
```

```go theme={null}
if err := ks.Unlock(account, "my-passphrase"); err != nil {
    log.Fatal(err)
}

tx := types.NewTx(&types.DynamicFeeTx{
    ChainID:   chainID,
    Nonce:     nonce,
    GasTipCap: tip,
    GasFeeCap: feeCap,
    Gas:       21000,
    To:        &recipient,
    Value:     big.NewInt(1e18),
})

signedTx, err := ks.SignTx(account, tx, chainID)
if err != nil {
    log.Fatal(err)
}
```

<Tip>
  If you do not want to keep the key unlocked in memory, use `SignTxWithPassphrase` instead — it decrypts the key on demand and zeroes it immediately after signing.
</Tip>

### Sign without unlocking

```go theme={null}
func (ks *KeyStore) SignTxWithPassphrase(
    a accounts.Account, passphrase string,
    tx *types.Transaction, chainID *big.Int,
) (*types.Transaction, error)
```

### Listing and locking accounts

```go theme={null}
func (ks *KeyStore) Accounts() []accounts.Account
func (ks *KeyStore) Lock(addr common.Address) error
func (ks *KeyStore) HasAddress(addr common.Address) bool
```

### Importing / exporting encrypted JSON keys

```go theme={null}
// Import an existing Web3 Secret Storage JSON key
func (ks *KeyStore) Import(keyJSON []byte, passphrase, newPassphrase string) (accounts.Account, error)

// Export to a JSON key encrypted with newPassphrase
func (ks *KeyStore) Export(a accounts.Account, passphrase, newPassphrase string) (keyJSON []byte, err error)
```
