move comments to read me

This commit is contained in:
Austin 2025-12-10 13:34:41 -05:00
parent 1036b6833a
commit 4dd7280484
3 changed files with 119 additions and 230 deletions

116
README.md
View File

@ -159,6 +159,122 @@ The `fsc_utils` dbt package is a centralized repository consisting of various db
```
- `utils.udf_encode_contract_call`: Encodes EVM contract function calls into ABI-encoded calldata format for eth_call RPC requests. Handles all Solidity types including tuples and arrays.
```
-- Simple function with no inputs
SELECT utils.udf_encode_contract_call(
PARSE_JSON('{"name": "totalSupply", "inputs": []}'),
ARRAY_CONSTRUCT()
);
-- Returns: 0x18160ddd
-- Function with single address parameter
SELECT utils.udf_encode_contract_call(
PARSE_JSON('{
"name": "balanceOf",
"inputs": [{"name": "account", "type": "address"}]
}'),
ARRAY_CONSTRUCT('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48')
);
-- Returns: 0x70a08231000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
-- Function with multiple parameters
SELECT utils.udf_encode_contract_call(
PARSE_JSON('{
"name": "transfer",
"inputs": [
{"name": "to", "type": "address"},
{"name": "amount", "type": "uint256"}
]
}'),
ARRAY_CONSTRUCT('0x1234567890123456789012345678901234567890', 1000000)
);
-- Complex function with nested tuples
SELECT utils.udf_encode_contract_call(
PARSE_JSON('{
"name": "swap",
"inputs": [{
"name": "params",
"type": "tuple",
"components": [
{"name": "tokenIn", "type": "address"},
{"name": "tokenOut", "type": "address"},
{"name": "amountIn", "type": "uint256"}
]
}]
}'),
ARRAY_CONSTRUCT(
ARRAY_CONSTRUCT(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
1000000
)
)
);
```
- `utils.udf_create_eth_call`: Creates an eth_call JSON-RPC request object from contract address and encoded calldata. Supports block parameter as string or number (auto-converts numbers to hex).
```
-- Using default 'latest' block
SELECT utils.udf_create_eth_call(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'0x70a08231000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
);
-- Using specific block number (auto-converted to hex)
SELECT utils.udf_create_eth_call(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
'0x70a08231000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
18500000
);
```
- `utils.udf_create_eth_call_from_abi`: Convenience function that combines contract call encoding and JSON-RPC request creation in a single call. Recommended for most use cases.
```
-- Simple balanceOf call with default 'latest' block
SELECT utils.udf_create_eth_call_from_abi(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
PARSE_JSON('{
"name": "balanceOf",
"inputs": [{"name": "account", "type": "address"}]
}'),
ARRAY_CONSTRUCT('0xbcca60bb61934080951369a648fb03df4f96263c')
);
-- Same call but at a specific block number
SELECT utils.udf_create_eth_call_from_abi(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
PARSE_JSON('{
"name": "balanceOf",
"inputs": [{"name": "account", "type": "address"}]
}'),
ARRAY_CONSTRUCT('0xbcca60bb61934080951369a648fb03df4f96263c'),
18500000
);
-- Using ABI from a table
WITH abi_data AS (
SELECT
abi,
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' as contract_address,
'0xbcca60bb61934080951369a648fb03df4f96263c' as user_address
FROM ethereum.silver.flat_function_abis
WHERE contract_address = LOWER('0x43506849d7c04f9138d1a2050bbf3a0c054402dd')
AND function_name = 'balanceOf'
)
SELECT
utils.udf_create_eth_call_from_abi(
contract_address,
abi,
ARRAY_CONSTRUCT(user_address)
) as rpc_call
FROM abi_data;
```
## **Streamline V 2.0 Functions**
The `Streamline V 2.0` functions are a set of macros and UDFs that are designed to be used with `Streamline V 2.0` deployments.

View File

@ -303,6 +303,7 @@
RUNTIME_VERSION = '3.10'
PACKAGES = ('eth-abi')
HANDLER = 'encode_call'
COMMENT = 'Encodes EVM contract function calls into ABI-encoded calldata format for eth_call RPC requests. Handles all Solidity types including tuples and arrays.'
sql: |
{{ fsc_utils.create_udf_encode_contract_call() | indent(4) }}
@ -366,6 +367,7 @@
NULL
LANGUAGE SQL
STRICT IMMUTABLE
COMMENT = 'Convenience function that combines contract call encoding and JSON-RPC request creation for eth_call. Encodes function call from ABI and creates RPC request with default block parameter "latest".'
sql: |
{{ schema }}.udf_create_eth_call(
contract_address,
@ -383,6 +385,7 @@
NULL
LANGUAGE SQL
STRICT IMMUTABLE
COMMENT = 'Convenience function that combines contract call encoding and JSON-RPC request creation for eth_call. Encodes function call from ABI and creates RPC request with specified block parameter.'
sql: |
{{ schema }}.udf_create_eth_call(
contract_address,

View File

@ -1010,233 +1010,3 @@ def encode_call(function_abi, input_values):
})
{% endmacro %}
{% macro udf_encode_contract_call_comment() %}
Encodes EVM contract function calls into hex calldata format for eth_call RPC requests.
PURPOSE:
Converts human-readable function parameters into ABI-encoded calldata that can be sent
to Ethereum nodes via JSON-RPC. Handles all Solidity types including complex nested
structures like tuples and arrays.
PARAMETERS:
function_abi (VARIANT):
- JSON object containing the function ABI definition
- Must include: "name" (string) and "inputs" (array of input definitions)
- Each input needs: "name", "type", and optionally "components" for tuples
input_values (ARRAY):
- Array of values matching the function inputs in order
- Values should be provided as native Snowflake types:
* addresses: strings (with or without 0x prefix)
* uint/int: numbers
* bool: booleans
* bytes/bytes32: hex strings (with or without 0x prefix)
* arrays: Snowflake arrays
* tuples: Snowflake arrays in component order
RETURNS:
STRING: Complete calldata as hex string with 0x prefix
- Format: 0x{4-byte selector}{encoded parameters}
- Can be used directly in eth_call RPC requests
- Returns JSON error object if encoding fails
EXAMPLES:
-- Simple function with no inputs
SELECT utils.udf_encode_contract_call(
PARSE_JSON(''{"name": "totalSupply", "inputs": []}''),
ARRAY_CONSTRUCT()
);
-- Returns: 0x18160ddd
-- Function with single address parameter
SELECT utils.udf_encode_contract_call(
PARSE_JSON(''{
"name": "balanceOf",
"inputs": [{"name": "account", "type": "address"}]
}''),
ARRAY_CONSTRUCT(''0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'')
);
-- Returns: 0x70a08231000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
-- Function with multiple parameters
SELECT utils.udf_encode_contract_call(
PARSE_JSON(''{
"name": "transfer",
"inputs": [
{"name": "to", "type": "address"},
{"name": "amount", "type": "uint256"}
]
}''),
ARRAY_CONSTRUCT(''0x1234567890123456789012345678901234567890'', 1000000)
);
-- Complex function with nested tuples
SELECT utils.udf_encode_contract_call(
PARSE_JSON(''{
"name": "swap",
"inputs": [{
"name": "params",
"type": "tuple",
"components": [
{"name": "tokenIn", "type": "address"},
{"name": "tokenOut", "type": "address"},
{"name": "amountIn", "type": "uint256"}
]
}]
}''),
ARRAY_CONSTRUCT(
ARRAY_CONSTRUCT(
''0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'',
''0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'',
1000000
)
)
);
TYPICAL WORKFLOW:
1. Get function ABI from crosschain.evm.dim_contract_abis
2. Prepare input values as Snowflake arrays
3. Encode using this function
4. Execute via eth_call RPC (live.udf_api)
5. Decode response using utils.udf_evm_decode_trace
SUPPORTED TYPES:
- address: Ethereum addresses
- uint8, uint16, ..., uint256: Unsigned integers
- int8, int16, ..., int256: Signed integers
- bool: Boolean values
- bytes, bytes1, ..., bytes32: Fixed and dynamic byte arrays
- string: Dynamic strings
- Arrays: Any type followed by []
- Tuples: Nested structures with components
- Nested combinations: tuple[], tuple[][], etc.
NOTES:
- Function selector is automatically calculated using Keccak256
- Compatible with existing utils.udf_evm_text_signature and utils.udf_keccak256
- Handles gas-optimized function names (e.g., selector 0x00000000)
- Tuples must be provided as arrays in component order
- Empty arrays are valid for array-type parameters
ERROR HANDLING:
- Returns JSON error object on failure
- Check if result starts with "{" to detect errors
- Error object includes: error message, traceback, function name, types
RELATED FUNCTIONS:
- utils.udf_evm_text_signature: Generate function signature
- utils.udf_keccak256: Calculate function selector
- utils.udf_evm_decode_trace: Decode call results
{% endmacro %}
{% macro udf_create_eth_call_from_abi_comment() %}
Convenience function that combines contract call encoding and JSON-RPC request creation for eth_call.
PURPOSE:
Simplifies the workflow of creating eth_call JSON-RPC requests by combining ABI encoding
and RPC call construction into a single function call. This is the recommended approach for
most use cases where you want to query contract state via eth_call.
PARAMETERS:
contract_address (STRING):
- Ethereum contract address (with or without 0x prefix)
- Example: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
function_abi (VARIANT):
- JSON object containing the function ABI definition
- Must include: "name" (string) and "inputs" (array of input definitions)
- Each input needs: "name", "type", and optionally "components" for tuples
- Can be retrieved from tables like crosschain.evm.dim_contract_abis or ethereum.silver.flat_function_abis
input_values (ARRAY):
- Array of values matching the function inputs in order
- Values should be provided as native Snowflake types:
* addresses: strings (with or without 0x prefix)
* uint/int: numbers
* bool: booleans
* bytes/bytes32: hex strings (with or without 0x prefix)
* arrays: Snowflake arrays
* tuples: Snowflake arrays in component order
block_parameter (VARIANT, optional):
- Block identifier for the eth_call request
- If NULL or omitted: defaults to 'latest'
- If NUMBER: automatically converted to hex format (e.g., 18500000 -> '0x11a7f80')
- If STRING: used directly (e.g., 'latest', '0x11a7f80', 'pending')
RETURNS:
OBJECT: Complete JSON-RPC request object ready for eth_call
- Format: {"jsonrpc": "2.0", "method": "eth_call", "params": [...], "id": "..."}
- Can be used directly with RPC execution functions like live.udf_api
EXAMPLES:
-- Simple balanceOf call with default 'latest' block
SELECT utils.udf_create_eth_call_from_abi(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
PARSE_JSON('{
"name": "balanceOf",
"inputs": [{"name": "account", "type": "address"}]
}'),
ARRAY_CONSTRUCT('0xbcca60bb61934080951369a648fb03df4f96263c')
);
-- Same call but at a specific block number
SELECT utils.udf_create_eth_call_from_abi(
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
PARSE_JSON('{
"name": "balanceOf",
"inputs": [{"name": "account", "type": "address"}]
}'),
ARRAY_CONSTRUCT('0xbcca60bb61934080951369a648fb03df4f96263c'),
18500000
);
-- Using ABI from a table
WITH abi_data AS (
SELECT
abi,
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' as contract_address,
'0xbcca60bb61934080951369a648fb03df4f96263c' as user_address
FROM ethereum.silver.flat_function_abis
WHERE contract_address = LOWER('0x43506849d7c04f9138d1a2050bbf3a0c054402dd')
AND function_name = 'balanceOf'
)
SELECT
utils.udf_create_eth_call_from_abi(
contract_address,
abi,
ARRAY_CONSTRUCT(user_address)
) as rpc_call
FROM abi_data;
TYPICAL WORKFLOW:
1. Get function ABI from contract ABI tables (crosschain.evm.dim_contract_abis, etc.)
2. Prepare input values as Snowflake arrays matching the function signature
3. Call this function with contract address, ABI, and inputs
4. Execute the returned RPC call object via live.udf_api or similar
5. Decode the response using utils.udf_evm_decode_trace or similar decoder
ADVANTAGES OVER MODULAR APPROACH:
- Single function call instead of two (encode + create)
- Cleaner, more readable SQL
- Better for AI systems (fewer steps to explain)
- Less error-prone (no intermediate variables)
- More intuitive function name
WHEN TO USE MODULAR FUNCTIONS INSTEAD:
- When you need to reuse encoded calldata for multiple RPC calls
- When you need encoded calldata for transaction construction
- When building complex workflows with intermediate steps
RELATED FUNCTIONS:
- utils.udf_encode_contract_call: Encode function calls to calldata (used internally)
- utils.udf_create_eth_call: Create RPC call from encoded calldata (used internally)
- utils.udf_evm_text_signature: Generate function signature from ABI
- utils.udf_keccak256: Calculate function selector hash
- utils.udf_evm_decode_trace: Decode eth_call response results
{% endmacro %}