Tengo una función que hace uso de la hora actual ( now
). El Contrato en su conjunto es un token de Crowdfunding y el costo de los tokens difiere según la fecha y la hora en que se compran.
¿Cómo se simulan diferentes momentos al probar un contrato inteligente? Por ejemplo, con respecto al código a continuación, me gustaría realizar pruebas unitarias para averiguar si el código para establecer el precio es correcto, pero no puedo cambiar el valor de now
.
¿Sería una buena solución simplemente sustituir la now
palabra clave por otra variable de prueba temporal, por ejemplo, now_sim
y luego cambiarla manualmente now_sim
durante la simulación?
if (now < (startTime + 1 days)) {
currentPrice = safeDiv(safeMul(price, 80), 100); // 20 % discount (x * 80 / 100)
}
else if (now < (startTime + 2 days)) {
currentPrice = safeDiv(safeMul(price, 90), 100); // 10 % discount (x * 90 / 100)
}
else if (now < (startTime + 12 days)) {
// 1 % reduction in the discounted rate from day 2 until day 12 (sliding scale per second)
// 8640000 is 60 x 60 x 24 x 100 (100 for 1%) (60 x 60 x 24 for seconds per day)
currentPrice = price - safeDiv(safeMul((startTime + 12 days) - now), price), 8640000);
}
else {
currentPrice = price;
}
En general, sí, probablemente sea mejor establecer valores estáticos para todas las variables de prueba importantes.
En el contrato, now
es el block.timeStamp
.
Este sello de tiempo es aproximado en la práctica, con variaciones de hasta quince minutos.
Consultaría el contrato o blockchain para obtener el tiempo que realmente se usó.
En situaciones similares, he tenido la prueba esperando un bloque minado con una marca de tiempo más allá de un tiempo que estoy esperando. Puedo ver cómo esto será un problema si tiene que esperar 12 días.
Podría ser bueno desglosar y parametrizar los hitos para que pueda probar con intervalos más pequeños, de modo que todo pueda pasar todas las pruebas en uno o dos minutos. Posiblemente no satisfactorio para una prueba "final", pero suficiente para las pruebas iniciales.
Espero eso ayude.
Si usa pyethereum para realizar pruebas, lo cual recomiendo encarecidamente, es encantador, puede modificar directamente la marca de tiempo del bloque simulado que está minando su transacción.
self.s = t.state()
self.s.block.timestamp = self.s.block.timestamp + 86400
self.s.mine(1)
some_val = your_contract.do_something(some_parameter)
self.assertEqual(some_val, whatever)
Vea un ejemplo de trabajo aquí (quizás un poco desactualizado): https://github.com/realitykeys/subjectivocracy/blob/master/contracts/test.py#L85
Rob Hitchens
RFV
evm_increaseTime
sería la mejor opción para simular diferentes tiempos.RFV
evm_increaseTime
desde la consola de truffle. ¿Tal vez no puedes ayudar?Rob Hitchens