wallet precio etherscan criptomoneda ethereum solidity smartcontracts

precio - ¿Cómo saber si una dirección de Ethereum es un contrato?



ethereum wallet (6)

Edición: la solidez ha cambiado desde que esta respuesta se escribió por primera vez, @ manuel-aráoz tiene la respuesta correcta.

En la solidez no hay forma de verificar si una dirección es un contrato. Uno de los objetivos de Ethereum es que los humanos y los contratos inteligentes sean tratados por igual. Esto lleva a un futuro en el que los contratos inteligentes interactúan a la perfección con los humanos y otros contratos. Podría cambiar en el futuro, pero por ahora una dirección arbitraria es ambigua.

Una dirección en Solidity puede ser una cuenta o un contrato (u otras cosas, como una transacción). Cuando tengo una variable x, que tiene una dirección, ¿cómo puedo probar si es un contrato o no?

(Sí, he leído el capítulo sobre tipos en el documento)


Esto no es algo que pueda consultar dentro de un contrato usando Solidity, pero si solo desea saber si una dirección contiene el código del contrato o no, puede verificar usando su consola geth o similar con, por ejemplo:

> eth.getCode("0xbfb2e296d9cf3e593e79981235aed29ab9984c0f")

con la cadena hexadecimal (aquí 0xbfb2e296d9cf3e593e79981235aed29ab9984c0f ) como la dirección que desea consultar. Esto devolverá el código de bytes almacenado en esa dirección.

También puede usar un escáner de blockchain para encontrar el código fuente del contrato en esa dirección, por ejemplo, la biblioteca ecsol como se muestra en etherscan.io .


Lo que usted puede hacer, siempre que tenga la información a mano. Si la dirección del remitente de la transacción era nula o estaba desocupada, puede saber si la dirección es una cuenta de contrato o una EOA (cuenta de propiedad externa). es decir, cuando se envía una transacción de creación de contrato en la red, la dirección de recepción en la transacción es nula / no se utiliza.

Referencia de github: https://github.com/ethereum/go-ethereum/wiki/Contracts-and-Transactions

Espero que esto ayude.


Respuesta corta:

require(tx.origin == msg.sender);

tx.origin es una referencia de la dirección original que inicia esta llamada de función en serie, mientras que msg.sender es la dirección que llama directamente a la función de destino. Lo que significa que tx.origin debe ser un humano, msg.sender puede ser un contrato o un humano. Por lo tanto, si alguien lo llama desde un contrato, el msg.sender es una dirección de contrato que es diferente de tx.origin.

Sé que la mayoría de los contratos pueden usar el código de @Manuel Aráoz, que funciona en la mayoría de los casos. Pero si llama a una función dentro del constructor de un contrato, extcodesize devolverá 0, lo que falla la comprobación de isContract.

NOTA: NO use tx.origin en otras circunstancias si no tiene claro lo que representa porque.


Sí, puede usar un código de ensamblaje EVM para obtener el tamaño del código de la dirección:

function isContract(address addr) returns (bool) { uint size; assembly { size := extcodesize(addr) } return size > 0; }


La respuesta más votada con la función isContract que utiliza EXTCODESIZE se descubrió como hackeable.

La función devolverá false si se invoca desde el constructor de un contrato (porque el contrato aún no se ha implementado).

El código debe usarse con mucho cuidado, si es que lo hace, para evitar ataques de seguridad como:

https://www.reddit.com/r/ethereum/comments/916xni/how_to_pwn_fomo3d_a_beginners_guide ( hackable )

Para repeat

No utilice la verificación EXTCODESIZE para evitar que los contratos inteligentes llamen a una función. Esto no es infalible, puede ser subvertido por una llamada de un constructor, debido a que mientras el constructor se está ejecutando, EXTCODESIZE para esa dirección devuelve 0.

Consulte el código de muestra para un contrato que trucos EXTCODESIZE para devolver 0.

Si desea asegurarse de que un EOA está llamando a su contrato, se require(msg.sender == tx.origin) una forma simple require(msg.sender == tx.origin) . Sin embargo, la prevención de un contrato es un anti-pattern con consideraciones de security e interoperability .

Esto requerirá una revisión cuando se implemente la abstracción de la cuenta.