DOT20 - 波卡同质铭文协议(草案)

基本介绍

DOT-20是波卡同质铭文的标准协议,用于规范铭文的基本操作。DOT20在设计上参照了以太坊ERC20协议,并根据波卡特点做出优化,以便兼容主链以及基于Substrate的平行链铭文操作。

全局规范

  • 波卡铭文是通过创建utility batchAll(calls)类型的交易,并基于system remarkWithEvent(remark)中的memo解析进行运作的

  • memo内各个key的value若是数值无需加引号,包括<amt,start,end,reserve,max,lim>等字段,只要memo符合JSON标准格式即可

  • 同类型的交易,授权以及授权转账操作可以批量发出,通过在一个batchAll(calls)下面挂载多个具有相同op操作的calls来完成

  • 每笔batchAll交易的末尾可以加入一个操作符为memo的call,用于记录非交易信息(比如交易所的买单/卖单/成交信息,以便对账使用)

  • 铭文数据精度:整数位最大32位,小数位18位,铭文操作的数值范围 0 ~ 10^32,最小非零数值为1wei (10^-18)

  • memo内除了操作符规定字段以外的其他字段不会被索引识别,但这笔交易仍然可能是一个合法的铭文操作,在某些场景下可以用来扩展协议的使用方式。

操作符

操作者需要进入 Polkadot JS 进行以下操作

部署(Deploy)

使用 utility batchAll(calls)构造一个call
call0:system - remarkWithEvent(remark)
在remark: Bytes里填入以下json字符串

{
    "p": "dot-20", //协议名(必选)
    "op": "deploy", //部署操作(必选)
    "tick": "dota", //名称(必选),取值为3~6位英文字母,取值全链唯一,不分大小写,各字母需ascii验证
    "decimal": 18, //铭文精度(可选),取值为数字0~18,默认为18
    "mode": "fair", //发行模式(必选),取值为"fair","normal","owner"
    "amt": 5000000, //单个区块内奖励(fair模式必选)
    "start": 18681993, //铸造起始高度(fair,normal模式必选)
    "end": 18723992, //铸造结束高度(fair模式必选)
    "max": 210000000000, //最大发行量(normal模式必选)
    "lim": 1000000, //单次mint数量(normal模式必选)
    "admin": "1FKmjePh2YT58zzKbuNJEM1vXe7uY3HuCugpNVmt1EWJEv7S" //仅admin地址可以mint(owner模式必选)
}

共有三种发行模式:
  1.常规模式(normal,单次mint获得固定数量铭文)
  2.公平模式(fair,区块内平分铭文)
  3.控制者模式(owner,仅admin可以铸造铭文)

1:索引器会根据mode字段取值决定后续哪些字段可用,fair模式读取<amt, start, end>字段,normal模式读取<start, max, lim>字段,owner模式仅读取<admin>字段
2:索引对dota铭文部署进行特殊处理 [^1]
3:部署时去掉上述json每行在逗号之后的注释,memo需要符合json的数据结构
4:normal模式的max最大值为10^32,单次lim铸造数量不能高于max;fair模式中,amt*(end-start+1)不得高于10^32
5:start必须等于或晚于部署区块高度,否则部署失败
6:部署操作不支持批量操作

铸造(Mint)

使用 utility batchAll(calls)构造一个call(normal或者fair模式)或者多个call(owner模式)
call0:system - remarkWithEvent(remark)
在remark: Bytes里填入json字符串

{
    "p": "dot-20", //协议名(必选)
    "op": "mint", //铸造操作(必选)
    "tick": "dota", //名称(必选)
    "to": "1FKmjePh2YT58zzKbuNJEM1vXe7uY3HuCugpNVmt1EWJEv7S" //铭文接收地址(可选),默认为交易发起者地址
    "lim": 800000 //铭文铸造数量(fair模式此字段内容无意义,normal模式可选,默认为单次mint的最大值,owner模式必选)
}

1:接收地址需符合SS58地址标准,波卡主网为1开头的4748位长度字符串
2:对于normal模式,单次铸造默认为部署字段中的lim数量
3:对于normal或者fair铸造模式,索引器在同一区块内仅计入同一个发送者的首笔交易的首个call,其他交易会被忽略。故这两种发行模式下的铸造不支持批量操作
4:在normal模式下,如果已铸造总量等于max,则后续铸造失败
5:在fair模式下,如果某个区块内无人Mint,则该区块内的铭文会被销毁,而铭文总量也会减少相应数量
6:在owner模式下,支持批量铸造铭文并发送至多个地址,交易结构参照批量转账

转账(Transfer)

使用 utility batchAll(calls)构造一个或多个call
call0:system - remarkWithEvent(remark)
在remark: Bytes里填入json字符串,所有字段均为必选

{
    "p": "dot-20", //协议名
    "op": "transfer", //转账操作
    "tick": "dota", //名称
    "amt": 1000000, //转账数量
    "to": "1FKmjePh2YT58zzKbuNJEM1vXe7uY3HuCugpNVmt1EWJEv7S" //铭文转账目标地址
}

[可选]call1:system - remarkWithEvent(remark)
[可选]call2:system - remarkWithEvent(remark)
...
[可选]calln:system - remarkWithEvent(remark)
[可选]calln+1:system - remarkWithEvent(remark)
{
    "p": "dot-20", //协议名
    "op": "memo", //记事本操作
    "text": "your extra messages here" //写入本次操作备注
}


1:接收地址需符合SS58地址标准,波卡主网为1开头的4748位长度字符串
2:转账支持批量操作,call1~calln的memo格式参照call0,符合转账json标准,支持批量发送不同tick铭文至不同目标地址
3:以上转账操作中如果出现任何一笔错误,则这批转账全部失败
4:除了最后一个call的操作符是memo以外,其他所有call的操作符必须为transfer,否则交易失败
5:转账目标地址不限,包括个人地址与黑洞地址0x0

