Precompiled Contracts
Kaia provides several useful precompiled contracts, none of which are state-changing. These contracts are implemented in the platform itself as a native implementation, which means they are part of the Kaia client specifications. The precompiled contracts from address 0x01 through 0x0A are the same as those in Ethereum. The utility of precompiles falls into four major categories: . Elliptic curve digital signature recovery. . Hash Methods . Memory copying . Methods to enable elliptic curve maths for zk proofs. Kaia additionally implements precompiled contracts from 0x3FD through 0x3FF to support new Kaia features.
Contracts deployed before the istanbul EVM hardfork should use the original addresses.
- case 1) The contracts deployed in Kairos at block number
#75373310
recognizes 0x09, 0x0a, and 0x0b as addresses of vmLog, feePayer, and validateSender, respectively, and blake2f cannot be used. - case 2) The contracts deployed in Kairos at block number
#75373314
recognizes 0x09 as the address of blake2f, and recognizes 0x3fd, 0x3fe, and 0xff as addresses of vmLog, feePayer, and validateSender.
Precompiled contracts related hardfork changes can be found at the bottom of this page. Go to Hardfork Changes.
Address 0x01: ecrecover(hash, v, r, s)
The address 0x01 implements ecrecover. It returns the address from the given signature by calculating a recovery function of ECDSA. It is the only precompile that comes with a solidity wrapper. Its function prototype is as follows:
hàm ecRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) chế độ xem công khai trả về (địa chỉ) { địa chỉ r = ecrecover(băm, v, r, s); // hàm nguyên mẫu yêu cầu(r != address(0), "chữ ký không hợp lệ");} // trình bao bọc solidity
Address 0x02: sha256(data)
The address 0x02 implements SHA256 hash. It returns a SHA256 hash from the given data. It is mostly used by Bitcoin and Zcash as Ethereum uses Keccak256. Its function prototype is as follows:
function sha256(uint256 numberToHash) public view returns (bytes32 hash) { (bool ok, bytes memory hashData) = address(0x02).staticcall(abi.encode(numberToHash)); require(ok); hash = abi.decode(hashData, (bytes32));}
usage in Yul / Inline Assembly:
function sha256Yul(uint256 numberToHash) public view returns (bytes32) { assembly { mstore(0, numberToHash) // store number in the zeroth memory word let ok := staticcall(gas(), 2, 0, 32, 0, 32) if iszero(ok) { revert(0,0) } return(0, 32) }}
Address 0x03: ripemd160(data)
The address 0x03 implements RIPEMD160 hash. It returns a RIPEMD160 hash from the given data. Its function prototype is as follows:
function RIPEMD160(bytes calldata data) public view returns (bytes20 h) { (bool ok, bytes memory out) = address(0x03).staticcall(data); require(ok); h = bytes20(abi.decode(out, (bytes32)) << 96);}
Address 0x04: datacopy(data)
The address 0x04 implements datacopy (i.e., identity function). It returns the input data directly without any modification. This precompiled contract is not supported by the Solidity compiler. The following code with inline assembly can be used to call this precompiled contract.
hàm callDatacopy(byte bộ nhớ dữ liệu) trả về công khai (byte bộ nhớ) { byte bộ nhớ ret = byte mới (dữ liệu.chiều dài); lắp ráp { cho len := mload(dữ liệu) nếu iszero(gọi(gas, 0x04, 0, thêm(dữ liệu, 0x20), len, thêm(ret, 0x20), len)) { không hợp lệ() } } trả về ret;}
Address 0x05: bigModExp(base, exp, mod)
The address 0x05 implements the formula base**exp % mod
. It returns the result from the given data. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract. Note that although this precompiled contract supports an arbitrary length of inputs, the below code uses a fixed length of inputs as an example.
function callBigModExp(bytes32 base, bytes32 exponent, bytes32 modulus) public returns (bytes32 result) { assembly { // free memory pointer let memPtr := mload(0x40) // length of base, exponent, modulus mstore(memPtr, 0x20) mstore(add(memPtr, 0x20), 0x20) mstore(add(memPtr, 0x40), 0x20) // assign base, exponent, modulus mstore(add(memPtr, 0x60), base) mstore(add(memPtr, 0x80), exponent) mstore(add(memPtr, 0xa0), modulus) // call the precompiled contract BigModExp (0x05) let success := call(gas, 0x05, 0x0, memPtr, 0xc0, memPtr, 0x20) switch success case 0 { revert(0x0, 0x0) } default { result := mload(memPtr) } }}
Address 0x06: bn256Add(ax, ay, bx, by)
The address 0x06 implements a native elliptic curve point addition. It returns an elliptic curve point representing (ax, ay) + (bx, by)
such that (ax, ay) and (bx, by) are valid points on the curve bn256. This precompiled contract is not supported by the Solidity compiler. The following code can be used to call this precompiled contract.
function callBn256Add(bytes32 ax, bytes32 ay, bytes32 bx, bytes32 by) public returns (bytes32[2] memory result) { bytes32[4] memory input; input[0] = ax; input[1] = ay; input[2] = bx; input[3] = by; assembly { let success := call(gas, 0x06, 0, input, 0x80, result, 0x40) switch success case 0 { revert(0,0) } }}