Estoy tratando de heredar y anular la función de pago de un padre (y agregar algunos modificadores y lógica), pero hasta ahora parece que no puedo hacerlo.
Mi primer intento intuitivo fue algo como esto:
contract foo {
function test() public payable returns (uint256) {
return msg.value;
}
}
contract bar is foo {
function test() public payable returns (uint256) {
return super.test.value(msg.value / 2)();
}
}
y recibió un error de compilación:
TypeError: Member "value" not found or not visible after argument-dependent lookup in function () - did you forget the "payable" modifier?
super.test.value(msg.value)();
Dar a la función un nombre diferente tampoco funciona, por lo que no es un problema primordial.
contract foo {
function test() public payable returns (uint256) {
return msg.value;
}
}
contract bar is foo {
function anotherTest() public payable returns (uint256) {
return super.test.value(msg.value / 2)();
}
}
Llegué un poco más lejos al engañar al compilador con una conversión, pero obviamente esto no es bueno, ya que causaría un bucle infinito en el tiempo de ejecución:
contract foo {
function test() public payable returns (uint256) {
return msg.value;
}
}
contract bar is foo {
function test() public payable returns (uint256) {
return foo(address(this)).test.value(msg.value / 2)();
}
}
Lo que funciona es combinar los dos, es decir, darle un nombre y un casting diferentes:
contract foo {
function test() public payable returns (uint256) {
return msg.value;
}
}
contract bar is foo {
function anotherTest() public payable returns (uint256) {
return foo(address(this)).test.value(msg.value / 2)();
}
}
Ahora llamar a bar.test() con 6 wei devuelve 6 y llamar a bar.anotherTest() devuelve 3. Pero esto no es exactamente lo que quiero, ya que todavía expone test() a través de bar.
Entonces, ¿qué estoy haciendo mal, o es esto por diseño? Realmente me gustaría entender por qué Solidity se comporta de esta manera y si hay una solución para lograr lo que quiero. ¡gracias!
Ya que foo
es el contrato base de bar
cuando llamas super.test()
te estás llamando a ti mismo dentro del mismo contrato.
Ahora está tratando de enviarse la mitad msg.value
y la otra mitad seguirá estando en su contrato.
Recomiendo pasar el valor deseado como parámetro de la función.
jhuang
super.test()
sin.value
o con un parámetro sería suficiente. ¡Gracias!