Binary Data
Note
By default ctc
will perform end-to-end encoding/decoding of many operations. The low-level functions listed here are only needed if you need to work directly with raw binary data.
Examples
Note
These examples are crafted as a Jupyter notebook. You can download the original notebook file here.
Also note that inside Jupyter notebooks, await
can be used freely outside of asyncio.run()
.
In [1]:
import ctc
In [2]:
contract_address = '0x956f47f50a910163d8bf957cf5846d573e7f87ca'
wallet_address = '0x06cb22615ba53e60d67bf6c341a0fd5e718e1655'
Get hash of data¶
In [3]:
ctc.keccak('0xdeadbeef')
Out[3]:
'0xd4fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1'
Get hash of text¶
In [4]:
ctc.keccak_text('goodbye')
Out[4]:
'0x795d549ea199f3d64ea49f5792287667c58f283ef1d500cba523a8fe1fc3d430'
Convert between binary formats¶
In [5]:
encoded = '0xdeadbeef'
print('prefix_hex:', ctc.binary_convert(encoded, 'prefix_hex'))
print()
print('raw_hex:', ctc.binary_convert(encoded, 'raw_hex'))
print()
print('integer:', ctc.binary_convert(encoded, 'integer'))
print()
print('binary:', ctc.binary_convert(encoded, 'binary'))
prefix_hex: 0xdeadbeef raw_hex: deadbeef integer: 3735928559 binary: b'\xde\xad\xbe\xef'
ABI Encoding / Decoding¶
In [6]:
data_to_encode = [
['int128', 4000],
['int16', 300],
[['int128', 'int16'], (4000, 300)],
[['int16', 'string', 'bool'], (123, 'hello there', False)],
]
In [7]:
# encode
for types, data in data_to_encode:
encoded = ctc.abi_encode(data, types)
as_hex = ctc.binary_convert(encoded, 'prefix_hex')
print()
print('original:', data)
print('encoded:', as_hex)
original: 4000 encoded: 0x0000000000000000000000000000000000000000000000000000000000000fa0 original: 300 encoded: 0x000000000000000000000000000000000000000000000000000000000000012c original: (4000, 300) encoded: 0x0000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000000000000000000000000000000000000000000012c original: (123, 'hello there', False) encoded: 0x000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b68656c6c6f207468657265000000000000000000000000000000000000000000
In [8]:
# encode packed
for types, data in data_to_encode:
encoded = ctc.abi_encode_packed(data, types)
as_hex = ctc.binary_convert(encoded, 'prefix_hex')
print()
print('original:', data)
print('encoded:', as_hex)
original: 4000 encoded: 0x00000000000000000000000000000fa0 original: 300 encoded: 0x012c original: (4000, 300) encoded: 0x00000000000000000000000000000fa0012c original: (123, 'hello there', False) encoded: 0x007b68656c6c6f20746865726500
In [9]:
# decode
for types, data in data_to_encode:
encoded = ctc.abi_encode(data, types)
as_hex = ctc.binary_convert(encoded, 'prefix_hex')
decoded = ctc.abi_decode(encoded, types)
print()
print('original:', data)
print('encoded:', as_hex)
print('decoded:', decoded)
original: 4000 encoded: 0x0000000000000000000000000000000000000000000000000000000000000fa0 decoded: 4000 original: 300 encoded: 0x000000000000000000000000000000000000000000000000000000000000012c decoded: 300 original: (4000, 300) encoded: 0x0000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000000000000000000000000000000000000000000012c decoded: (4000, 300) original: (123, 'hello there', False) encoded: 0x000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b68656c6c6f207468657265000000000000000000000000000000000000000000 decoded: (123, 'hello there', False)
RLP encoding / decoding¶
In [10]:
for types, data in data_to_encode:
encoded = ctc.rlp_encode(data)
decoded = ctc.rlp_decode(encoded, types)
# if isinstance(types, str):
# decoded = ctc.binary_convert(decoded, 'integer')
print()
print('original:', data)
print('encoded:', encoded)
print('decoded:', decoded)
original: 4000 encoded: 0x820fa0 decoded: 4000 original: 300 encoded: 0x82012c decoded: 300 original: (4000, 300) encoded: 0xc6820fa082012c decoded: [4000, 300] original: (123, 'hello there', False) encoded: 0xce7b8b68656c6c6f20746865726580 decoded: [123, 'hello there', False]
Encode call data¶
In [11]:
function_abi = await ctc.async_get_function_abi(
contract_address=contract_address,
function_name='balanceOf',
)
In [12]:
encoded_call_data = ctc.encode_call_data(
function_abi=function_abi,
parameters=[wallet_address],
)
encoded_call_data
Out[12]:
'0x70a0823100000000000000000000000006cb22615ba53e60d67bf6c341a0fd5e718e1655'
Decode call data¶
In [13]:
decoded_call_data = ctc.decode_call_data(
encoded_call_data,
function_abi=function_abi,
)
decoded_call_data
Out[13]:
{'function_abi': {'inputs': [{'internalType': 'address', 'name': 'account', 'type': 'address'}], 'name': 'balanceOf', 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}], 'stateMutability': 'view', 'type': 'function'}, 'function_selector': '0x70a08231', 'parameters': ['0x06cb22615ba53e60d67bf6c341a0fd5e718e1655'], 'named_parameters': {'account': '0x06cb22615ba53e60d67bf6c341a0fd5e718e1655'}}
Decode function output¶
In [14]:
import ctc.rpc
In [15]:
raw_function_output = await ctc.rpc.async_eth_call(
to_address=contract_address,
call_data=encoded_call_data,
decode_response=False,
)
auto_decoded_function_output = await ctc.rpc.async_eth_call(
to_address=contract_address,
call_data=encoded_call_data,
function_abi=function_abi,
decode_response=True,
)
manually_decoded_function_output = ctc.decode_function_output(
encoded_output=raw_function_output,
function_abi=function_abi,
)
print('raw_function_output:', raw_function_output)
print('auto_decoded_function_output:', auto_decoded_function_output)
print('manually_decoded_function_output:', manually_decoded_function_output)
raw_function_output: 0x00000000000000000000000000000000000000000000a5c8cfd416300389df58 auto_decoded_function_output: 782894794107289757933400 manually_decoded_function_output: 782894794107289757933400
Reference
[none]
.. autofunction:: ctc.binary.convert .. autofunction:: ctc.binary.decode_call_data .. autofunction:: ctc.binary.decode_function_output .. autofunction:: ctc.binary.decode_types .. autofunction:: ctc.binary.encode_call_data .. autofunction:: ctc.binary.encode_types .. autofunction:: ctc.binary.keccak .. autofunction:: ctc.binary.keccak_text