# Web3 Methods

The `web3_*` namespace contains methods specific to the web3 client implementation.

### web3\_clientVersion

Returns the current client version string.

#### Parameters

None

#### Returns

`String` - The current client version

#### Example

**Request:**

```json
{
  "jsonrpc": "2.0",
  "method": "web3_clientVersion",
  "params": [],
  "id": 1
}
```

**Response:**

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "OPN/v1.0.0/linux-amd64/go1.19"
}
```

**JavaScript Example:**

```javascript
const version = await web3.eth.getNodeInfo();
console.log('Client version:', version);
// Output: OPN/v1.0.0/linux-amd64/go1.19
```

### web3\_sha3

Returns Keccak-256 (not SHA3-256) hash of the given data.

#### Parameters

1. `DATA` - The data to hash

#### Returns

`DATA` - The Keccak-256 hash of the given data

#### Example

**Request:**

```json
{
  "jsonrpc": "2.0",
  "method": "web3_sha3",
  "params": ["0x68656c6c6f20776f726c64"],
  "id": 2
}
```

**Response:**

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": "0x5b2c76da96136d193336fad3fbc049867b8ca157da22f69ae0e4923648250acc"
}
```

**JavaScript Examples:**

```javascript
// Using web3.js
const hash = web3.utils.sha3('hello world');
console.log('Hash:', hash);
// Output: 0x5b2c76da96136d193336fad3fbc049867b8ca157da22f69ae0e4923648250acc

// Direct RPC call
const dataHex = web3.utils.utf8ToHex('hello world');
const hash = await web3.eth.call({
  jsonrpc: '2.0',
  method: 'web3_sha3',
  params: [dataHex],
  id: 1
});
```

#### Important Notes

1. **Not SHA3-256**: This method returns Keccak-256, not the final SHA3-256 standard
2. **Ethereum Compatibility**: Matches Ethereum's implementation exactly
3. **Input Format**: Input must be hex-encoded with 0x prefix

#### Common Use Cases

**Hashing Strings**

```javascript
function hashString(text) {
  const hex = web3.utils.utf8ToHex(text);
  return web3.utils.sha3(hex);
}

const hashedMessage = hashString('Hello OPN Chain!');
console.log('Hashed message:', hashedMessage);
```

**Creating Function Selectors**

```javascript
// Get function selector (first 4 bytes of hash)
function getFunctionSelector(signature) {
  const hash = web3.utils.sha3(signature);
  return hash.substring(0, 10); // 0x + 8 chars = 4 bytes
}

const selector = getFunctionSelector('transfer(address,uint256)');
console.log('Function selector:', selector);
// Output: 0xa9059cbb
```

**Generating Deterministic Addresses**

```javascript
// CREATE2 address calculation
function calculateCreate2Address(deployer, salt, bytecode) {
  const bytecodeHash = web3.utils.sha3(bytecode);
  
  const payload = web3.utils.encodePacked(
    '0xff',
    deployer,
    salt,
    bytecodeHash
  );
  
  const hash = web3.utils.sha3(payload);
  return '0x' + hash.substring(26); // Last 20 bytes
}
```

### Error Handling

Both methods have minimal error conditions:

#### web3\_clientVersion Errors

This method rarely fails, but possible errors:

```javascript
try {
  const version = await web3.eth.getNodeInfo();
} catch (error) {
  if (error.code === -32603) {
    console.error('Internal JSON-RPC error');
  }
}
```

#### web3\_sha3 Errors

Common errors and their handling:

```javascript
try {
  // Invalid hex string
  const hash = await web3.utils.sha3('not hex');
} catch (error) {
  console.error('Invalid input:', error.message);
}

// Proper error handling
function safeHash(input) {
  try {
    // Ensure proper hex encoding
    if (!web3.utils.isHexStrict(input)) {
      input = web3.utils.utf8ToHex(input);
    }
    return web3.utils.sha3(input);
  } catch (error) {
    console.error('Hash error:', error);
    return null;
  }
}
```

### Performance Considerations

#### Batch Hashing

For multiple hash operations, consider batching:

```javascript
async function batchHash(inputs) {
  const batch = new web3.BatchRequest();
  const promises = [];
  
  inputs.forEach((input, index) => {
    const request = {
      jsonrpc: '2.0',
      method: 'web3_sha3',
      params: [web3.utils.utf8ToHex(input)],
      id: index
    };
    
    promises.push(new Promise((resolve) => {
      batch.add(
        web3.eth.call.request(request, (err, result) => {
          resolve(result);
        })
      );
    }));
  });
  
  batch.execute();
  return Promise.all(promises);
}

// Usage
const hashes = await batchHash(['hello', 'world', 'OPN', 'Chain']);
```

#### Client-Side vs RPC

For better performance, use client-side hashing when possible:

```javascript
// ❌ Slower - RPC call
const hash1 = await web3.currentProvider.send({
  jsonrpc: '2.0',
  method: 'web3_sha3',
  params: ['0x48656c6c6f'],
  id: 1
});

// ✅ Faster - Client-side
const hash2 = web3.utils.sha3('0x48656c6c6f');
```

### Integration Examples

#### With Smart Contracts

```solidity
// Solidity contract using keccak256
contract HashChecker {
    function verifyHash(
        string memory data,
        bytes32 expectedHash
    ) public pure returns (bool) {
        return keccak256(abi.encodePacked(data)) == expectedHash;
    }
}
```

```javascript
// JavaScript verification
const data = "Hello OPN!";
const hash = web3.utils.sha3(data);

const contract = new web3.eth.Contract(abi, address);
const isValid = await contract.methods.verifyHash(data, hash).call();
console.log('Hash valid:', isValid);
```

#### Event Topic Generation

```javascript
// Generate event topic for filtering
function getEventTopic(eventSignature) {
  return web3.utils.sha3(eventSignature);
}

// Example: Transfer(address,address,uint256)
const transferTopic = getEventTopic('Transfer(address,address,uint256)');

// Use in event filter
const filter = {
  address: tokenAddress,
  topics: [transferTopic],
  fromBlock: 0,
  toBlock: 'latest'
};

const events = await web3.eth.getPastLogs(filter);
```

### Compatibility Notes

#### Ethereum Compatibility

OPN Chain's implementation matches Ethereum exactly:

```javascript
// This code works identically on Ethereum and OPN Chain
const ethereumHash = web3.utils.sha3('test');
const opnHash = web3.utils.sha3('test');
console.assert(ethereumHash === opnHash, 'Hashes match!');
```

#### Library Support

All major libraries support these methods:

```javascript
// Web3.js
const hash1 = web3.utils.sha3(data);

// Ethers.js
const hash2 = ethers.utils.keccak256(data);

// Viem
import { keccak256 } from 'viem';
const hash3 = keccak256(data);

// All produce the same result
```

### Security Considerations

#### Hash Collisions

While extremely unlikely, be aware of theoretical risks:

```javascript
// Use sufficient data length for security
function secureHash(data) {
  // Add salt for extra security
  const salt = web3.utils.randomHex(32);
  return web3.utils.sha3(
    web3.utils.encodePacked(salt, data)
  );
}
```

#### Input Validation

Always validate inputs before hashing:

```javascript
function validateAndHash(input) {
  // Validate input
  if (!input || typeof input !== 'string') {
    throw new Error('Invalid input');
  }
  
  // Sanitize
  const sanitized = input.trim();
  
  // Hash
  return web3.utils.sha3(sanitized);
}
```

***

**Questions?** Join our [Discord](https://discord.gg/iopn) for help!
