onlyOwner y pregunta de prueba

Tengo problemas con este modificador y con uno que me gustaría usar para otros contratos. Me imagino que si entiendo por qué esto es un problema, probablemente pueda hacer el resto correctamente.

ingrese la descripción de la imagen aquí

Puedo compilar, migrar (que también inserta un registro) y probar, pero si uso el modificador onlyOwner, funciona para el registro de migración pero falla en la inserción del registro de prueba. ¿Por qué? ¿La prueba de trufas no usa la misma cuenta que la implementación? y si es así, ¿no debería funcionar?

ingrese la descripción de la imagen aquí

El modificador que quiero para los otros contratos es algo como esto:
modificador (no funciona del todo):

// modifiers  
/**
* @dev Modifer onlyBy for Access Control
*/
modifier onlyBy(address _credentialOrgAddress){
    uint32 foundAccount = 0;
    CredentialOrgFactory cof = CredentialOrgFactory(credentialOrgContractAddress);
    if (cof.isCredentialOrg(_credentialOrgAddress)){
        foundAccount = 1;
    }
    require(foundAccount == 1, "Not Credentialing Org");
    _;
}

código de solidez:

pragma solidity ^0.4.21;  

/**
 * @title CredentialOrgFactory
 * @dev The CredentialOrgFactory allows the contract owner to add new credentialing orgs  */  
import "./Pausable.sol";  
import "./SafeMath32.sol";  

contract CredentialOrgFactory is Pausable {

/**
*  @dev Library useage for safemath for uint32
*/
using SafeMath32 for uint32;

/**
* @dev mappings
*/
mapping(address => CredentialOrg) addressToCredentialOrg;

/**
* @dev events for contract
* One for the create CredentialOrg and one for the basic 'logging'.
*/
event CredentialOrgCreateEvent(string shortName, address schoolAddress, string detail);
event CredentialOrgEvent(address schoolAddress, string detail);

/**
* @dev CredentialOrg Count
*/
uint32 private credentialOrgCount;

/**
* @dev Primary CredentialOrg structure, and following array.
*/
struct CredentialOrg {
    string shortName;          // School shortName (len 30)
    string officialSchoolName; // official school shortName (70 or less)
    address schoolAddress;
}

CredentialOrg[] private credentialOrgs; // array to hold Credentialing Orgs

/**
* @dev class constructor
*/
constructor() public {
    credentialOrgCount = 0;
}

// functions
function getOwner()
public view
returns (address returnedOwner)
{
    returnedOwner = owner;
}

/**
* @dev allows owner to create new credentialing orgs
* @param _shortName shortName of Credentialing orgs
* @param _officialSchoolName official School Name
* @param _schoolAddress address of credential org.
* @return createStatus bool noting creation status success or failure
*/
function createCredentialOrg(string _shortName, string _officialSchoolName, address _schoolAddress) //onlyOwner
public 
returns (bool createStatus)
{
    emit CredentialOrgCreateEvent(_shortName, _schoolAddress, "New Org Add (PRE)");
    require(bytes(_shortName).length > 0 && bytes(_shortName).length < 31, "createCredentialOrg shortName problem");
    require(bytes(_officialSchoolName).length > 0 && bytes(_officialSchoolName).length < 70, "createCredentialOrg officalSchoolName length problem");
    require(_schoolAddress != 0, "createCredentialOrg (FAIL) school Address can not be 0");
    createStatus = false;
    uint32 position = uint32(credentialOrgs.push(CredentialOrg(_shortName, _officialSchoolName, _schoolAddress)));
    if (position > 0){
        addressToCredentialOrg[_schoolAddress] = credentialOrgs[position.sub(1)];
        credentialOrgCount = credentialOrgCount.add(1);
        createStatus = true;
        emit CredentialOrgCreateEvent(_shortName, _schoolAddress, "createCredentialOrg (SUCCESS)");
    } else {
        emit CredentialOrgCreateEvent(_shortName, _schoolAddress, "createCredentialOrg (FAIL)");
    }
    return (createStatus);
}

/**
* @dev allows selection of a credentialingOrg by position
* @param _credentialOrgPosition allows selection of credentialing orgs details.
* @return shortName - shortName of Credential Org
* @return officialSchooName - official school name
* @return school -the schools ethereum address 
*/
function selectCredentialOrgByPosition(uint32 _credentialOrgPosition) 
public view 
returns (string shortName, string officialSchoolName, address schoolAddress)
{
    shortName = "";
    officialSchoolName = "";
    schoolAddress = 0;
    require(_credentialOrgPosition >= 0, "selectCredentialOrg - position had to be greater or equal to 0.");
    if (_credentialOrgPosition < credentialOrgCount){
        emit CredentialOrgEvent(msg.sender, "selectCredentialOrg~position - (SUCCESS)");
        return (credentialOrgs[_credentialOrgPosition].shortName, credentialOrgs[_credentialOrgPosition].officialSchoolName, credentialOrgs[_credentialOrgPosition].schoolAddress);
    } else {
        emit CredentialOrgEvent(msg.sender, "selectCredentialOrg~position - (FAIL) top boundry exceeded.");
        return (shortName, officialSchoolName, schoolAddress);
    }
}

/**
* @dev allows selection of a credentialingOrg by address
* @param _credentialOrgAddress allows selection of credentialing orgs details.
* @return shortName - shortName of Credential Org
* @return officialSchooName - official school name
* @return school -the schools ethereum address 
*/
function selectCredentialOrgByAddress(address _credentialOrgAddress) 
public view 
returns (string shortName, string officialSchoolName, address schoolAddress)
{
    require(_credentialOrgAddress != 0, "selectCredentialOrg - Address 0 not valid");
    CredentialOrg memory testCred = addressToCredentialOrg[_credentialOrgAddress];
    if (testCred.schoolAddress != 0){
        emit CredentialOrgEvent(msg.sender, "selectCredentialOrg~address - (SUCCESS)");
        return (testCred.shortName, testCred.officialSchoolName, testCred.schoolAddress);
    } else {
        emit CredentialOrgEvent(msg.sender, "selectCredentialOrg~address - (FAIL)");
        return ("", "", 0);
    }
}

/**
* @dev allows checking if credentialOrg exists
* @param _credentialOrgAddress function returns bool if an address is a credentialingOrg
* @return isAddress returns true if address is Credentialing Org, false if not.
*/
function isCredentialOrg(address _credentialOrgAddress) 
public view
returns (bool isOrgAddress)
{
    isOrgAddress = false;
    CredentialOrg memory testCredentialOrg = addressToCredentialOrg[_credentialOrgAddress];
    if (testCredentialOrg.schoolAddress != 0){
        isOrgAddress = true;
        emit CredentialOrgEvent(msg.sender, "isCredentialOrg - (SUCCESS)");
    } else {
        emit CredentialOrgEvent(msg.sender, "isCredentialOrg - (FAIL)");
    }
    return (isOrgAddress);
}

/**
* @dev returns the credentialOrgCount
* @return returnOrgCount - returns the total credential orgs count
*/
function selectOrgCount()
public view
returns (uint32 returnOrgCount)
{
    returnOrgCount = credentialOrgCount;
    emit CredentialOrgEvent(msg.sender, "selectOrgCount - (SUCCESS)");
    return (returnOrgCount);
}

}
¿Qué estás haciendo en las pruebas fallidas?
creando una credencialOrg. Actualicé el repositorio de git para demostrarlo, comentando todo excepto el primer contrato. La única variación en las pruebas es el modificador onlyOwner. [ github.com/shaddow1201/CredentialVerify] (GitHubLink al proyecto) aquí está la configuración de ganache: screencast.com/t/3p9dlHeDI y errores detallados: screencast.com/t/9lpwXtiE0

