name: mvx_cross_contract_storage description: 使用storage_mapper_from_address直接读取同一分片合约的存储。
MultiversX 跨合约存储读取
直接读取另一个合约的存储映射器——无需代理调用的气体开销,无异步复杂性。
何时使用
| 标准 | storage_mapper_from_address |
代理调用 |
|---|---|---|
| 仅同一分片 | 是(必需) | 跨分片工作 |
| 只读 | 是 | 读写 |
| 需要在目标上计算 | 否 | 是 |
| 气体成本 | ~存储读取成本 | ~执行 + 存储 |
| 需要知道存储密钥 | 是 | 否(使用ABI) |
核心模式
#[multiversx_sc::module]
pub trait ExternalStorageModule {
// 简单值
#[storage_mapper_from_address("total_supply")]
fn external_total_supply(&self, contract_address: ManagedAddress) -> SingleValueMapper<BigUint, ManagedAddress>;
// 复合键(特定于代币)
#[storage_mapper_from_address("balance")]
fn external_balance(&self, contract_address: ManagedAddress, token_id: &TokenIdentifier) -> SingleValueMapper<BigUint, ManagedAddress>;
// 模块前缀键
#[storage_mapper_from_address("pause_module:paused")]
fn external_paused(&self, contract_address: ManagedAddress) -> SingleValueMapper<bool, ManagedAddress>;
}
关键规则
- 字符串必须完全匹配目标合约中的存储密钥
- 第一个参数必须是
ManagedAddress - 返回类型的第二个泛型必须是
ManagedAddress - 额外参数成为复合键部分
如何发现存储密钥
- 源代码:目标中的
#[storage_mapper("key")] - ABI:
.abi.json列出所有密钥 - 模块密钥:前缀如
pause_module:paused
安全
- 仅同一分片:跨分片读取默默返回默认值——无错误
- 陈旧数据:反映目标在当前位置的状态
- 密钥更改:如果目标在升级中重命名密钥,读取默默中断
- 只读:无法写入另一个合约的存储
反模式
- 未验证空结果(默默获取默认0/false)
- 未验证目标在同一分片