Flutter Polkadot数据编码插件polkadart_scale_codec的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter Polkadot数据编码插件polkadart_scale_codec的使用

polkadart_scale_codec 是一个用于在 Flutter 和 Dart 中编码和解码由 polkadot 支持的类型的库。

让我们开始吧

支持的类型

类型 符号
无符号整数 u8, u16, u32, u64, u128, u256
有符号整数 i8, i16, i32, i64, i128, i256
字符串 Str
布尔值 bool
紧凑表示法 Compact<T>
枚举 _enum
复合结构 {}
固定长度向量 [u8, length]
位向量 BitVec
可选项 Option<T>
元组 (K, V, T....)
结果类型 Result<Ok, Err>

使用方法

无符号整数(u8 | u16 | u32)

//
// 编码
var output = HexOutput();

final value = 69;

U8Codec.codec.encodeTo(value, output);

// 0x45
var encodedHex = output.toString();

//
// 解码
var input = Input.fromHex(encodedHex);

// 69
var decoded = U8Codec.codec.decode(input);

无符号整数(u64 | u128 | u256)

//
// 编码
var output = HexOutput();

final value = BigInt.parse('115792089237316195423570985008687907853269984665640564039457584007913129639935');

U256Codec.codec.encodeTo(value, output);

// 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
var encodedHex = output.toString();

//
// 解码
var input = Input.fromHex(encodedHex);

// BigInt.parse('115792089237316195423570985008687907853269984665640564039457584007913129639935');
var decoded = U256Codec.codec.decode(input);

有符号整数(i8 | i16 | i32)

//
// 编码
var output = HexOutput();

final value = -128;

I8Codec.codec.encodeTo(value, output);

// 0x80
var encodedHex = output.toString();

//
// 解码
var input = Input.fromHex(encodedHex);

// -128
var decoded = I8Codec.codec.decode(input);

有符号整数(i64 | i128 | i256)

//
// 编码
var output = HexOutput();

final value = BigInt.parse('-9223372036854775808');

I64Codec.codec.encodeTo(value, output);

// 0x0000000000000080
var encodedHex = output.toString();

//
// 解码
var input = Input.fromHex(encodedHex);

// BigInt.parse('-9223372036854775808')
var decoded = I64Codec.codec.decode(input);

紧凑表示法

//
// 编码
var output = HexOutput();

final value = 69;

CompactCodec.codec.encodeTo(value, output);

// 0x1501
var encodedHex = output.toString();

//
// 解码
var input = Input.fromHex(encodedHex);

// 69
var decoded = CompactCodec.codec.decode(input);

可选项

final value = Option.some(true);

final output = HexOutput();
  
OptionCodec(BoolCodec.codec).encodeTo(value, output);

// 0x0101
var encodedHex = output.toString();

final input = Input.fromHex(encodedHex);

// Option.some(true)
var decoded = OptionCodec(BoolCodec.codec).decode(input);

// 或者
// None
final value = Option.none();

final output = HexOutput();
  
OptionCodec(BoolCodec.codec).encodeTo(value, output);

// 0x00
var encodedHex = output.toString();

final input = Input.fromHex(encodedHex);

// Option.none()
var decoded = OptionCodec(BoolCodec.codec).decode(input);

位向量

// 初始化编解码器对象
final codec = BitSequenceCodec(BitStore.U8, BitOrder.LSB);

final value = '11111';

final bitArray = BitArray.parseBinary(value);

final output = HexOutput();

codec.encodeTo(bitArray, output);

// 0x1f
final encodedHex = output.toString();

final input = Input.fromHex(encodedHex);

// BitArray.parseBinary('11111')
var decoded = codec.decode(input);

枚举

// 忽略:不必要的类型转换
final extraDataCodec = CompositeCodec({
  'index': U8Codec.codec,
  'name': StrCodec.codec,
  'customTuple': TupleCodec([
    SimpleEnumCodec.fromList(['Red', 'Orange']),
    BoolCodec.codec,
  ]),
}) as Codec;

final codec = ComplexEnumCodec.sparse(
  {
    0: MapEntry('Plain', StrCodec.codec),
    1: MapEntry('ExtraData', extraDataCodec),
  },
);

final value = MapEntry('ExtraData', MapEntry('index', 1, 'name', 'polkadart', 'customTuple', ['Red', true]));
final output = HexOutput();

codec.encodeTo(value, output);

// 0x010124706f6c6b61646172740001
final encodedHex = output.toString();

final input = Input.fromHex(encodedHex);

// MapEntry('ExtraData', {
//       'index': 1,
//       'name': 'polkadart',
//       'customTuple': ['Red', true],
//     })
var decoded = codec.decode(input);

