Skip to main content

Precompile Contracts

On top of a set of opcodes, EVM also offers advanced functionalities through precompiled contracts. These are special contracts bundled with EVM at fixed addresses that can be called with a determined gas. The gas is purely the contractual cost, neither the cost of the call itself nor the instructions to put the parameters in memory.

Precompiled contract addresses start from 1 and increment for each contract. New hardforks may introduce new precompiled contracts. Similar to the regular contracts, new contracts are called from opcodes with instructions, such as CALL.

For all precompiled contracts, inputs that are shorter than expected are assumed to be virtually padded with zeros at the end, whereas any surplus bytes at the end of inputs that are longer than expected are ignored.

The address precompile contract is described by the last 2 bytes:

Byte range [0..18]Byte range [18..20]
000000000000000000000000000000000000addr

EcRecover

ADDRESSMINIMUM GASINPUTOUTPUT
0x00000000000000000000000000000000000000013000hash, v, r, spublicAddress

EcRecover is a elliptic curve digital signature algorithm (ECDSA) public key recovery function. For details, see this page.

SHA2-256

ADDRESSMINIMUM GASINPUTOUTPUT
0x000000000000000000000000000000000000000260datahash

SHA2-256 is the hash function used in Bitcoin. For details, see this page

RIPEMD-160

ADDRESSMINIMUM GASINPUTOUTPUT
0x0000000000000000000000000000000000000003600datahash

A hash function. For details, see this page.

Identity

ADDRESSMINIMUM GASINPUTOUTPUT
0x000000000000000000000000000000000000000415datadata

Identity copies and returns input data. For details, see this page.

Modexp

ADDRESSMINIMUM GASINPUTOUTPUT
0x0000000000000000000000000000000000000005200Bsize, Esize, Msize, B, E, Mvalue

Modexp is an arbitrary-precision exponentiation under modulo. For details, see this page.

EcAdd

ADDRESSMINIMUM GASINPUTOUTPUT
0x0000000000000000000000000000000000000006150x1, x2, y1, y2x, y

EcAdd is the point addition (ADD) on the elliptic curve alt_bn128. For details, see this page.

EcMul

ADDRESSMINIMUM GASINPUTOUTPUT
0x00000000000000000000000000000000000000076000x1, x2, sx, y

EcMul is the scalar multiplication (MUL) on the elliptic curve alt_bn128. For details, see this page.

EcPairing

ADDRESSMINIMUM GASINPUTOUTPUT
0x000000000000000000000000000000000000000845000x1, y1, x2, y2, …, xk, yksuccess

EcPairing is the bilinear function on groups on the elliptic curve alt_bn128. For details, see this page.

Blake2f

ADDRESSMINIMUM GASINPUTOUTPUT
0x00000000000000000000000000000000000000090rounds, h, m, t, fh

Blake2f is the compression function F used in the BLAKE2 cryptographic hashing algorithm. For details, see this page.

GetHeader

ADDRESSMINIMUM GASINPUTOUTPUT
0x000000000000000000000000000000000000010242000hashheader view

Get the header of a relayed CKB block header by hash.

Inputs

Click here to view ABI
struct Input {
bytes32 hash;
}

Output

Click here to view ABI
struct Header {
uint32 version;
uint32 compactTarget;
uint64 timestamp;
uint64 number;
uint64 epoch;
bytes32 parentHash;
bytes32 transactionsRoot;
bytes32 proposalsHash;
bytes32 extraHash;
bytes32 dao;
uint128 nonce;
bytes extension;
bytes32 blockHash;
}

GetCell

ADDRESSMINIMUM GASINPUTOUTPUT
0x000000000000000000000000000000000000010342000out pointcell info

Get the relayed cell information by out point.

Inputs

Click here to view ABI
struct OutPoint {
bytes32 txHash;
uint32 index;
}

Output

Click here to view ABI
struct CellInfo {
OutPoint outPoint;
CellOutput output;
bytes data;
}

struct CellOutput {
uint64 capacity;
Script lock;
Script[] type_;
}

CallCkbVm

ADDRESSMINIMUM GASINPUTOUTPUT
0x0000000000000000000000000000000000000104300cell dep, argsbig-endian bytes

Call a script that runs in CKB-VM and return the execute result.

Inputs

Click here to view ABI
struct CellDep {
OutPoint outPoint;
uint32 index;
}

struct InputArgs {
bytes[] args;
}

Output

Click here to view ABI
struct Result {
int8 ret;
}

Example

Click here to view example
contract CallCkbVm {
event CallCkbVmEvent(int8);
event NotGetCellEvent();

int8 ret;

function testCallCkbVm(
bytes32 txHash,
uint32 index,
uint8 depType,
bytes[] memory input_args
) public {
OutPoint memory outPoint = OutPoint(txHash, index);
(bool isSuccess, bytes memory res) = address(0x0104).staticcall(
abi.encode(CellDep(outPoint, depType), input_args)
);

if (isSuccess) {
ret = int8(uint8(res[0]));
emit CallCkbVmEvent(ret);
} else {
emit NotGetCellEvent();
}
}

function callCkbVm() public view returns (int8) {
return ret;
}
}