跳至主要内容

4.1 链下智能合约

智能合约采用sCrypt提供的比特币智能合约高级语言编写,以确保索引验证器在有限时间内完成执行。此外,支持包括Swap、Oracle和零知识证明在内的高级用例。

以下是一个简单的链下合约示例:

export class N20_Sample extends SmartContract {
@prop()
readonly tick: ByteString

@prop()
readonly max: bigint

@prop()
readonly lim: bigint

@prop()
readonly dec: bigint

constructor(tick: ByteString, max: bigint, lim: bigint, dec: bigint) {
super(...arguments)
this.tick = tick
this.max = max
this.lim = lim
this.dec = dec
}

@method()
public mint(tick: ByteString, amt: bigint) {
assert(tick == this.tick, 'Tick does not match')
assert(amt <= this.lim, 'Amount check failed')
}

@method()
public transfer(tick: ByteString, amt: bigint) {
assert(tick == this.tick, 'Tick does not match')
assert(amt <= this.lim, 'Amount check failed')
}
}

minttransfer函数用于验证N20的两项操作是否可以执行。只有当操作通过合约验证后,索引器才会记录账户余额的变化。

合约运行时变量

在智能合约运行期间,索引器提供以下常量和环境变量:

  • account: ByteString, 当前交易发起人的账号
  • inputSatoshis: bigint, 当前输入的聪数(解锁UTXO的Satoshi数量)
  • height: bigint, 当前高度;当交易未确认时,为最新高度加6
  • total: bigint, 已铸造的代币数量
  • creator: ByteString, 代币被创建时的创建者账号
  • blockHash: ByteString, 当前区块的哈希,未确认时为空字符串
  • blockTime: bigint, 当前区块的时间戳,未确认时为0
  • indexInBlock: bigint, 当前交易在区块中的索引,未确认时为0
  • indexInChain: bigint, 当前交易在链中的索引,未确认时为0
  • tx: ByteString, 当前交易的十六进制表示
  • txId: ByteString, 当前交易的ID
  • version: bigint, 当前交易的版本号,通常为2
  • nLockTime: bigint, 当前交易的nLockTime
  • inputs: 当前交易输入的数组,每个输入包括:
    • prevTxId: ByteString, 前一个交易的ID
    • outputIndex: bigint, 前一个交易的输出索引
    • sequenceNumber: bigint, 解锁的序列号
  • outputs: 当前交易输出的数组,每个输出包括:
    • script: ByteString, 输出的脚本
    • satoshis: bigint, 输出的聪数
  • balance: 当前account持有tick的余额
    • confirmed: bigint, 已确认的交易余额
    • unconfirmed: bigint, 未确认的交易余额
  • noteBalance: 当前account持有NOTE的余额
    • confirmed: bigint, 已确认的交易余额
    • unconfirmed: bigint, 未确认的交易余额
  • pre_*: 前一个交易的变量
小心

不要在方法的参数中使用运行时变量。

信息

pre_*变量仅用于transfer方法。

运行时变量示例

