¿Cómo escribir un puntero de función en Solidity?

Tengo una función que toma un parámetro de tipo function (uint256) view returns (uint256).

Quiero pasarle un puntero a una función de tipo function (uint256) pure returns (uint256).

Obviamente, no debería haber ningún problema con pasar esta purefunción a un parámetro que espera una viewfunción, porque los tipos de parámetro y de retorno son los mismos y pureson incluso más limitantes que view. Sin embargo, me sale este TypeError:

TypeError: tipo no válido para el argumento en la llamada a la función. Conversión implícita no válida de function (uint256) pure returns (uint256)a function (uint256) view returns (uint256)solicitada.

Cosas que he probado:

Asignar la función a una variable local da un TypeError similar:

function(uint256) view returns(uint256) a = func;

TypeError: el tipo function (uint256) pure returns (uint256)no se puede convertir implícitamente al tipo esperadofunction (uint256) view returns (uint256)

La sintaxis habitual de conversión de tipos de Solidity da un ParserError en la functionpalabra clave

function(uint256) view returns(uint256) a = function(uint256) view returns(uint256)  (func);

ParserError: Expresión primaria esperada

-------

Me di cuenta de que TypeError sigue diciéndome que el puntero de función no es implicitlyconvertible. ¿Hay alguna manera de convertirlo explícitamente?

¿Qué operación quieres hacer que este trabajo es necesario para ello?
Tengo una función de orden superior que toma una viewfunción como parámetro. Quiero pasarle una purefunción.
La pregunta principal es que operación te hace pasar una función como parámetro a otra función? ¿No es posible hacerlo con métodos ordinarios?
Sí, podría alinear el código de mi función de orden superior donde sea que se llame, pero no quiero duplicar ese código en todas partes. Mi situación es: tengo un token no fungible con un montón de propiedades calculadas dinámicamente (implementadas como vistas o funciones puras). Algunas de esas propiedades son en realidad solo combinaciones de otras propiedades. Por ejemplo, la propiedad G puede ser verdadera solo si ((A o B) y (C+D+E+F >= 6)) es verdadera. Para calcular GI no necesariamente necesito todo AF, por lo que combino las funciones de propiedad usando funciones de orden superior que implementan un comportamiento de atajo.

Respuestas (2)

Actualización: en las versiones recientes de Solidity, los punteros de función puros ahora se pueden convertir implícitamente para ver los punteros de función.

No encontré una solución a este problema, así que envié un problema en Github: https://github.com/ethereum/solidity/issues/4349

Encontré dos formas de solucionar el problema:

1: Degradar todas mis funciones puras para ver.

2: use el ensamblaje en línea para asignar a una variable local, eludiendo así el sistema de tipo Solidity:

function(uint256)view returns(uint256) a;
assembly { a := func }

No puedo entender tu punto.

En solidity no existen punteros de función, porque el mecanismo de llamada es pasar el control al contrato inteligente que posee la función y usar la tabla ABI para saltar allí a la primera instrucción de la función.

¡Así que no hay un puntero a una función que pueda usar como lo hace en C!

En Solidity la dirección de cualquier función ES la dirección ethereum de su contrato inteligente

Es decir, de forma cualitativa, la dirección (función foo()) es la dirección del contrato inteligente que implementa foo()

¡Puede ser que no entendí bien tu pregunta!


EDITAR DESPUÉS DE LOS COMENTARIOS

Typecast no se puede aplicar al tipo de función, que yo sepa, solo se puede realizar una conversión implícita y esta ES la demostración de que el puntero de función como lvalue NO EXISTE.

De documentos de solidez:

"Un valor de tipo de función externa se puede convertir explícitamente en dirección, lo que da como resultado la dirección del contrato de la función.

Una función tipo A es implícitamente convertible a una función tipo B si y solo si sus tipos de parámetros son idénticos, sus tipos de devolución son idénticos, su propiedad interna/externa es idéntica y la mutabilidad de estado de A no es más restrictiva que la mutabilidad de estado de B. En particular:

Las funciones puras se pueden convertir en funciones de visualización y funciones no pagables. Las funciones de visualización se pueden convertir en funciones no pagables. Las funciones de pago se pueden convertir en funciones no pagables.

No son posibles otras conversiones entre tipos de funciones. "

De todos modos, si estamos aquí para aprender, entonces espero aprender algo nuevo de usted pronto.

Compruebe también la función como parámetro

Está hablando de funciones externas, mi pregunta es sobre punteros de función para funciones internas. Para esos, ciertamente hay punteros a funciones internas como en C.
Sí, existen direcciones locales iguales a la primera instrucción de cualquier función, pero no puedes extraerlas por lenguaje de alto nivel (Solidity), ¡ni usar encasillado sobre ellas!
Supongamos que tiene una función pura interna: function testFunc(uint256 x) internal pure returns (uint256 y) { return x+5; }ahora puede colocar su puntero de función en una variable local con el tipo apropiado: function(uint256) internal pure returns (uint256) func = testFunc;y puede llamar a la función a través de su puntero de función:func(345)
Mi pregunta es sobre la capacidad de emitir un puntero de función de tipo function (uint256) internal pure returns (uint256)a tipo function (uint256) internal view returns (uint256). ¿Entiendes ahora?
Además, por favor, no hables con tanta certeza sobre algo que no sabes. Es muy grosero.
Estás en la parte equivocada de la colina. Edito la respuesta para agregar lo que sé.
Cuando hice la pregunta, no fue posible realizar conversiones entre tipos de punteros de función, ni siquiera conversiones implícitas. Creé un problema de github y envié una solicitud de extracción. Se implementó y ahora los punteros de función puros se pueden convertir implícitamente para ver funciones. (Escribí el código que agregó esa característica) No entiendo en qué colina crees que estoy en el lado equivocado.
No entiendo tu punto. ¿Está preguntando sobre la conversión explícita (es decir, por encasillado) o sobre la conversión implícita (es decir, sin encasillado)? No creo que el puntero de función sea un ivalue. ¿Lo es?