0.1.2 • Published 4 years ago

@solong/iparser v0.1.2

Weekly downloads
-
License
ISC
Repository
-
Last release
4 years ago

Solana合约Instruction的JSON解析约定

背景

由于Solana的Instruction中的data部分没有严肃的ABI约定,因此在钱包签名Transaction 中的Instruction,没法很好的展示Instruction的内容。因此大家急需一套规则来解析 Instruction中的data部分给用户确认。

约定

这里参照ETH的ABI的JSON定义The JSON format for a contract’s interface

我们取其中的function部分,然后给inputs的单元增加一个value的部分,由业务方自己按照自己项目 的序列化方式,将其解析成一个这样的结构,然后返回给钱包。这样钱包就可以展示Instruction的内容了。

npm.io

JSON格式为:

  • type: 固定为:"instruction"
  • name: instuction的名字
  • program: 合约地址
  • inputs: 一个对象数组,表示参数,包含了:
    • name: 参数名
    • value: 具体值,以string来表示
    • components: 嵌套对象,如果值不是简单类型,而是类似Array/Map等其他嵌套JSON 则以Object类型返回,在展示的时候,通过JSON序列化成字符串进行展示

这里的初衷只是为了在展示给用户看的时候,尽量人为可读一些,不同于传统的ABI策略,类似anchor 虽然提供了类似abi的机制,但是在解析成人为可读方面,一个实现较为繁琐,二个 从IDL定义的变量名未必普通非程序猿用户易懂。

这里的定义通过name表示哪个指令,然后拼接K-V对来表示调用了哪些参数,也就是这里的name和value,name可以尽量定义 的人为可读一些,这样用户更容易理解,而不是ABI中定义的,程序猿更容易理解。

示例

1. System.createAccount

先来看其定义:

/**
* Create account system transaction params
* @typedef {Object} CreateAccountParams
* @property {PublicKey} fromPubkey
* @property {PublicKey} newAccountPubkey
* @property {number} lamports
* @property {number} space
* @property {PublicKey} programId
*/
export type CreateAccountParams = {|
    fromPubkey: PublicKey,
    newAccountPubkey: PublicKey,
    lamports: number,
    space: number,
    programId: PublicKey,
|};

这里可以定义成这样:

{
    "type": "instruction", 
    "name": "CreateAccount", 
    "program": "11111111111111111111111111111111", 
    "inputs": [
        {
            "name": "fromPubkey", 
            "value": "EBA5RN8pZuGnTGfUiKcLoU7Vzf8kyXurmpRTu5k7jb7x"
        }, 
        {
            "name": "newAccountPubkey", 
            "value": "EBA5RN8pZuGnTGfUiKcLoU7Vzf8kyXurmpRTu5k7jb7x"
        }, 
        {
            "name": "lamports", 
            "value": "128"
        }, 
        {
            "name": "space", 
            "value": "128"
        }
    ]
}