使用Sui天气预言机获取全球实时天气数据

使用Sui预言机将天气数据集成到apps中,或者将其不确定性作为一个独特的随机数生成器应用到各个app中。

使用Sui天气预言机获取全球实时天气数据

新的Sui天气预言机为全球1000多个城市的建设者提供天气数据,并作为一个独特的随机数生成器,适用于需要可信赖的随机结果的游戏和投注应用。它由基于Sui的智能合约和一个从OpenWeather API获取天气数据的后端服务组成,任何人都可以将天气数据集成到他们的应用中。

Sui天气预言机为其支持的任何城市提供温度、湿度和风力等信息。这个预言机可以被其他需要可靠和去中心化的天气信息的智能合约或应用程序使用,比如旅行、保险、农业、竞猜或游戏等各种用途。

来自OpenWeather的法国巴黎天气显示
Sui天气预言机可以实现使用OpenWeather API追踪天气和其他应用数据

天气是自然界中最不可预测和复杂的现象之一,利用天气的随机性可以提供一个有趣的用例。天气预报员在很大程度上做了一项令人钦佩的工作,预测雨水或晴天,诸如特定温度或风速之类的细枝末节超出了目前科学的范畴。 

作为科学、数学和工程许多领域的基本概念,随机性可以用于生成安全的加密密钥、测试假设或模拟复杂系统。然而,生成真正的随机性并不容易,因为大多数物理或计算过程在某种程度上是确定性或有偏差的。使用天气数据作为预言机输入提供了均匀分布且独立于任何先前输出的随机输出。

应用中的预言机数据

Sui和其他区块链上的预言机充当通道,连接到链外数据,包括体育比分、股票价格和天气。直接在应用中显示这些数据是最明显的用途,使得开发者可以创建股票投资组合管理工具、天气追踪器和实时足球排名。当然,以这种方式使用数据可能变得更加复杂,比如应用程序使用体育比分来为幻想联赛提供信息就是一个例子。 

游戏可以直接基于预言机数据构建。例如,预言机可以提供各种竞猜比赛的赔率和结果,比如体育比赛、彩票抽奖。 

当开发者使用提供不可预测数据的预言机来生成随机性时,事情变得更加有趣。例如,一个预言机可以使用真实世界的事件,比如天气数据、体育赛果或股票价格,为游戏创建随机结果。另外,预言机可以使用密码学方法,比如哈希函数或数字签名,生成安全且可证明的随机数。预言机数据来自于一个可验证的独立于应用的来源,这使得随机结果具有可信度。

天气数据可以作为随机性的种子,来决定游戏中角色行动的结果。(图片来源:RPGMaker)

基于预言机不可预测数据的随机性可以被融入游戏机制。例如,在角色扮演游戏中,预言机可以决定角色行动的成功或失败,比如施放法术、黑客入侵电脑或说服NPC。预言机也可以影响游戏世界,比如改变天气、生成敌人或触发事件。游戏可以使用预言机的数据来创建一个公平且一致的随机性,而不受游戏开发者或玩家的影响。

Sui天气预言机

预言机将使Sui平台上的新一代应用成为可能,将现实世界的数据连接到其高性能平台上。鉴于OpenWeather API的易用性和其数据的实用性,天气预言机是Sui的一个很好的补充。 

使用案例

Sui天气预言机对许多需要天气数据的应用非常有用,例如:

  • 随机性:天气数据可以用作各种目的的随机源,比如生成随机数、选择获胜者或创建独特的NFT。例如,一个随机数生成器可以使用特定位置在特定时间的温度、湿度或风速作为种子。
  • 竞猜和游戏:应用可以使用Sui天气预言机的数据来实现天气预测、以天气为主题的游戏或基于天气的奖励。例如,一个游戏可以让用户竞猜一个城市的天气,或者一个应用可以根据不同地点的天气为用户提供NFT。
  • 其他用例:保险、旅行、教育或研究的应用可以使用天气数据。例如,应用可以将天气数据纳入计算自然灾害风险、规划旅行行程、教授学生天气模式或协助设置科学实验等方面。

预言机结构

Sui天气预言机为全球1000多个城市提供最新的天气信息,包括三个组件:一个外部服务、一个内部服务和一个智能合约。外部服务是OpenWeather API,提供来自各种来源的当前天气数据。内部服务是天气预言机的后端,每10分钟从OpenWeather API获取天气数据,并更新每个城市的天气状况。智能合约是Sui天气预言机合约,将天气数据存储在Sui区块链上,并允许用户以安全透明的方式访问。用户还可以利用天气数据开发各种依赖于天气的去中心化应用,比如游戏。

