Interacting with contracts
Eclair provides a simple way to interact with smart contracts using familiar Solidity syntax.
Calling contracts and sending transactions
For any contract loaded, all the functions of the contract defined in its ABI are available as methods on the contract object.
By default, calling a view function will call it and return the result, while calling a non-view function will send a transaction and returns the transaction hash. Sending a transaction requires an account to be loaded.
The behavior can be changed by using one of the following method on the returned function object:
call
: Call the function and return the resulttraceCall
: Same as call but also prints the trace of the call (also potentially shows better error messages)send
: Sends a transaction to the function and return the resultencode
: ABI-encodes the function call
>> dai = repl.fetchAbi("DAI", 0x6B175474E89094C44Da98b954EedeAC495271d0F)
>> dai.balanceOf(0x4DEDf26112B3Ec8eC46e7E31EA5e123490B05B8B)
49984400000000000000000000
>> repl.loadPrivateKey()
>> dai.balanceOf.send(0x4DEDf26112B3Ec8eC46e7E31EA5e123490B05B8B)
Transaction(0x6a2f1b956769d06257475d18ceeec9ee9487d91c97d36346a3cc84d568e36e5c)
>> dai.balanceOf.encode(0x4DEDf26112B3Ec8eC46e7E31EA5e123490B05B8B)
0x70a082310000000000000000000000004dedf26112b3ec8ec46e7e31ea5e123490b05b8b
>> dai.transfer(0x4DEDf26112B3Ec8eC46e7E31EA5e123490B05B8B, 1e18)
Transaction(0xf3e85039345ff864bb216b10e84c7d009e99ec55b370dae22706b0d48ea41583)
Transaction options
There are different options available when calling and sending transactions to contracts.
The options can be passed using the {key: value}
Solidity syntax, for example:
>> tx = weth.deposit{value: 1e18}()
The following options are currently supported:
value
: sets themsg.value
of the transactionblock
: sets the block number to execute the call on (only works for calls, not for sending transactions)from
: sets thefrom
for the call (only works for calls, not for sending transactions)gasLimit
: sets the gas limit to use for the transactionmaxFee
: sets the maximum fee to pay for the transactionpriorityFee
: sets the priority fee to pay for the transactiongasPrice
: sets gas price to use for the (legacy) transaction
Transaction receipts
After sending a transaction, you can get the transaction receipt using the Transaction.getReceipt
method.
>> tx = dai.approve(0x83F20F44975D03b1b09e64809B757c47f942BEeA, 1e18)
>> tx.getReceipt()
TransactionReceipt { tx_hash: 0x248ad948d1e4eefc6ccb271cac2001ebbdb2346beddc7656b1f9518f216c8b02, block_hash: 0x688517fe5e540b4e3953ed3ba84cc4d70903ddffb981a66c51ca49ca13c90bb1, block_number: 20380613, status: true, gas_used: 46146, gas_price: 4547819249 }
>> _.logs
[Log { address: 0x6B175474E89094C44Da98b954EedeAC495271d0F, topics: [0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925, 0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266, 0x00000000000000000000000083f20f44975d03b1b09e64809b757c47f942beea], data: 0x0000000000000000000000000000000000000000000000000de0b6b3a7640000 }]
If the ABI of the contract emitting the log is loaded, the logs will automatically be decoded and the decoded arguments will be available in the args
property of each log.
Events
Eclair provides a way to fetch events emitted by a contract using the events.fetch
method.
>> events.fetch{fromBlock: 20490506, toBlock: 20490512}(0xe07F9D810a48ab5c3c914BA3cA53AF14E4491e8A)[0]
Log { address: 0xe07F9D810a48ab5c3c914BA3cA53AF14E4491e8A, topics: [0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8, 0x000000000000000000000000f081470f5c6fbccf48cc4e5b82dd926409dcdd67], data: 0x00000000000000000000000000000000000000000000000e8bd6d724bc4c7886, args: Transfer { from: 0xBA12222222228d8Ba445958a75a0704d566BF2C8, to: 0xf081470f5C6FBCCF48cC4e5B82Dd926409DcdD67, value: 268330894800999708806 } }
The events.fetch
accepts either a single address or a list of addresses as the first argument, as well as some options
to filter the logs returned.
It returns a list of logs that match the given criteria, and automatically decodes each log if the ABI is loaded.
Options
The events.fetch
method accepts the following options:
fromBlock
: the block number to start fetching events fromtoBlock
: the block number to stop fetching events attopic0
: topic0 of the eventtopic1
: topic1 of the eventtopic2
: topic2 of the eventtopic3
: topic3 of the event
By default, it will try to fetch from the first ever block to the latest block. In many cases, the RPC provider will reject the request because too much data would be returned, in which case options above will need to be added to restrict the size of the response.
To only get one type of event, e.g. Transfer
, you can filter using topic0
and the selector of the desired event.
>> events.fetch{fromBlock: 20490506, toBlock: 20490512, topic0: ERC20.Approval.selector}(0xe07F9D810a48ab5c3c914BA3cA53AF14E4491e8A)[0]
Log { address: 0xe07F9D810a48ab5c3c914BA3cA53AF14E4491e8A, topics: [0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925, 0x0000000000000000000000008149dc18d39fdba137e43c871e7801e7cf566d41, 0x000000000000000000000000ea50f402653c41cadbafd1f788341db7b7f37816], data: 0x000000000000000000000000000000000000000000000025f273933db5700000, args: Approval { owner: 0x8149DC18D39FDBa137E43C871e7801E7CF566D41, spender: 0xeA50f402653c41cAdbaFD1f788341dB7B7F37816, value: 700000000000000000000 } }