NOTE协议在持续升级
· 1分钟阅读
NOTE协议自2024年2月推出概念验证版索引器以来,已经吸引了广泛关注。根据用户反馈和需求,我们不断对协议进行升级改进。
截至4月4日,我们已经实施了以下升级:
- 完全展开了Payload数据区,使得Payload数据既可以存储在解锁脚本中,也可以存放在赎回脚本中。
- 引入了N20的Burn方法,现在可以销毁Token了。
- 对链下合约执行环境进行了扩展,增加了大量环境变量,包括区块信息(如区块时间、区块哈希、区块高度)以及交易信息(如交易哈希、所有输入和输出)。此外,还包括了Tick信息,例如mint的总额等。
- 对索引器代码进行了大规模重构。
本次升级的目标之一是让任何人都能参与到NOTE智能合约的开发中来。这意味着任何人都可以创建属于自己的智能合约,并将其发布到NOTE索引器上,从而完成数字资产的发行。我们正在制作一个详尽的合约创建教程。
通过2月份发布的POW挖矿合约,我们可以窥见NOTE协议的强大功能。
我们添加了一些注释来帮助大家更好地理解:
//每个合约都是一个继承自SmartContract的子类,它里面的成员变量都是 只读的,需要使用@prop()装饰器来修饰。
export class N20_Pow extends SmartContract {
@prop()
readonly tick: ByteString
@prop()
readonly max: bigint
@prop()
readonly lim: bigint
@prop()
readonly dec: bigint
@prop()
readonly bitwork: ByteString
@prop()
readonly start: bigint
//合约如果包含成员变量,需要使用构造函数进行初始化
constructor(tick: ByteString, max: bigint, lim: bigint, dec: bigint, bitwork: ByteString, start: bigint) {
super(...arguments)
// 数字资产的标识符,名字
this.tick = tick
// 数字资产的最大发行量,如果不设置上限,可以指定为0
this.max = max
// 每个交易的挖矿上限,不能超过最大值
this.lim = lim
// 数字资产的小数单位,比如dec=8,那么1个代币后面就要跟8个零,所有的数量值amt,包括max和lim都是此影响。100000000表示1.00000000
this.dec = dec
//挖矿难度,每笔交易的hash256需要的前置字符
this.bitwork = bitwork
// 挖矿合约的起始高度,用于防止提前预挖
this.start = start
}
//挖矿的区块限制算法,需要使用@method()装饰器 来修饰
@method()
getBlockLimit(height: bigint): bigint {
assert(height >= this.start, 'Block height is too low')
//每1000个区块减半一次,减半的次数由区块高度减去起始高度决定
let halvings = (height - this.start) / 1000n
// 最多减半7次
halvings = halvings > 7n ? 7n : halvings
// 每次减半挖矿数量限额都减半。此处使用2进制rshift操作符实现除以2的操作
const subsidy = rshift(this.lim, halvings)
return subsidy
}
// 挖矿的数量限制算法,需要使用@method()装饰器来修饰
@method()
getAmountLimit(currentMined: bigint): bigint {
// 从当前已经挖矿的数量占总量的多少开始数量限制
let miningAmount = this.lim
let threshold = this.max / 2n
//循环7次,每次循环,如果当前挖矿数量达到阈值,则将挖矿数量减半,并更新阈值
for (let halving = 0n; halving < 7n; halving++) {
if (currentMined >= threshold) {
miningAmount /= 2n // Halve the mining amount
threshold += rshift(this.max, halving + 2n) // Update the next threshold
}
}
return miningAmount
}
@method()
public mint(tick: ByteString, amt: bigint, total: bigint, height: bigint, tx: ByteString) {
//检查交易的hash256的前置字符是否符合挖矿合约的难度要求
const txid = hash256(tx)
assert(slice(txid, 0n, len(this.bitwork)) == this.bitwork, 'not match target')
// 检查挖矿总量是否超过最大发行量
assert(this.max == 0n || total <= this.max, 'Over max')
assert(tick == this.tick, 'Tick does not match')
// 检查挖矿数量是否超过区块限制以及总量减半限制
const limit1 = this.getBlockLimit(height)
const limit2 = this.getAmountLimit(total)
const limit = limit1 > limit2 ? limit2 : limit1
assert(amt <= limit && amt <= this.max - total, 'Amount check failed')
}
// 转移Token的方法,需要使用@method()装饰器来修饰
@method()
public transfer(tick: ByteString) {
assert(tick == this.tick, 'Tick does not match')
}
}
注意
在上面的代码中有一个BUG. 如果你希望使用它发行资产,注意不要让max=0. 任何资产发行都需要谨慎测试合约。
本次升级新增了Burn方法,允许销毁Token。以下是一个新示例:
//此例子没有使用构造函数,而是使用静态设置参数的方式,因为数值完全在合约中,无法复用给其他的数字资产
export class N20_Joss extends SmartContract {
//joss paper 纸钱:一种金银纸,被剪成类似钱币的形状,在神像前焚烧的纸钱。
@prop()
static tick: ByteString = toByteString('JOSS', true)
//没有发行上限
@prop()
static max: bigint = 0n
//每次可以发行1万个
@prop()
static lim: bigint = 10000n
//没有小数位
@prop()
static dec: bigint = 0n
@method()
public mint(tick: ByteString, amt: bigint) {
assert(tick == N20_Joss.tick, 'Tick does not match')
//发行数量不能超过限额1万
assert(amt == N20_Joss.lim, 'Limit does not match')
}
@method()
public transfer() {
//不能转账
assert(false)
}
@method()
public burn(tick: ByteString) {
//可以烧掉
assert(tick == N20_Joss.tick, 'Tick does not match')
}
}
N20_Joss合约部署在BTC主网的交易是: https://mempool.space/tx/c2cda4c9da3a91bd245d9f6250b5ca8f2ec81d50c14821e87a033fde1f3b5561
NOTE协议支持智能合约,这是其与其他协议最大的不同。NOTE钱包和索引器为智能合约提供了执行环境,使用户能够编写自己的智能合约。关于智能合约的基础知识,可以参考:
为何比特币智能合约是图灵完备的语言:
NOTE协议的智能合约开发教程即将推出,敬请期待。