复合结构

// 复合结构编解码器
final codec = CompositeCodec({
  'index': U8Codec.codec,
  'name': StrCodec.codec,
  'customTuple': TupleCodec([
    SimpleEnumCodec.fromList(['Red', 'Orange']),
    BoolCodec.codec,
  ]),
}) as Codec;

final value = {
      'index': 1,
      'name': 'polkadart',
      'customTuple': ['Red', true],
};

final output = HexOutput();

codec.encodeTo(value, output);

// 0x0124706f6c6b61646172740001
final encodedHex = output.toString();

final input = Input.fromHex(encodedHex);

// {
//  'index': 1,
//  'name': 'polkadart',
//  'customTuple': ['Red', true],
// }
var decoded = codec.decode(input);

结果类型(Ok, Err)

// 创建类型解析的注册表
final registry = Registry();

// 注册自定义编解码器
registry.registerCustomCodec({'A':'Result<u8, bool>'});

// 初始化scale编解码器
final codec = ScaleCodec(registry);

final output = HexOutput();

codec.encodeTo('A', MapEntry('Ok', 42), output);

// 0x002a
final encodedHex = output.toString();

final input = Input.fromHex(encodedHex);

// MapEntry('Ok', 42)
var decoded = codec.decode('A', input);

// 或者
//
// 对于Err字段
//
final value = MapEntry('Err', false);

codec.encodeTo('A', value, output);
// 0x0100
final encodedHex = output.toString();

// MapEntry('Err', false)
var decoded = codec.decode('A', input);

完整示例

以下是一个完整的示例,展示了如何使用 polkadart_scale_codec 进行编码和解码。

import 'package:polkadart_scale_codec/polkadart_scale_codec.dart';

