Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

16 Días
9 Hrs
41 Min
15 Seg
Curso de Introducción a OpenZeppelin

Curso de Introducción a OpenZeppelin

Sebastián Leonardo Perez

Sebastián Leonardo Perez

Propiedad con Ownable

2/19
Recursos

Una necesidad muy frecuente en un contrato inteligente es poder controlar el acceso al contrato y restringir el mismo al dueño del contrato.

Propiedad de un contrato

Por lo general, la dirección que despliega el contrato se convierte en el owner del mismo. Puedes obtener la dirección de quién realice el despliegue con msg.sender, asignárselo a una variable y, con la misma, hacer la validación del dueño del contrato.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract MiContrato {

    address private owner;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Debes ser el owner del contrato para continuar");
        _;
    }

    function functionParaElOwner() public onlyOwner {}
}

Propiedad del contrato con OpenZeppelin

Al tratarse de un caso de uso muy trivial e importante, puedes utilizar una librería de OpenZeppelin para solucionarlo en menos líneas de código.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

import "@openzeppelin/contracts/access/Ownable.sol";

contract MiContrato is Ownable {

    function functionParaElOwner() public onlyOwner {}
}

Tu contrato hereda de Ownable para disponer del modificador onlyOwner. De esta forma, aseguras tu contrato a no cometer ningún error con respecto a la manipulación de su dueño.

Cambiar el dueño de un contrato

El contrato Ownable de OpenZeppelin trae consigo dos características más que pueden serte de utilidad en la lógica que tengas que desarrollar en tu propio contrato.

La primera es la posibilidad de cambiar el dueño del contrato. La función transferOwnership(address) recibe por parámetro una dirección y asignará la misma como nuevo owner del contrato.

Cabe destacar que solo el actual dueño del contrato puede llamar a esta función y ceder la propiedad del contrato.

La segunda característica es la posibilidad de que el dueño actual del contrato renuncie a este. La función renounceOwnership() le asignará un 0 a la variable que guarda la dirección del dueño del contrato, haciendo imposible su recuperación.

¡Ten cuidado!

Es importante tener cuidado con esta función, ya que el contrato podría quedar inutilizable si nadie es el owner del mismo.

Conclusión

Tener la posibilidad de que una sola cuenta ejecute determinadas acciones en un contrato puede llevar a centralizar el mismo. Impleméntalo en casos de uso donde verdaderamente una sola persona deba poder gestionarlo y tener un buen motivo para que así sea.

Sin embargo, administrar correctamente el owner de un contrato es crucial para evitar robos de fondos o identidades en un proyecto y utilizar contratos ya probados y auditados como lo es Ownable de OpenZeppelin es más que aconsejable hacerlo.


Contribución creada por: Kevin Fiorentino (Platzi contributor).

Aportes 5

Preguntas 5

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Revisando la librería, veo que al renunciar al owner lo que pasa es que se transfiere el owner del contrato a la dirección ‘0’, por lo que entiendo que en Solidity no se puede quedar un contrato sin owner, simplemente se le asigna a 0 para que ninguna dirección sea la dueña.

Es interesante porque a partir de ahí, sería imposible reasignar el owner si no se llama a la función desde la dirección “0”, elegante y sencillo.

Esas funciones para renunciar al owner se podrían usar por ejemplo si tenemos ciertos pasos previos a empezar la operación del contrato?

Digamos que hay una función que asigna tokens manualmente de acuerdo a un nivel de usuario, esto en una ICO o similar, una vez que terminó esa etapa se podría dejar al contrato trabajando en automático y para darle transparencia al asunto, inutilizar esa función de asignación manual renunciando al owner, de este modo el contrato trabajaría solo de acuerdo a las reglas programadas.

Es algo así o podría ser?

Muy buen inicio de curso, aplicando los aprendido durante las últimas clases del curso de introducción a solidity, larga vida a las clases y a la herencia

Éste es el contrato Ownable

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

Aunque peligroso el método que permite renunciar al contrato se puede utilizar como mecanismo de seguridad para dejar un contrato obsoleto, algo así como quemar el contrato si se sospecha que la cuenta del dueño del contrato fue robada.
¿También me pregunto qué otros usos o bajo qué circunstancias alguien quisiera renunciar a sus permisos dentro del contrato?
Igual que terrible si alguien accede a tu cuenta y renuncia a los permisos solo por hacerte daño…