Giter Site home page Giter Site logo

stylus-sdk-rs's Introduction


Logo

The Stylus SDK

Rust contracts on Arbitrum »

Overview

The Stylus SDK enables smart contract developers to write programs for Arbitrum chains written in the Rust programming language. Stylus programs are compiled to WebAssembly and can then be deployed on-chain to execute alongside Solidity smart contracts. Stylus programs are not only orders of magnitude cheaper and faster but also enable what was thought to be previously impossible for WebAssembly: EVM-interoperability.

For information about deploying Rust smart contracts, see the Cargo Stylus CLI Tool. For more information about Stylus, see Stylus: A Gentle Introduction. For a simpler intro to Stylus Rust development, see the Quick Start guide.

Comprehensive documentation on the Rust SDK can be found here.

Feature highlights

The SDK makes it easy to develop Ethereum ABI-equivalent Stylus contracts in Rust. It provides a full suite of types and shortcuts that abstract away the details of Ethereum's storage layout, making it easy to just write Rust. For an in depth exploration of the features, please see comprehensive Feature Overview.

Some of the features available in the SDK include:

  • Generic, storage-backed Rust types for programming Solidity-equivalent smart contracts with optimal storage caching.
  • Simple macros for writing language-agnostic methods and entrypoints.
  • Automatic export of Solidity interfaces for interoperability across programming languages.
  • Powerful primitive types backed by the feature-rich Alloy.

Rust programs written with the Stylus SDK can call and be called by Solidity smart contracts due to ABI equivalence with Ethereum programming languages. In fact, existing Solidity DEXs can list Rust tokens without modification, and vice versa.

use stylus_sdk::{alloy_primitives::U256, prelude::*};

// Generate Solidity-equivalent, Rust structs backed by storage.
sol_storage! {
  #[entrypoint]
  pub struct Counter {
    uint256 number;
  }
}

#[external]
impl Counter {
  // Gets the number value from storage.
  pub fn number(&self) -> Result<U256, Vec<u8>> {
    Ok(self.number.get())
  }

  // Sets a number in storage to a user-specified value.
  pub fn set_number(&mut self, new_number: U256) -> Result<(), Vec<u8>> {
    self.number.set(new_number);
    Ok(())
  }
}

Additionally, the Stylus SDK supports #[no_std] for contracts that wish to opt out of the standard library. In fact, the entire SDK is available from #[no_std], so no special feature flag is required. This can be helpful for reducing binary size, and may be preferable in pure-compute use cases like cryptography.

Most users will want to use the standard library, which is available since the Stylus VM supports rustc's wasm32-unknown-unknown target triple. In the future we may add wasm32-wasi too, along with floating point and SIMD, which the Stylus VM does not yet support.

Don't know Rust?

The Stylus VM supports more than just Rust. In fact, any programming language that compiles down to WebAssembly could in principle be deployed to Stylus-enabled chains. The table below includes the official ports of the SDK, with more coming soon.

Repo Use cases License
Rust SDK Everything! Apache 2.0 or MIT
C/C++ SDK Cryptography and algorithms Apache 2.0 or MIT
Bf SDK Educational Apache 2.0 or MIT
Cargo Stylus Deploying Stylus programs Apache 2.0 or MIT

Want to write your own? Join us in the #stylus channel on discord!

Developing Stylus Programs

The Stylus SDK is just one of the building blocks in creating and deploying WebAssembly programs to Arbitrum chains. To create a new Stylus project from a hello-world example and deploy it onchain, check out some of our tools below:

Repo Use cases License
Stylus Hello World Rust Stylus starter template Apache 2.0 or MIT
Cargo Stylus CLI Deploying Stylus programs Apache 2.0 or MIT

License

© 2022-2023 Offchain Labs, Inc.

This project is licensed under either of

at your option.

The SPDX license identifier for this project is MIT OR Apache-2.0.

stylus-sdk-rs's People

Contributors

afosan avatar chrisco512 avatar cygaar avatar defernus avatar gzeoneth avatar howjmay avatar josepbove avatar joshuacolvin0 avatar mikebenfield avatar rachel-bousfield avatar rauljordan avatar rootulp avatar tsahee avatar xpanvictor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stylus-sdk-rs's Issues

Old alloy dependencies (EIP-712 nested struct hashing bug)

Currently, stylus-sdk-rs depends on alloy-primitives and alloy-sol-types version 0.3.1. This version contains a known EIP-712 nested struct hashing bug (alloy-rs/core#257).

Example: eip712_signing_hash for Mail produces an incorrect hash.

sol! {
      struct Person {
          string name;
          address wallet;
      }

      struct Mail {
          Person from;
          Person to;
          string contents;
      }
  }

README hyperlink returns 404

image

The "Cargo Stylus CLI Tool" URL in the second paragraph of the README resolves to https://github.com/OffchainLabs/stylus-sdk-rs/blob/stylus/CargoStylus which is 404 not found.

Unable to declare non #[entrypoint] struct with #[borrow] and generics

Stylus version: 0.4.2

This code does not compile:

sol_storage! {
    pub struct Erc20Burnable<T>  {
        #[borrow]
        Erc20<T> erc20;
    }
}

I think it should, it represents an abstract class in Solidity with generic types

Note: without generic T in struct declaration it works fine (eg.: when type is MyTokenParams struct that implements Erc20Params trait)

bug: Solidity type aliases defined inside `sol!` macro cannot be used as Solidity struct members

Issue:

sol! {
    type Foo as uint32;
    struct Bar {
        Foo foo;
    }
}

will fail to compile

Cause: alloy-sol-macro transitive dependency v0.3.1 vs 0.3.2, former one generating such SolStruct impl that it requires all fields to be SolStructs themselves, while latter one doesn't require it.
Yet, v0.3.2 cannot be picked by resolver. It requires syn-solidity = "0.3.2" while latest stylus-proc 0.4.1 has strict requirement syn-solidity = "=0.3.1"

Proposed solution: relax requirement in stylus-proc to syn-solidity = "0.3.1"

EDIT: Seems syn-solidity was pinned due to breaking changes. While requirement can't be simply relaxed back, I'll leave this bug here.

bug: cannot inherit from contract that makes external call

It's quite unwieldy to inherit from a contract that makes a call to another contract, stemming from the fact that the parent contract isn't the entrypoint and thus doesn't implement TopLevelStorage when it is being inherited from.

I've managed to work around this by manually implementing CallContext (and StaticCallContext, in my case) for the parent contract, but this feels hacky and easy to misappropriate.

From what I gather, the TopLevelStorage trait is leveraged in this way to flush the storage cache in reentrant calls, but the inheritance situation I've laid out isn't really one of reentrancy...

I certainly lack some context on how the TopLevelStorage trait is implemented and intended to be leveraged, but this feels like it should be possible without enabling the reentrant flag

Project template not compatible with workspaces

The current template used to in cargo stylus new contains [profile] section in Cargo.toml which makes it incompatible with workspaces. Since that template has .cargo/config.toml anyway, it would be reasonable to move all profile settings there

[Feature] Provide a mechanism to set `msg::sender`

In our in-house unit-testing abstractions (which are based on this PoC), we have tried to find a way to set msg::sender. However, I think there is no way right now, because it is private to the SDK:

pub(crate) static mut SENDER: hostio::CachedOption<Address> = hostio::CachedOption::new(||{
    let mut data = Address::ZERO;
    unsafe {
        hostio::msg_sender(data.as_mut_ptr())
    };
    data.into()
})

Could we make this pub (though global mutable statics need to be treated with care) or is there a way to modify this I am missing?

feature: Solidity struct type support in `sol_interface!` macro

Hi there,
I'm trying to define an interface using the sol_interface! macro, in which a function returns a custom type (struct).
Ideally, I would like to be able to use the sol! macro from alloy-sol-types to define my struct.
When I try this, for example:

use stylus_sdk::prelude::*;
use alloy_sol_types::sol;

sol! {
  struct MyStruct {
    uint256 myNum;
  }
}

sol_interface! {
  interface IMyInterface {
    function doThing() returns (MyStruct);
  }
}

I get the error:

proc macro panicked
message: not yet implemented: Solidity type SolChallenges is not yet implemented in sol_interface!

I dug around in the code a bit, and it seems that sol_interface! can't interpret any struct types.

The ability to do so (particularly in tandem with the sol! macro) would be amazing, as currently, I believe my only option is to return a tuple type and manually deserialize it.

Function override does not work with inheritance as expected

Stylus version: 0.4.2

Class structure:

We want to implement a classic MyToken contract that that inherits from Erc20 and change it's behavior by overriding the implementation of update(..) virtual method from Erc20.

Erc20 is implemented with OpenZeppelin code as reference (link here)

Solidity way:

abstract contract ERC20  { 
   //.....
   function _update(address from, address to, uint256 value) internal virtual {
       // function body
    }
   //other Erc20 functions
}

contract MyToken is ERC20, Pausable {
    constructor {...}

    function _update(address from, address to, uint256 value) internal virtual override {
       // new logic goes here
       // after new logic is executed we want to run base impl from ERC20
        super._update(from, to, value); 
    }
}

To do the same with Stylus following structure hierarchy was defined:

sol_storage! {
    pub struct Erc20<T> {
        // here goes the erc20 fields
    }
}

impl<T: Erc20Params> Erc20<T> {
    pub fn update(&mut self, from: Address, to: Address, value: U256) -> Result<(), Vec<u8>> {
    // method body
   }
}

#[external]
impl<T: Erc20Params> Erc20<T> {
    pub fn transfer(&mut self, to: Address, value: U256) -> Result<bool, Erc20Error> {
        let owner = msg::sender();
        self.transfer_internal(owner, to, value)?;
        Ok(true)
    }
  
  fn transfer_internal(&mut self, from: Address, to: Address, value: U256) -> Result<(), Erc20Error> {
        if from == Address::ZERO {
            return Err(Erc20Error::Erc20InvalidSpender(Erc20InvalidSpender {
                spender: Address::ZERO,
            }));    
        }
        if to == Address::ZERO {
            return Err(Erc20Error::Erc20InvalidReceiver(Erc20InvalidReceiver {
                receiver: Address::ZERO,
            }));
        }
        self.update(from, to, value)
    }

  // other methods of Erc20
}

-------------- MyToken impl
sol_storage! {
    #[entrypoint]  
    pub struct MyToken {
        #[borrow]
        Erc20<MyTokenParams> erc20;
    }
}
impl MyToken {
    pub fn update(&mut self, from: Address, to: Address, value: U256) -> Result<(), Vec<u8>> {
        // new logic comes here
        self.erc20.update(from, to, value)?;
        Ok(())
    }
}
#[external]
#[inherit(Erc20<MyTokenParams>)]
impl MyToken {
  // body if MyToken 
}

Issue

Expected behavior: when Erc20 methods call self.update(..) like in example above in transfer_internal(..) method, execution goes to overridden function defined in MyToken impl

Current behavior: calling self.update(..) inside transfer_internal(..) executes the update(..) from Erc20 impl

Iterable Map

stylus is using the same storage system as solidity so StorageMap is not iterable, but in some cases iterable map is very important and people always need to implement something like openzeppelin EnumerableMap

Storage access issues with multi-level inheritance

Stylus version: 0.4.2

Contract structure

I have 3 contracts:

  • Erc20 (abstract)
  • Erc20Burnable (abstract, inherits Erc20)
  • MyToken (concrete implementation, inherits Erc20 and Erc20Burnable)

Erc20 is standard erc20 impl, I will omit the methods implementation, just mention the ones used test cases:

sol_storage! {
  pub struct Erc20<T> {
      mapping(address => uint256) balances;
      mapping(address => mapping(address => uint256)) allowances;
      uint256 total_supply;
      PhantomData<T> phantom;
  }
}

impl<T: Erc20Params> Erc20<T> {

    pub fn mint(&mut self, account: Address, value: U256) -> Result<(), Erc20Error> { .... }

    pub fn burn(&mut self, account: Address, value: U256) -> Result<(), Erc20Error> { ....}

    pub fn update(&mut self, from: Address, to: Address, value: U256) -> Result<(), Erc20Error> { .... }
}

#[external]
impl<T: Erc20Params> Erc20<T> {
  ...
    pub fn balance_of(&self, address: Address) -> Result<U256, Erc20Error> {
        Ok(self.balances.get(address))
    }
  ... (other methods are also implemented)
}

Erc20Burnable is standard Erc20 extension link to solidity impl here

sol_storage! {
    pub struct Erc20Burnable  {
        #[borrow]
        Erc20<MyTokenParams> erc20;
    }
}

#[external]
#[inherit(Erc20<MyTokenParams>)]
impl Erc20Burnable  {

    pub fn burn(&mut self, account: Address, amount: U256) -> Result<(), Erc20Error> {
        self.erc20.burn(account, amount)
    }

    pub fn balance_of_burn(&self, address: Address) -> Result<U256, Erc20Error> {
        Ok(self.erc20.balances.get(address))
    }
}

MyToken is the concreate contract impl that extends Erc20 and Erc20Burnable

sol_storage! {
    #[entrypoint]
    pub struct MyToken {
        #[borrow]
        Erc20<MyTokenParams> erc20;
        #[borrow]
        Erc20Burnable erc20_burnable;
    }
}

#[external]
#[inherit(Erc20<MyTokenParams>, Erc20Burnable)]
impl MyToken {

    pub fn mint(&mut self, account: Address, amount: U256) -> Result<(), Erc20Error> {
        self.erc20.mint(account, amount)
    }

    pub fn balance_of_burn_erc(&self, address: Address) -> Result<U256, Erc20Error> {
        self.erc20_burnable.balance_of_burn(address)
    }

    pub fn balance_of_direct(&self, address: Address) -> Result<U256, Erc20Error> {
        Ok(self.erc20.balances.get(address))
    }
}

Issue

After minting tokens with MyToken::mint(..) when trying to access balances from Erc20Burnable methods instead of actual value the call returns 0. It looks like it can not access right storage. Contract code is called correctly (I checked with throwing errors inside the Erc20 methods) but storage is not accessed in proper way.

simplified code (I'm using ether-rs but full test will take a lot of lines)

// balance taken with Erc20 balance_of method
let alice_balance = token.balance_of_burn(alice_address).call().await.unwrap();

// balance taken with call to Erc20Burnable method 
let alice_balance_burn = token.balance_of_burn(alice_address).call().await.unwrap();

// balance taken from MyToken method calling Erc20Burnable method
let alice_balance_of_burn_erc = token.balance_of_burn_erc(alice_address).call().await.unwrap();

// balance taken from MyToken method directly reading Erc20 blances mapping
let alice_balance_of_direct = token.balance_of_direct(alice_address).call().await.unwrap();

All methods being called on Erc20Burnable (value of alice_balance_burn, alice_balance_of_burn_erc) are returning 0

[Bug] Can't use any `alloy_primitives::Uint` other than `U256` in contract boundaries

Given the following contract:

sol_storage! {
    pub struct Test {
        uint8 t;
    }
}

#[external]
impl Test {
    pub fn getter(&mut self) -> U8 {
        self.t.get()
    }

    pub fn setter(&mut self, t: U8) {
        self.t.set(t)
    }
}

we get this compiler error:

error[E0271]: type mismatch resolving `<IntBitCount<8> as SupportedInt>::Uint == Uint<8, 1>`
  --> src/lib.rs:43:1
   |
43 | #[external]
   | ^^^^^^^^^^^ expected `Uint<8, 1>`, found `u8`
   |
   = note: expected struct `alloy_primitives::Uint<8, 1>`
                found type `u8`
   = note: required for `alloy_primitives::Uint<8, 1>` to implement `AbiType`
   = note: required for `alloy_primitives::Uint<8, 1>` to implement `EncodableReturnType`

Given that Storage* types use alloy_primitives at the accessor boundaries I would expect the SDK to handle this conversion for contract boundaries for me. Note that U256 works fine.

I get the same error inside the SDK if we add this here:

test_type!(uint8, "uint8", Uint<8, 1>);

A simple workaround for now is to use Rust types at the contract boundaries and make the conversion explicit. In the above example, that would be something like:

    pub fn getter(&mut self) -> u8 {
        self.t.get().byte(0)
    }

Equivalent of Solidity constructor

Is there an equivalent of Solidity constructor in Stylus? If not, is there any Stylus specific pattern you would suggest to achieve the same behavior?

I want to set a state variable to a value from msg context or passed as an argument to the constructor. Sharing a simple example Solidity contract to illustrate.

contract Example {
    address public owner;
    uint256 public num;

    constructor(uint256 _num) {
        owner = msg.sender;
        num = _num;
    }
}

edit: I have found an example using init function and initialized variable. It still seems possible that someone frontruns you to call init function (e.g. to become "owner" of the contract). Another example hardcodes the "owner" to prevent that.

edit2: I have just found the part about constructors here. I feel it might be helpful to have a link to it under "Developer reference" section.

Implement #[derive(SolidityError)]

Currently for errors it's necessary to define an error within a sol! block and also to impl fn from(err: Error) -> Vec<u8> for each error to encode the error as a Solidity compatible error by calling .encode() on the resulting error. To simplify this, a proc macro for #[derive(SolidityError)] should be defined.

New project created from template fails to check on Windows 10

OS: Windows 10 x64
Rust: 1.72.0
VS Build Tools 2022: 14.37.32822
cargo-stylus: 0.1.4

Steps to reproduce:

cargo stylus new fails-to-check
cd fails-to-check
cargo stylus check

Expected: check succeeds

Actual: check fails with

C:\Users\User\Projects\rust\banana>cargo stylus check
   Compiling stylus-proc v0.2.0
error: linking with `link.exe` failed: exit code: 1120
  |
  = note: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.37.32822\\bin\\HostX64\\x64\\link.exe" "/DEF:C:\\Users\\User\\AppData\\Local\\Temp\\rustcr8GcD6\\lib.def" "/NOLOGO" "C:\\Users\\User\\AppData\\Local\\Temp\\rustcr8GcD6\\symbols.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.00.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.01.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.02.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.03.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.04.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.05.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.06.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.07.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.08.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.09.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.10.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.11.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.12.rcgu.o" "C:\\Users\\User\\Projects\\ru13:37anana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.13.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.stylus_proc.83163f0ef4e4b294-cgu.14.rcgu.o" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.597j31fbz26ay48m.rcgu.rmeta" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.4344t86givcbs09f.rcgu.o" "/LIBPATH:C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps" "/LIBPATH:C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\liballoy_sol_types-5a259fff226a8c8d.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\liballoy_primitives-ad93b03a55794adf.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libbytes-2629ad7a6b9f5b39.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libitoa-d82fb866234c4626.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libtiny_keccak-d785abbb23dedae6.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libcrunchy-bd7b0301a3421ac9.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libhex_literal-1a07e78cb7103a90.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libconst_hex-cf762f4939371a55.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libcpufeatures-a362dc69d5aecbb1.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libcfg_if-68ed1fdf91f680d9.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libruint-11472cd88664c931.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libregex-26645200aa3c460a.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libregex_automata-a7795895a91c8ec6.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libaho_corasick-153ee297c3c4833a.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libmemchr-3b175fd84d47fb88.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libregex_syntax-b14ab3613e58f22f.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\liblazy_static-e5b7c24c07e81089.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libconvert_case-246738cad95f624f.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libunicode_segmentation-227882cd0f839168.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libsyn-6c640defbe227f11.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libsyn_solidity-2bcf61e580952b36.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libsyn-9593710509d5adab.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libsha3-d0a2bb5ae1657cfb.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libkeccak-caec9986c2e88504.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libdigest-9bb7c392faf6bf0e.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libblock_buffer-189cb1558a01866b.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libcrypto_common-14e9097dc4b7d81e.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libgeneric_array-2f51704f92b5a637.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libtypenum-d3806966f15e0878.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libquote-16664d29e1bc1113.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libproc_macro2-c573fdce701e4132.rlib" "C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\libunicode_ident-db62c766faf1da5b.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libproc_macro-7b90843133975eeb.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-0f357f0f8e8eb48f.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-57325150de1d69ac.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_demangle-7a221d01d4c27fb2.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd_detect-7bffc6b402bc9229.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libhashbrown-3fd39796b57f4908.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_alloc-8572e8a98839f6d6.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libminiz_oxide-6e930372a69395c9.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libadler-ad696ea66c589e9d.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-0a3e7125dc6e7fef.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcfg_if-7d7ae0874b44dfcc.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liblibc-2e82681b8e87518e.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-5ed5a0d27d7423da.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_core-e970d604d303b37d.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-e73f27a013927059.rlib" "C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-fbb34b1faced902f.rlib" "kernel32.lib" "advapi32.lib" "bcrypt.lib" "kernel32.lib" "ntdll.lib" "userenv.lib" "ws2_32.lib" "kernel32.lib" "ws2_32.lib" "kernel32.lib" "msvcrt.lib" "/NXCOMPAT" "/LIBPATH:C:\\Users\\User\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "/OUT:C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.dll" "/OPT:REF,NOICF" "/DLL" "/IMPLIB:C:\\Users\\User\\Projects\\rust\\banana\\target\\release\\deps\\stylus_proc-b80a7200cb344d25.dll.lib" "/DEBUG:NONE"
  = note:    Creating library C:\Users\User\Projects\rust\banana\target\release\deps\stylus_proc-b80a7200cb344d25.dll.lib and object C:\Users\User\Projects\rust\banana\target\release\deps\stylus_proc-b80a7200cb344d25.dll.exp
          liballoy_primitives-ad93b03a55794adf.rlib(alloy_primitives-ad93b03a55794adf.alloy_primitives.8ed169664c9e1a12-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol native_keccak256 referenced in function _ZN16alloy_primitives5utils9keccak2569keccak25617hb59fee3098333425E
          C:\Users\User\Projects\rust\banana\target\release\deps\stylus_proc-b80a7200cb344d25.dll : fatal error LNK1120: 1 unresolved externals


error: could not compile `stylus-proc` (lib) due to previous error
Stylus checks failed: failed to build project to WASM: cargo build command failed

cargo run --example counter have problem

cargo run --example counter
   Compiling ethers-providers v2.0.9
   Compiling ethers-contract-abigen v2.0.9
   Compiling ethers-signers v2.0.9
   Compiling alloy-sol-types v0.3.1
   Compiling mio v0.8.8
error[E0432]: unresolved import `crate::sys::IoSourceState`
  --> /Users/davirain/.cargo/registry/src/index.crates.io-6f17d22bba15001f/mio-0.8.8/src/io_source.rs:12:5
   |
12 | use crate::sys::IoSourceState;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ no `IoSourceState` in `sys`

error[E0432]: unresolved import `crate::sys::tcp`
  --> /Users/davirain/.cargo/registry/src/index.crates.io-6f17d22bba15001f/mio-0.8.8/src/net/tcp/listener.rs:15:17
   |
15 | use crate::sys::tcp::{bind, listen, new_for_addr};
   |                 ^^^ could not find `tcp` in `sys`

error[E0432]: unresolved import `crate::sys::tcp`
  --> /Users/davirain/.cargo/registry/src/index.crates.io-6f17d22bba15001f/mio-0.8.8/src/net/tcp/stream.rs:13:17
   |
13 | use crate::sys::tcp::{connect, new_for_addr};
   |                 ^^^ could not find `tcp` in `sys`

error[E0433]: failed to resolve: could not find `Selector` in `sys`
   --> /Users/davirain/.cargo/registry/src/index.crates.io-6f17d22bba15001f/mio-0.8.8/src/poll.rs:300:18

Is it okay to `unsafe impl TopLevelStorage for X`?

Whenever you try to use the Call::new_in API, Self must be bound by TopLevelStorage + BorrowMut<Self>, which means that you end up with a lot of &mut (impl TopLevelStorage + BorrowMut<Self>) instead of a receiver argument.

This is not great, and would definitely be surprising to devs. It is my understanding that it is safe to do unsafe impl TopLevelStorage for X where X is used as a field of the entrypoint contract, and is marked as #[borrow]. I think this is safe because when routing calls to the "sub-contract" (?), it effectively becomes the top-level storage because of #[borrow].

Is this mental model correct? Should this unsafe impl block be handled by #[borrow]?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.