【在 Nervos CKB 上做开发】Nervos CKB脚本编程简介[2]:脚本基础

本文介绍了如何在Nervos CKB上进行脚本编程,从基本语法到编写和部署实际脚本。通过示例展示了如何防止数据中出现特定字符串的脚本代码,并详细解释了其工作原理。最后,讨论了使用Duktape在CKB上运行JavaScript的可能性,提供了一道思考题,并预告了下篇将探讨自定义用户定义token(UDT)的内容。
摘要由CSDN通过智能技术生成

CKB脚本编程简介[2]:脚本基础

原文作者:Xuejie原文链接:Introduction to CKB Script Programming 2: Script本文译者:Shooter,Jason,Orange (排名不分先后)

上一篇我们介绍了当前 CKB 的验证模型。这一篇会更加有趣一点,我们要向大家展示如何将脚本代码真正部署到 CKB 网络上去。我希望在你看完本文后,你可以有能力自行去探索 CKB 的世界并按照你自己的意愿去编写新的脚本代码。

需要注意的是,尽管我相信目前的 CKB 的编程模型已经相对稳定了,但是开发仍在进行中,因此未来还可能会有一些变化。我将尽力确保本文始终处于最新的状态,但是如果在过程到任何疑惑,本文以 此版本下的 CKB 作为依据。

警告:这是一篇很长的文章,因为我想为下周更有趣的话题提供充足的内容。所以如果你没有充足的时间,你不必马上完成它。我在试着把它分成几个独立的不凡,这样你就可以一次尝试一个。

语法

在继续之前,我们先来区分两个术语:脚本(script)和脚本代码(script code)

在本文以及整个系列文章内,我们将区分脚本和脚本代码。脚本代码实际上是指你编写和编译并在 CKB 上运行的程序。而脚本,实际上是指 CKB 中使用的脚本数据结构,它会比脚本代码稍微多一点点:

pub struct Script {
    pub args: Vec<Bytes>,
    pub code_hash: H256,
    pub hash_type: ScriptHashType,
    }

我们目前可以先忽略hash_type,之后的文章再来解释什么是hash_type以及它有什么有趣的用法。在这篇文章的后面,我们会说明code_hash实际上是用来标识脚本代码的,所以目前我们可以只把它当成脚本代码。那脚本还包括什么呢?脚本还包括args这个部分,它是用来区分脚本和脚本代码的。args在这里可以用来给一个 CKB 脚本提供额外的参数,比如:虽然大家可能都会使用相同的默认的 lock script code,但是每个人可能都有自己的 pubkey hash,args 就是用来保存 pubkey hash 的位置。这样,每一个CKB 的用户都可以拥有不同的 lock script ,但是却可以共用同样的 lock script code。

请注意,在大多数情况下,脚本和脚本代码是可以互换使用的,但是如果你在某些地方感到了困惑,那么你可能有必要考虑一下两者间的区别。

一个最小的 CKB 脚本代码

你可能之前就已经听所过了,CKB (编者注:此处指的应该是 CKB VM)是基于开源的 RISC-V 指令集编写的。但这到底意味着什么呢?用我自己的话来说,这意味着我们(在某种程度上)在 CKB 中嵌入了一台真正的微型计算机,而不是一台虚拟机。一台真正的计算机的好处是,你可以用任何语言编写任何你想写的逻辑。在这里,我们展示的前面几个例子将会用 C语言编写,以保持简单性(我是说工具链中的简单性,而不是语言),之后我们还会切换到基于 JavaScript 的脚本代码,并希望在本系列中展示更多的语言。记住,在 CKB 上有无限的可能!

正如我们提到的,CKB VM 更像是一台真正的微型计算机。CKB 的代码脚本看起来也更像是我们在电脑上跑的一个常见的 Unix 风格的可执行程序。

int main(int argc, char* argv[])
{
  return 0;
}

当你的代码通过 C 编译器编译时,它将成为可以在 CKB 上运行的脚本代码。换句话说,CKB 只是采用了普通的旧式 Unix 风格的可执行程序(但使用的是 RISC-V 体系结构,而不是流行的 x86 体系结构),并在虚拟机环境中运行它。如果程序的返回代码是 0 ,我们认为脚本成功了,所有非零的返回代码都将被视为失败脚本。

在上面的例子中,我们展示了一个总是成功的脚本代码。因为返回代码总是 0。但是请不要使用这个作为您的 lock script code ,否则您的 token 可能会被任何人拿走。

但是显然上面的例子并不有趣,这里我们从一个有趣的想法开始:我个人不是很喜欢胡萝卜。我知道胡萝卜从营养的角度来看是很好的,但我还是想要避免它的味道。如果现在我想设定一个规则,比如我想让我在 CKB 上的 Cell 里面都没有以carrot开头的数据?让我们编写一个脚本代码来实现这一点。

为了确保没有一个 cell 在 cell data中包含carrot,我们首先需要一种方法来读取脚本中的 cell data。CKB 提供了syscalls来帮助解决这个问题。

为了确保 CKB 脚本的安全性,每个脚本都必须在与运行 CKB 的主计算机完全分离的隔离环境中运行。这样它就不能访问它不需要的数据,比如你的私钥或密码。然而,要使得脚本有用,必须有特定的数据要访问,比如脚本保护的 cell 或脚本验证的事务。CKB 提供了syscalls来确保这一点,syscalls是在 RISC-V 的标准中定义的,它们提供了访问环境中某些资源的方法。在正常情况下,这里的环境指的是操作系统,但是在 CKB VM 中,环境指的是实际的 CKB 进程。使用syscalls, CKB脚本可以访问包含自身的整个事务,包括输入(inputs)、输出(outpus)、见证(witnesses)和 deps。

好消息是,我们已经将syscalls封装在了一个易于使用的头文件中,非常欢迎您在这里查看这个文件,了解如何实现syscalls。最重要的是,您可以只获取这个头文件并使用包装函数来创建您想要的系统调用。

现在有了syscalls,我们可以从禁止使用carrot的脚本开始:

#include <memory.h>
#include "ckb_syscalls.h"

int main(int argc, char* argv[]) {
  int ret;
  size_t index = 0;
  volatile uint64_t len = 0; /* (1) */
  unsigned char buffer[6];

  while 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值