Skip to content

A Vending Machine contract written in Stylus. It includes deployment scripts and a Rust script to interact with the contract, serving as a reference for building and interacting with Stylus-based contracts.

Notifications You must be signed in to change notification settings

OffchainLabs/stylus-quickstart-vending-machine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Stylus Cupcake Example

An example project for writing Arbitrum Stylus contracts in Rust using the stylus-sdk. It includes a Rust implementation of a vending machine Ethereum smart contract.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

// Rule 2: The vending machine's rules can't be changed by anyone.
contract VendingMachine {
    // state variables = internal memory of the vending machine
    mapping(address => uint) private _cupcakeBalances;
    mapping(address => uint) private _cupcakeDistributionTimes;

    function giveCupcakeTo(address userAddress) public returns (bool) {
        // this code is unnecessary, but we're keeping it here so you can compare it to the JS implementation
        if (_cupcakeDistributionTimes[userAddress] == 0) {
            _cupcakeBalances[userAddress] = 0;
            _cupcakeDistributionTimes[userAddress] = 0;
        }

        // Rule 1: The vending machine will distribute a cupcake to anyone who hasn't recently received one.
        uint fiveSecondsFromLastDistribution = _cupcakeDistributionTimes[userAddress] + 5 seconds;
        bool userCanReceiveCupcake = fiveSecondsFromLastDistribution <= block.timestamp;
        if (userCanReceiveCupcake) {
            _cupcakeBalances[userAddress]++;
            _cupcakeDistributionTimes[userAddress] = block.timestamp;
            return true;
        } else {
            revert("HTTP 429: Too Many Cupcakes (you must wait at least 5 seconds between cupcakes)");
        }
    }

    // Getter function for the cupcake balance of a user
    function getCupcakeBalanceFor(address userAddress) public view returns (uint) {
        return _cupcakeBalances[userAddress];
    }
}

ABI Export

You can export the Solidity ABI for your contract by using the cargo stylus tool as follows:

cargo stylus export-abi

which outputs:

/**
 * This file was automatically generated by Stylus and represents a Rust contract.
 * For more information, please see [The Stylus SDK](https://github.com/OffchainLabs/stylus-sdk-rs).
 */

interface VendingMachine {
    function giveCupcakeTo(address user_address) external returns (bool);

    function getCupcakeBalanceFor(address user_address) external view returns (uint256);
}

Deploying

You can use the cargo stylus command to deploy your contract to the Stylus-enabled Arbitrum Sepolia testnet. First, we can use the tool to check if our contract compiles to valid WASM for Stylus and verify that the deployment will succeed without submitting a transaction. By default, this will use the Arbitrum Sepolia testnet public RPC endpoint. See here for more information.

cargo stylus check

Next, we deploy:

cargo stylus deploy \
  --private-key-path=<PRIVKEY_FILE_PATH>

Calling Your Contract

This example includes how to call and transact with your contract in Rust using ethers-rs under examples/vending_machine.rs. Your contracts are also Ethereum ABI equivalent if using the Stylus SDK, meaning they can be called and transacted with using any other Ethereum tooling.

By using the contract address from your deployment step above and your wallet, you can attempt to call the vending machine contract and interact with it.

To run the example, set the following env vars or place them in a .env file this project, then:

STYLUS_CONTRACT_ADDRESS=<the onchain address of your deployed contract>
PRIV_KEY_PATH=<the file path for your priv key to transact with>
RPC_URL=https://sepolia-rollup.arbitrum.io/rpc
USER_ADDRESS=<the address of the user you want to interact with>

Alternatively, you can copy the .env-sample into a .env file:

cp .env-sample .env

Next, run:

cargo run --example vending_machine --target=<YOUR_ARCHITECTURE>

Where you can find YOUR_ARCHITECTURE by running rustc -vV | grep host. For M1 Apple computers, for example, this is aarch64-apple-darwin and for most Linux x86 it is x86_64-unknown-linux-gnu.

About

A Vending Machine contract written in Stylus. It includes deployment scripts and a Rust script to interact with the contract, serving as a reference for building and interacting with Stylus-based contracts.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages