DubheSuiContractsAddress System

Address System

The address_system module provides utilities for resolving caller identity and converting between chain address formats. It is particularly relevant for DApps that want to support users from EVM or Solana chains via Dubhe Channel.

Note: In the current storage model, per-user data is stored in UserStorage objects — the storage object itself is the user’s identity. You no longer need to derive a resource_account string from ctx.sender() for storage operations.


ensure_origin

use dubhe::address_system;
 
let sender: String = address_system::ensure_origin(ctx);

ensure_origin reads ctx and returns the caller’s address as a lowercase hex string (without the 0x prefix).

For native Sui transactions this is always a 64-character hex string derived from the 32-byte Sui address:

ctx.sender() = 0x1462cab50fe5998f8161378e5265f7920bfd9fbce604d602619962f608837217
ensure_origin → "1462cab50fe5998f8161378e5265f7920bfd9fbce604d602619962f608837217"

When used with Dubhe Channel (cross-chain transactions), ensure_origin automatically returns the original EVM or Solana address string instead of the Sui address.

When to use ensure_origin: Use it when you need the caller’s address as a string — for example, to emit it in an event, store it as a regular field value, or pass it as a key in a keyed resource. You do not need it merely to read or write user data in UserStorage.


Address conversion utilities

The module provides helpers for converting between chain address formats:

use dubhe::address_system;
use std::ascii::string;
 
// Convert an EVM hex address to its mapped Sui address
let sui_addr: address = address_system::evm_to_sui(
    string(b"0x9168765ee952de7c6f8fc6fad5ec209b960b7622")
);
 
// Convert a Solana Base58 address to its mapped Sui address
let sui_addr: address = address_system::solana_to_sui(
    string(b"3vy8k1NAc3Q9EPvqrAuS4DG4qwbgVqfxznEdtcrL743L")
);

Both functions abort if the input is malformed (wrong length or invalid encoding).


Multi-chain support

ensure_origin is designed to support transactions relayed from EVM and Solana chains via Dubhe Channel (under development). When a cross-chain transaction is received, ensure_origin automatically returns the original EVM or Solana address string instead of the Sui address, keeping caller identity consistent across chains.

For native Sui DApps this is transparent — ensure_origin behaves exactly like a typed ctx.sender() that returns a String.


Testing

Use the built-in test helpers to simulate different chain contexts in unit tests:

#[test]
public fun test_ensure_origin_returns_sender() {
    let sender = @0x1462cab50fe5998f8161378e5265f7920bfd9fbce604d602619962f608837217;
    let mut scenario = test_scenario::begin(sender);
    let ctx = test_scenario::ctx(&mut scenario);
 
    let origin = address_system::ensure_origin(ctx);
    assert!(origin == string(b"1462cab50fe5998f8161378e5265f7920bfd9fbce604d602619962f608837217"));
 
    scenario.end();
}
 
// Simulate an EVM relay context (requires Dubhe Channel for production use)
#[test]
public fun test_evm_context() {
    let mut scenario = test_scenario::begin(@0x1);
    address_system::setup_evm_scenario(
        &mut scenario,
        b"0x9168765EE952de7C6f8fC6FaD5Ec209B960b7622"
    );
    let ctx = test_scenario::ctx(&mut scenario);
 
    // Returns the original 40-char EVM address (lowercase, no 0x)
    let origin = address_system::ensure_origin(ctx);
    assert!(origin == string(b"9168765ee952de7c6f8fc6fad5ec209b960b7622"));
 
    scenario.end();
}

The setup_evm_scenario and setup_solana_scenario helpers are #[test_only] and are never available in production builds.