授权(Approve)

使用 utility batchAll(calls)构造一个或多个call
call0:system - remarkWithEvent(remark)
在remark: Bytes里填入json字符串,所有字段均为必选

{
    "p": "dot-20", //协议名
    "op": "approve", //授权操作
    "tick": "dota", //名称
    "amt": 100000000, //授权数量,最大值为10^32
    "to": "1FKmjePh2YT58zzKbuNJEM1vXe7uY3HuCugpNVmt1EWJEv7S" //铭文被授权人地址
}

[可选]call1:system - remarkWithEvent(remark)
[可选]call2:system - remarkWithEvent(remark)
...
[可选]calln:system - remarkWithEvent(remark)
[可选]calln+1:system - remarkWithEvent(remark)
{
    "p": "dot-20", //协议名
    "op": "memo", //备注操作
    "text": "your extra messages here" //写入本次操作备注
}

1:授权数量可由授权人更新,授权的最大值为10^32,更新数值为0等价于取消授权
2:授权支持批量操作,call1~calln的memo格式参照call0,符合授权json标准,支持批量授权不同tick铭文至不同地址
3:以上授权操作中如果出现任何一笔错误(比如没有这个tick),则这批授权全部失败
4:授权数量可以多于用户目前持有的铭文余额
5:除了最后一个call的操作符是memo以外,其他所有call的操作符必须为approve,否则交易失败

授权转账(TransferFrom)

使用 utility batchAll(calls)构造一个或多个call
call0:system - remarkWithEvent(remark)
在remark: Bytes里填入json字符串,所有字段均为必选

{
    "p": "dot-20", //协议名
    "op": "transferFrom", //授权转账操作
    "tick": "dota", //名称
    "amt": 9900, //转账数量
    "from": "1FKmjePh2YT58zzKbuNJEM1vXe7uY3HuCugpNVmt1EWJEv7S", //铭文授权人地址
    "to": "1GF1ir7LCjK35qSzEGi6tVPQ4Gh7enWFVgGQ5QuUfVZn8zLX" //铭文转账目标地址
}

[可选]call1:system - remarkWithEvent(remark)
{
    "p": "dot-20", //协议名
    "op": "transferFrom", //授权转账操作
    "tick": "idot", //名称
    "amt": 99, //转账数量
    "from": "1GF1ir7LCjK35qSzEGi6tVPQ4Gh7enWFVgGQ5QuUfVZn8zLX", //铭文授权人地址
    "to": "1FKmjePh2YT58zzKbuNJEM1vXe7uY3HuCugpNVmt1EWJEv7S" //铭文转账目标地址
}
[可选]call2:system - remarkWithEvent(remark)
{
    "p": "dot-20", //协议名
    "op": "transferFrom", //授权转账操作
    "tick": "dota", //名称
    "amt": 100, //转账数量
    "from": "1FKmjePh2YT58zzKbuNJEM1vXe7uY3HuCugpNVmt1EWJEv7S", //铭文授权人地址
    "to": "13EADjZkn3b7PjCUxYZBsgvm8ANVnEaAVp21tiekxTWEQWha" //铭文转账目标地址
}
[可选]call3:system - remarkWithEvent(remark)
{
    "p": "dot-20", //协议名
    "op": "transferFrom", //授权转账操作
    "tick": "idot", //名称
    "amt": 1, //转账数量
    "from": "1GF1ir7LCjK35qSzEGi6tVPQ4Gh7enWFVgGQ5QuUfVZn8zLX", //铭文授权人地址
    "to": "13EADjZkn3b7PjCUxYZBsgvm8ANVnEaAVp21tiekxTWEQWha" //铭文转账目标地址
}

[可选]calln:system - remarkWithEvent(remark)
[可选]calln+1:system - remarkWithEvent(remark)
{
    "p": "dot-20", //协议名
    "op": "memo", //记事本操作
    "text": "your extra messages here" //写入本次操作备注
}

1:仅能由铭文被授权人地址发起交易
2:发送成功后,扣除发送者从授权人处获得的approve相应数额,并从授权人地址转账铭文至目标地址。对于每个tick以及每个授权人,需要保证铭文转出数量总和小于授权人对发送者的授权数量,同时小于授权人当前拥有的铭文数量
3:授权转账支持批量操作,call1~calln的memo格式参照call0,符合授权转账json标准,支持批量授权转账不同tick从不同的授权人地址发送至不同的转账目标地址
4:以上授权转账操作中如果出现任何一笔错误,则这批授权转账全部失败
5:除了最后一个call的操作符是memo以外,其他所有call的操作符必须为transferFrom,否则交易失败

批量捆绑操作

使用 utility batch(calls)构造一个或多个batchAll(calls)
call0:utility - batchAll(calls)
    call:call:0
    call:call:1
    ...
    call:call:n

call1:utility - batchAll(calls)
    call:call:0
    call:call:1
    ...
    call:call:n    

call2:utility - batchAll(calls)

...

callm:utility - batchAll(calls)
    call:call:0
    call:call:1
    ...
    call:call:n

1: 一个batch内可以加载多个batchAll,通过一个批量捆绑交易同时完成转账、授权、代理转账操作
2:batch操作内的任何一笔batchAll被判定为失效,不影响后续其他batchAll操作的有效性判定
3:根据协议约定,部署(deploy)与铸造(mint)不支持批量操作

参考

[^1]: DOTA部署交易

修订记录

v0.11

  • 协议草案

Last updated