5

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.

  • Since you're using a private chain, not sure if this helps: ethereum.stackexchange.com/questions/1607/… – eth Nov 3 '16 at 1:40
  • Thank you! We already tried that; should have added to the original post. Unfortunately, it did not solve the issue / change results. – Jacob Eberhardt Nov 3 '16 at 8:32
  • There is also no problem to call a function in a mined contract by its address in the way shown above. But when you are using normal contracts, the name of the interface function (foo) has to be identical to the name in the normal contract because the name is part of the signature. – Kyroy Nov 3 '16 at 15:05
1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.