WeaveVM Precompiles
About WeaveVM precompiled contracts
What Are Precompiled Contracts?
Ethereum uses precompiles to efficiently implement cryptographic primitives within the EVM instead of re-implementing these primitives in Solidity.
The following precompiles are currently included: ecrecover, sha256, blake2f, ripemd-160, Bn256Add, Bn256Mul, Bn256Pairing, the identity function, modular exponentiation, and point evaluation.
Ethereum precompiles behave like smart contracts built into the Ethereum protocol. The ten precompiles live in addresses 0x01 to 0x0A. WeaveVM supports all of these 10 standard precompiles and adds new custom precompiles starting at the 23rd byte representing the letter "W" position (index) in the alphabet. Therefore, WeaveVM precompiles start at address 0x17 (23rd byte).
WeaveVM Precompiles List
0x01 (0x0000000000000000000000000000000000000001
)
ecRecover
3000
hash, v, r, s
publicAddress
Elliptic curve digital signature algorithm (ECDSA) public key recovery function
0x02 (0x0000000000000000000000000000000000000002
)
SHA2-256
60
data
hash
Hash function
0x03 (0x0000000000000000000000000000000000000003
)
RIPEMD-160
600
data
hash
Hash function
0x04 (0x0000000000000000000000000000000000000004
)
identity
15
data
data
Returns the input
0x05 (0x0000000000000000000000000000000000000005
)
modexp
200
Bsize, Esize, Msize, B, E, M
value
Arbitrary-precision exponentiation under modulo
0x06 (0x0000000000000000000000000000000000000006
)
ecAdd
150
x1, y1, x2, y2
x, y
Point addition (ADD) on the elliptic curve alt_bn128
0x07 (0x0000000000000000000000000000000000000007
)
ecMul
6000
x1, y1, s
x, y
Scalar multiplication (MUL) on the elliptic curve alt_bn128
0x08 (0x0000000000000000000000000000000000000008
)
ecPairing
45000
x1, y1, x2, y2, ..., xk, yk
success
Bilinear function on groups on the elliptic curve alt_bn128
0x09 (0x0000000000000000000000000000000000000009
)
blake2f
0
rounds, h, m, t, f
h
Compression function F used in the BLAKE2 cryptographic hashing algorithm
0x0A (0x000000000000000000000000000000000000000A
)
point evaluation
50000
bytes
bytes
Verify p(z) = y given commitment that corresponds to the polynomial p(x) and a KZG proof. Also verify that the provided commitment matches the provided versioned_hash.
0x17 (0x0000000000000000000000000000000000000017
)
arweave_upload
10003
bytes
bytes
upload bytes array to Arweave and get back the upload TXID in bytes
0x18 (0x0000000000000000000000000000000000000018
)
arweave_read
10003
bytes
bytes
retrieve an Arweave TXID data in bytes
0x20 (0x0000000000000000000000000000000000000020
)
read_block
10003
bytes
bytes
retrieve a WeaveVM's block data (from genesis) pulling it from Arweave
0x21 (0x0000000000000000000000000000000000000021
)
kyve_trustless_api_blob
10003
bytes
bytes
retrieve a historical Ethereum blob data from WeaveVM's smart contract layer
Outlining WeaveVM New Precompiles
1- Precompile 0x17: upload data from Solidity to Arweave
The WeaveVM Precompile at address 0x17 (0x0000000000000000000000000000000000000017
) enables data upload (in byte format) from Solidity to Arweave, and returns the data TXID (in byte format). In Alphanet V1, data uploads are limited to 100KB. Future network updates will remove this limitation and introduce a higher data cap.
Solidity code example:
pragma solidity ^0.8.0;
contract ArweaveUploader {
function upload_to_arweave(string memory dataString) public view returns (bytes memory) {
// Convert the string parameter to bytes
bytes memory data = abi.encodePacked(dataString);
// pc address: 0x0000000000000000000000000000000000000017
(bool success, bytes memory result) = address(0x17).staticcall(data);
return result;
}
2- Precompile 0x18: read Arweave data from Solidity
This precompile, at address 0x18 (0x0000000000000000000000000000000000000018
), completes the data pipeline between WeaveVM and Arweave, making it bidirectional. It enables retrieving data from Arweave in bytes for a given Arweave TXID.
The 0x18 precompile allows user input to choose their Arweave gateway for resolving a TXID. If no gateway URL is provided, the precompile defaults to arweave.net
.
The format of the precompile bytes input (string representation) should be as follows: gateway_url;arweave_txid
The table below outlines the max Arweave transaction size that can be read in WeaveVM smart contracts for each testnet release (Note: these are theoretical numbers based on network metrics calculations).
Alphanet V1
300,000,000
16
(300,000,000 - 21,000) / 16 = 18,748,687
Alphanet V1.5
300,000,000
8
(300,000,000 - 21,000) / 8 = 37,497,375
Alphanet V2
1,000,000,000
8
(1,000,000,000 - 21,000) / 8 = 124,997,375
Solidity code example:
pragma solidity ^0.8.0;
contract ArweaveReader {
function read_from_arweave(string memory txIdOrGatewayAndTxId) public view returns (bytes memory) {
// Convert the string parameter to bytes
bytes memory data = abi.encodePacked(txIdOrGatewayAndTxId);
// pc address: 0x0000000000000000000000000000000000000018
(bool success, bytes memory result) = address(0x18).staticcall(data);
return result;
}
}
3- Precompile 0x20: Access to WeaveVM' historical blocks
This precompile, at address 0x20(0x0000000000000000000000000000000000000020
), lets smart contract developers not access only the most recent 256 blocks, but any block data starting at genesis. To explain how to request block data using the 0x20 precompile, here is a code example:
pragma solidity ^0.8.0;
contract WeaveVmBlockReader {
function read_block() public view returns (bytes memory) {
// Convert the string parameter to bytes
string memory blockIdAndField = "141550;hash";
bytes memory data = abi.encodePacked(blockIdAndField);
(bool success, bytes memory result) = address(0x20).staticcall(data);
return result;
}
}
As you can see, for the query variable we have three “parameters” separated by a semicolon ”;” (gateway;wvm_block_id;block_field
format)
An Arweave gateway (optional and fallback to arweave.net if not provided): https://ar-io.dev
WeaveVM’s block number to fetch, target block: 141550
The field of the block struct to access, in this case: hash
Only the gateway is an optional parameter, and regarding the field of the block struct to access, here is the Block struct that the 0x20 precompile uses:
#[serde(rename_all = "camelCase")]
pub struct Block {
pub base_fee_per_gas: Option<String>, // "baseFeePerGas"
pub blob_gas_used: Option<String>, // "blobGasUsed"
pub difficulty: Option<String>, // "difficulty"
pub excess_blob_gas: Option<String>, // "excessBlobGas"
pub extra_data: Option<String>, // "extraData"
pub gas_limit: Option<String>, // "gasLimit"
pub gas_used: Option<String>, // "gasUsed"
pub hash: Option<String>, // "hash"
pub logs_bloom: Option<String>, // "logsBloom"
pub miner: Option<String>, // "miner"
pub mix_hash: Option<String>, // "mixHash"
pub nonce: Option<String>, // "nonce"
pub number: Option<String>, // "number"
pub parent_beacon_block_root: Option<String>, // "parentBeaconBlockRoot"
pub parent_hash: Option<String>, // "parentHash"
pub receipts_root: Option<String>, // "receiptsRoot"
pub seal_fields: Vec<String>, // "sealFields" as an array of strings
pub sha3_uncles: Option<String>, // "sha3Uncles"
pub size: Option<String>, // "size"
pub state_root: Option<String>, // "stateRoot"
pub timestamp: Option<String>, // "timestamp"
pub total_difficulty: Option<String>, // "totalDifficulty"
pub transactions: Vec<String>, // "transactions" as an array of strings
}
Check out the 0x20 source code here
4- Precompile 0x21: Native access to archived Ethereum blobs
This precompile, at address 0x21 (0x0000000000000000000000000000000000000021
), is a unique solution for native access to blobs data (not just commitments) from the smart contract layer. This precompile fetches from the KYVE Trustless API the blobs data that KYVE archives for their supported networks.
Therefore, with 0x21, KYVE clients will have, for the first time, the ability to fetch their archived blobs from an EVM smart contract layer instead of wrapping the Trustless API in oracles and making expensive calls.
0x21 lets you fetch KYVE's Ethereum blob data starting at Ethereum's block 19426589 - the first block with a recorded EIP-4844 transaction. To retrieve a blob from the Trustless API, in the 0x21 staticcall you need to specify the Ethereum block number, blob index in the transaction, and the blob field you want to retrieve, in this format: block_number;blob_index.field
N.B: blob_index represents the blob index in the KYVE’s Trustless API JSON response:
pragma solidity ^0.8.0;
contract KyveBlobsTrustlessApi {
function getBlob
() public view returns (bytes memory) {
// Convert the string parameter to bytes
string memory query = "20033081;0.blob";
bytes memory data = abi.encodePacked(query);
(bool success, bytes memory result) = address(0x21).staticcall(data);
return result;
}
}
The eip-4844 transaction fields that you can access from the 0x21 query are:
blob (raw blob data, the body)
kzg_commitment
kzg_proof
slot
Advantages of 0x21 (use cases)
Native access to blob data from smart contract layer
Access to permanently archived blobs
Opens up longer verification windows for rollups using KYVE for archived blobs and WeaveVM for settlement layer
Enables using blobs for purposes beyond rollups DA, opening doors for data-intensive blob-based applications with permanent blob access
Check out the 0x21 precompile source code here.
Last updated