El modificador utilizado para verificar si un contrato llama a una función en Solidity utilizó el código ensamblador extsize
. Me pregunto por qué se hace esto. Usar ensamblador me parece muy "hackish" (¿por qué solidity no tiene una función 'normal' para verificar esto?). El código en cuestión es
modifier noContract(address _addr){
uint32 size;
assembly {
size := extcodesize(_addr)
}
require (size == 0);
_;
}
(editado de https://ethereum.stackexchange.com/a/15642/33191 )
¿Por qué no usarlo msg.sender == tx.orgin
como cheque? ¿Hay una laguna en esto?
¿La razón para usarlo es extsize
que esto podría usar (ligeramente) menos gas?
tx.origin
debe usarse en circunstancias EXTREMADAMENTE raras. Cuando verifica tx.origin
, está verificando de quién se originó la llamada, por lo que, si se usa incorrectamente, puede abrir vulnerabilidades extremas o posiblemente romper la funcionalidad de su contrato.
person a -> contract-a -> contract-b
si lo marca , se resolverá en la dirección de tx.origin
no en la dirección de . Si marca será .contract-b
person a
contract-a
msg.sender
contract-a
La razón por la que se usa el ensamblaje, como usted señala, es que actualmente no existe ninguna función integrada de solidez para manejar eso. Solidity es todavía un lenguaje bastante joven, por lo que no es sorprendente.
Solo hay algunas maneras en que esto puede suceder:
1) Específicamente funciones de programación o lógica que obliga al contrato a llamarse a sí mismo
2) Realización de llamadas a contratos desconocidos que pueden desencadenar la ejecución de código de respaldo
La opción 1 no es realmente un problema, ya que es muy fácil de controlar, pero la opción 2 puede exponerlo a intentos de piratería en su contrato, ya que el contrato desconocido al que está llamando podría implementar una función alternativa que desencadenaría llamadas a su contrato.
Creo que es mejor que su problema se resuelva al encontrar qué funciones permiten que el contrato se llame a sí mismo y cambie esas funciones, mientras elimina las llamadas a contratos desconocidos que podrían desencadenar la ejecución de código para el cual no sabe el resultado. Podría implementar alguna hechicería de ensamblaje para evitar que esto suceda, pero para mí eso suena como que lo abre a posibles vulnerabilidades.
tx.origin
dado que una llamada nunca puede originarse en una cuenta de contrato, siempre tiene que originarse en un EOA (al menos por ahora, hasta la abstracción de la cuenta). En realidad, nunca debería usarlo tx.origin
, es peligroso y debe usarse en circunstancias extremas. Parece que lo que está buscando se puede resolver mediante el rediseño del contrato, en lugar de intentar implementar una solución de pirateo.tx.origin
es buscar el remitente de la llamada, mientras que extcodesize
es buscar el tamaño del código almacenado. Creo que extcodesize con ensamblaje probablemente sería un poco más barato que usartx.origin
tx.origin
tiene algo de mala sangre ligada a su uso debido a que conduce a una serie de vulnerabilidades que conducen a hacks de alto perfil. Dicho esto, se trata de cómo implementa tx.origin
. ¡La mejor de las suertes!
Lauri Peltonen
JBrouwer
usuario19510
JBrouwer