Empujar la dirección a la matriz de otro contrato devuelve TypeError: Miembro "push" no encontrado o no visible después de la búsqueda dependiente del argumento en la función

Contrato User.sol tiene una función requestValidationque interactúa con otro contrato. Su propósito es insertar la dirección del propietario del contrato de User.sol en la matriz pendingRequests, almacenada en el otro contrato (TrustEntity.sol).

Contrato Usuario.sol

pragma solidity ^0.4.11;
import "browser/TrustEntity.sol";

contract User {
    // State variables
    // The contract address for the TrustEntity
    TrustEntity trustEntity;
    address owner = msg.sender;
    bool verified = false;
    uint creationTime = now;
    uint level = 0;

    // Set trustEntity's deployed contract address
    function User(address _trustEntity) {
        trustEntity = TrustEntity(_trustEntity);
    }

    function requestValidation() {
        trustEntity.pendingRequests.push(owner);
    }
}

Contrato TrustEntity.sol

pragma solidity ^0.4.11;
import "browser/User.sol";

contract TrustEntity {
    address owner;
    address registry;
    address[] public pendingRequests;

    function verifyUsers() {
        /*
        Whenever a user requests verification, his
        address should be pushed to the pendingRequests
        array, so it can then be fetched to verify or
        reject
        */
    }   
}

Remix me da el siguiente mensaje de error:

browser/User.sol:19:6: TypeError: Member "push" not found or not visible after argument-dependent lookup in function (uint256) constant external returns (address)
        trustEntity.pendingRequests.push(owner);
        ^------------------------------^

Intenté ingresar a una matriz almacenada en el contrato, que funciona. Al igual que

pragma solidity ^0.4.11;
import "browser/TrustEntity.sol";

contract User {
    // State variables
    // The contract address for the TrustEntity
    TrustEntity trustEntity;
    address owner = msg.sender;
    bool verified = false;
    uint creationTime = now;
    uint level = 0;
    address[] public pendingRequests;

    // Set trustEntity's deployed contract address
    function User(address _trustEntity) {
        trustEntity = TrustEntity(_trustEntity);
    }

    function requestValidation() {
        pendingRequests.push(owner);
    }
}

así que no entiendo por qué no funcionaría para otro contrato. ¿Está relacionado con tener ETH para pagar una transacción, ya que es una función que altera el estado?

No puedo ingresar a una matriz almacenada en el contrato en 0.6.0 como pudiste hacer en ^ 0.4.11

Respuestas (1)

Los contratos no obtienen acceso de escritura en el estado de los demás. El publicmodificador solo significa que el valor es legible. Suponiendo que usted es el desarrollador de TrustEntity, puedo sugerirle un par de opciones:

  1. Elimine el contrato de usuario por completo, almacenando toda la información sobre los usuarios en el contrato de TrustEntity.
  2. Escriba un "establecedor" en TrustEntity, como TrustEntity.pushPending(address)(con los controles de cuenta apropiados para evitar el acceso de escritura global)

En mi opinión, el primero es el uso más estándar, basado en su objetivo aparente. Por ejemplo, los contratos de token suelen almacenar toda la información sobre los propietarios del token de forma centralizada, en lugar de agregar contratos separados para cada usuario.

La opción dos agrega una gran cantidad de costos de gas e hinchazón de blockchain, y agrega más área de superficie para errores de seguridad.

Eso funcionó, saludos! Elegí la opción 2 porque necesito muchas otras funciones en el contrato de usuario y me gustaría mantener esas 2 separadas. Además, es una aplicación de juguete, por lo que funcionará por ahora.