Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/releases.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Release Notes
=============

- Unreleased Breaking Changes
- Remove deprecated ``call``, ``buildTransaction``,
``transact``, and ``estimateGas`` methods
- `#1232 <https://github.com/ethereum/web3.py/pull/1232>`_


v5.0.0-alpha.4
--------------
Expand Down
30 changes: 11 additions & 19 deletions tests/core/contracts/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,8 +581,7 @@ def some_address(address_conversion_func):
return address_conversion_func('0x5B2063246F2191f18F2675ceDB8b28102e957458')


def invoke_contract(api_style=None,
api_call_desig='call',
def invoke_contract(api_call_desig='call',
contract=None,
contract_function=None,
func_args=[],
Expand All @@ -592,34 +591,27 @@ def invoke_contract(api_style=None,
if api_call_desig not in allowable_call_desig:
raise ValueError("allowable_invoke_method must be one of: %s" % allowable_call_desig)

if api_style == 'func_first':
function = contract.functions[contract_function]
result = getattr(function(*func_args, **func_kwargs), api_call_desig)(tx_params)
elif api_style == 'func_last':
api_call_cls = getattr(contract, api_call_desig)
with pytest.deprecated_call():
result = getattr(api_call_cls(tx_params), contract_function)(*func_args, **func_kwargs)
else:
raise ValueError("api_style must be 'func_first or func_last'")
function = contract.functions[contract_function]
result = getattr(function(*func_args, **func_kwargs), api_call_desig)(tx_params)

return result


@pytest.fixture(params=['func_first', 'func_last'])
@pytest.fixture
def transact(request):
return functools.partial(invoke_contract, request.param, api_call_desig='transact')
return functools.partial(invoke_contract, api_call_desig='transact')


@pytest.fixture(params=['func_first', 'func_last'])
@pytest.fixture
def call(request):
return functools.partial(invoke_contract, request.param, api_call_desig='call')
return functools.partial(invoke_contract, api_call_desig='call')


@pytest.fixture(params=['func_first', 'func_last'])
@pytest.fixture
def estimateGas(request):
return functools.partial(invoke_contract, request.param, api_call_desig='estimateGas')
return functools.partial(invoke_contract, api_call_desig='estimateGas')


@pytest.fixture(params=['func_first', 'func_last'])
@pytest.fixture
def buildTransaction(request):
return functools.partial(invoke_contract, request.param, api_call_desig='buildTransaction')
return functools.partial(invoke_contract, api_call_desig='buildTransaction')
304 changes: 0 additions & 304 deletions web3/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

"""
import copy
import functools
import itertools

from eth_abi import (
Expand Down Expand Up @@ -49,7 +48,6 @@
)
from web3._utils.decorators import (
combomethod,
deprecated_for,
)
from web3._utils.empty import (
empty,
Expand Down Expand Up @@ -301,59 +299,6 @@ def factory(cls, web3, class_name=None, **kwargs):
#
# Contract Methods
#
@classmethod
@deprecated_for("contract.constructor.transact")
def deploy(cls, transaction=None, args=None, kwargs=None):
"""
Deploys the contract on a blockchain.

Example:

.. code-block:: python

>>> MyContract.deploy(
transaction={
'from': web3.eth.accounts[1],
'value': 12345,
},
args=('DGD', 18),
)
'0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060'

:param transaction: Transaction parameters for the deployment
transaction as a dict

:param args: The contract constructor arguments as positional arguments
:param kwargs: The contract constructor arguments as keyword arguments

:return: hexadecimal transaction hash of the deployment transaction
"""
if transaction is None:
deploy_transaction = {}
else:
deploy_transaction = dict(**transaction)

if not cls.bytecode:
raise ValueError(
"Cannot deploy a contract that does not have 'bytecode' associated "
"with it"
)

if 'data' in deploy_transaction:
raise ValueError(
"Cannot specify `data` for contract deployment"
)

if 'to' in deploy_transaction:
raise ValueError(
"Cannot specify `to` for contract deployment"
)

deploy_transaction['data'] = cls._encode_constructor_data(args, kwargs)

txn_hash = cls.web3.eth.sendTransaction(deploy_transaction)
return txn_hash

@classmethod
def constructor(cls, *args, **kwargs):
"""
Expand Down Expand Up @@ -392,255 +337,6 @@ def encodeABI(cls, fn_name, args=None, kwargs=None, data=None):

return encode_abi(cls.web3, fn_abi, fn_arguments, data)

@combomethod
@deprecated_for("contract.functions.<method name>.estimateGas")
def estimateGas(self, transaction=None):
"""
Estimate the gas for a call
"""
if transaction is None:
estimate_transaction = {}
else:
estimate_transaction = dict(**transaction)

if 'data' in estimate_transaction:
raise ValueError("Cannot set data in call transaction")
if 'to' in estimate_transaction:
raise ValueError("Cannot set to in call transaction")

if self.address:
estimate_transaction.setdefault('to', self.address)
if self.web3.eth.defaultAccount is not empty:
estimate_transaction.setdefault('from', self.web3.eth.defaultAccount)

if 'to' not in estimate_transaction:
if isinstance(self, type):
raise ValueError(
"When using `Contract.estimateGas` from a contract factory "
"you must provide a `to` address with the transaction"
)
else:
raise ValueError(
"Please ensure that this contract instance has an address."
)

contract = self

class Caller:
def __getattr__(self, function_name):
callable_fn = functools.partial(
estimate_gas_for_function,
contract.address,
contract.web3,
function_name,
estimate_transaction,
contract.abi,
None,
)
return callable_fn

return Caller()

@combomethod
@deprecated_for("contract.<functions/events>.<method name>.call")
def call(self, transaction=None):
"""
Execute a contract function call using the `eth_call` interface.

This method prepares a ``Caller`` object that exposes the contract
functions and public variables as callable Python functions.

Reading a public ``owner`` address variable example:

.. code-block:: python

ContractFactory = w3.eth.contract(
abi=wallet_contract_definition["abi"]
)

# Not a real contract address
contract = ContractFactory("0x2f70d3d26829e412A602E83FE8EeBF80255AEeA5")

# Read "owner" public variable
addr = contract.functions.owner().call()

:param transaction: Dictionary of transaction info for web3 interface
:return: ``Caller`` object that has contract public functions
and variables exposed as Python methods
"""
if transaction is None:
call_transaction = {}
else:
call_transaction = dict(**transaction)

if 'data' in call_transaction:
raise ValueError("Cannot set data in call transaction")

if self.address:
call_transaction.setdefault('to', self.address)
if self.web3.eth.defaultAccount is not empty:
call_transaction.setdefault('from', self.web3.eth.defaultAccount)

if 'to' not in call_transaction:
if isinstance(self, type):
raise ValueError(
"When using `Contract.call` from a contract factory you "
"must provide a `to` address with the transaction"
)
else:
raise ValueError(
"Please ensure that this contract instance has an address."
)

contract = self

class Caller:
def __getattr__(self, function_name):
callable_fn = functools.partial(
call_contract_function,
contract.web3,
contract.address,
contract._return_data_normalizers,
function_name,
call_transaction,
'latest',
contract.abi,
None,
)
return callable_fn

return Caller()

@combomethod
@deprecated_for("contract.<functions/events>.<method name>.transact")
def transact(self, transaction=None):
"""
Execute a contract function call using the `eth_sendTransaction`
interface.

You should specify the account that pays the gas for this transaction
in `transaction`. If no account is specified the coinbase account of
web3 interface is used.

Example:

.. code-block:: python

# Assume we have a Wallet contract with the following methods.
# * Wallet.deposit() # deposits to `msg.sender`
# * Wallet.deposit(address to) # deposits to the account indicated
# by the `to` parameter.
# * Wallet.withdraw(address amount)

>>> wallet = Wallet(address='0xDc3A9Db694BCdd55EBaE4A89B22aC6D12b3F0c24')
# Deposit to the `web3.eth.coinbase` account.
>>> wallet.functions.deposit().transact({'value': 12345})
'0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060'
# Deposit to some other account using funds from `web3.eth.coinbase`.
>>> wallet.functions.deposit(web3.eth.accounts[1]).transact({'value': 54321})
'0xe122ba26d25a93911e241232d3ba7c76f5a6bfe9f8038b66b198977115fb1ddf'
# Withdraw 12345 wei.
>>> wallet.functions.withdraw(12345).transact()

The new public transaction will be created. Transaction receipt will
be available once the transaction has been mined.

:param transaction: Dictionary of transaction info for web3 interface.
Variables include ``from``, ``gas``, ``value``, ``gasPrice``, ``nonce``.

:return: ``Transactor`` object that has contract
public functions exposed as Python methods.
Calling these methods will execute a transaction against the contract.

"""
if transaction is None:
transact_transaction = {}
else:
transact_transaction = dict(**transaction)

if 'data' in transact_transaction:
raise ValueError("Cannot set data in call transaction")

if self.address is not None:
transact_transaction.setdefault('to', self.address)
if self.web3.eth.defaultAccount is not empty:
transact_transaction.setdefault('from', self.web3.eth.defaultAccount)

if 'to' not in transact_transaction:
if isinstance(self, type):
raise ValueError(
"When using `Contract.transact` from a contract factory you "
"must provide a `to` address with the transaction"
)
else:
raise ValueError(
"Please ensure that this contract instance has an address."
)

contract = self

class Transactor:
def __getattr__(self, function_name):
callable_fn = functools.partial(
transact_with_contract_function,
contract.address,
contract.web3,
function_name,
transact_transaction,
contract.abi,
None,
)
return callable_fn

return Transactor()

@combomethod
@deprecated_for("contract.<functions/events>.<method name>.buildTransaction")
def buildTransaction(self, transaction=None):
"""
Build the transaction dictionary without sending
"""
if transaction is None:
built_transaction = {}
else:
built_transaction = dict(**transaction)

if 'data' in built_transaction:
raise ValueError("Cannot set data in call buildTransaction")

if isinstance(self, type) and 'to' not in built_transaction:
raise ValueError(
"When using `Contract.buildTransaction` from a contract factory "
"you must provide a `to` address with the transaction"
)
if not isinstance(self, type) and 'to' in built_transaction:
raise ValueError("Cannot set to in call buildTransaction")

if self.address:
built_transaction.setdefault('to', self.address)

if 'to' not in built_transaction:
raise ValueError(
"Please ensure that this contract instance has an address."
)

contract = self

class Caller:
def __getattr__(self, function_name):
callable_fn = functools.partial(
build_transaction_for_function,
contract.address,
contract.web3,
function_name,
built_transaction,
contract.abi,
None,
)
return callable_fn

return Caller()

@combomethod
def all_functions(self):
return find_functions_by_identifier(
Expand Down