Tengo 2 contratos, Usuario y Registro, interactuando y quiero probar sus interacciones con Truffle. Actualmente mi(s) prueba(s) para Usuario son
contract('User', function(accounts) {
// many tests here which only depend on User contract
})
Ahora quiero probar la interacción entre el contrato de usuario y un contrato de registro. Las partes relevantes de cada uno son
Usuario.sol
pragma solidity ^0.4.11;
import "./Registry.sol";
contract User {
address owner;
address reg;
bool verified;
Registry registry = Registry(reg);
// Register in the system
function register(bytes32 _id)
onlyOwner
{
registry.register(_id);
}
function getContractAddress(bytes32 _id)
onlyOwner
{
registry.getContractAddress(_id);
}
function getPublicAddress(bytes32 _id)
onlyOwner
{
registry.getPublicAddress(_id);
}
function verify()
onlyReg
{
verified = true;
}
}
Registro.sol
pragma solidity ^0.4.11;
import "./User.sol";
contract Registry {
mapping(bytes32 => address) ID;
mapping(address => address) Contract;
function register(bytes32 _id) {
ID[_id] = tx.origin;
Contract[tx.origin] = msg.sender;
}
function getPublicAddress(bytes32 _id) constant returns (address) {
return (ID[_id]);
}
function getContractAddress(bytes32 _id) constant returns (address) {
return Contract[ID[_id]];
}
function verify() {
User requester = User(msg.sender);
requester.verify();
}
}
¿Cómo puedo escribir una prueba en la que se implementa el Registro para poder probar register()
, getContractAddress()
etc.?
Revisé los documentos pero no encontré ejemplos allí.
EDITAR: solo para complementar la respuesta que se dio
agregué esto
contract('User', function(accounts) {
var user
var registry // new part based on your answer
Registry.new().then((inst) => {
registry = inst;
})
// Check contract was deployed
it("Should retrieve deployed contract", function(done) {
// test
})
Funciona y más abajo tengo una prueba para establecer/obtener la dirección de registro que funciona bien (lo que significa que cuando llamo a un método en el contrato, la dirección ya está allí). El problema está en esta prueba.
// Should not find user
it("Should not find user", function(done) {
patient.getPublicAddress(web3.fromAscii("123456789"), {from:accounts[0], to:patient.address})
.then(function(res) {
assert.equal(res, 0);
done()
}, function(error) {
// Force an error if callback fails.
console.error(error)
assert.equal(true, false)
done()
})
})
regresa Error: VM Exception while processing transaction: invalid opcode
_ Hay esta pregunta aquí , pero no entendí cómo hacer que funcione desde allí (aunque hice públicas las asignaciones en el Registro).
Primero debe implementar el contrato de registro y luego el usuario.
Puede agregar un constructor al contrato de usuario para crear una instancia reg
con la dirección del contrato de registro.
Además, al hacer su mapeo global public
, el compilador de solidez creará automáticamente funciones getter, que serán necesarias para la prueba.
El constructor para Usuario se vería así:
function User(address _registry) {
reg = _registry;
}
En un archivo js para su prueba de trufas, puede comenzar escribiendo una cadena de promesas para cumplir con sus contratos. (Suponiendo que haya compilado y escrito migraciones para los contratos)
const Registry = artifacts.require('./Registry.sol')
const User = artifacts.require('./User.sol')
let registry
let user
let id = '0x...' // bytes 32 id
Registry.new().then((inst) => {
registry = inst
return User.new(registry.address)
}).then((inst) => {
user = inst
return user.register.call(id)
}).then((res) => {
return registry.ID.call(id)
}).then((res) => {
assert.equal(user.address, res)
})
mcansado
Error: VM Exception while processing transaction: invalid opcode
. He editado la pregunta para incluir eso.smatthewenglish