Rust数据校验库near-schema-checker-lib的使用,高效实现Near协议数据结构与模式验证
Rust数据校验库near-schema-checker-lib的使用,高效实现Near协议数据结构与模式验证
near-schema-checker-lib是一个用于NEAR协议数据结构和模式验证的Rust库,版本0.30.3,采用MIT或Apache-2.0双重许可。
安装方法
在项目目录中运行以下Cargo命令:
cargo add near-schema-checker-lib
或者在Cargo.toml中添加:
near-schema-checker-lib = "0.30.3"
示例代码
以下是使用near-schema-checker-lib进行NEAR协议数据结构验证的完整示例:
use near_schema_checker_lib::{validate_schema, SchemaError};
use serde_json::{json, Value};
fn main() -> Result<(), SchemaError> {
// 定义NEAR协议数据的JSON Schema
let schema = json!({
"type": "object",
"properties": {
"account_id": {
"type": "string",
"pattern": "^[a-z0-9._-]+$"
},
"amount": {
"type": "string",
"pattern": "^[0-9]+$"
},
"action": {
"type": "string",
"enum": ["transfer", "stake", "create_account"]
}
},
"required": ["account_id", "amount", "action"]
});
// 待验证的NEAR协议交易数据
let transaction_data = json!({
"account_id": "alice.near",
"amount": "1000000000000000000000000",
"action": "transfer"
});
// 执行验证
validate_schema(&schema, &transaction_data)?;
println!("Transaction data is valid!");
Ok(())
}
特性
- 高效验证NEAR协议特定的数据结构
- 支持JSON Schema验证标准
- 与NEAR核心组件深度集成
- 提供详细的错误报告机制
这个库主要由nearprotocol-ci团队维护,是NEAR协议生态系统的核心组件之一。
完整示例代码
以下是基于提供内容的完整示例,展示了更复杂的NEAR协议数据结构验证场景:
use near_schema_checker_lib::{validate_schema, SchemaError};
use serde_json::{json, Value};
fn main() -> Result<(), SchemaError> {
// 定义更复杂的NEAR协议JSON Schema
let schema = json!({
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "NEAR Protocol Transaction",
"description": "Schema for validating NEAR transactions",
"type": "object",
"properties": {
"sender": {
"type": "string",
"pattern": "^[a-z0-9._-]+$",
"description": "发送者账户ID"
},
"receiver": {
"type": "string",
"pattern": "^[a-z0-9._-]+$",
"description": "接收者账户ID"
},
"amount": {
"type": "string",
"pattern": "^[0-9]+$",
"description": "转账金额(以yoctoNEAR为单位)"
},
"action": {
"type": "string",
"enum": ["transfer", "stake", "create_account", "delete_account", "add_key"],
"description": "交易类型"
},
"gas": {
"type": "string",
"pattern": "^[0-9]+$",
"description": "gas费用"
},
"public_key": {
"type": "string",
"pattern": "^ed25519:[A-Za-z0-9+/=]+$",
"description": "公钥(可选)"
}
},
"required": ["sender", "receiver", "amount", "action", "gas"],
"additionalProperties": false
});
// 待验证的NEAR协议交易数据
let transaction_data = json!({
"sender": "alice.near",
"receiver": "bob.near",
"amount": "1000000000000000000000000", // 1 NEAR (以yoctoNEAR为单位)
"action": "transfer",
"gas": "100000000000000",
"public_key": "ed25519:7P3k4Q4X8Jk6tY2RvT2v9JkXhY7sVv1W2z3X4y5Z6A7B8C9D0E"
});
// 执行验证
match validate_schema(&schema, &transaction_data) {
Ok(_) => println!("交易数据验证通过!"),
Err(e) => eprintln!("验证失败: {:?}", e),
}
Ok(())
}
这个完整示例展示了:
- 更复杂的JSON Schema定义,包含更多NEAR协议特有的字段
- 添加了模式描述信息
- 包含了可选字段的验证
- 更完善的错误处理
- 展示了NEAR协议中常见的字段格式验证
在使用时,您可以根据实际需求调整schema和交易数据结构,以适应不同的NEAR协议验证场景。
1 回复
Rust数据校验库near-schema-checker-lib的使用:高效实现Near协议数据结构与模式验证
完整示例demo
以下是一个完整的NEAR合约示例,展示如何使用near-schema-checker-lib验证合约方法参数:
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::{env, near_bindgen, serde_json};
use near_schema_checker_lib::{Schema, SchemaType, CustomValidator};
use lazy_static::lazy_static;
// 定义自定义验证器检查NEAR账户ID格式
fn validate_near_account(value: &serde_json::Value) -> Result<(), String> {
if let Some(s) = value.as_str() {
if s.ends_with(".near") {
Ok(())
} else {
Err("账户ID必须以.near结尾".to_string())
}
} else {
Err("账户ID必须是字符串".to_string())
}
}
// 预编译常用Schema实例
lazy_static! {
static ref TRANSFER_SCHEMA: Schema = Schema::new()
.field("receiver_id", SchemaType::Custom(Box::new(CustomValidator::new(validate_near_account))))
.field("amount", SchemaType::U128)
.field("memo", SchemaType::Optional(Box::new(SchemaType::String)));
static ref NFT_METADATA_SCHEMA: Schema = Schema::new()
.field("title", SchemaType::String)
.field("description", SchemaType::Optional(Box::new(SchemaType::String)))
.field("media", SchemaType::String)
.field("media_hash", SchemaType::Optional(Box::new(SchemaType::String)));
}
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct Contract {
pub owner_id: String,
}
#[near_bindgen]
impl Contract {
#[init]
pub fn new(owner_id: String) -> Self {
// 验证owner_id格式
let owner_schema = Schema::new()
.field("owner_id", SchemaType::Custom(Box::new(CustomValidator::new(validate_near_account))));
owner_schema.validate(&serde_json::json!({"owner_id": owner_id.clone()}))
.expect("无效的owner_id格式");
Self { owner_id }
}
// 转账方法
pub fn transfer(&mut self, params: serde_json::Value) {
// 验证转账参数
TRANSFER_SCHEMA.validate(¶ms)
.unwrap_or_else(|e| env::panic_str(&format!("无效的转账参数: {}", e)));
// 这里添加实际的转账逻辑...
env::log_str("转账操作已验证通过");
}
// 创建NFT方法
pub fn mint_nft(&mut self, metadata: serde_json::Value) {
// 验证NFT元数据
NFT_METADATA_SCHEMA.validate(&metadata)
.unwrap_or_else(|e| env::panic_str(&format!("无效的NFT元数据: {}", e)));
// 这里添加实际的NFT铸造逻辑...
env::log_str("NFT元数据已验证通过");
}
}
// 测试模块
#[cfg(test)]
mod tests {
use super::*;
use near_sdk::test_utils::{get_logs, VMContextBuilder};
use near_sdk::{testing_env, AccountId, VMContext};
fn get_context() -> VMContext {
VMContextBuilder::new()
.signer_account_id(AccountId::new_unchecked("alice.near".to_string()))
.build()
}
#[test]
fn test_transfer() {
let context = get_context();
testing_env!(context);
let mut contract = Contract::new("owner.near".to_string());
// 测试有效转账
let valid_transfer = serde_json::json!({
"receiver_id": "bob.near",
"amount": "1000000000000000000000000"
});
contract.transfer(valid_transfer);
assert_eq!(get_logs(), vec!["转账操作已验证通过"]);
// 测试无效转账 - 会panic
let invalid_transfer = serde_json::json!({
"receiver_id": "invalid_account",
"amount": "100"
});
let result = std::panic::catch_unwind(|| {
contract.transfer(invalid_transfer);
});
assert!(result.is_err());
}
#[test]
fn test_mint_nft() {
let context = get_context();
testing_env!(context);
let mut contract = Contract::new("owner.near".to_string());
// 测试有效NFT元数据
let valid_metadata = serde_json::json!({
"title": "My NFT",
"media": "https://example.com/nft.jpg"
});
contract.mint_nft(valid_metadata);
assert_eq!(get_logs(), vec!["NFT元数据已验证通过"]);
}
}
这个完整示例展示了:
- 如何使用自定义验证器验证NEAR账户ID格式
- 如何使用预编译Schema实例提高性能
- 如何在合约方法中验证输入参数
- 如何编写测试用例验证数据校验功能
- 如何处理验证失败的情况
您可以根据实际需求修改Schema定义和验证逻辑,以适应不同的NEAR合约开发场景。