赚取存储返利

Sui天气预言机通过存储返利机制来减轻将其实时数据存储在网络上的成本。Sui支持在其基础设施和token经济模型中进行链上存储,通过在其Gas费中增加存储费用来实现。从存储费用中产生的资金有助于补偿网络运营商维护硬件以存储数据和处理交易的成本。为了控制链上数据的数量,删除链上数据将产生存储基金返利。 

Sui天气预言机将天气数据存储并更新到区块链上。管理员支付一次性费用以创建初始的CityWeatherOracle对象列表,并在更新每个城市的天气数据时获得返利。返利与更新的数据量和频率成比例。通过这种方式,管理员可以以较低的成本在区块链上存储和更新天气数据。

利用Sui对象显示

Sui天气预言机使用Sui对象显示标准来根据当前天气条件动态更新每个城市的图标,例如显示雨云或太阳。Sui对象显示标准是一个模板引擎,允许对任何类型的对象进行链上管理和链下显示。它使用一个模板字符串,可以用对象的数据进行替换,比如城市的天气ID。链下显示由后端服务处理,向Sui资源浏览器提供每个受支持城市的图标。图标来自一个预定义的图标集,代表不同的天气条件,比如晴天、多云、雨天和雪天。

各种天气图标
Sui对象显示标准可用于显示代表不同天气条件的图标(图片由Freepik上的coolvector提供

Sui Weather Oracle智能合约 

Sui天气预言机智能合约为全球1000多个地点提供实时和历史天气数据,并支持基于城市天气数据铸造天气NFT。该智能合约还使用了Sui对象显示标准,使得在区块链上动态且可定制地显示天气数据和天气NFT成为可能。该智能合约有四个主要功能:
add_city, remove_city, updatemint

  oracle::weather 模块定义了以下内容:

AdminCap结构体代表预言机所有者的管理员权限。

struct AdminCap has key, store { id: UID }

WEATHER结构体代表设置一个发布者。

struct WEATHER has drop {}

WeatherOracle结构体代表预言机本身。它有以下字段 id, address, namedescription 分别代表存储预言机的标识符、所有者地址、名称和描述。

struct WeatherOracle has key {
    id: UID,
    address: address,
    name: String,
    description: String,
}

CityWeatherOracle结构体代表特定城市的天气数据。它有以下字段 id, geoname_id, name, country, latitude, positive_latitude, longitude, positive_longitude, weather_id, temp, pressure, humidity, visibility, wind_speed, wind_deg, wind_gust, cloudsdt ,分别存储城市的唯一ID、地理位置名称ID、名称、 国家、纬度、正纬度、经度、正经度、天气ID、温度、压力、湿度、能见度、风速、风向、阵风、云量、时间戳。

struct CityWeatherOracle has key, store {
    id: UID,
    geoname_id: u32,
    name: String,
    country: String,
    latitude: u32,
    positive_latitude: bool,
    longitude: u32,
    positive_longitude: bool,
    weather_id: u16,
    temp: u32,
    pressure: u32,
    humidity: u8,
    visibility: u16,
    wind_speed: u16,
    wind_deg: u16,
    wind_gust: Option<u16>,
    clouds: u8,
    dt: u32
}

一个 init 函数,在部署期间初始化合约,创建 WeatherOracle 的新实例并公开共享它,同时创建 AdminCap 的新实例并将其转移到发送者。

fun init(otw: WEATHER, ctx: &mut TxContext) {
    package::claim_and_keep(otw, ctx);

    let cap = AdminCap { id: object::new(ctx) };
    transfer::share_object(WeatherOracle {
        id: object::new(ctx),
        address: tx_context::sender(ctx),
        name: string::utf8(b"SuiMeteo"),
        description: string::utf8(b"A weather oracle for posting weather updates (temperature, pressure, humidity, visibility, wind metrics and cloud state) for major cities around the world. Currently the data is fetched from https://openweathermap.org. SuiMeteo provides the best available information, but it does not guarantee its accuracy, completeness, reliability, suitability, or availability. Use it at your own risk and discretion."),
    });
    transfer::public_transfer(cap, tx_context::sender(ctx));
}

  add_city 公共函数,允许 AdminCap 的所有者通过提供 geoname_ID, name, country, latitudelongitude向预言机服务添加新的城市。该函数创建一个带有默认天气数据的 CityWeatherOracle 新实例,并将其作为动态字段添加到预言机中,使用 geoname_ID 作为key。

public fun add_city(
    _: &AdminCap, 
    oracle: &mut WeatherOracle, 
    geoname_id: u32,
    name: String,
    country: String,
    latitude: u32,
    positive_latitude: bool,
    longitude: u32,
    positive_longitude: bool,
    ctx: &mut TxContext
) {
    dof::add(&mut oracle.id, geoname_id, 
        CityWeatherOracle {
            id: object::new(ctx),
            geoname_id,
            name, 
            country, 
            latitude, 
            positive_latitude, 
            longitude, 
            positive_longitude,
            weather_id: 0,
            temp: 0,
            pressure: 0,
            humidity: 0,
            visibility: 0,
            wind_speed: 0,
            wind_deg: 0,
            wind_gust: option::none(),
            clouds: 0,
            dt: 0
        }
    );
}

  remove_city 公共函数,允许 AdminCap 的所有者通过提供 geoname_ID从预言机服务中删除现有城市。该函数从预言机的动态字段中移除相应的 CityWeatherOracle 实例并删除对象。

public fun remove_city(_: &AdminCap, oracle: &mut WeatherOracle, geoname_id: u32) {
    let CityWeatherOracle { id, geoname_id: _, name: _, country: _, latitude: _, positive_latitude: _, longitude: _, positive_longitude: _, weather_id: _, temp: _, pressure: _, humidity: _, visibility: _, wind_speed: _, wind_deg: _, wind_gust: _, clouds: _, dt: _ } = dof::remove(&mut oracle.id, geoname_id);
    object::delete(id);
}

  update 公共函数,允许预言机所有者通过提供 geoname_ID 和新的天气数据来更新现有城市的天气数据。该函数使用新的天气数据改变相应的 CityWeatherOracle 实例。

public fun update(
    _: &AdminCap,
    oracle: &mut WeatherOracle,
    geoname_id: u32,
    weather_id: u16,
    temp: u32,
    pressure: u32,
    humidity: u8,
    visibility: u16,
    wind_speed: u16,
    wind_deg: u16,
    wind_gust: Option<u16>,
    clouds: u8,
    dt: u32
) {
    let city_weather_oracle_mut = dof::borrow_mut<u32, CityWeatherOracle>(&mut oracle.id, geoname_id);
    city_weather_oracle_mut.weather_id = weather_id;
    city_weather_oracle_mut.temp = temp;
    city_weather_oracle_mut.pressure = pressure;
    city_weather_oracle_mut.humidity = humidity;
    city_weather_oracle_mut.visibility = visibility;
    city_weather_oracle_mut.wind_speed = wind_speed;
    city_weather_oracle_mut.wind_deg = wind_deg;
    city_weather_oracle_mut.wind_gust = wind_gust;
    city_weather_oracle_mut.clouds = clouds;
    city_weather_oracle_mut.dt = dt;
}

集成Sui天气预言机

在Move项目中使用Sui天气预言机需要将其作为依赖项添加到项目的 Move.toml 文件中:

[package]
name = "..."version = "..."

[dependencies]
Sui = { git = "<https://github.com/MystenLabs/sui.git>", subdir = "crates/sui-framework/packages/sui-framework", rev = "..." }
oracle = { git = "<https://github.com/MystenLabs/apps>", subdir = "weather-oracle", rev = "db04fbd17d6ba91ade45c32f609b949fb47d209b" }

[addresses]
...
oracle = "0x8378b3bd39931aa74a6aa3a820304c1109d327426e4275183ed0b797eb6660a8"

创建这个依赖项使得开发者可以在Move代码中导入 oracle::weather 模块,并利用天气预言机及其函数。Sui天气预言机为全球不同城市提供实时天气数据,如温度、湿度和风速。 city_weather_oracle_temp 函数检索该城市以开尔文为单位乘以1,000的温度,通过给定的 geoname_ID.

例如,以下代码获取法国巴黎(2988507)当前的温度:

use oracle::weather::{WeatherOracle};

fun get_temp(weather_oracle: &WeatherOracle): u32 {
    let geoname_id = 2988507; // Paris, France
    oracle::weather::city_weather_oracle_temp(weather_oracle, geoname_id)
}

将数据桥接到Sui

过去几十年中大数据的崛起创造了庞大的数据库,代表了各种真实世界的现象和活动,从海洋洋流到曼哈顿的交通流。对这些数据的负责使用会产生对人们生活有积极影响的应用程序,无论是帮助预测森林火灾危险还是以公平方式提供热门音乐会门票。 

在Sui上预言机的传播将增加应用程序与人们日常生活的相关性,使得该网络成为现代数字基础设施中不可或缺的一部分。