note: { amt: 10000000000n, op: 'transfer', p: 'n20', tick: 'WUKONG#8' },
dataMap: {
constructor: {
bitwork: '3230',
dec: 8,
desc: 'A sample token showcasing a mining contract with progressively increasing difficulty.',
lim: 900000000000n,
max: 81000000000000n,
op: '6465706c6f79',
p: '6e3230',
sch: 'd594416d99151d3bf962f53a792b1eb244646b984985c863fa8ee27bdfce2992',
start: 41305,
tick: '57554b4f4e472338'
},
transfer: {
bitwork: '3230',
dec: 8,
desc: 'A sample token showcasing a mining contract with progressively increasing difficulty.',
lim: 900000000000n,
max: 81000000000000n,
op: '7472616e73666572',
p: '6e3230',
sch: 'd594416d99151d3bf962f53a792b1eb244646b984985c863fa8ee27bdfce2992',
start: 41305,
tick: '57554b4f4e472338',
amt: [ 10000000000n, 5390000000000n ],
height: 44176,
blockHash: '',
blockTime: 0n,
indexInBlock: 0n,
indexInChain: 0n,
tx: '020000000001029ca52125503b229f19287eb5c1af3a713b0f07e00251a6c3cc4e4983dd8ad7e90000000000ffffffff8b154ed3ef950c5b1c24e8bd04cf17df35c8be2e52dbfe90c83221010783c3280200000000ffffffff032202000000000000225120fb1397257ecba1b51739192853c08209235bb662482eaebf6556170442d7f0502202000000000000225120fb1397257ecba1b51739192853c08209235bb662482eaebf6556170442d7f050542a270000000000160014bc5fa59b7108e0ec633e66233684bef4d4dbad4808401c715b2d877412f895eb20c88c65b90288843a56426cf49031343994c4f56c050e0657d059de04c6fa9149553fbe55d65d8a9c50f750f2adee6d4ad2cc4f7fdc2e84a3616d74cf00000002540be400a26f70a87472616e73666572a170a36e3230a47469636ba857554b4f4e472338000000002a044e4f54456d6d6d20da6c71b73fb5462258b16c60f30465fc5985fe9e63610e671f7c8bfddab3b115ac41c0da6c71b73fb5462258b16c60f30465fc5985fe9e63610e671f7c8bfddab3b1152a56124065fd50baecd89ca4204fbfaa0b66021d78891c9b7b9255a11b1341140248304502210093786529225604a185a4bf893c13e576b1f7cee338d5968ae41c1bdc7e523782022068259b0f910fa7c53eae6cfde0e798593110527289dda17b36eab75631ce7abe012102da6c71b73fb5462258b16c60f30465fc5985fe9e63610e671f7c8bfddab3b11500000000',
inputs: [
{
prevTxId: 'e9d78add83494eccc3a65102e0070f3b713aafc1b57e28199f223b502521a59c',
outputIndex: 0n,
sequenceNumber: 4294967295n
},
{
prevTxId: '28c38307012132c890fedb522ebec835df17cf04bde8241c5b0c95efd34e158b',
outputIndex: 2n,
sequenceNumber: 4294967295n
}
],
outputs: [
{
script: '5120fb1397257ecba1b51739192853c08209235bb662482eaebf6556170442d7f050',
satoshis: 546n
},
{
script: '5120fb1397257ecba1b51739192853c08209235bb662482eaebf6556170442d7f050',
satoshis: 546n
},
{
script: '0014bc5fa59b7108e0ec633e66233684bef4d4dbad48',
satoshis: 2566740n
}
],
nLockTime: 0,
txId: '88e0ba59cd2b8b7f795b81c06f94e961a2eaa14359c231318d9cb23ff17a0b94',
version: 2,
account: '209e7f0e21d5314ff6d0370200565f1831a84b8c6666331dca00d8d16dbdcc24',
inputIndex: 0,
inputSatoshis: 546n,
prevTxId: 'e9d78add83494eccc3a65102e0070f3b713aafc1b57e28199f223b502521a59c',
outputIndex: 0,
prev_amt: [ 5400000000000n ],
prev_op: '7472616e73666572',
prev_p: '6e3230',
prev_tick: '57554b4f4e472338',
prev_script: '5120fb1397257ecba1b51739192853c08209235bb662482eaebf6556170442d7f050',
prev_satoshis: 546n,
prev_height: 44132,
prev_blockHash: '0000000000000018483c2904d32ba0d8bd292063ef713d14f5ea5ccc02e10ce7',
prev_blockTime: 1725938902,
prev_indexInBlock: 52,
prev_indexInChain: 44132000052,
prev_sender: '209e7f0e21d5314ff6d0370200565f1831a84b8c6666331dca00d8d16dbdcc24',
total: 72900000000000n,
creator: '6d96a0c6127ef53b161678a8426056c19526a36d1790c72b7f9b118b64e9d4f5',
balance: { confirmed: 5387700000000n, unconfirmed: 0n },
noteBalance: { confirmed: 188751436666n, unconfirmed: 0n }
}
}

说明:

  • constructor字段里包含了合约的初始化参数
  • transfer字段里包含了转账时可以用到的常量或者变量,合约的初始化时的参数也可以使用,比如desc字段来自用户自定义的描述