void main() {
  ///
  ///
  /// 数组示例
  ///
  ///
  {
    final output = HexOutput();
    ArrayCodec(U8Codec.codec, 4).encodeTo([1, 2, 3, 4], output);
    print(output.toString()); // 0x01020304
  }

  {
    final input = Input.fromHex('0x0001010002010300');
    final result = ArrayCodec(
      TupleCodec([U8Codec.codec, BoolCodec.codec]),
      4,
    ).decode(input);
    print(result); // [ [0, true], [1, false], [2, true], [3, false] ]
  }

  ///
  ///
  /// B树映射示例
  ///
  ///

  {
    final output = HexOutput();
    BTreeMapCodec(
            keyCodec: BTreeMapCodec(
                keyCodec: U32Codec.codec, valueCodec: BoolCodec.codec),
            valueCodec: BoolCodec.codec)
        .encodeTo({
      {632: false}: true
    }, output);
    print(output.toString()); // '0x0404780200000001'
  }

  {
    final input = Input.fromHex('0x0404780200000001');
    final result = BTreeMapCodec(
      keyCodec: BTreeMapCodec(
        keyCodec: U32Codec.codec,
        valueCodec: BoolCodec.codec,
      ),
      valueCodec: BoolCodec.codec,
    ).decode(input);
    print(result.toString()); // { {632: false}: true }
  }

  ///
  ///
  /// 紧凑大整数示例
  ///
  ///
  {
    final byteInput = Input.fromHex('0x130000000000000001');
    final decoded = CompactCodec.codec.decode(byteInput);
    print(decoded); // 72057594037927936

    final output = HexOutput();
    CompactCodec.codec.encodeTo(decoded, output);
    print(output.toString()); // 0x130000000000000001
  }

  ///
  ///
  /// 紧凑大整数示例
  ///
  ///
  {
    final byteInput = Input.fromHex('13ffffffffffffffff');
    final decoded = CompactBigIntCodec.codec.decode(byteInput);
    print(decoded); // 18446744073709551615

    final output = HexOutput();
    CompactBigIntCodec.codec.encodeTo(decoded, output);
    print(output.toString()); // 13ffffffffffffffff
  }

  ///
  ///
  /// 复合结构示例
  ///
  ///
  {
    final codec = CompositeCodec(
      {
        'a': U8Codec.codec,
        'b': BoolCodec.codec,
      },
    );

    final input = Input.fromHex('0x2a01');
    final decoded = codec.decode(input);
    print(decoded); // {a: 42, b: true}

    final output = HexOutput();
    codec.encodeTo(
      {'a': 42, 'b': true},
      output,
    );
    print(output.toString()); // '0x2a01'
  }

  ///
  ///
  /// 可选项示例
  ///
  ///
  {
    final codec =
        OptionCodec(TupleCodec([CompactCodec.codec, BoolCodec.codec]));

    final output = HexOutput();
    codec.encodeTo([3, true], output);
    print(output.toString()); // '0x010c01'

    final input = Input.fromHex('0x010c01');
    final decoded = codec.decode(input);
    print(decoded); // [3, true]
  }

  ///
  ///
  /// 有符号整数示例
  ///
  ///
  {
    final input = Input.fromHex(
        '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f');
    final decoded = I256Codec.codec.decode(input);
    print(
        decoded); // BigInt.parse('57896044618658097711785492504343953926634992332820282019728792003956564819967')

    final output = HexOutput();
    I256Codec.codec.encodeTo(decoded, output);
    print(output
        .toString()); // 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f
  }

  ///
  ///
  /// 无符号整数示例
  ///
  ///
  {
    final input = Input.fromHex(
        '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
    final decoded = U256Codec.codec.decode(input);
    print(
        decoded); //  BigInt.parse('115792089237316195423570985008687907853269984665640564039457584007913129639935')

    final output = HexOutput();
    U256Codec.codec.encodeTo(decoded, output);
    print(output
        .toString()); // 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  }

  ///
  ///
  /// 元组示例
  ///
  ///
  {
    final codec = TupleCodec([CompactCodec.codec, BoolCodec.codec]);

    final output = HexOutput();
    codec.encodeTo([3, true], output);
    print(output.toString()); // 0x0c01

    final input = Input.fromHex('0x0c01');
    final decoded = codec.decode(input);
    print(decoded); // [3, true]
  }
}

更多关于Flutter Polkadot数据编码插件polkadart_scale_codec的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Polkadot数据编码插件polkadart_scale_codec的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用polkadart_scale_codec插件来编码和解码Polkadot数据的示例代码。polkadart_scale_codec是一个Flutter插件,用于处理Polkadot的SCALE编码,SCALE是Polkadot及其生态系统中的核心数据序列化格式。

首先,确保你已经在你的pubspec.yaml文件中添加了polkadart_scale_codec依赖:

dependencies:
  flutter:
    sdk: flutter
  polkadart_scale_codec: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

接下来是一个简单的示例代码,展示如何使用polkadart_scale_codec进行编码和解码操作:

import 'package:flutter/material.dart';
import 'package:polkadart_scale_codec/polkadart_scale_codec.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Polkadot SCALE Codec Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String encodedData = '';
  String decodedData = '';

  void encodeData() {
    // 创建一个示例数据,例如一个整数列表
    List<int> data = [1, 2, 3, 4, 5];
    
    // 使用ScaleCodec进行编码
    ScaleCodec codec = ScaleCodec();
    Uint8List encoded = codec.encode(data);
    
    // 将编码后的数据转换为十六进制字符串
    encodedData = encoded.map((byte) => byte.toRadixString(16).padStart(2, '0')).join('');
    
    // 更新UI
    setState(() {});
  }

  void decodeData() {
    // 假设我们有一个之前编码过的十六进制字符串
    String hexString = '0100000002000000030000000400000005000000';
    
    // 将十六进制字符串转换为Uint8List
    Uint8List encoded = Uint8List.fromList(hexStringToBytes(hexString));
    
    // 使用ScaleCodec进行解码
    ScaleCodec codec = ScaleCodec();
    List<int> decoded = codec.decode<List<int>>(encoded);
    
    // 更新解码后的数据
    decodedData = decoded.toString();
    
    // 更新UI
    setState(() {});
  }

  // 辅助函数:将十六进制字符串转换为Uint8List
  Uint8List hexStringToBytes(String hexString) {
    int len = hexString.length;
    Uint8List bytes = Uint8List(len / 2);
    for (int i = 0; i < len; i += 2) {
      bytes[i / 2] = int.parse(hexString.substring(i, i + 2), 16);
    }
    return bytes;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Polkadot SCALE Codec Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('Encoded Data (Hex):'),
            Text(encodedData),
            SizedBox(height: 16),
            Text('Decoded Data:'),
            Text(decodedData),
            SizedBox(height: 32),
            Row(
              children: [
                ElevatedButton(
                  onPressed: encodeData,
                  child: Text('Encode Data'),
                ),
                SizedBox(width: 16),
                ElevatedButton(
                  onPressed: decodeData,
                  child: Text('Decode Data'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,它有两个按钮,一个用于编码数据,另一个用于解码数据。编码按钮将一个整数列表编码为SCALE格式,并将其转换为十六进制字符串显示。解码按钮将一个预定义的十六进制字符串解码回原始的整数列表并显示。

注意:ScaleCodec的使用可能需要根据你实际的数据结构进行调整。这个示例仅展示了基本的编码和解码操作。在实际应用中,你可能需要处理更复杂的数据结构,并可能需要深入了解SCALE编码的规范。

回到顶部