difftreelog
Add `ecrecovery` and `sr25519` precompiles
in: master
18 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2274,7 +2274,7 @@
"hash256-std-hasher",
"rlp",
"rlp-derive",
- "sha3",
+ "sha3 0.10.6",
"triehash",
]
@@ -2292,7 +2292,7 @@
"rlp",
"scale-info",
"serde",
- "sha3",
+ "sha3 0.10.6",
"triehash",
]
@@ -2350,7 +2350,7 @@
"rlp",
"scale-info",
"serde",
- "sha3",
+ "sha3 0.10.6",
]
[[package]]
@@ -2380,7 +2380,7 @@
"hex",
"proc-macro2",
"quote",
- "sha3",
+ "sha3 0.10.6",
"syn",
]
@@ -2415,7 +2415,7 @@
"environmental",
"evm-core",
"primitive-types 0.12.1",
- "sha3",
+ "sha3 0.10.6",
]
[[package]]
@@ -4958,7 +4958,7 @@
"digest 0.10.6",
"multihash-derive",
"sha2 0.10.6",
- "sha3",
+ "sha3 0.10.6",
"unsigned-varint",
]
@@ -5280,6 +5280,7 @@
"cumulus-primitives-utility",
"derivative",
"evm-coder",
+ "fp-evm",
"fp-evm-mapping",
"fp-rpc",
"fp-self-contained",
@@ -5294,6 +5295,7 @@
"impl-trait-for-tuples",
"log",
"logtest",
+ "num_enum",
"orml-tokens",
"orml-traits",
"orml-vesting",
@@ -5309,6 +5311,7 @@
"pallet-evm-coder-substrate",
"pallet-evm-contract-helpers",
"pallet-evm-migration",
+ "pallet-evm-precompile-simple",
"pallet-evm-transaction-payment",
"pallet-foreign-assets",
"pallet-fungible",
@@ -5333,6 +5336,7 @@
"parachain-info",
"parity-scale-codec 3.2.1",
"polkadot-parachain",
+ "precompile-utils-macro",
"rmrk-rpc",
"scale-info",
"serde",
@@ -6005,6 +6009,16 @@
]
[[package]]
+name = "pallet-evm-precompile-simple"
+version = "2.0.0-dev"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.33#c37ced433a29baad45899d6ab364fe437f97570e"
+dependencies = [
+ "fp-evm",
+ "ripemd",
+ "sp-io",
+]
+
+[[package]]
name = "pallet-evm-transaction-payment"
version = "0.1.1"
dependencies = [
@@ -8595,6 +8609,17 @@
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
+name = "precompile-utils-macro"
+version = "0.1.0"
+dependencies = [
+ "num_enum",
+ "proc-macro2",
+ "quote",
+ "sha3 0.8.2",
+ "syn",
+]
+
+[[package]]
name = "predicates"
version = "2.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -8850,6 +8875,7 @@
"cumulus-primitives-utility",
"derivative",
"evm-coder",
+ "fp-evm",
"fp-evm-mapping",
"fp-rpc",
"fp-self-contained",
@@ -8864,6 +8890,7 @@
"impl-trait-for-tuples",
"log",
"logtest",
+ "num_enum",
"orml-tokens",
"orml-traits",
"orml-vesting",
@@ -8879,6 +8906,7 @@
"pallet-evm-coder-substrate",
"pallet-evm-contract-helpers",
"pallet-evm-migration",
+ "pallet-evm-precompile-simple",
"pallet-evm-transaction-payment",
"pallet-foreign-assets",
"pallet-fungible",
@@ -8901,6 +8929,7 @@
"parachain-info",
"parity-scale-codec 3.2.1",
"polkadot-parachain",
+ "precompile-utils-macro",
"rmrk-rpc",
"scale-info",
"serde",
@@ -9249,6 +9278,15 @@
]
[[package]]
+name = "ripemd"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f"
+dependencies = [
+ "digest 0.10.6",
+]
+
+[[package]]
name = "rlp"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -10961,6 +10999,19 @@
[[package]]
name = "sha3"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf"
+dependencies = [
+ "block-buffer 0.7.3",
+ "byte-tools",
+ "digest 0.8.1",
+ "keccak",
+ "opaque-debug 0.2.3",
+]
+
+[[package]]
+name = "sha3"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9"
@@ -11396,7 +11447,7 @@
"byteorder",
"digest 0.10.6",
"sha2 0.10.6",
- "sha3",
+ "sha3 0.10.6",
"sp-std",
"twox-hash",
]
@@ -13026,6 +13077,7 @@
"cumulus-primitives-utility",
"derivative",
"evm-coder",
+ "fp-evm",
"fp-evm-mapping",
"fp-rpc",
"fp-self-contained",
@@ -13040,6 +13092,7 @@
"impl-trait-for-tuples",
"log",
"logtest",
+ "num_enum",
"orml-tokens",
"orml-traits",
"orml-vesting",
@@ -13055,6 +13108,7 @@
"pallet-evm-coder-substrate",
"pallet-evm-contract-helpers",
"pallet-evm-migration",
+ "pallet-evm-precompile-simple",
"pallet-evm-transaction-payment",
"pallet-foreign-assets",
"pallet-fungible",
@@ -13077,6 +13131,7 @@
"parachain-info",
"parity-scale-codec 3.2.1",
"polkadot-parachain",
+ "precompile-utils-macro",
"rmrk-rpc",
"scale-info",
"serde",
pallets/refungible/src/erc_token.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -19,11 +19,6 @@
//! Provides ERC-20 standart support implementation and EVM API for unique extensions for Refungible Pallet.
//! Method implementations are mostly doing parameter conversion and calling Nonfungible Pallet methods.
-extern crate alloc;
-
-#[cfg(not(feature = "std"))]
-use alloc::format;
-
use core::{
char::{REPLACEMENT_CHARACTER, decode_utf16},
convert::TryInto,
runtime/common/config/ethereum.rsdiffbeforeafterboth--- a/runtime/common/config/ethereum.rs
+++ b/runtime/common/config/ethereum.rs
@@ -7,8 +7,10 @@
use sp_runtime::{RuntimeAppPublic, Perbill};
use crate::{
runtime_common::{
- dispatch::CollectionDispatchT, ethereum::sponsoring::EvmSponsorshipHandler,
- config::sponsoring::DefaultSponsoringRateLimit, DealWithFees,
+ config::sponsoring::DefaultSponsoringRateLimit,
+ DealWithFees,
+ dispatch::CollectionDispatchT,
+ ethereum::{precompiles::UniquePrecompiles, sponsoring::EvmSponsorshipHandler},
},
Runtime, Aura, Balances, RuntimeEvent, ChainId,
};
@@ -34,6 +36,7 @@
const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);
parameter_types! {
pub BlockGasLimit: U256 = U256::from((NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightTimePerGas::get()).ref_time());
+ pub PrecompilesValue: UniquePrecompiles<Runtime> = UniquePrecompiles::<_>::new();
}
pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
@@ -62,8 +65,8 @@
type CallOrigin = EnsureAddressTruncated<Self>;
type WithdrawOrigin = EnsureAddressTruncated<Self>;
type AddressMapping = HashedAddressMapping<Self::Hashing>;
- type PrecompilesType = ();
- type PrecompilesValue = ();
+ type PrecompilesType = UniquePrecompiles<Self>;
+ type PrecompilesValue = PrecompilesValue;
type Currency = Balances;
type RuntimeEvent = RuntimeEvent;
type OnMethodCall = (
runtime/common/ethereum/mod.rsdiffbeforeafterboth--- a/runtime/common/ethereum/mod.rs
+++ b/runtime/common/ethereum/mod.rs
@@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+pub mod precompiles;
pub mod self_contained_call;
pub mod sponsoring;
pub mod transaction_converter;
runtime/common/ethereum/precompiles/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/precompiles/mod.rs
@@ -0,0 +1,44 @@
+use pallet_evm::{Precompile, PrecompileHandle, PrecompileResult, PrecompileSet};
+use sp_core::H160;
+use sp_std::marker::PhantomData;
+
+use pallet_evm_precompile_simple::{ECRecover};
+use sr25519::Sr25519Precompile;
+
+mod sr25519;
+mod utils;
+
+pub struct UniquePrecompiles<R>(PhantomData<R>);
+
+impl<R> UniquePrecompiles<R>
+where
+ R: pallet_evm::Config,
+{
+ pub fn new() -> Self {
+ Self(Default::default())
+ }
+ pub fn used_addresses() -> [H160; 2] {
+ [hash(1), hash(20482)]
+ }
+}
+impl<R> PrecompileSet for UniquePrecompiles<R>
+where
+ R: pallet_evm::Config,
+{
+ fn execute(&self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
+ match handle.code_address() {
+ a if a == hash(1) => Some(ECRecover::execute(handle)),
+ // Sr25519 0x5002
+ a if a == hash(20482) => Some(Sr25519Precompile::<R>::execute(handle)),
+ _ => None,
+ }
+ }
+
+ fn is_precompile(&self, address: H160) -> bool {
+ Self::used_addresses().contains(&address)
+ }
+}
+
+fn hash(a: u64) -> H160 {
+ H160::from_low_u64_be(a)
+}
runtime/common/ethereum/precompiles/sr25519.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/precompiles/sr25519.rs
@@ -0,0 +1,87 @@
+use fp_evm::{Context, ExitSucceed, PrecompileHandle, PrecompileOutput};
+use pallet_evm::Precompile;
+use sp_core::{crypto::UncheckedFrom, sr25519, H256};
+use sp_std::marker::PhantomData;
+use sp_std::prelude::*;
+
+use super::utils::{Bytes, EvmDataReader, EvmDataWriter, EvmResult, FunctionModifier, Gasometer};
+
+#[precompile_utils_macro::generate_function_selector]
+#[derive(Debug, PartialEq)]
+pub enum Action {
+ Verify = "verify(bytes32,bytes,bytes)",
+}
+
+/// A precompile to wrap substrate sr25519 functions.
+pub struct Sr25519Precompile<Runtime>(PhantomData<Runtime>);
+
+impl<Runtime: pallet_evm::Config> Precompile for Sr25519Precompile<Runtime> {
+ fn execute(handle: &mut impl PrecompileHandle) -> EvmResult<PrecompileOutput> {
+ log::trace!(target: "sr25519-precompile", "In sr25519 precompile");
+
+ let gasometer = Gasometer::new();
+
+ let (mut input, selector) = EvmDataReader::new_with_selector(&gasometer, handle.input())?;
+ let input = &mut input;
+
+ gasometer.check_function_modifier(
+ handle.context(),
+ handle.is_static(),
+ FunctionModifier::View,
+ )?;
+
+ match selector {
+ // Dispatchables
+ Action::Verify => Self::verify(input, &gasometer, handle.context()),
+ }
+ }
+}
+
+impl<Runtime: pallet_evm::Config> Sr25519Precompile<Runtime> {
+ fn verify(
+ input: &mut EvmDataReader,
+ gasometer: &Gasometer,
+ _: &Context,
+ ) -> EvmResult<PrecompileOutput> {
+ // Bound check
+ input.expect_arguments(gasometer, 3)?;
+
+ // Parse arguments
+ let public: sr25519::Public =
+ sr25519::Public::unchecked_from(input.read::<H256>(gasometer)?).into();
+ let signature_bytes: Vec<u8> = input.read::<Bytes>(gasometer)?.into();
+ let message: Vec<u8> = input.read::<Bytes>(gasometer)?.into();
+
+ // Parse signature
+ let signature_opt = sr25519::Signature::from_slice(&signature_bytes[..]);
+
+ let signature = if let Some(sig) = signature_opt {
+ sig
+ } else {
+ // Return `false` if signature length is wrong
+ return Ok(PrecompileOutput {
+ exit_status: ExitSucceed::Returned,
+ output: EvmDataWriter::new().write(false).build(),
+ });
+ };
+
+ log::trace!(
+ target: "sr25519-precompile",
+ "Verify signature {:?} for public {:?} and message {:?}",
+ signature, public, message,
+ );
+
+ let is_confirmed = sp_io::crypto::sr25519_verify(&signature, &message[..], &public);
+
+ log::trace!(
+ target: "sr25519-precompile",
+ "Verified signature {:?} is {:?}",
+ signature, is_confirmed,
+ );
+
+ Ok(PrecompileOutput {
+ exit_status: ExitSucceed::Returned,
+ output: EvmDataWriter::new().write(is_confirmed).build(),
+ })
+ }
+}
runtime/common/ethereum/precompiles/utils/data.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/precompiles/utils/data.rs
@@ -0,0 +1,486 @@
+// Copyright 2019-2022 PureStake Inc.
+// Copyright 2022 Stake Technologies
+// This file is part of Utils package, originally developed by Purestake Inc.
+// Utils package used in Astar Network in terms of GPLv3.
+//
+// Utils is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Utils is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Utils. If not, see <http://www.gnu.org/licenses/>.
+
+use super::{EvmResult, Gasometer};
+
+use sp_std::borrow::ToOwned;
+use core::{any::type_name, ops::Range};
+use sp_core::{H160, H256, U256};
+use sp_std::{convert::TryInto, vec, vec::Vec};
+
+/// The `address` type of Solidity.
+/// H160 could represent 2 types of data (bytes20 and address) that are not encoded the same way.
+/// To avoid issues writing H160 is thus not supported.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub struct Address(pub H160);
+
+impl From<H160> for Address {
+ fn from(a: H160) -> Address {
+ Address(a)
+ }
+}
+
+impl From<Address> for H160 {
+ fn from(a: Address) -> H160 {
+ a.0
+ }
+}
+
+/// The `bytes`/`string` type of Solidity.
+/// It is different from `Vec<u8>` which will be serialized with padding for each `u8` element
+/// of the array, while `Bytes` is tightly packed.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Bytes(pub Vec<u8>);
+
+impl From<&[u8]> for Bytes {
+ fn from(a: &[u8]) -> Self {
+ Self(a.to_owned())
+ }
+}
+
+impl From<&str> for Bytes {
+ fn from(a: &str) -> Self {
+ a.as_bytes().into()
+ }
+}
+
+impl Into<Vec<u8>> for Bytes {
+ fn into(self: Self) -> Vec<u8> {
+ self.0
+ }
+}
+
+/// Wrapper around an EVM input slice, helping to parse it.
+/// Provide functions to parse common types.
+#[derive(Clone, Copy, Debug)]
+pub struct EvmDataReader<'a> {
+ input: &'a [u8],
+ cursor: usize,
+}
+
+impl<'a> EvmDataReader<'a> {
+ /// Create a new input parser.
+ pub fn new(input: &'a [u8]) -> Self {
+ Self { input, cursor: 0 }
+ }
+
+ /// Create a new input parser from a selector-initial input.
+ pub fn new_with_selector<T>(gasometer: &Gasometer, input: &'a [u8]) -> EvmResult<(Self, T)>
+ where
+ T: num_enum::TryFromPrimitive<Primitive = u32>,
+ {
+ if input.len() < 4 {
+ return Err(gasometer.revert("tried to parse selector out of bounds"));
+ }
+
+ let mut buffer = [0u8; 4];
+ buffer.copy_from_slice(&input[0..4]);
+ let selector = T::try_from_primitive(u32::from_be_bytes(buffer)).map_err(|_| {
+ log::trace!(
+ target: "precompile-utils",
+ "Failed to match function selector for {}",
+ type_name::<T>()
+ );
+ gasometer.revert("unknown selector")
+ })?;
+
+ Ok((Self::new(&input[4..]), selector))
+ }
+
+ /// Check the input has at least the correct amount of arguments before the end (32 bytes values).
+ pub fn expect_arguments(&self, gasometer: &Gasometer, args: usize) -> EvmResult {
+ if self.input.len() >= self.cursor + args * 32 {
+ Ok(())
+ } else {
+ Err(gasometer.revert("input doesn't match expected length"))
+ }
+ }
+
+ /// Read data from the input.
+ /// Must be provided a gasometer to generate correct Revert errors.
+ /// TODO : Benchmark and add cost of parsing to gasometer ?
+ pub fn read<T: EvmData>(&mut self, gasometer: &Gasometer) -> EvmResult<T> {
+ T::read(self, gasometer)
+ }
+
+ /// Reads a pointer, returning a reader targetting the pointed location.
+ pub fn read_pointer(&mut self, gasometer: &Gasometer) -> EvmResult<Self> {
+ let offset: usize = self
+ .read::<U256>(gasometer)
+ .map_err(|_| gasometer.revert("tried to parse array offset out of bounds"))?
+ .try_into()
+ .map_err(|_| gasometer.revert("array offset is too large"))?;
+
+ if offset >= self.input.len() {
+ return Err(gasometer.revert("pointer points out of bounds"));
+ }
+
+ Ok(Self {
+ input: &self.input[offset..],
+ cursor: 0,
+ })
+ }
+
+ /// Move the reading cursor with provided length, and return a range from the previous cursor
+ /// location to the new one.
+ /// Checks cursor overflows.
+ fn move_cursor(&mut self, gasometer: &Gasometer, len: usize) -> EvmResult<Range<usize>> {
+ let start = self.cursor;
+ let end = self
+ .cursor
+ .checked_add(len)
+ .ok_or_else(|| gasometer.revert("data reading cursor overflow"))?;
+
+ self.cursor = end;
+
+ Ok(start..end)
+ }
+}
+
+/// Help build an EVM input/output data.
+///
+/// Functions takes `self` to allow chaining all calls like
+/// `EvmDataWriter::new().write(...).write(...).build()`.
+/// While it could be more ergonomic to take &mut self, this would
+/// prevent to have a `build` function that don't clone the output.
+#[derive(Clone, Debug)]
+pub struct EvmDataWriter {
+ pub(crate) data: Vec<u8>,
+ offset_data: Vec<OffsetDatum>,
+ selector: Option<u32>,
+}
+
+#[derive(Clone, Debug)]
+struct OffsetDatum {
+ // Offset location in the container data.
+ offset_position: usize,
+ // Data pointed by the offset that must be inserted at the end of container data.
+ data: Vec<u8>,
+ // Inside of arrays, the offset is not from the start of array data (length), but from the start
+ // of the item. This shift allow to correct this.
+ offset_shift: usize,
+}
+
+impl EvmDataWriter {
+ /// Creates a new empty output builder (without selector).
+ pub fn new() -> Self {
+ Self {
+ data: vec![],
+ offset_data: vec![],
+ selector: None,
+ }
+ }
+
+ /// Return the built data.
+ pub fn build(mut self) -> Vec<u8> {
+ Self::bake_offsets(&mut self.data, self.offset_data);
+
+ if let Some(selector) = self.selector {
+ let mut output = selector.to_be_bytes().to_vec();
+ output.append(&mut self.data);
+ output
+ } else {
+ self.data
+ }
+ }
+
+ /// Add offseted data at the end of this writer's data, updating the offsets.
+ fn bake_offsets(output: &mut Vec<u8>, offsets: Vec<OffsetDatum>) {
+ for mut offset_datum in offsets {
+ let offset_position = offset_datum.offset_position;
+ let offset_position_end = offset_position + 32;
+
+ // The offset is the distance between the start of the data and the
+ // start of the pointed data (start of a struct, length of an array).
+ // Offsets in inner data are relative to the start of their respective "container".
+ // However in arrays the "container" is actually the item itself instead of the whole
+ // array, which is corrected by `offset_shift`.
+ let free_space_offset = output.len() - offset_datum.offset_shift;
+
+ // Override dummy offset to the offset it will be in the final output.
+ U256::from(free_space_offset)
+ .to_big_endian(&mut output[offset_position..offset_position_end]);
+
+ // Append this data at the end of the current output.
+ output.append(&mut offset_datum.data);
+ }
+ }
+
+ /// Write arbitrary bytes.
+ /// Doesn't handle any alignement checks, prefer using `write` instead if possible.
+ fn write_raw_bytes(mut self, value: &[u8]) -> Self {
+ self.data.extend_from_slice(value);
+ self
+ }
+
+ /// Write data of requested type.
+ pub fn write<T: EvmData>(mut self, value: T) -> Self {
+ T::write(&mut self, value);
+ self
+ }
+
+ /// Writes a pointer to given data.
+ /// The data will be appended when calling `build`.
+ /// Initially write a dummy value as offset in this writer's data, which will be replaced by
+ /// the correct offset once the pointed data is appended.
+ ///
+ /// Takes `&mut self` since its goal is to be used inside `EvmData` impl and not in chains.
+ pub fn write_pointer(&mut self, data: Vec<u8>) {
+ let offset_position = self.data.len();
+ H256::write(self, H256::repeat_byte(0xff));
+
+ self.offset_data.push(OffsetDatum {
+ offset_position,
+ data,
+ offset_shift: 0,
+ });
+ }
+}
+
+impl Default for EvmDataWriter {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+/// Data that can be converted from and to EVM data types.
+pub trait EvmData: Sized {
+ fn read(reader: &mut EvmDataReader, gasometer: &Gasometer) -> EvmResult<Self>;
+ fn write(writer: &mut EvmDataWriter, value: Self);
+}
+
+impl EvmData for H256 {
+ fn read(reader: &mut EvmDataReader, gasometer: &Gasometer) -> EvmResult<Self> {
+ let range = reader.move_cursor(gasometer, 32)?;
+
+ let data = reader
+ .input
+ .get(range)
+ .ok_or_else(|| gasometer.revert("tried to parse H256 out of bounds"))?;
+
+ Ok(H256::from_slice(data))
+ }
+
+ fn write(writer: &mut EvmDataWriter, value: Self) {
+ writer.data.extend_from_slice(value.as_bytes());
+ }
+}
+
+impl EvmData for Address {
+ fn read(reader: &mut EvmDataReader, gasometer: &Gasometer) -> EvmResult<Self> {
+ let range = reader.move_cursor(gasometer, 32)?;
+
+ let data = reader
+ .input
+ .get(range)
+ .ok_or_else(|| gasometer.revert("tried to parse H160 out of bounds"))?;
+
+ Ok(H160::from_slice(&data[12..32]).into())
+ }
+
+ fn write(writer: &mut EvmDataWriter, value: Self) {
+ H256::write(writer, value.0.into());
+ }
+}
+
+impl EvmData for U256 {
+ fn read(reader: &mut EvmDataReader, gasometer: &Gasometer) -> EvmResult<Self> {
+ let range = reader.move_cursor(gasometer, 32)?;
+
+ let data = reader
+ .input
+ .get(range)
+ .ok_or_else(|| gasometer.revert("tried to parse U256 out of bounds"))?;
+
+ Ok(U256::from_big_endian(data))
+ }
+
+ fn write(writer: &mut EvmDataWriter, value: Self) {
+ let mut buffer = [0u8; 32];
+ value.to_big_endian(&mut buffer);
+ writer.data.extend_from_slice(&buffer);
+ }
+}
+
+macro_rules! impl_evmdata_for_uints {
+ ($($uint:ty, )*) => {
+ $(
+ impl EvmData for $uint {
+ fn read(reader: &mut EvmDataReader, gasometer: &Gasometer) -> EvmResult<Self> {
+ let range = reader.move_cursor(gasometer, 32)?;
+
+ let data = reader
+ .input
+ .get(range)
+ .ok_or_else(|| gasometer.revert(alloc::format!(
+ "tried to parse {} out of bounds", core::any::type_name::<Self>()
+ )))?;
+
+ let mut buffer = [0u8; core::mem::size_of::<Self>()];
+ buffer.copy_from_slice(&data[32 - core::mem::size_of::<Self>()..]);
+ Ok(Self::from_be_bytes(buffer))
+ }
+
+ fn write(writer: &mut EvmDataWriter, value: Self) {
+ let mut buffer = [0u8; 32];
+ buffer[32 - core::mem::size_of::<Self>()..].copy_from_slice(&value.to_be_bytes());
+ writer.data.extend_from_slice(&buffer);
+ }
+ }
+ )*
+ };
+}
+
+impl_evmdata_for_uints!(u16, u32, u64, u128,);
+
+// The implementation for u8 is specific, for performance reasons.
+impl EvmData for u8 {
+ fn read(reader: &mut EvmDataReader, gasometer: &Gasometer) -> EvmResult<Self> {
+ let range = reader.move_cursor(gasometer, 32)?;
+
+ let data = reader
+ .input
+ .get(range)
+ .ok_or_else(|| gasometer.revert("tried to parse u64 out of bounds"))?;
+
+ Ok(data[31])
+ }
+
+ fn write(writer: &mut EvmDataWriter, value: Self) {
+ let mut buffer = [0u8; 32];
+ buffer[31] = value;
+
+ writer.data.extend_from_slice(&buffer);
+ }
+}
+
+impl EvmData for bool {
+ fn read(reader: &mut EvmDataReader, gasometer: &Gasometer) -> EvmResult<Self> {
+ let h256 = H256::read(reader, gasometer)
+ .map_err(|_| gasometer.revert("tried to parse bool out of bounds"))?;
+
+ Ok(!h256.is_zero())
+ }
+
+ fn write(writer: &mut EvmDataWriter, value: Self) {
+ let mut buffer = [0u8; 32];
+ if value {
+ buffer[31] = 1;
+ }
+
+ writer.data.extend_from_slice(&buffer);
+ }
+}
+
+impl<T: EvmData> EvmData for Vec<T> {
+ fn read(reader: &mut EvmDataReader, gasometer: &Gasometer) -> EvmResult<Self> {
+ let mut inner_reader = reader.read_pointer(gasometer)?;
+
+ let array_size: usize = inner_reader
+ .read::<U256>(gasometer)
+ .map_err(|_| gasometer.revert("tried to parse array length out of bounds"))?
+ .try_into()
+ .map_err(|_| gasometer.revert("array length is too large"))?;
+
+ let mut array = vec![];
+
+ let mut item_reader = EvmDataReader {
+ input: inner_reader
+ .input
+ .get(32..)
+ .ok_or_else(|| gasometer.revert("try to read array items out of bound"))?,
+ cursor: 0,
+ };
+
+ for _ in 0..array_size {
+ array.push(item_reader.read(gasometer)?);
+ }
+
+ Ok(array)
+ }
+
+ fn write(writer: &mut EvmDataWriter, value: Self) {
+ let mut inner_writer = EvmDataWriter::new().write(U256::from(value.len()));
+
+ for inner in value {
+ // Any offset in items are relative to the start of the item instead of the
+ // start of the array. However if there is offseted data it must but appended after
+ // all items (offsets) are written. We thus need to rely on `compute_offsets` to do
+ // that, and must store a "shift" to correct the offsets.
+ let shift = inner_writer.data.len();
+ let item_writer = EvmDataWriter::new().write(inner);
+
+ inner_writer = inner_writer.write_raw_bytes(&item_writer.data);
+ for mut offset_datum in item_writer.offset_data {
+ offset_datum.offset_shift += 32;
+ offset_datum.offset_position += shift;
+ inner_writer.offset_data.push(offset_datum);
+ }
+ }
+
+ writer.write_pointer(inner_writer.build());
+ }
+}
+
+impl EvmData for Bytes {
+ fn read(reader: &mut EvmDataReader, gasometer: &Gasometer) -> EvmResult<Self> {
+ let mut inner_reader = reader.read_pointer(gasometer)?;
+
+ // Read bytes/string size.
+ let array_size: usize = inner_reader
+ .read::<U256>(gasometer)
+ .map_err(|_| gasometer.revert("tried to parse bytes/string length out of bounds"))?
+ .try_into()
+ .map_err(|_| gasometer.revert("bytes/string length is too large"))?;
+
+ // Get valid range over the bytes data.
+ let range = inner_reader.move_cursor(gasometer, array_size)?;
+
+ let data = inner_reader
+ .input
+ .get(range)
+ .ok_or_else(|| gasometer.revert("tried to parse bytes/string out of bounds"))?;
+
+ let bytes = Self(data.to_owned());
+
+ Ok(bytes)
+ }
+
+ fn write(writer: &mut EvmDataWriter, value: Self) {
+ let length = value.0.len();
+
+ // Pad the data.
+ // Leave it as is if a multiple of 32, otherwise pad to next
+ // multiple or 32.
+ let chunks = length / 32;
+ let padded_size = match length % 32 {
+ 0 => chunks * 32,
+ _ => (chunks + 1) * 32,
+ };
+
+ let mut value = value.0.to_vec();
+ value.resize(padded_size, 0);
+
+ writer.write_pointer(
+ EvmDataWriter::new()
+ .write(U256::from(length))
+ .write_raw_bytes(&value)
+ .build(),
+ );
+ }
+}
runtime/common/ethereum/precompiles/utils/macro/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/precompiles/utils/macro/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "precompile-utils-macro"
+authors = [ "StakeTechnologies", "PureStake" ]
+description = ""
+edition = "2018"
+version = "0.1.0"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+num_enum = { version = "0.5.3", default-features = false }
+proc-macro2 = "1.0"
+quote = "1.0"
+sha3 = "0.8"
+syn = { version = "1.0", features = [ "extra-traits", "fold", "full", "visit" ] }
runtime/common/ethereum/precompiles/utils/macro/src/lib.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/precompiles/utils/macro/src/lib.rs
@@ -0,0 +1,115 @@
+// Copyright 2019-2022 PureStake Inc.
+// Copyright 2022 Stake Technologies
+// This file is part of Utils package, originally developed by Purestake Inc.
+// Utils package used in Astar Network in terms of GPLv3.
+//
+// Utils is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Utils is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Utils. If not, see <http://www.gnu.org/licenses/>.
+
+#![crate_type = "proc-macro"]
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+use proc_macro2::Literal;
+use quote::{quote, quote_spanned};
+use sha3::{Digest, Keccak256};
+use std::convert::TryInto;
+use syn::{parse_macro_input, spanned::Spanned, Expr, ExprLit, Ident, ItemEnum, Lit};
+
+/// This macro allows to associate to each variant of an enumeration a discriminant (of type u32
+/// whose value corresponds to the first 4 bytes of the Hash Keccak256 of the character string
+///indicated by the user of this macro.
+///
+/// Usage:
+///
+/// ```ignore
+/// #[generate_function_selector]
+/// enum Action {
+/// Toto = "toto()",
+/// Tata = "tata()",
+/// }
+/// ```
+///
+/// Extanded to:
+///
+/// ```rust
+/// #[repr(u32)]
+/// enum Action {
+/// Toto = 119097542u32,
+/// Tata = 1414311903u32,
+/// }
+/// ```
+///
+#[proc_macro_attribute]
+pub fn generate_function_selector(_: TokenStream, input: TokenStream) -> TokenStream {
+ let item = parse_macro_input!(input as ItemEnum);
+
+ let ItemEnum {
+ attrs,
+ vis,
+ enum_token,
+ ident,
+ variants,
+ ..
+ } = item;
+
+ let mut ident_expressions: Vec<Ident> = vec![];
+ let mut variant_expressions: Vec<Expr> = vec![];
+ for variant in variants {
+ match variant.discriminant {
+ Some((_, Expr::Lit(ExprLit { lit, .. }))) => {
+ if let Lit::Str(lit_str) = lit {
+ let selector = u32::from_be_bytes(
+ Keccak256::digest(lit_str.value().as_ref())[..4]
+ .try_into()
+ .unwrap(),
+ );
+ ident_expressions.push(variant.ident);
+ variant_expressions.push(Expr::Lit(ExprLit {
+ lit: Lit::Verbatim(Literal::u32_suffixed(selector)),
+ attrs: Default::default(),
+ }));
+ } else {
+ return quote_spanned! {
+ lit.span() => compile_error("Expected literal string");
+ }
+ .into();
+ }
+ }
+ Some((_eg, expr)) => {
+ return quote_spanned! {
+ expr.span() => compile_error("Expected literal");
+ }
+ .into()
+ }
+ None => {
+ return quote_spanned! {
+ variant.span() => compile_error("Each variant must have a discriminant");
+ }
+ .into()
+ }
+ }
+ }
+
+ (quote! {
+ #(#attrs)*
+ #[derive(num_enum::TryFromPrimitive, num_enum::IntoPrimitive)]
+ #[repr(u32)]
+ #vis #enum_token #ident {
+ #(
+ #ident_expressions = #variant_expressions,
+ )*
+ }
+ })
+ .into()
+}
runtime/common/ethereum/precompiles/utils/mod.rsdiffbeforeafterboth--- /dev/null
+++ b/runtime/common/ethereum/precompiles/utils/mod.rs
@@ -0,0 +1,95 @@
+// Copyright 2019-2022 PureStake Inc.
+// Copyright 2022 Stake Technologies
+// This file is part of Utils package, originally developed by Purestake Inc.
+// Utils package used in Astar Network in terms of GPLv3.
+//
+// Utils is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Utils is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Utils. If not, see <http://www.gnu.org/licenses/>.
+
+use sp_std::borrow::ToOwned;
+use fp_evm::{Context, ExitRevert, PrecompileFailure};
+use sp_core::U256;
+use sp_std::marker::PhantomData;
+
+mod data;
+
+pub use data::{Bytes, EvmData, EvmDataReader, EvmDataWriter};
+
+/// Alias for Result returning an EVM precompile error.
+pub type EvmResult<T = ()> = Result<T, PrecompileFailure>;
+
+/// Helper functions requiring a Runtime.
+/// This runtime must of course implement `pallet_evm::Config`.
+#[derive(Clone, Copy, Debug)]
+pub struct RuntimeHelper<Runtime>(PhantomData<Runtime>);
+
+/// Represents modifiers a Solidity function can be annotated with.
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum FunctionModifier {
+ /// Function that doesn't modify the state.
+ View,
+ /// Function that modifies the state and accept funds.
+ Payable,
+}
+
+/// Custom Gasometer to record costs in precompiles.
+/// It is advised to record known costs as early as possible to
+/// avoid unecessary computations if there is an Out of Gas.
+///
+/// Provides functions related to reverts, as reverts takes the recorded amount
+/// of gas into account.
+#[derive(Clone, Copy, Debug)]
+pub struct Gasometer();
+
+impl Gasometer {
+ /// Create a new Gasometer with provided gas limit.
+ /// None is no limit.
+ pub fn new() -> Self {
+ Self()
+ }
+
+ /// Revert the execution, making the user pay for the the currently
+ /// recorded cost. It is better to **revert** instead of **error** as
+ /// erroring consumes the entire gas limit, and **revert** returns an error
+ /// message to the calling contract.
+ ///
+ /// TODO : Record cost of the input based on its size and handle Out of Gas ?
+ /// This might be required if we format revert messages using user data.
+ #[must_use]
+ pub fn revert(&self, output: impl AsRef<[u8]>) -> PrecompileFailure {
+ PrecompileFailure::Revert {
+ exit_status: ExitRevert::Reverted,
+ output: output.as_ref().to_owned(),
+ }
+ }
+
+ #[must_use]
+ /// Check that a function call is compatible with the context it is
+ /// called into.
+ pub fn check_function_modifier(
+ &self,
+ context: &Context,
+ is_static: bool,
+ modifier: FunctionModifier,
+ ) -> EvmResult {
+ if is_static && modifier != FunctionModifier::View {
+ return Err(self.revert("can't call non-static function in static context"));
+ }
+
+ if modifier != FunctionModifier::Payable && context.apparent_value > U256::zero() {
+ return Err(self.revert("function is not payable"));
+ }
+
+ Ok(())
+ }
+}
runtime/opal/Cargo.tomldiffbeforeafterboth1################################################################################2# Package34cargo-features = ["workspace-inheritance"]56[package]7authors = ['Unique Network <support@uniquenetwork.io>']8build = 'build.rs'9description = 'Opal Runtime'10edition = '2021'11homepage = 'https://unique.network'12license = 'GPLv3'13name = 'opal-runtime'14repository = 'https://github.com/UniqueNetwork/unique-chain'15version = "0.9.33"1617[package.metadata.docs.rs]18targets = ['x86_64-unknown-linux-gnu']1920[features]21default = ['std', 'opal-runtime']22runtime-benchmarks = [23 'hex-literal',24 'frame-benchmarking',25 'frame-support/runtime-benchmarks',26 'frame-system-benchmarking',27 'frame-system/runtime-benchmarks',28 'pallet-ethereum/runtime-benchmarks',29 'pallet-evm-migration/runtime-benchmarks',30 'pallet-evm-coder-substrate/runtime-benchmarks',31 'pallet-balances/runtime-benchmarks',32 'pallet-timestamp/runtime-benchmarks',33 'pallet-common/runtime-benchmarks',34 'pallet-structure/runtime-benchmarks',35 'pallet-fungible/runtime-benchmarks',36 'pallet-refungible/runtime-benchmarks',37 'pallet-nonfungible/runtime-benchmarks',38 'pallet-proxy-rmrk-core/runtime-benchmarks',39 'pallet-proxy-rmrk-equip/runtime-benchmarks',40 'pallet-foreign-assets/runtime-benchmarks',41 'pallet-unique/runtime-benchmarks',42 'pallet-inflation/runtime-benchmarks',43 'pallet-app-promotion/runtime-benchmarks',44 'pallet-unique-scheduler-v2/runtime-benchmarks',45 'pallet-xcm/runtime-benchmarks',46 'sp-runtime/runtime-benchmarks',47 'xcm-builder/runtime-benchmarks',48 'pallet-maintenance/runtime-benchmarks',49]50try-runtime = [51 'frame-try-runtime',52 'frame-try-runtime?/try-runtime',53 'frame-executive/try-runtime',54 'frame-support/try-runtime',55 'frame-system/try-runtime',56 'cumulus-pallet-parachain-system/try-runtime',57 'parachain-info/try-runtime',58 'pallet-aura/try-runtime',59 'cumulus-pallet-aura-ext/try-runtime',60 'pallet-balances/try-runtime',61 'pallet-randomness-collective-flip/try-runtime',62 'pallet-timestamp/try-runtime',63 'pallet-transaction-payment/try-runtime',64 'pallet-treasury/try-runtime',65 'pallet-sudo/try-runtime',66 'orml-vesting/try-runtime',67 'orml-xtokens/try-runtime',68 'orml-tokens/try-runtime',69 'cumulus-pallet-xcmp-queue/try-runtime',70 'pallet-xcm/try-runtime',71 'cumulus-pallet-xcm/try-runtime',72 'cumulus-pallet-dmp-queue/try-runtime',73 'pallet-inflation/try-runtime',74 'pallet-unique/try-runtime',75 'pallet-configuration/try-runtime',76 'pallet-charge-transaction/try-runtime',77 'pallet-common/try-runtime',78 'pallet-fungible/try-runtime',79 'pallet-refungible/try-runtime',80 'pallet-nonfungible/try-runtime',81 'pallet-structure/try-runtime',82 'pallet-proxy-rmrk-core/try-runtime',83 'pallet-proxy-rmrk-equip/try-runtime',84 'pallet-app-promotion/try-runtime',85 'pallet-foreign-assets/try-runtime',86 'pallet-ethereum/try-runtime',87 'pallet-evm/try-runtime',88 'pallet-evm-coder-substrate/try-runtime',89 'pallet-evm-contract-helpers/try-runtime',90 'pallet-evm-transaction-payment/try-runtime',91 'pallet-evm-migration/try-runtime',92 'pallet-base-fee/try-runtime',93 'pallet-unique-scheduler-v2/try-runtime',94 'pallet-maintenance/try-runtime',95 'pallet-test-utils?/try-runtime',96]97std = [98 'codec/std',99 'cumulus-pallet-aura-ext/std',100 'cumulus-pallet-parachain-system/std',101 'cumulus-pallet-xcm/std',102 'cumulus-pallet-xcmp-queue/std',103 'cumulus-primitives-core/std',104 'cumulus-primitives-utility/std',105 'frame-try-runtime/std',106 'frame-executive/std',107 'frame-support/std',108 'frame-system/std',109 'frame-system-rpc-runtime-api/std',110 'pallet-aura/std',111 'pallet-balances/std',112 # 'pallet-contracts/std',113 # 'pallet-contracts-primitives/std',114 # 'pallet-contracts-rpc-runtime-api/std',115 # 'pallet-contract-helpers/std',116 'pallet-randomness-collective-flip/std',117 'pallet-sudo/std',118 'pallet-timestamp/std',119 'pallet-transaction-payment/std',120 'pallet-transaction-payment-rpc-runtime-api/std',121 'pallet-treasury/std',122 'pallet-evm/std',123 'pallet-evm-migration/std',124 'pallet-evm-contract-helpers/std',125 'pallet-evm-transaction-payment/std',126 'pallet-evm-coder-substrate/std',127 'pallet-ethereum/std',128 'pallet-base-fee/std',129 'fp-rpc/std',130 'up-rpc/std',131 'app-promotion-rpc/std',132 'fp-evm-mapping/std',133 'fp-self-contained/std',134 'parachain-info/std',135 'serde',136 'pallet-inflation/std',137 'pallet-configuration/std',138 'pallet-app-promotion/std',139 'pallet-common/std',140 'pallet-structure/std',141 'pallet-fungible/std',142 'pallet-refungible/std',143 'pallet-nonfungible/std',144 'pallet-proxy-rmrk-core/std',145 'pallet-proxy-rmrk-equip/std',146 'pallet-unique/std',147 'pallet-unique-scheduler-v2/std',148 'pallet-charge-transaction/std',149 'up-data-structs/std',150 'sp-api/std',151 'sp-block-builder/std',152 "sp-consensus-aura/std",153 'sp-core/std',154 'sp-inherents/std',155 'sp-io/std',156 'sp-offchain/std',157 'sp-runtime/std',158 'sp-session/std',159 'sp-std/std',160 'sp-transaction-pool/std',161 'sp-version/std',162 'xcm/std',163 'xcm-builder/std',164 'xcm-executor/std',165 'up-common/std',166 'rmrk-rpc/std',167 'evm-coder/std',168 'up-sponsorship/std',169170 "orml-vesting/std",171 "orml-tokens/std",172 "orml-xtokens/std",173 "orml-traits/std",174 "pallet-foreign-assets/std",175176 'pallet-maintenance/std',177 'pallet-test-utils?/std',178]179limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']180opal-runtime = [181 'refungible',182 'rmrk',183 'app-promotion',184 'foreign-assets',185 'pallet-test-utils',186]187become-sapphire = []188189refungible = []190scheduler = []191rmrk = []192foreign-assets = []193app-promotion = []194195################################################################################196# Substrate Dependencies197198[dependencies.codec]199default-features = false200features = ['derive']201package = 'parity-scale-codec'202version = '3.1.2'203204[dependencies.frame-benchmarking]205default-features = false206git = "https://github.com/paritytech/substrate"207optional = true208branch = "polkadot-v0.9.33"209210[dependencies.frame-try-runtime]211default-features = false212git = "https://github.com/paritytech/substrate"213optional = true214branch = "polkadot-v0.9.33"215216[dependencies.frame-executive]217default-features = false218git = "https://github.com/paritytech/substrate"219branch = "polkadot-v0.9.33"220221[dependencies.frame-support]222default-features = false223git = "https://github.com/paritytech/substrate"224branch = "polkadot-v0.9.33"225226[dependencies.frame-system]227default-features = false228git = "https://github.com/paritytech/substrate"229branch = "polkadot-v0.9.33"230231[dependencies.frame-system-benchmarking]232default-features = false233git = "https://github.com/paritytech/substrate"234optional = true235branch = "polkadot-v0.9.33"236237[dependencies.frame-system-rpc-runtime-api]238default-features = false239git = "https://github.com/paritytech/substrate"240branch = "polkadot-v0.9.33"241242[dependencies.hex-literal]243optional = true244version = '0.3.3'245246[dependencies.serde]247default-features = false248features = ['derive']249optional = true250version = '1.0.130'251252[dependencies.pallet-aura]253default-features = false254git = "https://github.com/paritytech/substrate"255branch = "polkadot-v0.9.33"256257[dependencies.pallet-balances]258default-features = false259git = "https://github.com/paritytech/substrate"260branch = "polkadot-v0.9.33"261262# Contracts specific packages263# [dependencies.pallet-contracts]264# git = 'https://github.com/paritytech/substrate'265# default-features = false266# branch = 'master'267# version = '4.0.0-dev'268269# [dependencies.pallet-contracts-primitives]270# git = 'https://github.com/paritytech/substrate'271# default-features = false272# branch = 'master'273# version = '4.0.0-dev'274275# [dependencies.pallet-contracts-rpc-runtime-api]276# git = 'https://github.com/paritytech/substrate'277# default-features = false278# branch = 'master'279# version = '4.0.0-dev'280281[dependencies.pallet-randomness-collective-flip]282default-features = false283git = "https://github.com/paritytech/substrate"284branch = "polkadot-v0.9.33"285286[dependencies.pallet-sudo]287default-features = false288git = "https://github.com/paritytech/substrate"289branch = "polkadot-v0.9.33"290291[dependencies.pallet-timestamp]292default-features = false293git = "https://github.com/paritytech/substrate"294branch = "polkadot-v0.9.33"295296[dependencies.pallet-transaction-payment]297default-features = false298git = "https://github.com/paritytech/substrate"299branch = "polkadot-v0.9.33"300301[dependencies.pallet-transaction-payment-rpc-runtime-api]302default-features = false303git = "https://github.com/paritytech/substrate"304branch = "polkadot-v0.9.33"305306[dependencies.pallet-treasury]307default-features = false308git = "https://github.com/paritytech/substrate"309branch = "polkadot-v0.9.33"310311[dependencies.sp-arithmetic]312default-features = false313git = "https://github.com/paritytech/substrate"314branch = "polkadot-v0.9.33"315316[dependencies.sp-api]317default-features = false318git = "https://github.com/paritytech/substrate"319branch = "polkadot-v0.9.33"320321[dependencies.sp-block-builder]322default-features = false323git = "https://github.com/paritytech/substrate"324branch = "polkadot-v0.9.33"325326[dependencies.sp-core]327default-features = false328git = "https://github.com/paritytech/substrate"329branch = "polkadot-v0.9.33"330331[dependencies.sp-consensus-aura]332default-features = false333git = "https://github.com/paritytech/substrate"334branch = "polkadot-v0.9.33"335336[dependencies.sp-inherents]337default-features = false338git = "https://github.com/paritytech/substrate"339branch = "polkadot-v0.9.33"340341[dependencies.sp-io]342default-features = false343git = "https://github.com/paritytech/substrate"344branch = "polkadot-v0.9.33"345346[dependencies.sp-offchain]347default-features = false348git = "https://github.com/paritytech/substrate"349branch = "polkadot-v0.9.33"350351[dependencies.sp-runtime]352default-features = false353git = "https://github.com/paritytech/substrate"354branch = "polkadot-v0.9.33"355356[dependencies.sp-session]357default-features = false358git = "https://github.com/paritytech/substrate"359branch = "polkadot-v0.9.33"360361[dependencies.sp-std]362default-features = false363git = "https://github.com/paritytech/substrate"364branch = "polkadot-v0.9.33"365366[dependencies.sp-transaction-pool]367default-features = false368git = "https://github.com/paritytech/substrate"369branch = "polkadot-v0.9.33"370371[dependencies.sp-version]372default-features = false373git = "https://github.com/paritytech/substrate"374branch = "polkadot-v0.9.33"375376[dependencies.smallvec]377version = '1.6.1'378379################################################################################380# Cumulus dependencies381382[dependencies.parachain-info]383default-features = false384git = "https://github.com/paritytech/cumulus"385branch = "polkadot-v0.9.33"386387[dependencies.cumulus-pallet-aura-ext]388git = "https://github.com/paritytech/cumulus"389branch = "polkadot-v0.9.33"390default-features = false391392[dependencies.cumulus-pallet-parachain-system]393git = "https://github.com/paritytech/cumulus"394branch = "polkadot-v0.9.33"395default-features = false396397[dependencies.cumulus-primitives-core]398git = "https://github.com/paritytech/cumulus"399branch = "polkadot-v0.9.33"400default-features = false401402[dependencies.cumulus-pallet-xcm]403git = "https://github.com/paritytech/cumulus"404branch = "polkadot-v0.9.33"405default-features = false406407[dependencies.cumulus-pallet-dmp-queue]408git = "https://github.com/paritytech/cumulus"409branch = "polkadot-v0.9.33"410default-features = false411412[dependencies.cumulus-pallet-xcmp-queue]413git = "https://github.com/paritytech/cumulus"414branch = "polkadot-v0.9.33"415default-features = false416417[dependencies.cumulus-primitives-utility]418git = "https://github.com/paritytech/cumulus"419branch = "polkadot-v0.9.33"420default-features = false421422[dependencies.cumulus-primitives-timestamp]423git = "https://github.com/paritytech/cumulus"424branch = "polkadot-v0.9.33"425default-features = false426427################################################################################428# Polkadot dependencies429430[dependencies.polkadot-parachain]431git = "https://github.com/paritytech/polkadot"432branch = "release-v0.9.33"433default-features = false434435[dependencies.xcm]436git = "https://github.com/paritytech/polkadot"437branch = "release-v0.9.33"438default-features = false439440[dependencies.xcm-builder]441git = "https://github.com/paritytech/polkadot"442branch = "release-v0.9.33"443default-features = false444445[dependencies.xcm-executor]446git = "https://github.com/paritytech/polkadot"447branch = "release-v0.9.33"448default-features = false449450[dependencies.pallet-xcm]451git = "https://github.com/paritytech/polkadot"452branch = "release-v0.9.33"453default-features = false454455################################################################################456# local dependencies457458[dependencies]459orml-vesting.workspace = true460orml-xtokens.workspace = true461orml-tokens.workspace = true462orml-traits.workspace = true463464log = { version = "0.4.16", default-features = false }465up-common = { path = "../../primitives/common", default-features = false }466scale-info = { version = "2.0.1", default-features = false, features = [467 "derive",468] }469derivative = "2.2.0"470pallet-unique = { path = '../../pallets/unique', default-features = false }471up-rpc = { path = "../../primitives/rpc", default-features = false }472app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false }473rmrk-rpc = { path = "../../primitives/rmrk-rpc", default-features = false }474fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }475pallet-inflation = { path = '../../pallets/inflation', default-features = false }476pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }477up-data-structs = { path = '../../primitives/data-structs', default-features = false }478pallet-configuration = { default-features = false, path = "../../pallets/configuration" }479pallet-common = { default-features = false, path = "../../pallets/common" }480pallet-structure = { default-features = false, path = "../../pallets/structure" }481pallet-fungible = { default-features = false, path = "../../pallets/fungible" }482pallet-refungible = { default-features = false, path = "../../pallets/refungible" }483pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }484pallet-proxy-rmrk-core = { default-features = false, path = "../../pallets/proxy-rmrk-core", package = "pallet-rmrk-core" }485pallet-proxy-rmrk-equip = { default-features = false, path = "../../pallets/proxy-rmrk-equip", package = "pallet-rmrk-equip" }486pallet-charge-transaction = { git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.33", package = "pallet-template-transaction-payment", default-features = false, version = "3.0.0" }487pallet-unique-scheduler-v2 = { path = '../../pallets/scheduler-v2', default-features = false }488pallet-evm-migration = { path = '../../pallets/evm-migration', default-features = false }489pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }490pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }491pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }492pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }493pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }494pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }495fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }496fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }497evm-coder = { default-features = false, path = '../../crates/evm-coder' }498up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.33' }499pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }500pallet-maintenance = { default-features = false, path = "../../pallets/maintenance" }501502################################################################################503# Test dependencies504505pallet-test-utils = { optional = true, default-features = false, path = "../../test-pallets/utils" }506507################################################################################508# Other Dependencies509510impl-trait-for-tuples = "0.2.2"511512################################################################################513# Dev Dependencies514515[dev-dependencies.logtest]516version = "2.0.0"517518################################################################################519# Build Dependencies520521[build-dependencies.substrate-wasm-builder]522git = "https://github.com/paritytech/substrate"523branch = "polkadot-v0.9.33"1################################################################################2# Package34cargo-features = ["workspace-inheritance"]56[package]7authors = ['Unique Network <support@uniquenetwork.io>']8build = 'build.rs'9description = 'Opal Runtime'10edition = '2021'11homepage = 'https://unique.network'12license = 'GPLv3'13name = 'opal-runtime'14repository = 'https://github.com/UniqueNetwork/unique-chain'15version = "0.9.33"1617[package.metadata.docs.rs]18targets = ['x86_64-unknown-linux-gnu']1920[features]21default = ['std', 'opal-runtime']22runtime-benchmarks = [23 'hex-literal',24 'frame-benchmarking',25 'frame-support/runtime-benchmarks',26 'frame-system-benchmarking',27 'frame-system/runtime-benchmarks',28 'pallet-ethereum/runtime-benchmarks',29 'pallet-evm-migration/runtime-benchmarks',30 'pallet-evm-coder-substrate/runtime-benchmarks',31 'pallet-balances/runtime-benchmarks',32 'pallet-timestamp/runtime-benchmarks',33 'pallet-common/runtime-benchmarks',34 'pallet-structure/runtime-benchmarks',35 'pallet-fungible/runtime-benchmarks',36 'pallet-refungible/runtime-benchmarks',37 'pallet-nonfungible/runtime-benchmarks',38 'pallet-proxy-rmrk-core/runtime-benchmarks',39 'pallet-proxy-rmrk-equip/runtime-benchmarks',40 'pallet-foreign-assets/runtime-benchmarks',41 'pallet-unique/runtime-benchmarks',42 'pallet-inflation/runtime-benchmarks',43 'pallet-app-promotion/runtime-benchmarks',44 'pallet-unique-scheduler-v2/runtime-benchmarks',45 'pallet-xcm/runtime-benchmarks',46 'sp-runtime/runtime-benchmarks',47 'xcm-builder/runtime-benchmarks',48 'pallet-maintenance/runtime-benchmarks',49]50try-runtime = [51 'frame-try-runtime',52 'frame-try-runtime?/try-runtime',53 'frame-executive/try-runtime',54 'frame-support/try-runtime',55 'frame-system/try-runtime',56 'cumulus-pallet-parachain-system/try-runtime',57 'parachain-info/try-runtime',58 'pallet-aura/try-runtime',59 'cumulus-pallet-aura-ext/try-runtime',60 'pallet-balances/try-runtime',61 'pallet-randomness-collective-flip/try-runtime',62 'pallet-timestamp/try-runtime',63 'pallet-transaction-payment/try-runtime',64 'pallet-treasury/try-runtime',65 'pallet-sudo/try-runtime',66 'orml-vesting/try-runtime',67 'orml-xtokens/try-runtime',68 'orml-tokens/try-runtime',69 'cumulus-pallet-xcmp-queue/try-runtime',70 'pallet-xcm/try-runtime',71 'cumulus-pallet-xcm/try-runtime',72 'cumulus-pallet-dmp-queue/try-runtime',73 'pallet-inflation/try-runtime',74 'pallet-unique/try-runtime',75 'pallet-configuration/try-runtime',76 'pallet-charge-transaction/try-runtime',77 'pallet-common/try-runtime',78 'pallet-fungible/try-runtime',79 'pallet-refungible/try-runtime',80 'pallet-nonfungible/try-runtime',81 'pallet-structure/try-runtime',82 'pallet-proxy-rmrk-core/try-runtime',83 'pallet-proxy-rmrk-equip/try-runtime',84 'pallet-app-promotion/try-runtime',85 'pallet-foreign-assets/try-runtime',86 'pallet-ethereum/try-runtime',87 'pallet-evm/try-runtime',88 'pallet-evm-coder-substrate/try-runtime',89 'pallet-evm-contract-helpers/try-runtime',90 'pallet-evm-transaction-payment/try-runtime',91 'pallet-evm-migration/try-runtime',92 'pallet-base-fee/try-runtime',93 'pallet-unique-scheduler-v2/try-runtime',94 'pallet-maintenance/try-runtime',95 'pallet-test-utils?/try-runtime',96]97std = [98 'codec/std',99 'cumulus-pallet-aura-ext/std',100 'cumulus-pallet-parachain-system/std',101 'cumulus-pallet-xcm/std',102 'cumulus-pallet-xcmp-queue/std',103 'cumulus-primitives-core/std',104 'cumulus-primitives-utility/std',105 'frame-try-runtime/std',106 'frame-executive/std',107 'frame-support/std',108 'frame-system/std',109 'frame-system-rpc-runtime-api/std',110 'pallet-aura/std',111 'pallet-balances/std',112 # 'pallet-contracts/std',113 # 'pallet-contracts-primitives/std',114 # 'pallet-contracts-rpc-runtime-api/std',115 # 'pallet-contract-helpers/std',116 'pallet-randomness-collective-flip/std',117 'pallet-sudo/std',118 'pallet-timestamp/std',119 'pallet-transaction-payment/std',120 'pallet-transaction-payment-rpc-runtime-api/std',121 'pallet-treasury/std',122 'pallet-evm/std',123 'pallet-evm-migration/std',124 'pallet-evm-contract-helpers/std',125 'pallet-evm-transaction-payment/std',126 'pallet-evm-coder-substrate/std',127 'pallet-ethereum/std',128 'pallet-base-fee/std',129 'fp-rpc/std',130 'up-rpc/std',131 'app-promotion-rpc/std',132 'fp-evm-mapping/std',133 'fp-self-contained/std',134 'parachain-info/std',135 'serde',136 'pallet-inflation/std',137 'pallet-configuration/std',138 'pallet-app-promotion/std',139 'pallet-common/std',140 'pallet-structure/std',141 'pallet-fungible/std',142 'pallet-refungible/std',143 'pallet-nonfungible/std',144 'pallet-proxy-rmrk-core/std',145 'pallet-proxy-rmrk-equip/std',146 'pallet-unique/std',147 'pallet-unique-scheduler-v2/std',148 'pallet-charge-transaction/std',149 'up-data-structs/std',150 'sp-api/std',151 'sp-block-builder/std',152 "sp-consensus-aura/std",153 'sp-core/std',154 'sp-inherents/std',155 'sp-io/std',156 'sp-offchain/std',157 'sp-runtime/std',158 'sp-session/std',159 'sp-std/std',160 'sp-transaction-pool/std',161 'sp-version/std',162 'xcm/std',163 'xcm-builder/std',164 'xcm-executor/std',165 'up-common/std',166 'rmrk-rpc/std',167 'evm-coder/std',168 'up-sponsorship/std',169170 "orml-vesting/std",171 "orml-tokens/std",172 "orml-xtokens/std",173 "orml-traits/std",174 "pallet-foreign-assets/std",175176 'pallet-maintenance/std',177 'pallet-test-utils?/std',178]179limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']180opal-runtime = [181 'refungible',182 'rmrk',183 'app-promotion',184 'foreign-assets',185 'pallet-test-utils',186]187become-sapphire = []188189refungible = []190scheduler = []191rmrk = []192foreign-assets = []193app-promotion = []194195################################################################################196# Substrate Dependencies197198[dependencies.codec]199default-features = false200features = ['derive']201package = 'parity-scale-codec'202version = '3.1.2'203204[dependencies.frame-benchmarking]205default-features = false206git = "https://github.com/paritytech/substrate"207optional = true208branch = "polkadot-v0.9.33"209210[dependencies.frame-try-runtime]211default-features = false212git = "https://github.com/paritytech/substrate"213optional = true214branch = "polkadot-v0.9.33"215216[dependencies.frame-executive]217default-features = false218git = "https://github.com/paritytech/substrate"219branch = "polkadot-v0.9.33"220221[dependencies.frame-support]222default-features = false223git = "https://github.com/paritytech/substrate"224branch = "polkadot-v0.9.33"225226[dependencies.frame-system]227default-features = false228git = "https://github.com/paritytech/substrate"229branch = "polkadot-v0.9.33"230231[dependencies.frame-system-benchmarking]232default-features = false233git = "https://github.com/paritytech/substrate"234optional = true235branch = "polkadot-v0.9.33"236237[dependencies.frame-system-rpc-runtime-api]238default-features = false239git = "https://github.com/paritytech/substrate"240branch = "polkadot-v0.9.33"241242[dependencies.hex-literal]243optional = true244version = '0.3.3'245246[dependencies.serde]247default-features = false248features = ['derive']249optional = true250version = '1.0.130'251252[dependencies.pallet-aura]253default-features = false254git = "https://github.com/paritytech/substrate"255branch = "polkadot-v0.9.33"256257[dependencies.pallet-balances]258default-features = false259git = "https://github.com/paritytech/substrate"260branch = "polkadot-v0.9.33"261262# Contracts specific packages263# [dependencies.pallet-contracts]264# git = 'https://github.com/paritytech/substrate'265# default-features = false266# branch = 'master'267# version = '4.0.0-dev'268269# [dependencies.pallet-contracts-primitives]270# git = 'https://github.com/paritytech/substrate'271# default-features = false272# branch = 'master'273# version = '4.0.0-dev'274275# [dependencies.pallet-contracts-rpc-runtime-api]276# git = 'https://github.com/paritytech/substrate'277# default-features = false278# branch = 'master'279# version = '4.0.0-dev'280281[dependencies.pallet-randomness-collective-flip]282default-features = false283git = "https://github.com/paritytech/substrate"284branch = "polkadot-v0.9.33"285286[dependencies.pallet-sudo]287default-features = false288git = "https://github.com/paritytech/substrate"289branch = "polkadot-v0.9.33"290291[dependencies.pallet-timestamp]292default-features = false293git = "https://github.com/paritytech/substrate"294branch = "polkadot-v0.9.33"295296[dependencies.pallet-transaction-payment]297default-features = false298git = "https://github.com/paritytech/substrate"299branch = "polkadot-v0.9.33"300301[dependencies.pallet-transaction-payment-rpc-runtime-api]302default-features = false303git = "https://github.com/paritytech/substrate"304branch = "polkadot-v0.9.33"305306[dependencies.pallet-treasury]307default-features = false308git = "https://github.com/paritytech/substrate"309branch = "polkadot-v0.9.33"310311[dependencies.sp-arithmetic]312default-features = false313git = "https://github.com/paritytech/substrate"314branch = "polkadot-v0.9.33"315316[dependencies.sp-api]317default-features = false318git = "https://github.com/paritytech/substrate"319branch = "polkadot-v0.9.33"320321[dependencies.sp-block-builder]322default-features = false323git = "https://github.com/paritytech/substrate"324branch = "polkadot-v0.9.33"325326[dependencies.sp-core]327default-features = false328git = "https://github.com/paritytech/substrate"329branch = "polkadot-v0.9.33"330331[dependencies.sp-consensus-aura]332default-features = false333git = "https://github.com/paritytech/substrate"334branch = "polkadot-v0.9.33"335336[dependencies.sp-inherents]337default-features = false338git = "https://github.com/paritytech/substrate"339branch = "polkadot-v0.9.33"340341[dependencies.sp-io]342default-features = false343git = "https://github.com/paritytech/substrate"344branch = "polkadot-v0.9.33"345346[dependencies.sp-offchain]347default-features = false348git = "https://github.com/paritytech/substrate"349branch = "polkadot-v0.9.33"350351[dependencies.sp-runtime]352default-features = false353git = "https://github.com/paritytech/substrate"354branch = "polkadot-v0.9.33"355356[dependencies.sp-session]357default-features = false358git = "https://github.com/paritytech/substrate"359branch = "polkadot-v0.9.33"360361[dependencies.sp-std]362default-features = false363git = "https://github.com/paritytech/substrate"364branch = "polkadot-v0.9.33"365366[dependencies.sp-transaction-pool]367default-features = false368git = "https://github.com/paritytech/substrate"369branch = "polkadot-v0.9.33"370371[dependencies.sp-version]372default-features = false373git = "https://github.com/paritytech/substrate"374branch = "polkadot-v0.9.33"375376[dependencies.smallvec]377version = '1.6.1'378379################################################################################380# Cumulus dependencies381382[dependencies.parachain-info]383default-features = false384git = "https://github.com/paritytech/cumulus"385branch = "polkadot-v0.9.33"386387[dependencies.cumulus-pallet-aura-ext]388git = "https://github.com/paritytech/cumulus"389branch = "polkadot-v0.9.33"390default-features = false391392[dependencies.cumulus-pallet-parachain-system]393git = "https://github.com/paritytech/cumulus"394branch = "polkadot-v0.9.33"395default-features = false396397[dependencies.cumulus-primitives-core]398git = "https://github.com/paritytech/cumulus"399branch = "polkadot-v0.9.33"400default-features = false401402[dependencies.cumulus-pallet-xcm]403git = "https://github.com/paritytech/cumulus"404branch = "polkadot-v0.9.33"405default-features = false406407[dependencies.cumulus-pallet-dmp-queue]408git = "https://github.com/paritytech/cumulus"409branch = "polkadot-v0.9.33"410default-features = false411412[dependencies.cumulus-pallet-xcmp-queue]413git = "https://github.com/paritytech/cumulus"414branch = "polkadot-v0.9.33"415default-features = false416417[dependencies.cumulus-primitives-utility]418git = "https://github.com/paritytech/cumulus"419branch = "polkadot-v0.9.33"420default-features = false421422[dependencies.cumulus-primitives-timestamp]423git = "https://github.com/paritytech/cumulus"424branch = "polkadot-v0.9.33"425default-features = false426427################################################################################428# Polkadot dependencies429430[dependencies.polkadot-parachain]431git = "https://github.com/paritytech/polkadot"432branch = "release-v0.9.33"433default-features = false434435[dependencies.xcm]436git = "https://github.com/paritytech/polkadot"437branch = "release-v0.9.33"438default-features = false439440[dependencies.xcm-builder]441git = "https://github.com/paritytech/polkadot"442branch = "release-v0.9.33"443default-features = false444445[dependencies.xcm-executor]446git = "https://github.com/paritytech/polkadot"447branch = "release-v0.9.33"448default-features = false449450[dependencies.pallet-xcm]451git = "https://github.com/paritytech/polkadot"452branch = "release-v0.9.33"453default-features = false454455################################################################################456# local dependencies457458[dependencies]459orml-vesting.workspace = true460orml-xtokens.workspace = true461orml-tokens.workspace = true462orml-traits.workspace = true463464log = { version = "0.4.16", default-features = false }465up-common = { path = "../../primitives/common", default-features = false }466scale-info = { version = "2.0.1", default-features = false, features = [467 "derive",468] }469derivative = "2.2.0"470pallet-unique = { path = '../../pallets/unique', default-features = false }471up-rpc = { path = "../../primitives/rpc", default-features = false }472app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false }473rmrk-rpc = { path = "../../primitives/rmrk-rpc", default-features = false }474fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }475fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }476pallet-inflation = { path = '../../pallets/inflation', default-features = false }477pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }478up-data-structs = { path = '../../primitives/data-structs', default-features = false }479pallet-configuration = { default-features = false, path = "../../pallets/configuration" }480pallet-common = { default-features = false, path = "../../pallets/common" }481pallet-structure = { default-features = false, path = "../../pallets/structure" }482pallet-fungible = { default-features = false, path = "../../pallets/fungible" }483pallet-refungible = { default-features = false, path = "../../pallets/refungible" }484pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }485pallet-proxy-rmrk-core = { default-features = false, path = "../../pallets/proxy-rmrk-core", package = "pallet-rmrk-core" }486pallet-proxy-rmrk-equip = { default-features = false, path = "../../pallets/proxy-rmrk-equip", package = "pallet-rmrk-equip" }487pallet-charge-transaction = { git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.33", package = "pallet-template-transaction-payment", default-features = false, version = "3.0.0" }488pallet-unique-scheduler-v2 = { path = '../../pallets/scheduler-v2', default-features = false }489pallet-evm-migration = { path = '../../pallets/evm-migration', default-features = false }490pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }491pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }492pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }493pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }494pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }495pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }496fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }497fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }498pallet-evm-precompile-simple = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }499evm-coder = { default-features = false, path = '../../crates/evm-coder' }500up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.33' }501pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }502pallet-maintenance = { default-features = false, path = "../../pallets/maintenance" }503precompile-utils-macro = { path = "../common/ethereum/precompiles/utils/macro" }504num_enum = { version = "0.5.3", default-features = false }505506################################################################################507# Test dependencies508509pallet-test-utils = { optional = true, default-features = false, path = "../../test-pallets/utils" }510511################################################################################512# Other Dependencies513514impl-trait-for-tuples = "0.2.2"515516################################################################################517# Dev Dependencies518519[dev-dependencies.logtest]520version = "2.0.0"521522################################################################################523# Build Dependencies524525[build-dependencies.substrate-wasm-builder]526git = "https://github.com/paritytech/substrate"527branch = "polkadot-v0.9.33"runtime/opal/src/lib.rsdiffbeforeafterboth--- a/runtime/opal/src/lib.rs
+++ b/runtime/opal/src/lib.rs
@@ -25,6 +25,8 @@
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
+extern crate alloc;
+
use frame_support::parameter_types;
use sp_version::RuntimeVersion;
runtime/quartz/Cargo.tomldiffbeforeafterboth--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -463,6 +463,7 @@
pallet-unique = { path = '../../pallets/unique', default-features = false }
up-rpc = { path = "../../primitives/rpc", default-features = false }
app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false }
+fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
pallet-inflation = { path = '../../pallets/inflation', default-features = false }
pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
@@ -486,10 +487,13 @@
pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
+pallet-evm-precompile-simple = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.33' }
pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
pallet-maintenance = { default-features = false, path = "../../pallets/maintenance" }
+precompile-utils-macro = { path = "../common/ethereum/precompiles/utils/macro" }
+num_enum = { version = "0.5.3", default-features = false }
################################################################################
# Other Dependencies
runtime/quartz/src/lib.rsdiffbeforeafterboth--- a/runtime/quartz/src/lib.rs
+++ b/runtime/quartz/src/lib.rs
@@ -25,6 +25,8 @@
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
+extern crate alloc;
+
use frame_support::parameter_types;
use sp_version::RuntimeVersion;
runtime/unique/Cargo.tomldiffbeforeafterboth--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -479,11 +479,15 @@
pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
+fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
+pallet-evm-precompile-simple = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.33" }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.33' }
pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
pallet-maintenance = { default-features = false, path = "../../pallets/maintenance" }
+precompile-utils-macro = { path = "../common/ethereum/precompiles/utils/macro" }
+num_enum = { version = "0.5.3", default-features = false }
################################################################################
# Other Dependencies
runtime/unique/src/lib.rsdiffbeforeafterboth--- a/runtime/unique/src/lib.rs
+++ b/runtime/unique/src/lib.rs
@@ -25,6 +25,8 @@
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
+extern crate alloc;
+
use frame_support::parameter_types;
use sp_version::RuntimeVersion;
tests/src/eth/precompile.test.tsdiffbeforeafterboth--- /dev/null
+++ b/tests/src/eth/precompile.test.ts
@@ -0,0 +1,112 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+import {IKeyringPair} from '@polkadot/types/types';
+
+import {expect, itEth, usingEthPlaygrounds} from './util';
+
+describe('Precompiles', () => {
+ let donor: IKeyringPair;
+
+ before(async function() {
+ await usingEthPlaygrounds(async (_, privateKey) => {
+ donor = await privateKey({filename: __filename});
+ });
+ });
+
+ itEth('ecrecover is supported', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const ecrecoverCompiledСontract = await helper.ethContract.compile(
+ 'ECRECOVER',
+ `
+ // SPDX-License-Identifier: MIT
+ pragma solidity ^0.8.17;
+
+ contract ECRECOVER{
+ address addressTest = 0x12Cb274aAD8251C875c0bf6872b67d9983E53fDd;
+ bytes32 msgHash1 = 0xc51dac836bc7841a01c4b631fa620904fc8724d7f9f1d3c420f0e02adf229d50;
+ bytes32 msgHash2 = 0xc51dac836bc7841a01c4b631fa620904fc8724d7f9f1d3c420f0e02adf229d51;
+ uint8 v = 0x1b;
+ bytes32 r = 0x44287513919034a471a7dc2b2ed121f95984ae23b20f9637ba8dff471b6719ef;
+ bytes32 s = 0x7d7dc30309a3baffbfd9342b97d0e804092c0aeb5821319aa732bc09146eafb4;
+
+
+ function verifyValid() public view returns(bool) {
+ // Use ECRECOVER to verify address
+ return ecrecover(msgHash1, v, r, s) == (addressTest);
+ }
+
+ function verifyInvalid() public view returns(bool) {
+ // Use ECRECOVER to verify address
+ return ecrecover(msgHash2, v, r, s) == (addressTest);
+ }
+ }
+ `,
+ );
+
+ const ecrecoverСontract = await helper.ethContract.deployByAbi(owner, ecrecoverCompiledСontract.abi, ecrecoverCompiledСontract.object);
+ expect(await ecrecoverСontract.methods.verifyValid().call({from: owner})).to.be.true;
+ expect(await ecrecoverСontract.methods.verifyInvalid().call({from: owner})).to.be.false;
+ });
+
+ itEth('sr25519 is supported', async ({helper}) => {
+ const owner = await helper.eth.createAccountWithBalance(donor);
+ const sr25519CompiledСontract = await helper.ethContract.compile(
+ 'SR25519Contract',
+ `
+ // SPDX-License-Identifier: MIT
+ pragma solidity ^0.8.17;
+
+ /**
+ * @title SR25519 signature interface.
+ */
+ interface SR25519 {
+ /**
+ * @dev Verify signed message using SR25519 crypto.
+ * @return A boolean confirming whether the public key is signer for the message.
+ */
+ function verify(
+ bytes32 public_key,
+ bytes calldata signature,
+ bytes calldata message
+ ) external view returns (bool);
+ }
+
+ contract SR25519Contract{
+ SR25519 public constant sr25519 = SR25519(0x0000000000000000000000000000000000005002);
+
+ bytes32 public_key = 0x96b2f9237ed0890fbeed891ebb81b91ac0d5d5b6e3afcdbc95df1b68d9f14036;
+ bytes signature = hex"4a5d733d7c568f2e88abf0467fd497f87c1be3e940ed897efdf9da72eaad394ef9918cb574ee99c54485775b17a0deaf46ff7a1f10346cea39fff0e4ede97689";
+ bytes message1 = hex"7372323535313920697320737570706f72746564";
+ bytes message2 = hex"7372323535313920697320737570706f7274656401";
+
+
+ function verifyValid() public view returns(bool) {
+ return sr25519.verify(public_key, signature, message1);
+ }
+
+ function verifyInvalid() public view returns(bool) {
+ return sr25519.verify(public_key, signature, message2);
+ }
+ }
+ `,
+ );
+
+ const sr25519Сontract = await helper.ethContract.deployByAbi(owner, sr25519CompiledСontract.abi, sr25519CompiledСontract.object);
+ expect(await sr25519Сontract.methods.verifyValid().call({from: owner})).to.be.true;
+ expect(await sr25519Сontract.methods.verifyInvalid().call({from: owner})).to.be.false;
+ });
+});
\ No newline at end of file
tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -60,7 +60,7 @@
}
async compile(name: string, src: string, imports?: ContractImports[]): Promise<CompiledContract> {
- const out = JSON.parse(solc.compile(JSON.stringify({
+ const compiled = JSON.parse(solc.compile(JSON.stringify({
language: 'Solidity',
sources: {
[`${name}.sol`]: {
@@ -74,7 +74,18 @@
},
},
},
- }), {import: await this.findImports(imports)})).contracts[`${name}.sol`][name];
+ }), {import: await this.findImports(imports)}));
+
+ const hasErrors = compiled['errors']
+ && compiled['errors'].length > 0
+ && compiled.errors.some(function(err: any) {
+ return err.severity == 'error';
+ });
+
+ if (hasErrors) {
+ throw compiled.errors;
+ }
+ const out = compiled.contracts[`${name}.sol`][name];
return {
abi: out.abi,