Transaction objects#
When sending a transaction, either a return value or a full transaction object can be returned.
The default behavior is to return the return value. This can be changed by setting the return_tx
keyword argument to True
.
When returning a transaction object, it is not waited for the transaction to be mined. This can be
done by calling wait()
on the transaction object:
Accessing some of the transaction object's properties also performs an implicit wait()
.
Generating pytypes
with return_tx=True
It is possible to generate pytypes
with return_tx=True
as the default behavior.
It should be noted that this does not change the default return_tx
value of the low-level
transact
method. This method is not generated in pytypes
, but inherited from Account
and
will use the default False
value.
Alternatively, tx_callback
can be registered on a Chain
instance. The callback receives a single
argument, the transaction object. This can be used to process all transactions in a single place.
from woke.testing import *
from pytypes.contracts.Counter import Counter
def tx_callback(tx: TransactionAbc):
print(tx.console_logs)
@default_chain.connect()
def test_callback():
default_chain.tx_callback = tx_callback
counter = Counter.deploy(from_=default_chain.accounts[0])
counter.increment(from_=default_chain.accounts[0])
Warning
tx_callback
is not invoked for transactions with return_tx=True
!
Transaction properties#
Every transaction object has the following properties:
Property | Description | Note |
---|---|---|
block |
Block the transaction was mined in |
performs implicit wait() |
call_trace |
CallTrace instance representing the call trace of the transaction |
performs implicit wait() |
chain |
Chain the transaction was sent to |
|
console_logs |
list of console.log calls made by the transaction |
performs implicit wait() |
cumulative_gas_used |
gas consumed by this and all previous transactions in the same block | performs implicit wait() |
data |
data sent in the transaction | |
error |
native (pytypes ) revert error, None if the transaction succeeded |
performs implicit wait() |
events |
list of native (pytypes ) events emitted by the transaction |
performs implicit wait() |
from_ |
Account the transaction was sent from |
|
gas_limit |
gas limit specified in the transaction | |
gas_used |
gas used by the transaction | performs implicit wait() |
nonce |
nonce specified in the transaction | |
r |
r part of the ECDSA signature |
performs implicit wait() |
raw_error |
UnknownTransactionRevertedError instance, None if the transaction succeeded |
performs implicit wait() |
raw_events |
list of UnknownEvent instances emitted by the transaction |
performs implicit wait() |
return_value |
return value of the transaction | performs implicit wait() , raises error if the transaction failed |
s |
s part of the ECDSA signature |
performs implicit wait() |
status |
status of the transaction, 1 for success, 0 for failure, -1 for pending |
|
to |
Account the transaction was sent to |
|
tx_hash |
string hash of the transaction | |
tx_index |
index of the transaction in the block | performs implicit wait() |
type |
type of the transaction, 0 for legacy, 1 for EIP-2930, 2 for EIP-1559 |
|
value |
amount of Wei sent in the transaction |
Legacy transactions (type 0
) have the following additional properties:
Property | Description | Note |
---|---|---|
gas_price |
gas price specified in the transaction | |
v |
ECDSA signature recovery ID |
Info
Only legacy transactions are currently supported.
Multiple transactions in a single block#
It is possible to send multiple transactions in a way that they are mined in the same block. This can be achieved in the following steps:
- Disable
automine
on theChain
instance - Send any number of transactions with
return_tx=True
andgas_limit="auto"
- Re-enable
automine
- Call
.mine()
on theChain
instance - Wait for the block to be mined
from woke.testing import *
from pytypes.contracts.Counter import Counter
@default_chain.connect()
def test_multiple_txs():
default_chain.default_tx_account = default_chain.accounts[0]
counter = Counter.deploy()
# temporarily disable automine
with default_chain.change_automine(False):
tx1 = counter.increment(return_tx=True, gas_limit="auto")
tx2 = counter.increment(return_tx=True, gas_limit="auto")
tx3 = counter.increment(return_tx=True, gas_limit="auto")
default_chain.mine()
assert tx1.block == tx2.block == tx3.block
Changing automine
While it is possible to change the automine
property of a Chain
instance manually, it is not recommended.
In a case when a test connects to an existing chain and an exception is raised before automine
is re-enabled,
the chain will be left in automine
disabled state. This can be overcome by using the change_automine
context
manager.