Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dawn/non specific precompiles #978

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.2 <0.9.0;

contract RecoverPublicKey {
function recoverPublicKey(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) public view returns (bytes memory) {
address precompileAddress = 0x0000000000000000000000000000000000000402;
(bool success, bytes memory publicKey) = precompileAddress.staticcall(
abi.encodeWithSignature(
"ECRecoverPublicKey(bytes32,uint8,bytes32,bytes32)",
hash,
v,
r,
s
)
);
require(success, "ECRecoverPublicKey failed");
return publicKey;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const { Web3 } = require('web3');
const web3 = new Web3('https://rpc.api.moonbase.moonbeam.network');

// Address and private key
const address = 'INSERT_RECEIVER_ADDRESS';
const pk1 =
'INSERT_SENDER_PRIVATE_KEY';
const msg = web3.utils.sha3('supercooltestmessage');

async function signMessage(pk) {
try {
// Sign and get signed message
const smsg = await web3.eth.accounts.sign(msg, pk);
console.log(smsg);
} catch (error) {
console.error(error);
}
}

signMessage(pk1);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div id="termynal" data-termynal>
<span data-ty="input"><span class="file-path"></span>node signMessage.js</span>
<span data-ty>{</span>
<span data-ty> message: '0x5836e21a51f25aad199e2e0feb5ca19673ed56b3811285f5124d7a8171d75851',</span>
<span data-ty> messageHash: '0xa69b720d0293b9e8f4e471afb80f9d410b825abe5ce524e7d5755fd2a00bf9de',</span>
<span data-ty> v: '0x1b',</span>
<span data-ty> r: '0xb7d4783ee3b34d6fbc419d5b7bc67002c511322c5c71b49a7d78a8b7e9c5b30a',</span>
<span data-ty> s: '0x4e5939eaef3917b1cb09af9e632cc9a727b64191b7ee40a6ae34f6fdde60a371',</span>
<span data-ty> signature: '0xb7d4783ee3b34d6fbc419d5b7bc67002c511322c5c71b49a7d78a8b7e9c5b30a4e5939eaef3917b1cb09af9e632cc9a727b64191b7ee40a6ae34f6fdde60a3711b'</span>
<span data-ty>}</span>
<span data-ty="input"><span class="file-path"></span></span>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@
| Contract | Address |
|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------:|
| [SHA3FIPS256](/builders/ethereum/precompiles/utility/eth-mainnet/#hashing-with-sha3fips256){target=\_blank} | 0x0000000000000000000000000000000000000400 |
| [Dispatch](https://polkadot-evm.github.io/frontier/rustdocs/pallet_evm_precompile_dispatch/struct.Dispatch.html){target=\_blank} | 0x0000000000000000000000000000000000000401 |
| Dispatch [Removed] | 0x0000000000000000000000000000000000000401 |
dawnkelly09 marked this conversation as resolved.
Show resolved Hide resolved
| [ECRecoverPublicKey](https://polkadot-evm.github.io/frontier/rustdocs/pallet_evm_precompile_simple/struct.ECRecoverPublicKey.html){target=\_blank} | 0x0000000000000000000000000000000000000402 |

=== "Moonriver"
| Contract | Address |
|:--------------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------:|
| [SHA3FIPS256](/builders/ethereum/precompiles/utility/eth-mainnet/#hashing-with-sha3fips256){target=\_blank} | 0x0000000000000000000000000000000000000400 |
| [Dispatch](https://polkadot-evm.github.io/frontier/rustdocs/pallet_evm_precompile_dispatch/struct.Dispatch.html){target=\_blank} | 0x0000000000000000000000000000000000000401 |
| Dispatch [Removed] | 0x0000000000000000000000000000000000000401 |
| [ECRecoverPublicKey](https://polkadot-evm.github.io/frontier/rustdocs/pallet_evm_precompile_simple/struct.ECRecoverPublicKey.html){target=\_blank} | 0x0000000000000000000000000000000000000402 |

=== "Moonbase Alpha"
| Contract | Address |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------------:|
| [SHA3FIPS256](/builders/ethereum/precompiles/utility/eth-mainnet/#hashing-with-sha3fips256){target=\_blank} | 0x0000000000000000000000000000000000000400 |
| [Dispatch](https://polkadot-evm.github.io/frontier/rustdocs/pallet_evm_precompile_dispatch/struct.Dispatch.html){target=\_blank} | 0x0000000000000000000000000000000000000401 |
| Dispatch [Removed] | 0x0000000000000000000000000000000000000401 |
| [ECRecoverPublicKey](https://polkadot-evm.github.io/frontier/rustdocs/pallet_evm_precompile_simple/struct.ECRecoverPublicKey.html){target=\_blank} | 0x0000000000000000000000000000000000000402 |
| [StorageCleaner](https://polkadot-evm.github.io/frontier/rustdocs/pallet_evm_precompile_storage_cleaner/struct.StorageCleanerPrecompile.html){target=\_blank} | 0x0000000000000000000000000000000000000403 |
3 changes: 2 additions & 1 deletion builders/ethereum/precompiles/utility/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ nav:
- index.md
- 'Ethereum Native': 'eth-mainnet.md'
- 'Precompile Registry': 'registry.md'
- 'Relay Data Verifier': 'relay-data-verifier.md'
- 'Relay Data Verifier': 'relay-data-verifier.md'
- 'Non-Network Specific': 'non-specific.md'
18 changes: 3 additions & 15 deletions builders/ethereum/precompiles/utility/eth-mainnet.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---
title: Ethereum MainNet Precompiles
description: Learn how to use the standard precompiled contracts availble on Ethereum such as ECRECOVER, SHA256, and more on Moonbeam.
keywords: ethereum, moonbeam, ecrecover, sha256, sha3FIPS256, ripemd-160, Bn128Add, Bn128Mul, Bn128Pairing
keywords: ethereum, moonbeam, ecrecover, sha256, ripemd-160, Bn128Add, Bn128Mul, Bn128Pairing
---

# Ethereum MainNet Precompiled Contracts

## Introduction {: #introduction }

Precompiled contracts in Ethereum are contracts that include complex cryptographic computations, but do not require the overhead of the EVM. There are nine precompiles that can be used within the EVM that handle specific common operations such as hashing and signature schemes.
Precompiled contracts in Ethereum are contracts that include complex cryptographic computations, but do not require the overhead of the EVM. These precompiles can be used within the EVM to handle specific common operations such as hashing and signature schemes.

The following precompiles are currently included: ecrecover, sha256, sha3FIPS256, ripemd-160, Bn128Add, Bn128Mul, Bn128Pairing, the identity function, and modular exponentiation.
The following precompiles are currently included: ecrecover, sha256, ripemd-160, Bn128Add, Bn128Mul, Bn128Pairing, the identity function, and modular exponentiation.

These precompiles are natively available on Ethereum and, to maintain Ethereum compatibility, they are also available on Moonbeam.

Expand Down Expand Up @@ -70,18 +70,6 @@ This hashing function returns the SHA256 hash from the given data. To test this

Once the contract is deployed, you can call the `checkHash()` method that returns **true** if the hash returned by `calculateHash()` is equal to the hash provided.

## Hashing with SHA3FIPS256 {: #hashing-with-sha3fips256 }

SHA3-256 is part of the SHA-3 family of cryptographic hashes codified in [FIPS202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) that produces an output 256 bits in length. Although the name is similar to SHA256, the SHA-3 family is built with an entirely different algorithm and accordingly produces a different hash output than SHA256 for the same input. You can verify this yourself using this [SHA3-256 Hash Calculator tool](https://md5calc.com/hash/sha3-256){target=\_blank}. After calculating the SHA3-256 output, change the algorithm in the drop-down selector to SHA256 and take note of the resulting output.

Currently there is no SHA3-256 support in Solidity, so it needs to be called with inline assembly. The following sample code can be used to call this precompile.

```solidity
--8<-- 'code/builders/ethereum/precompiles/utility/eth-mainnet/sha3fips.sol'
```

Using the [Remix compiler and deployment](/builders/ethereum/dev-env/remix/){target=\_blank} and with [MetaMask pointing to Moonbase Alpha](/tokens/connect/metamask/){target=\_blank}, you can deploy the contract and call the `sha3fips(bytes memory data)` method to return the encoded string of the data parameter.

## Hashing with RIPEMD160 {: #hashing-with-ripemd-160 }

This hashing function returns a RIPEMD160 hash from the given data. To test this precompile, you can use this [RIPEMD160 Hash Calculator tool](https://md5calc.com/hash/ripemd160){target=\_blank} to calculate the RIPEMD160 hash of any string. In this case, you'll do so again with `Hello World!`. You'll reuse the same code as before, but use the `ripemd160` function. Note that it returns a `bytes20` type variable:
Expand Down
103 changes: 103 additions & 0 deletions builders/ethereum/precompiles/utility/non-specific.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
title: Non-Network Specific Precompiles
description: Learn how to use precompiled contracts, which are not specific to Ethereum or Moonbeam, yet are supported for use in your application.
keywords: ethereum, moonbeam, StorageCleaner, ECRecoverPublicKey, sha3FIPS256
---

# Non-Network Specific Precompiled Smart Contracts

## Introduction {: #introduction }

A precompiled contract, or precompile, is a set of programmed functionalities hard-coded into the blockchain client. Precompiles perform computationally heavy tasks, such as cryptographic processes like hashing. Moving these functionalities to the blockchain client serves the dual purpose of making the computation more efficient than using a traditional smart contract and ensuring everyone has access to the complete and accurate set of processes and algorithms required to operate correctly.

Precompile functionality is bundled and shared under a smart contract address which allows interactions similar to those of a traditional smart contract. Some precompiled contracts are not specific to Ethereum or to Moonbeam, but are supported for use in your Moonbeam application.
dawnkelly09 marked this conversation as resolved.
Show resolved Hide resolved

The nonspecific precompiles currently included in this category include `StorageCleaner`, `ECRecoverPublicKey`, and `SHA3FIPS256`.

In the next section, you will learn more about the functionalities included in these precompiles.

## Clear Storage Entries with StorageCleaner {: #clear-storage-with-storagecleaner }

The primary function of the `StorageCleaner` precompile is to clear storage entry key-value pairs for a smart contract marked as self-destructed, previously referred to as 'suicided.' `StorageCleaner` includes functionality to iterate over a list of addresses to identify self-destructed contracts and delete the appropriate storage entries associated with identified addresses. You can also input a numeric limit to prevent the precompile from consuming too much gas.

With the implementation of [EIP-6780: SELFDESTRUCT](https://eips.ethereum.org/EIPS/eip-6780){target=\_blank} as part of the Ethereum Cancun/Dencun upgrade, contracts can only be self-destructed in the same transaction where they are created. This limitation keeps storage entries small and allows them to be automatically deleted during destruction. The `StorageCleaner` precompile remains available when a legacy contract needs storage entries cleared.

## Retrieve a Public Key with ECRecoverPublicKey {: verifying-signatures-ecrecoverpublickey }

The primary function of the `ECRecoverPublicKey` precompile is to recover the public key used to create a digital signature from a given message hash and signature. This precompile is similar to [ECRecover](/builders/ethereum/precompiles/utility/eth-mainnet/#verify-signatures-with-ecrecover/){target=\_blank}, with the exception of returning the public key of the account that signed the message rather than the account address.

In the following sections, you will learn how to use the `ECRecoverPublicKey` precompile.

### Checking Prerequisites {: checking-prerequisites }

--8<-- 'text/_common/install-nodejs.md'
dawnkelly09 marked this conversation as resolved.
Show resolved Hide resolved

The versions used in this example are v20.15.0 (Node.js) and 10.7.0 (npm). You will also need to install the [Web3](https://web3js.readthedocs.io/en/latest){target=\_blank} package by executing:

```bash
npm install --save web3
```

To verify the installed version of Web3, you can use the `ls` command:

```bash
npm ls web3
```

This example uses version 4.11.1. You will also use [Remix](/builders/ethereum/dev-env/remix/){target=\_blank}, connecting it to the Moonbase Alpha TestNet via [MetaMask](/tokens/connect/metamask/){target=\_blank}.

--8<-- 'text/_common/endpoint-examples.md'

### Retrieve Transaction Signature Values

To use the `ECRecoverPublicKey` precompile, you must first sign a message to create and retrieve the message hash and transaction signature values (`v`, `r`, `s`) to pass as arguments in the contract call. Always use security best practices when handling private keys.

Create a new file called `signMessage.js` in your project directory:

```bash
touch signMessage.js
```

Open `signMessage.js` in your code editor and add the following script to initialize Web3 with Moonbase Alpha TestNet, sign and hash the message, and return the signature values:

```js title="signMessage.js"
--8<-- 'code/builders/ethereum/precompiles/utility/nonspecific/signMessage.js'
```

Return to your terminal command line to run the script with this command:

```bash
node signMessage.js
```

This code will return the following object in the terminal:

--8<-- 'code/builders/ethereum/precompiles/utility/nonspecific/terminal/signature.md'

Save these values as you will need them in the next section.

### Test ECRecoverPublicKey Contract

You can now visit [Remix](https://remix.ethereum.org/){target=\_blank} to test the precompiled contract. Note that you could also use the Web3.js library, but in this case, you can go to Remix to ensure it is using the precompiled contract on the blockchain. The Solidity code you can use to retrieve the public key is the following:

```solidity title="RecoverPublicKey.sol"
--8<-- 'code/builders/ethereum/precompiles/utility/nonspecific/RecoverPublicKey.sol'
```

Using the [Remix compiler and deployment](/builders/ethereum/dev-env/remix/){target=\_blank} and with [MetaMask pointing to Moonbase Alpha](/tokens/connect/metamask/){target=\_blank}, you can deploy the contract and call the `recoverPublicKey()` method which returns the public key for the account that signed the message. You can now use this public key value for other cryptographic functions and verifications.

![Returned Public Key on Remix](/images/builders/ethereum/precompiles/utility/nonspecific/nonspecific-1.webp)
dawnkelly09 marked this conversation as resolved.
Show resolved Hide resolved

## Create a Hash with SHA3FIPS256 {: #create-a-hash-with-sha3fips256 }

SHA3-256 is part of the SHA-3 family of cryptographic hashes codified in [FIPS202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) that produces an output 256 bits in length. Although the name is similar to SHA256, the SHA-3 family is built with an entirely different algorithm and accordingly produces a different hash output than SHA256 for the same input. You can verify this yourself using this [SHA3-256 Hash Calculator tool](https://md5calc.com/hash/sha3-256){target=\_blank}. After calculating the SHA3-256 output, change the algorithm in the drop-down selector to SHA256 and take note of the resulting output.

Currently there is no SHA3-256 support in Solidity, so it needs to be called with inline assembly. The following sample code can be used to call this precompile.

```solidity
--8<-- 'code/builders/ethereum/precompiles/utility/eth-mainnet/sha3fips.sol'
```

Using the [Remix compiler and deployment](/builders/ethereum/dev-env/remix/){target=\_blank} and with [MetaMask pointing to Moonbase Alpha](/tokens/connect/metamask/){target=\_blank}, you can deploy the contract and call the `sha3fips(bytes memory data)` method to return the encoded string of the data parameter.
dawnkelly09 marked this conversation as resolved.
Show resolved Hide resolved

--8<-- 'text/_disclaimers/third-party-content-intro.md'
Binary file not shown.
Loading