Tengo un contrato de prueba simple:
contract TestContract {
address public owner;
address public someAddress;
function TestContract() public {
owner = msg.sender;
}
modifier onlyOwner {
assert(msg.sender == owner);
_;
}
function setSomeAddress(address _newAddress) onlyOwner public {
someAddress = _newAddress;
}
}
Según la documentación , debería poder llamar a una función de cambio de estado en un contrato como este:
transact_params = {
'from': addr_owner,
'gas': 21000,
'gas_price': 1,
}
my_contract_instance.transact(transact_params).setSomeAddress(w3.eth.accounts[1])
Sin embargo, esto arroja una excepción:
File "/usr/local/lib/python3.5/dist-packages/web3/contract.py", line 624, in _find_matching_fn_abi
raise ValueError("No matching functions found")
Intenté eliminar parámetros, verificar ABI (la definición está ahí), ... sin éxito. ¿Qué estoy haciendo mal? ¿Cómo puedo llamar a una función de cambio de estado con web3.py
?
A través del seguimiento, quedó claro que ConciseContract
se utilizó la fábrica de contratos personalizados. Eso se puede especificar de esta manera:
my_contract_instance = w3.eth.contract(..., ContractFactoryClass=ConciseContract)
ConciseContract
busca la primera llamada de función como un método de contrato. Así que esto:
my_contract_instance.transact(transact_params).setSomeAddress(w3.eth.accounts[1])
... intenta buscar el método transact()
que no está disponible en el contrato. Eso produce el error:
raise ValueError("No matching functions found")
En general, si obtiene ese error, significa que está tratando de interactuar con una función que no está definida en la ABI. Tenga en cuenta que las funciones dependen de los argumentos, por lo que si intenta llamar a la función definida en la ABI myfunc(int)
con una cadena como argumento, el mensaje será "No se encontraron funciones coincidentes".
ConciseContract
era el único tipo (no abstracto) de Contract
. Entonces, si entiendo correctamente, mi ejemplo original debería funcionar si elimino , ContractFactoryClass=ConciseContract
?ConciseContract
de contratos personalizados y sigo recibiendo el mismo error. ¿Puede extender su respuesta si sabe por qué?EDITAR: la respuesta a continuación es correcta para ConciseContract
.
La sintaxis correcta (probada en la versión 13.6.2
) es:
my_contract_instance.setSomeAddress(w3.eth.accounts[1], transact=transact_params)
Sin embargo, tenga cuidado: si lo entiendo correctamente, **kwargs
debe tener cero o un elemento que se use para especificar el tipo de llamada (la clave debe ser una de call
, transact
o estimateGas
). Si **kwargs
está vacío, call
se utiliza.
*args
luego se pasan a la función de contrato.
ConciseContract
fábrica por contrato. La sintaxis de su pregunta era correcta para la fábrica de contratos clásica/predeterminada.
tallista
juandodo
tallista