Me gustaría saber si es posible cambiar la dirección del remitente del mensaje de llamada de función del contrato al escribir pruebas unitarias en solidez. Realmente debería serlo, estaba tratando de averiguar cómo pero no pude.
pragma solidity ^0.4.4;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
contract A {
event Test(address add);
function test() {
Test(msg.sender);
}
}
contract TestA {
function test01() {
A a = A(DeployedAddresses.A());
a.test(); // <--- msg.sender is address(this), but how do we use a different account from testrpc?
}
}
En gitter obtuve una respuesta, así que intenté ejecutarlo así:
a.test({from: 0xf6a948bff792e4f42d7f17e5e4ebe20871d160f2});
Da el siguiente error:
TypeError: Wrong argument count for function call: 1 arguments given but expected 0. a.test({from: 0xf6a948bff792e4f42d7f17e5e4ebe20871d160f2});
Sistema operativo: Windows 10 Truffle versión: v3.4.11 Cliente Ethereum: testrpc v4.1.3 versión de nodo: v8.7.0 npm versión: 5.4.2
No puede cambiar la dirección del remitente desde Solidity. Las pruebas de solidez se ejecutan dentro de la EVM y no permite modificar el msg.sender. Es posible que una versión modificada de EVM proporcione dicha funcionalidad, pero no estoy al tanto de dicha modificación.
Puede modificar la función para probar para aceptar un parámetro adicional y pasar allí el remitente que desee
contract A {
// We cannot test directly deposit
function deposit(uint _amount) public {
doDeposit(msg.sender, _amount);
}
// But we can test doDeposit
function doDeposit(address _sender) public {
}
}
contract TestA {
address constant senderA = "0xA00...";
address constant senderB = "0xB00...";
function testDeposit() {
A a = A(DeployedAddresses.A());
a.doDeposit(senderA, 10000);
a.doDeposit(senderB, 10000);
}
}
No es ideal, pero puede ayudar a encontrar algunos errores.
Otra opción es usar la dirección del contrato de prueba
contract TestA {
address constant senderA = "0xA00...";
address constant senderB = "0xB00...";
function testMint() {
// TestA is the owner a
A a = new A(this);
// Only the owner TestA can mint
a.mint(senderA, 10000);
// make senderA approve TestA
a.doApprove(senderA, this, 1000);
// testA can make a transfer from senderA
a.transferFrom(senderA, senderB, 1000);
}
}
Dado que tiene un contrato (TestA) que llama a una función de otro contrato (A), msg.sender siempre será la dirección de TestA en la función de prueba de A, porque, para el contrato A, la dirección que envió el mensaje fue TestA.
Si desea registrar la dirección real que llamó a la función originalmente, tendría que hacer lo siguiente:
pragma solidity ^0.4.4;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
contract A {
event Test(address add);
function test(address _sender) {
Test(_sender);
}
}
contract TestA {
function test01() {
A a = A(DeployedAddresses.A());
a.test(msg.sender);
}
}
Aquí hay un enfoque alternativo que he estado usando de manera efectiva para manipular msg.sender
pruebas unitarias escritas en solidez:
SenderContract
y a ReceiverContract
, cada uno tendrá su propia dirección y cuando llamen, las funciones CUT msg.sender
se establecerán en sus direcciones implementadas.msg.sender
contendrá la dirección del contrato del actor en estas llamadas)
Marko Jakovic
ismael
onlyTest
modificador que verifica unatest
variable, pero es muy feo.momoja
ismael
momoja