[Ethereum] How to call the precompiled contracts from the contract

contract-debuggingcontract-invocationparityprecompiled-contractssolidity

I am trying to call one of the precompiled contracts from my contract. In this case, it is the ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address) function with the address 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);
  }

}

When commenting out the line last = prec.foo("\x00", uint8(0), "\x00", "\x00"); everything works fine and the Debug event is fired.

But when using the code as is, strange things happen.
The transaction is send and mined! BUT the Debug event is NOT fired.
Web3 also returns the transaction hash. Example Parity mining:

2016-11-02 16:24:28  Imported #176 ffbe…53cd (1 txs, 0.94 Mgas, 6.53 ms, 0.65 KiB)

I am using Parity and a private chain with the following genesis block: https://gist.github.com/Kyroy/741a275a7af7b60ae66dc59d27089dcd

I compiled the contract with the online compiler https://ethereum.github.io/browser-solidity/
and use a slightly modified version.
(Adding the myContract variable and the starting 0x to the data field)

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;
    }
 })

After the contract is mined, I use the following commands to listen for the event and call the function:

var evt = myContract.Debug(function (err, data) { console.log('Debug', err, data); });
myContract.testMe({from: web3.eth.accounts[1]});

I also tried to:

Build Parity myself with println! in the precompiled functions to test if they are called. They are not.
But when using sha256(..) my outputs appear on the console.

Use sha256(..) before and after last = prec.foo("\x00", uint8(0), "\x00", "\x00");.
The first line is executed and I see the output on the console.
But the line after the precompiled contract call is NOT executed.

Best Answer

The solution for this problem is quite simple. Use solc v0.3.6!

In solc v0.4.0 they added:

Function call throws if target contract does not have code

There is no code at the addresses of the precompiles, since they are directly handled in the clients, so this test fails. I do not know why my execution does not fail, though.

Related Topic