Skip to content

Commit

Permalink
code, code_size hostios
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Benfield committed Jan 24, 2024
1 parent f57b718 commit 038c360
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
18 changes: 17 additions & 1 deletion stylus-sdk/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use crate::hostio::{self, wrap_hostio};
use alloc::{vec, vec::Vec};
use alloy_primitives::B256;
use alloy_primitives::{Address, B256};
use alloy_sol_types::{token::WordToken, SolEvent, TopicList};

/// Emits an evm log from combined topics and data.
Expand Down Expand Up @@ -57,6 +57,22 @@ pub fn pay_for_memory_grow(pages: u16) {
unsafe { hostio::pay_for_memory_grow(pages) }
}

/// Get the code associated with the given `address`.
///
/// Start at `offset` into the code and write at most `size` bytes.
pub fn ext_code(address: &Address, offset: usize, size: Option<usize>) -> Vec<u8> {
let size = if let Some(sz) = size {
sz
} else {
unsafe { hostio::account_code_size(address.0.as_ptr()) }
};
let mut data = vec![0; size];
let size_written =
unsafe { hostio::account_code(address.0.as_ptr(), offset, size, data.as_mut_ptr()) };
data.truncate(size_written);
data
}

wrap_hostio!(
/// Gets the amount of gas remaining. See [`Ink and Gas`] for more information on Stylus's compute pricing.
///
Expand Down
8 changes: 8 additions & 0 deletions stylus-sdk/src/hostio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ extern "C" {
/// [`BALANCE`]: https://www.evm.codes/#31
pub fn account_balance(address: *const u8, dest: *mut u8);

/// Write the code associated with the given address into `dest`, starting
/// at `offset`, writing at most `size` bytes.
/// Returns the number of bytes written.
pub fn account_code(address: *const u8, offset: usize, size: usize, dest: *mut u8) -> usize;

/// Gets the code hash of the account at the given address. The semantics are equivalent
/// to that of the EVM's [`EXT_CODEHASH`] opcode. Note that the code hash of an account without
/// code will be the empty hash
Expand All @@ -36,6 +41,9 @@ extern "C" {
/// [`EXT_CODEHASH`]: https://www.evm.codes/#3F
pub fn account_codehash(address: *const u8, dest: *mut u8);

/// Get the size of the code associated with the given address.
pub fn account_code_size(address: *const u8) -> usize;

/// Reads a 32-byte value from permanent storage. Stylus's storage format is identical to
/// that of the EVM. This means that, under the hood, this hostio is accessing the 32-byte
/// value stored in the EVM state trie at offset `key`, which will be `0` when not previously
Expand Down
15 changes: 15 additions & 0 deletions stylus-sdk/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
//! let balance = account.balance();
//! ```

use alloc::vec;
use alloc::vec::Vec;

use crate::hostio;
use alloy_primitives::{b256, Address, B256, U256};

Expand All @@ -21,6 +24,9 @@ pub trait AddressVM {
/// The balance in wei of the account.
fn balance(&self) -> U256;

/// The code of the contract at the given address.
fn code(&self) -> Vec<u8>;

/// The codehash of the contract or [`EOA`] at the given address.
///
/// [`EOA`]: https://ethereum.org/en/developers/docs/accounts/#types-of-account
Expand All @@ -41,6 +47,15 @@ impl AddressVM for Address {
U256::from_be_bytes(data)
}

fn code(&self) -> Vec<u8> {
let size = unsafe { hostio::account_code_size(self.0.as_ptr()) };
let mut data = vec![0; size];
unsafe {
hostio::account_code(self.0.as_ptr(), 0, size, data.as_mut_ptr());
}
data
}

fn codehash(&self) -> B256 {
let mut data = [0; 32];
unsafe { hostio::account_codehash(self.0.as_ptr(), data.as_mut_ptr()) };
Expand Down

0 comments on commit 038c360

Please sign in to comment.