In this Wormhole I am exploring the existing precompiled contract currently supported by the Ethereum clients. Not only I am going to review which are the contracts/functionalities supported but also, I’m going to research on when are they used, and how to call them.
I’m taking the opportunity to explore how gas calculations are made and if the MetaMask gasAPI is returning correct values for these type of calls.
Arguments to Perform External Calls
- gas : amount of gas to send to the sub context to execute. The gas that is
not used by the sub context is returned to this one. - address : the account which context to execute.
- value : value in wei to send to the account.
- argsOffset : byte offset in the memory in bytes, the calldata of the
sub context. - argsSize : byte size to copy (size of the calldata).
- retOffset : byte offset in the memory in bytes, where to store the return
data of the sub context. - retSize : byte size to copy (size of the return data).
List of Precompiled Contracts
In the Geth repository we can find the list of existing pre-compiled contracts and their addresses. For example, in the case we would like to call bn256Add, we would need to specify the contract address 0x06 and so on.
- common.BytesToAddress([]byte{1}): &ecrecover{},
- common.BytesToAddress([]byte{2}): &sha256hash{},
- common.BytesToAddress([]byte{3}): &ripemd160hash{},
- common.BytesToAddress([]byte{4}): &dataCopy{},
- common.BytesToAddress([]byte{5}): &bigModExp{},
- common.BytesToAddress([]byte{6}): &bn256Add{},
- common.BytesToAddress([]byte{7}): &bn256ScalarMul{},
- common.BytesToAddress([]byte{8}): &bn256Pairing{},
Using Precompiled Contracts
Elliptic Curve Addition
contract PrecompiledCall {
event precompiledResult(bytes32[2]);
function callBn256Add(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public {
bytes32[2] memory result;
bytes32[4] memory input;
input[0] = ax;
input[1] = ay;
input[2] = bx;
input[3] = by;
// ECADD address 0x06
assembly {
let success := call
(5000000000000, 0x06, 0, input, 0x80, result, 0x40)
switch success
case 0 {
revert(0,0)
}
mstore(0x0, result)
}
emit precompiledResult(result);
}
Sources
- https://blog.qtum.org/precompiled-contracts-and-confidential-assets-55f2b47b231d