Estoy tratando de llamar a uno de los contratos precompilados de mi contrato. En este caso, es la ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)
función con la dirección 0x0..01.
pragma solidity ^0.4.3;
contract Precompile {
function foo (bytes32, uint8, bytes32, bytes32) returns (address);
}
contract Testcontract {
address last = 0x0;
event Debug(string message, address res);
Precompile prec = Precompile(0x0000000000000000000000000000000000000001);
function testMe () {
last = prec.foo("\x00", uint8(0), "\x00", "\x00");
Debug("testMe()", last);
}
}
Al comentar la línea, last = prec.foo("\x00", uint8(0), "\x00", "\x00");
todo funciona bien y el Debug
evento se dispara.
Pero cuando se usa el código tal como está, suceden cosas extrañas. ¡La transacción se envía y se extrae! PERO el Debug
evento NO se dispara. Web3 también devuelve el hash de la transacción. Ejemplo de minería de paridad:
2016-11-02 16:24:28 Imported #176 ffbe…53cd (1 txs, 0.94 Mgas, 6.53 ms, 0.65 KiB)
Estoy usando Parity y una cadena privada con el siguiente bloque de génesis: https://gist.github.com/Kyroy/741a275a7af7b60ae66dc59d27089dcd
Compilé el contrato con el compilador en línea https://ethereum.github.io/browser-solidity/ y utilicé una versión ligeramente modificada. (Agregando la myContract
variable y el inicio 0x
al data
campo)
var testcontractContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"testMe","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"message","type":"string"},{"indexed":false,"name":"res","type":"address"}],"name":"Debug","type":"event"}]);
var testcontract = testcontractContract.new(
{
from: web3.eth.accounts[0],
data: '0x60606040526000600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690836c010000000000000000000000009081020402179055506001600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690836c010000000000000000000000009081020402179055506102068061008e6000396000f360606040526000357c010000000000000000000000000000000000000000000000000000000090048063524158401461003c57610037565b610002565b346100025761004e6004805050610050565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663debc39516000600060405160200152604051827c0100000000000000000000000000000000000000000000000000000000028152600401808060008152602001506020018260ff168152602001806000815260200150602001806000815260200150602001915050602060405180830381600087803b156100025760325a03f1156100025750505060405180519060200150600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690836c010000000000000000000000009081020402179055507f14186b8ac9c91f14b0f16f9e886356157442bb899be26513dfe1d4d5929a5bac600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660405180806020018373ffffffffffffffffffffffffffffffffffffffff168152602001828103825260088152602001807f746573744d6528290000000000000000000000000000000000000000000000008152602001506020019250505060405180910390a15b56',
gas: 4700000
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
myContract = contract;
}
})
Después de extraer el contrato, uso los siguientes comandos para escuchar el evento y llamar a la función:
var evt = myContract.Debug(function (err, data) { console.log('Debug', err, data); });
myContract.testMe({from: web3.eth.accounts[1]});
También traté de:
Compilé Parity yo mismo con println!
las funciones precompiladas para probar si se llaman. Ellos no son. Pero al usar sha256(..)
mis salidas aparecen en la consola.
Usar sha256(..)
antes y después last = prec.foo("\x00", uint8(0), "\x00", "\x00");
. La primera línea se ejecuta y veo la salida en la consola. Pero la línea después de la llamada del contrato precompilado NO se ejecuta.
La solución a este problema es bastante simple. ¡Utilice solc v0.3.6!
En solc v0.4.0 agregaron:
La llamada de función se lanza si el contrato de destino no tiene código
No hay código en las direcciones de los precompilados, ya que se manejan directamente en los clientes, por lo que esta prueba falla. Sin embargo, no sé por qué mi ejecución no falla.
ética
jacob eberhardt
Kyroy
foo
) tiene que ser idéntico al nombre en el contrato normal porque el nombre es parte de la firma.