diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 430fd37..10e5347 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,5 +8,5 @@ Please provide a summary of the changes and any backward incompatibilities. - [ ] I have read the [DCO][DCO] and ensured that these changes comply. - [ ] I assign this work under its [open source licensing][terms]. -[DCO]: licenses/DCO.txt -[terms]: licenses/COPYRIGHT.md +[DCO]: https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/licenses/DCO.txt +[terms]: https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/licenses/COPYRIGHT.md diff --git a/Cargo.lock b/Cargo.lock index 6d6fa83..418fc24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -308,7 +308,7 @@ checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" [[package]] name = "mini-alloc" -version = "0.4.2" +version = "0.4.3" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-test", @@ -498,7 +498,7 @@ dependencies = [ [[package]] name = "stylus-proc" -version = "0.4.2" +version = "0.4.3" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -515,7 +515,7 @@ dependencies = [ [[package]] name = "stylus-sdk" -version = "0.4.2" +version = "0.4.3" dependencies = [ "alloy-primitives", "alloy-sol-types", diff --git a/Cargo.toml b/Cargo.toml index b38370b..d56cda7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["stylus-sdk", "stylus-proc", "mini-alloc"] resolver = "2" [workspace.package] -version = "0.4.2" +version = "0.4.3" edition = "2021" authors = ["Offchain Labs"] license = "MIT OR Apache-2.0" diff --git a/ci/smoke_test.sh b/ci/smoke_test.sh index fa23fd4..cb9b8bd 100755 --- a/ci/smoke_test.sh +++ b/ci/smoke_test.sh @@ -11,4 +11,4 @@ cargo stylus new counter cd counter echo "[workspace]" >> Cargo.toml -cargo stylus deploy --private-key $PRIV_KEY +cargo stylus deploy --private-key $PRIV_KEY -e https://stylus-testnet.arbitrum.io/rpc diff --git a/examples/erc20/Cargo.lock b/examples/erc20/Cargo.lock index 7988a62..8538f33 100644 --- a/examples/erc20/Cargo.lock +++ b/examples/erc20/Cargo.lock @@ -19,7 +19,7 @@ checksum = "e416903084d3392ebd32d94735c395d6709415b76c7728e594d3f996f2b03e65" dependencies = [ "alloy-rlp", "bytes", - "cfg-if", + "cfg-if 1.0.0", "const-hex", "derive_more", "hex-literal", @@ -137,6 +137,12 @@ dependencies = [ "libc", ] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" @@ -149,7 +155,7 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08849ed393c907c90016652a01465a12d86361cd38ad2a7de026c56a520cc259" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "hex", "serde", @@ -294,7 +300,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "wasi", ] @@ -368,11 +374,18 @@ version = "2.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e" +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + [[package]] name = "mini-alloc" version = "0.4.2" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", + "wee_alloc", ] [[package]] @@ -623,7 +636,7 @@ version = "0.4.2" dependencies = [ "alloy-primitives", "alloy-sol-types", - "cfg-if", + "cfg-if 1.0.0", "convert_case 0.6.0", "lazy_static", "proc-macro2", @@ -640,7 +653,7 @@ version = "0.4.2" dependencies = [ "alloy-primitives", "alloy-sol-types", - "cfg-if", + "cfg-if 1.0.0", "derivative", "fnv", "hex", @@ -689,7 +702,7 @@ version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "fastrand", "redox_syscall", "rustix", @@ -756,6 +769,40 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "memory_units", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/examples/erc20/src/erc20.rs b/examples/erc20/src/erc20.rs index e3a8669..12191bc 100644 --- a/examples/erc20/src/erc20.rs +++ b/examples/erc20/src/erc20.rs @@ -1,4 +1,4 @@ -use alloc::{string::String, vec::Vec}; +use alloc::string::String; use core::marker::PhantomData; use stylus_sdk::{ alloy_primitives::{Address, U256}, @@ -36,21 +36,12 @@ sol! { error InsufficientAllowance(address owner, address spender, uint256 have, uint256 want); } +#[derive(SolidityError)] pub enum Erc20Error { InsufficientBalance(InsufficientBalance), InsufficientAllowance(InsufficientAllowance), } -// We will soon provide a #[derive(SolidityError)] to clean this up -impl From for Vec { - fn from(err: Erc20Error) -> Vec { - match err { - Erc20Error::InsufficientBalance(e) => e.encode(), - Erc20Error::InsufficientAllowance(e) => e.encode(), - } - } -} - // These methods aren't exposed to other contracts // Note: modifying storage will become much prettier soon impl Erc20 { diff --git a/stylus-proc/src/lib.rs b/stylus-proc/src/lib.rs index 2b9893b..471b097 100644 --- a/stylus-proc/src/lib.rs +++ b/stylus-proc/src/lib.rs @@ -264,6 +264,35 @@ pub fn derive_erase(input: TokenStream) -> TokenStream { storage::derive_erase(input) } +/// Allows an error `enum` to be used in method signatures. +/// +/// ```ignore +/// sol! { +/// error InsufficientBalance(address from, uint256 have, uint256 want); +/// error InsufficientAllowance(address owner, address spender, uint256 have, uint256 want); +/// } +/// +/// #[derive(SolidityError)] +/// pub enum Erc20Error { +/// InsufficientBalance(InsufficientBalance), +/// InsufficientAllowance(InsufficientAllowance), +/// } +/// +/// #[external] +/// impl Contract { +/// pub fn fallible_method() -> Result<(), Erc20Error> { +/// // code that might revert +/// } +/// } +/// ``` +/// +/// Under the hood, the above macro works by implementing `From` for `Vec` +/// along with printing code for abi-export. +#[proc_macro_derive(SolidityError)] +pub fn derive_solidity_error(input: TokenStream) -> TokenStream { + methods::error::derive_solidity_error(input) +} + /// Defines the entrypoint, which is where Stylus execution begins. /// Without it the contract will fail to pass [`cargo stylus check`][check]. /// Most commonly this macro is used to annotate the top level storage `struct`. diff --git a/stylus-proc/src/methods/entrypoint.rs b/stylus-proc/src/methods/entrypoint.rs index 411acf8..98f3904 100644 --- a/stylus-proc/src/methods/entrypoint.rs +++ b/stylus-proc/src/methods/entrypoint.rs @@ -84,7 +84,7 @@ pub fn entrypoint(attr: TokenStream, input: TokenStream) -> TokenStream { output.extend(quote! { #[no_mangle] pub unsafe fn mark_used() { - stylus_sdk::evm::memory_grow(0); + stylus_sdk::evm::pay_for_memory_grow(0); panic!(); } diff --git a/stylus-proc/src/methods/error.rs b/stylus-proc/src/methods/error.rs new file mode 100644 index 0000000..968837f --- /dev/null +++ b/stylus-proc/src/methods/error.rs @@ -0,0 +1,57 @@ +// Copyright 2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/licenses/COPYRIGHT.md + +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, Fields, ItemEnum}; + +pub fn derive_solidity_error(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as ItemEnum); + let name = &input.ident; + let mut match_arms = quote!(); + let mut errors = vec![]; + for variant in input.variants { + let variant_name = variant.ident; + let error = match variant.fields { + Fields::Unnamed(e) if variant.fields.len() == 1 => e.unnamed.first().unwrap().clone(), + _ => error!(variant.fields, "Variant not a 1-tuple"), + }; + match_arms.extend(quote! { + #name::#variant_name(e) => stylus_sdk::alloy_sol_types::SolError::encode(&e), + }); + errors.push(error); + } + let mut output = quote! { + impl From<#name> for alloc::vec::Vec { + fn from(err: #name) -> alloc::vec::Vec { + match err { + #match_arms + } + } + } + }; + + if cfg!(feature = "export-abi") { + output.extend(quote! { + impl stylus_sdk::abi::export::internal::InnerTypes for #name { + fn inner_types() -> alloc::vec::Vec { + use alloc::{format, vec}; + use core::any::TypeId; + use stylus_sdk::abi::export::internal::InnerType; + use stylus_sdk::alloy_sol_types::SolError; + + vec![ + #( + InnerType { + name: format!("error {};", <#errors as SolError>::SIGNATURE.replace(',', ", ")), + id: TypeId::of::<#errors>(), + } + ),* + ] + } + } + }); + } + + output.into() +} diff --git a/stylus-proc/src/methods/external.rs b/stylus-proc/src/methods/external.rs index 848d2b5..0956b35 100644 --- a/stylus-proc/src/methods/external.rs +++ b/stylus-proc/src/methods/external.rs @@ -1,4 +1,4 @@ -// Copyright 2022-2023, Offchain Labs, Inc. +// Copyright 2022-2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/licenses/COPYRIGHT.md use crate::types::{self, Purity}; @@ -20,6 +20,7 @@ pub fn external(_attr: TokenStream, input: TokenStream) -> TokenStream { let mut selectors = quote!(); let mut match_selectors = quote!(); let mut abi = quote!(); + let mut types = vec![]; for item in input.items.iter_mut() { let ImplItem::Method(method) = item else { @@ -155,10 +156,7 @@ pub fn external(_attr: TokenStream, input: TokenStream) -> TokenStream { } }; let result = Self::#name(#storage #(#expand_args, )* ); - match result { - Ok(result) => Some(Ok(internal::encode_return_type(result))), - Err(err) => Some(Err(err.into())), - } + Some(EncodableReturnType::encode(result)) } }); @@ -258,7 +256,7 @@ pub fn external(_attr: TokenStream, input: TokenStream) -> TokenStream { #[inline(always)] fn route(storage: &mut S, selector: u32, input: &[u8]) -> Option { use stylus_sdk::{function_selector, alloy_sol_types::SolType}; - use stylus_sdk::abi::{internal, AbiType, Router}; + use stylus_sdk::abi::{internal, internal::EncodableReturnType, AbiType, Router}; use alloc::vec; #[cfg(feature = "export-abi")] @@ -281,6 +279,24 @@ pub fn external(_attr: TokenStream, input: TokenStream) -> TokenStream { return router.into(); } + for item in input.items.iter_mut() { + let ImplItem::Method(method) = item else { + continue; + }; + if let ReturnType::Type(_, ty) = &method.sig.output { + types.push(ty); + } + } + + let type_decls = quote! { + let mut seen = HashSet::new(); + for item in [].iter() #(.chain(&<#types as InnerTypes>::inner_types()))* { + if seen.insert(item.id) { + writeln!(f, "\n {}", item.name)?; + } + } + }; + let name = match *self_ty.clone() { Type::Path(path) => path.path.segments.last().unwrap().ident.clone().to_string(), _ => error!(self_ty, "Can't generate ABI for unnamed type"), @@ -312,12 +328,14 @@ pub fn external(_attr: TokenStream, input: TokenStream) -> TokenStream { fn fmt_abi(f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { use stylus_sdk::abi::{AbiType, GenerateAbi}; use stylus_sdk::abi::internal::write_solidity_returns; - use stylus_sdk::abi::export::{underscore_if_sol}; + use stylus_sdk::abi::export::{underscore_if_sol, internal::InnerTypes}; + use std::collections::HashSet; #(#inherited_abis)* write!(f, "interface I{}", #name)?; #is_clause write!(f, " {{")?; #abi + #type_decls writeln!(f, "}}")?; Ok(()) } diff --git a/stylus-proc/src/methods/mod.rs b/stylus-proc/src/methods/mod.rs index 256b033..d3e69d2 100644 --- a/stylus-proc/src/methods/mod.rs +++ b/stylus-proc/src/methods/mod.rs @@ -2,4 +2,5 @@ // For licensing, see https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/licenses/COPYRIGHT.md pub mod entrypoint; +pub mod error; pub mod external; diff --git a/stylus-proc/src/storage/mod.rs b/stylus-proc/src/storage/mod.rs index 3138f1c..cd6b38a 100644 --- a/stylus-proc/src/storage/mod.rs +++ b/stylus-proc/src/storage/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2023, Offchain Labs, Inc. +// Copyright 2023-2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/licenses/COPYRIGHT.md use crate::storage::proc::{SolidityField, SolidityFields, SolidityStruct, SolidityStructs}; @@ -214,12 +214,12 @@ pub fn derive_erase(input: TokenStream) -> TokenStream { self.#ident.erase(); }); } - let output = quote! { + quote! { impl #impl_generics stylus_sdk::storage::Erase for #name #ty_generics #where_clause { fn erase(&mut self) { #erase_fields } } - }; - output.into() + } + .into() } diff --git a/stylus-sdk/src/abi/export/internal.rs b/stylus-sdk/src/abi/export/internal.rs new file mode 100644 index 0000000..129183a --- /dev/null +++ b/stylus-sdk/src/abi/export/internal.rs @@ -0,0 +1,82 @@ +// Copyright 2024, Offchain Labs, Inc. +// For licensing, see https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/licenses/COPYRIGHT.md + +//! This module provides functions for code generated by `stylus-sdk-proc` for the `export-abi` command. +//! Most users shouldn't call these. + +use alloy_primitives::{Address, FixedBytes, Signed, Uint}; +use core::any::TypeId; + +/// Represents a unique Solidity Type. +pub struct InnerType { + /// Full interface string. + pub name: String, + /// Unique identifier for de-duplication when printing interfaces. + pub id: TypeId, +} + +/// Trait for collecting structs and error types. +pub trait InnerTypes { + /// Collect any structs and errors under the type. + /// Empty for primitives. + fn inner_types() -> Vec { + vec![] + } +} + +impl InnerTypes for Result +where + O: InnerTypes, + E: InnerTypes, +{ + fn inner_types() -> Vec { + let mut out = O::inner_types(); + out.extend(E::inner_types()); + out + } +} + +impl InnerTypes for Vec { + fn inner_types() -> Vec { + T::inner_types() + } +} + +impl InnerTypes for [T; N] { + fn inner_types() -> Vec { + T::inner_types() + } +} + +macro_rules! impl_inner { + ($ty:ident $($rest:ident)+) => { + impl_inner!($ty); + impl_inner!($($rest)+); + }; + ($ty:ident) => { + impl InnerTypes for $ty {} + }; +} + +impl_inner!(bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 String Address); + +impl InnerTypes for Uint {} +impl InnerTypes for Signed {} +impl InnerTypes for FixedBytes {} + +macro_rules! impl_tuple { + () => { + impl InnerTypes for () {} + }; + ($first:ident $(, $rest:ident)*) => { + impl<$first: InnerTypes $(, $rest: InnerTypes)*> InnerTypes for ( $first $(, $rest)* , ) { + fn inner_types() -> Vec { + vec![] + } + } + + impl_tuple! { $($rest),* } + }; +} + +impl_tuple!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X); diff --git a/stylus-sdk/src/abi/export.rs b/stylus-sdk/src/abi/export/mod.rs similarity index 97% rename from stylus-sdk/src/abi/export.rs rename to stylus-sdk/src/abi/export/mod.rs index c81c6c5..535291c 100644 --- a/stylus-sdk/src/abi/export.rs +++ b/stylus-sdk/src/abi/export/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2023, Offchain Labs, Inc. +// Copyright 2023-2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/licenses/COPYRIGHT.md //! Traits for exporting Solidity interfaces. @@ -12,6 +12,9 @@ use core::{fmt, marker::PhantomData}; use lazy_static::lazy_static; use regex::Regex; +#[doc(hidden)] +pub mod internal; + /// Trait for storage types so that users can print a Solidity interface to the console. /// This is auto-derived via the [`external`] macro when the `export-abi` feature is enabled. /// diff --git a/stylus-sdk/src/abi/internal.rs b/stylus-sdk/src/abi/internal.rs index 8ea4d53..84cb68d 100644 --- a/stylus-sdk/src/abi/internal.rs +++ b/stylus-sdk/src/abi/internal.rs @@ -1,19 +1,35 @@ -// Copyright 2023, Offchain Labs, Inc. +// Copyright 2023-2024, Offchain Labs, Inc. // For licensing, see https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/licenses/COPYRIGHT.md //! This module provides functions for code generated by `stylus-sdk-proc`. //! Most users shouldn't call these. -use crate::{abi::AbiType, console, msg}; +use crate::{abi::AbiType, console, msg, ArbResult}; use alloc::{vec, vec::Vec}; use alloy_primitives::U256; use alloy_sol_types::SolType; use core::fmt; -#[inline(always)] -pub fn encode_return_type(x: T) -> Vec { - // coerce types into a tuple of at least 1 element - <(T,) as AbiType>::SolType::encode(&(x,)) +pub trait EncodableReturnType { + fn encode(self) -> ArbResult; +} + +impl EncodableReturnType for T { + #[inline(always)] + fn encode(self) -> ArbResult { + // coerce types into a tuple of at least 1 element + Ok(<(T,) as AbiType>::SolType::encode(&(self,))) + } +} + +impl>> EncodableReturnType for Result { + #[inline(always)] + fn encode(self) -> ArbResult { + match self { + Ok(result) => result.encode(), + Err(err) => Err(err.into()), + } + } } #[inline(always)] @@ -42,12 +58,14 @@ pub fn failed_to_decode_arguments(err: alloy_sol_types::Error) { pub trait AbiResult { type OkType; - type ErrType; } impl AbiResult for Result { type OkType = O; - type ErrType = E; +} + +impl AbiResult for T { + type OkType = T; } pub fn write_solidity_returns(f: &mut fmt::Formatter) -> fmt::Result @@ -58,8 +76,8 @@ where if abi == "()" { Ok(()) } else if abi.starts_with('(') { - write!(f, " returns {}", abi) + write!(f, " returns {abi}") } else { - write!(f, " returns ({})", abi) + write!(f, " returns ({abi})") } } diff --git a/stylus-sdk/src/evm.rs b/stylus-sdk/src/evm.rs index 14b766d..f2b15fb 100644 --- a/stylus-sdk/src/evm.rs +++ b/stylus-sdk/src/evm.rs @@ -53,7 +53,7 @@ pub fn log(event: T) { /// This function exists to force the compiler to import this symbol. /// Calling it will unproductively consume gas. -pub fn memory_grow(pages: u16) { +pub fn pay_for_memory_grow(pages: u16) { unsafe { hostio::memory_grow(pages) } } diff --git a/stylus-sdk/src/hostio.rs b/stylus-sdk/src/hostio.rs index 0e78148..c115630 100644 --- a/stylus-sdk/src/hostio.rs +++ b/stylus-sdk/src/hostio.rs @@ -262,6 +262,8 @@ extern "C" { /// bounds, but rather copies the overlapping portion. The semantics are otherwise equivalent /// to that of the EVM's [`RETURN_DATA_COPY`] opcode. /// + /// Returns the number of bytes written. + /// /// [`RETURN_DATA_COPY`]: https://www.evm.codes/#3e pub fn read_return_data(dest: *mut u8, offset: usize, size: usize) -> usize; diff --git a/stylus-sdk/src/storage/map.rs b/stylus-sdk/src/storage/map.rs index 8b25f0c..660ae6b 100644 --- a/stylus-sdk/src/storage/map.rs +++ b/stylus-sdk/src/storage/map.rs @@ -186,7 +186,7 @@ impl StorageKey for String { impl StorageKey for Address { fn to_slot(&self, root: B256) -> U256 { - let int: U160 = self.0.try_into().unwrap(); + let int: U160 = self.0.into(); int.to_slot(root) } } diff --git a/stylus-sdk/src/types.rs b/stylus-sdk/src/types.rs index eb2594e..2c65cb5 100644 --- a/stylus-sdk/src/types.rs +++ b/stylus-sdk/src/types.rs @@ -37,13 +37,13 @@ pub trait AddressVM { impl AddressVM for Address { fn balance(&self) -> U256 { let mut data = [0; 32]; - unsafe { hostio::account_balance(self.0.as_ptr(), data.as_mut_ptr()) }; + unsafe { hostio::account_balance(self.as_ptr(), data.as_mut_ptr()) }; U256::from_be_bytes(data) } fn codehash(&self) -> B256 { let mut data = [0; 32]; - unsafe { hostio::account_codehash(self.0.as_ptr(), data.as_mut_ptr()) }; + unsafe { hostio::account_codehash(self.as_ptr(), data.as_mut_ptr()) }; data.into() }