diff --git a/integration-tests/internal/gas-hostfns/Cargo.toml b/integration-tests/internal/gas-hostfns/Cargo.toml index ffbdeb755dd..d1c76b4efa2 100755 --- a/integration-tests/internal/gas-hostfns/Cargo.toml +++ b/integration-tests/internal/gas-hostfns/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -ink = { path = "../../../crates/ink", default-features = false, features = ["unstable-hostfn"] } +ink = { path = "../../../crates/ink", default-features = false } [dev-dependencies] ink_e2e = { path = "../../../crates/e2e" } diff --git a/integration-tests/internal/misc-hostfns/Cargo.toml b/integration-tests/internal/misc-hostfns/Cargo.toml index 4b2dcfa013e..d80645032c3 100755 --- a/integration-tests/internal/misc-hostfns/Cargo.toml +++ b/integration-tests/internal/misc-hostfns/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" publish = false [dependencies] -ink = { path = "../../../crates/ink", default-features = false, features = ["unstable-hostfn"] } +ink = { path = "../../../crates/ink", default-features = false } hex-literal = "1" [dev-dependencies] diff --git a/integration-tests/public/contract-terminate/Cargo.toml b/integration-tests/public/contract-terminate/Cargo.toml index 8e12fde257c..389d6aa6dd9 100644 --- a/integration-tests/public/contract-terminate/Cargo.toml +++ b/integration-tests/public/contract-terminate/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" publish = false [dependencies] -ink = { path = "../../../crates/ink", default-features = false, features = ["unstable-hostfn"] } +ink = { path = "../../../crates/ink", default-features = false } [dev-dependencies] ink_e2e = { path = "../../../crates/e2e" } diff --git a/integration-tests/public/e2e-call-runtime/Cargo.toml b/integration-tests/public/e2e-call-runtime/Cargo.toml index c3a27e36cf5..742f99ffdc0 100644 --- a/integration-tests/public/e2e-call-runtime/Cargo.toml +++ b/integration-tests/public/e2e-call-runtime/Cargo.toml @@ -6,7 +6,7 @@ edition = "2024" publish = false [dependencies] -ink = { path = "../../../crates/ink", default-features = false, features = ["unstable-hostfn"] } +ink = { path = "../../../crates/ink", default-features = false } static_assertions = "1" [dev-dependencies] diff --git a/integration-tests/public/precompile/Cargo.toml b/integration-tests/public/precompile-demo/Cargo.toml old mode 100755 new mode 100644 similarity index 86% rename from integration-tests/public/precompile/Cargo.toml rename to integration-tests/public/precompile-demo/Cargo.toml index 1504ae62d33..0444c3fbec2 --- a/integration-tests/public/precompile/Cargo.toml +++ b/integration-tests/public/precompile-demo/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "precompile" -version = "6.0.0-alpha.3" +name = "precompile_demo" +version = "6.0.0-beta" authors = ["Use Ink "] edition = "2024" publish = false @@ -11,7 +11,7 @@ hex-literal = "1" [dev-dependencies] ink_e2e = { path = "../../../crates/e2e" } -blake2 = "0.10" +hex = { version = "0.4.3" } [lib] path = "lib.rs" diff --git a/integration-tests/public/precompile-demo/lib.rs b/integration-tests/public/precompile-demo/lib.rs new file mode 100644 index 00000000000..e3a0e324978 --- /dev/null +++ b/integration-tests/public/precompile-demo/lib.rs @@ -0,0 +1,94 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +/// This trait is an implementation of the Solidity interface found at +/// . +/// +/// The precompile code itself can be found at +/// . +/// +/// Note that it's possible to just implement the Solidity interface partially +/// in this trait. This can be useful if you just want to expose part of the +/// precompile functionality. +#[ink::contract_ref(abi = "sol")] +pub trait System { + /// Simple echo function. + /// + /// If `mode = 0`, the function reverts. + /// If `mode > 0`, the input `message` is echoed back to the caller. + /// + /// # Note + /// + /// This signature is the ink! equivalent of the following Solidity signature + /// + /// ```solidity + /// function echo(uint8 mode, bytes message) external view returns (bytes); + /// ``` + #[ink(message)] + #[allow(non_snake_case)] + fn echo(&self, mode: u8, message: ink::sol::DynBytes) -> ink::sol::DynBytes; +} + +#[ink::contract] +mod precompile_demo { + use super::System; + use ink::prelude::vec::Vec; + + #[ink(storage)] + pub struct PrecompileDemo; + + impl PrecompileDemo { + /// Initializes contract. + #[ink(constructor)] + #[allow(clippy::new_without_default)] + pub fn new() -> Self { + Self {} + } + + /// Calls the `echo` function from `ink-node`'s `DemoPrecompile`. + #[ink(message)] + pub fn call_echo(&self, data: Vec) -> Vec { + const DEMO_PRECOMPILE_ADDR: [u8; 20] = + hex_literal::hex!("00000000000000000000000000000000000B0000"); + let system_ref: super::SystemRef = + ink::Address::from(DEMO_PRECOMPILE_ADDR).into(); + let in_bytes = ink::sol::DynBytes(data); + let out_bytes = system_ref.echo(1, in_bytes); + out_bytes.0 + } + } + + #[cfg(all(test, feature = "e2e-tests"))] + mod e2e_tests { + use super::*; + use ink_e2e::ContractsBackend; + + type E2EResult = std::result::Result>; + + #[ink_e2e::test] + async fn call_echo_works(mut client: ink_e2e::Client) -> E2EResult<()> { + // given + let mut constructor = PrecompileDemoRef::new(); + let contract = client + .instantiate("precompile_demo", &ink_e2e::bob(), &mut constructor) + .submit() + .await + .expect("instantiate failed"); + let call_builder = contract.call_builder::(); + + // when + let data = vec![0x1, 0x2, 0x3, 0x4]; + let expected = data.clone(); + let call_echo = call_builder.call_echo(data); + let res = client + .call(&ink_e2e::bob(), &call_echo) + .submit() + .await + .expect("call_echo failed"); + + // then + assert_eq!(res.return_value(), expected); + + Ok(()) + } + } +} diff --git a/integration-tests/public/precompile/lib.rs b/integration-tests/public/precompile/lib.rs deleted file mode 100755 index 5f6d6e6197a..00000000000 --- a/integration-tests/public/precompile/lib.rs +++ /dev/null @@ -1,97 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std, no_main)] - -/// Defines (partial) interface of System precompile. -/// -/// See -#[ink::contract_ref(abi = "sol")] -pub trait System { - /// Computes Blake2b 256-bit hash of given input. - /// - /// # Note - /// - /// This signature is the ink! equivalent of the following Solidity signature - /// ```solidity - /// function hashBlake256(bytes memory input) external pure returns (bytes32 digest); - /// ``` - #[ink(message)] - #[allow(non_snake_case)] - fn hashBlake256(&self, data: ink::sol::DynBytes) -> ink::sol::FixedBytes<32>; -} - -#[ink::contract] -mod precompile { - use super::System; - use ink::prelude::vec::Vec; - - #[ink(storage)] - pub struct Precompile; - - impl Precompile { - /// Initializes contract. - #[ink(constructor)] - #[allow(clippy::new_without_default)] - pub fn new() -> Self { - Self {} - } - - /// Calls the `hashBlake256` function from the `System` precompile and returns the - /// result. - #[ink(message)] - pub fn blake2b_256(&self, data: Vec) -> [u8; 32] { - const SYS_ADDR: [u8; 20] = - hex_literal::hex!("0000000000000000000000000000000000000900"); - let system_ref: super::SystemRef = ink::Address::from(SYS_ADDR).into(); - let in_bytes = ink::sol::DynBytes(data); - let out_bytes = system_ref.hashBlake256(in_bytes); - out_bytes.0 - } - } - - #[cfg(all(test, feature = "e2e-tests"))] - mod e2e_tests { - use super::*; - use ink_e2e::ContractsBackend; - - type E2EResult = std::result::Result>; - - #[ink_e2e::test] - async fn blake2b_256_works(mut client: ink_e2e::Client) -> E2EResult<()> { - // Given - let mut constructor = PrecompileRef::new(); - let contract = client - .instantiate("precompile", &ink_e2e::bob(), &mut constructor) - .submit() - .await - .expect("instantiate failed"); - let call_builder = contract.call_builder::(); - - // Then - let data = vec![0x1, 0x2, 0x3, 0x4]; - let expected = blake2b_256_ref(&data); - let blake2b_256 = call_builder.blake2b_256(data); - let res = client - .call(&ink_e2e::bob(), &blake2b_256) - .submit() - .await - .expect("blake2x256 failed"); - assert_eq!(res.return_value(), expected); - - Ok(()) - } - - /// Returns the Blake2b 256-bit hash for the given input. - fn blake2b_256_ref(input: &[u8]) -> [u8; 32] { - use blake2::digest::{ - Digest as _, - consts::U32, - }; - - let mut output = [0u8; 32]; - let mut blake2 = blake2::Blake2b::::new(); - blake2.update(input); - let result = blake2.finalize(); - output.copy_from_slice(&result); - output - } - } -}