Respuestas (1)

El problema es que sus pruebas están en solidez y cada prueba es una función en contrato TestCredentialOrgFactory, y su prueba testInsertCredentialOrgestá llamando a una función enCredentialOrgFactory

function testInsertCredentialOrg() public {
    // ... Here msg.sender is web3.eth.accounts[0]
    testVal = credentialOrgFactory.createCredentialOrg(...);

}

Dentro testInsertCredentialOrgdel remitente está la dirección predeterminada de su nodo (generalmente la primera cuenta creada), es decir, el propietario o creador de CredentialOrgFactory.

Llamas credentialOrgFactory.createCredentialOrg()dentro de un contrato, esto cambia el remitente al contrato de llamadaTestCredentialOrgFactory

function createCredentialOrg(string _shortName, ...) 
public onlyOwner
returns (bool createStatus)
{
    // ... Here msg.sender is TestCredentialOrgFactory
}

Hay dos soluciones posibles

  1. Vuelva a escribir su prueba en javascript, podrá cambiar quién envía la transacción.

    Esta es la solución más flexible a menos que tenga muchas pruebas.

  2. Crea una instancia de tu contrato dentro de tu prueba

    function testInsertCredentialOrg() public {
        // The owner of credentialOrgFactory is TestCredentialOrgFactory
        CredentialOrgFactory credentialOrgFactory = new CredentialOrgFactory(...)
    
        // This call should succeed because the owner is TestCredentialOrgFactory
        testVal = credentialOrgFactory.createCredentialOrg(...);
    
    }
    

    Si su contrato necesita mucha gasolina para implementar su prueba, es posible que no le quede suficiente para ejecutarse.

trabajará en eso ahora. agradecer. Esperaba tener que eventualmente seguir la ruta de JS para las pruebas, pero esperaba mantener el conjunto de trabajo lo más pequeño posible al menos hasta la finalización de la clase. No había considerado instanciar dentro de la prueba, lo intentaré primero. Puedo salirme con la mía sin tener onlyOwner en el contrato CredentialOrgFactory, pero no los otros contratos que usarán isCredentialOrg para el control de acceso.
¡eso funciono! agregado: // pruebas regulares CredentialOrgFactory credentialOrgFactoryA = CredentialOrgFactory(DeployedAddresses.CredentialOrgFactory()); // onlyOwner prueba CredentialOrgFactory credentialOrgFactoryB = new CredentialOrgFactory();