Dune SQL represents varbinarys using the varbinary type.To make it simpler to work with varbinarys we have the following helper functions, which work with these two kinds of representation. They simplify interactions with varbinarys, as they automatically account for the 0x-prefix and use byte index instead of character index. For instance, the varbinary_substring methods take indexes by byte, not by character (twice the varbinary length).You can use these function to extract data from undecoded events logs, or calldata. For instance, if you have a function that takes a uint256 as an argument, you can use varbinary_to_uint256 to extract the value from the calldata. You’ll oftentimes need to use varbinary_substring to extract the correct part of the calldata or use other bytearray manipulation functions to get the correct value.
select tx_hash, data, varbinary_substring(data,97,32) as fee, varbinary_to_uint256(varbinary_substring(data,97,32)) as fee_uint256from optimism.logswhere contract_address = 0xa1ace9ce6862e865937939005b1a6c5ac938a11fand topic0 = 0xc9d5ada2ea384fe04826ecd1b258955ac73c3e2e20d755108eafde90bc5588d4-- sample transaction hashand tx_hash IN (0x3e3c558e7f723e3bb7de1d8f5f920ca206e3e878984296a2b8e6af2969003a19, 0xccfd2033adfb1fdd14fdfc047fe554ba7549e396abc6c559e9528a4259295b89)
The varbinary conversion functions throw an overflow exception if the varbinary is larger than the number of bytes supported of the type, even if the most significant bytes are all zero. It is possible to use varbinary_ltrim in order to trim the zero bytes from the left.Here is a dashboard with examples covering all of the below functions. For a more comprehensive look at all special DuneSQL functions, use this dashboard from cryptuschrist.
varbinary_to_integer(varbinary) → integerReturns the INTEGER value of a big-endian varbinary of length <= 4 representing the integer in two’s complement. If the varbinary has length < 4 it is padded with zero bytes.
-- convert bytearray to integer [result will be either 1 or 0]-- if 1 = true, 0 = falseSELECT tx_hash, varbinary_to_integer(varbinary_ltrim(varbinary_substring(data,1,32))) as isQuote_number, CASE WHEN varbinary_to_integer(varbinary_ltrim(varbinary_substring(data,1,32))) = 1 THEN TRUE ELSE FALSE END AS isQuoteFROM arbitrum.logsWHERE contract_address = 0xdaf4ffb05bfcb2c328c19135e3e74e1182c88283AND topic0 = 0xf1bc206c8d659bf05edd19865dbae82643062168ec3970d9d7c5468f900487d9LIMIT 10
varbinary_to_bigint(varbinary) → bigintReturns the BIGINT value of a big-endian varbinary of length <= 8 representing the bigint in two’s complement. If the varbinary has length < 8 it is padded with zero bytes.
-- convert bytearray to integer [result will be either 1 or 0]-- if 1 = true, 0 = falseSELECT tx_hash, varbinary_to_bigint(varbinary_ltrim(varbinary_substring(data,1,32))) as isQuote_number, CASE WHEN varbinary_to_bigint(varbinary_ltrim(varbinary_substring(data,1,32))) = 1 THEN TRUE ELSE FALSE END AS isQuoteFROM arbitrum.logsWHERE contract_address = 0xdaf4ffb05bfcb2c328c19135e3e74e1182c88283AND topic0 = 0xf1bc206c8d659bf05edd19865dbae82643062168ec3970d9d7c5468f900487d9LIMIT 10
varbinary_to_decimal(varbinary) → decimal(38,0)Returns the DECIMAL(38,0) value of a big-endian varbinary of length <= 16 representing the decimal(38,0) in two’s complement. If the varbinary has length < 16 it is padded with zero bytes.
-- using raw table to get usdc transfers amount-- transfer topic0 = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef-- usdc contract_address = 0xaf88d065e77c8cc2239327c5edb3a432268e5831SELECT tx_hash, data, varbinary_to_decimal(varbinary_ltrim(data)) as data_decimalFROM arbitrum.logsWHERE topic0 = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efAND contract_address = 0xaf88d065e77c8cc2239327c5edb3a432268e5831AND block_time >= NOW() - interval '1' dayLIMIT 50
varbinary_to_uint256(varbinary) → uint256Returns the UINT256 of a big-endian varbinary of length <= 32 representing the unsigned integer. If the varbinary has length < 32 it is padded with zero bytes.
select tx_hash, data, varbinary_substring(data,97,32) as fee, varbinary_to_uint256(varbinary_substring(data,97,32)) as fee_uint256from optimism.logswhere contract_address = 0xa1ace9ce6862e865937939005b1a6c5ac938a11fand topic0 = 0xc9d5ada2ea384fe04826ecd1b258955ac73c3e2e20d755108eafde90bc5588d4-- sample transaction hashand tx_hash IN (0x3e3c558e7f723e3bb7de1d8f5f920ca206e3e878984296a2b8e6af2969003a19, 0xccfd2033adfb1fdd14fdfc047fe554ba7549e396abc6c559e9528a4259295b89)
varbinary_to_int256(varbinary) → int256Returns the INT256 of a big-endian varbinary of length <= 32 representing the signed integer. If the varbinary has length < 32 it is padded with zero bytes.
select tx_hash, data, varbinary_substring(data,65,32) as sizeDelta, varbinary_to_int256(varbinary_substring(data,65,32)) as sizeDelta_int256from optimism.logswhere contract_address = 0xa1ace9ce6862e865937939005b1a6c5ac938a11fand topic0 = 0xc9d5ada2ea384fe04826ecd1b258955ac73c3e2e20d755108eafde90bc5588d4-- sample transaction hashand tx_hash IN (0x3e3c558e7f723e3bb7de1d8f5f920ca206e3e878984296a2b8e6af2969003a19, 0xccfd2033adfb1fdd14fdfc047fe554ba7549e396abc6c559e9528a4259295b89)
You cannot use cast(x as varbinary) in these cases as it will actually encode the string as varbinary which is different from converting the expression to varbinary.
varbinary_concat(varchar, varchar) → varcharConcatenates two varbinarys or strings.
-- concatenate varchar-- using typeof to check the datatypeSELECT varbinary_concat('0xabcd', '0x00ab') as varbinary_varchar_concat, typeof(varbinary_concat('0xabcd', '0x00ab')) as varbinary_varchar_type
varbinary_length(varbinary) → bigintReturns the length of a varbinary.
-- this will return 20SELECT varbinary_length(0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2)
varbinary_length(varchar) → bigintReturns the length of a string.
-- this will return 20SELECT typeof('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') as data_type, varbinary_length('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') varchar_length
varbinary_ltrim(varbinary) → varbinaryRemoves zero bytes or spaces from the beginning of a varbinary
-- this will remove the zeros at the front, -- returning 0xa2b80f9c09558945800ddf4f8786dcc8b1c44974SELECT varbinary_ltrim(0x000000000000000000000000a2b80f9c09558945800ddf4f8786dcc8b1c44974)
varbinary_ltrim(varchar) → varcharRemoves spaces from the beginning of a string.
-- this will remove the zeros at the front, -- returning 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2SELECT typeof('0x0000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') as data_type, varbinary_ltrim('0x0000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2') varchar_ltrim
varbinary_rtrim(varbinary) or varbinary_rtrim(varchar) → varbinary or varcharRemoves zero bytes or spaces from the end of a varbinary or string.
-- this will remove the zeros at the end, -- returning 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2SELECT varbinary_ltrim(0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000)
varbinary_position(varbinary, varbinary) → bigintReturns the index of the first occurrence of a given bytearray or string (or 0 if not found) within a varbinary or string.
-- get $ARKM claimers SELECT * FROM ethereum.transactionsWHERE block_time >= TIMESTAMP '2023-07-17' -- claim start dateAND varbinary_position(data,0x3d13f874) = 1 -- 0x3d13f874 is the methodIDAND successLIMIT 100
varbinary_position(varchar, varchar) → bigintReturns the index of the first occurrence of a given bytearray or string (or 0 if not found) within a varbinary or string.
-- search for '0x6cc2' and return its positionSELECT varbinary_position('0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2','0x6cc2')
varbinary_substring(varbinary, integer) → varbinaryReturns a suffix varbinary or string starting at a given index.
-- using varbinary_substring starting from the 21th index-- this returns 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 SELECT 0x0000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 as original_bytearray, varbinary_substring(0x0000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2,21) as bytearraysubstring_data
Returns a subvarbinary of a given length starting at an index.
-- getting the sizeDelta using varbinary_substring-- and converting to uint256 using varbinary_to_uint256SELECT tx_hash, varbinary_substring(data,65,32) as sizeDelta, varbinary_to_uint256(varbinary_substring(data,65,32)) as sizeDelta_uint256FROM optimism.logsWHERE contract_address = 0xa1ace9ce6862e865937939005b1a6c5ac938a11fAND topic0 = 0xc9d5ada2ea384fe04826ecd1b258955ac73c3e2e20d755108eafde90bc5588d4-- some sample transaction hashAND tx_hash IN (0x3e3c558e7f723e3bb7de1d8f5f920ca206e3e878984296a2b8e6af2969003a19, 0xccfd2033adfb1fdd14fdfc047fe554ba7549e396abc6c559e9528a4259295b89)
varbinary_substring(varbinary, integer, integer) → varbinaryReturns a subvarbinary of a given length starting at an index. Be aware that the length is in bytes, not characters.
-- returns 0xabcdefSELECT 0xabcdefabcdef as varbinary_data, varbinary_substring(0xabcdefabcdef,1,3) as varbinary_substring