编写一个watchdog.sh脚本_CKB脚本编程简介第二弹:脚本基础 | 火星技术帖

a6d46bbe2ae06ac651bdd69a9fcff24f.png

免责声明:本文旨在传递更多市场信息,不构成任何投资建议。文章仅代表作者观点,不代表火星财经官方立场。

小编:记得关注哦

来源:NervosNetwork

Xuejie 是 CKB-VM的核心开发者,他在自己的博客「Less is More」中,创作了一系列介绍 CKB 脚本编程的文章,用于补充白皮书中编写 CKB 脚本所需的所有缺失的细节实现。本文是该系列的第二篇,详细讲解了如何将脚本代码部署到 CKB 网络上,快来查看吧 ~^.^~

作者:Xuejie

原文链接:https://xuejie.space/2019_07_13_introduction_to_ckb_script_programming_script_basics/

译者:Shooter, Jason, Orange(排名不分先后)

校对:Joey

在上一篇文章里,我介绍了当前 CKB 的验证模型。这一篇会更加有趣一点,我们要向大家展示如何将脚本代码真正部署到 CKB 网络上去。我希望在你看完本文后,你可以有能力自行去探索 CKB 的世界并按照你自己的意愿去编写新的脚本代码。但是请注意,尽管我相信目前的 CKB 的编程模型已经相对稳定了,但是开发仍在进行中,因此未来还可能会有一些变化。我将尽力确保本文始终处于最新的状态,但是如果在过程到任何疑惑,本文以此版本下的 CKB 作为依据:

https://github.com/nervosnetwork/ckb/commit/80b51a9851b5d535625c5d144e1accd38c32876b

Tips:这是一篇很长的文章,因为我想为下周更有趣的话题提供充足的内容。所以如果你时间不太够,你不必马上读完。我会试着把它分成几个独立的部分,这样你就可以一次读其中一部分。

语法

在开始之前,我们先来区分两个术语:脚本(Script)脚本代码(Script Code)

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

pub struct Script {    pub args: Vec

我们目前可以先忽略 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-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:

https://github.com/nervosnetwork/ckb-system-scripts/blob/66d7da8ec72dffaa7e9c55904833951eca2422a9/c/ckb_syscalls.h

最重要的是,您可以只获取这个头文件并使用包装函数来创建您想要的系统调用。现在有了 syscalls,我们可以从禁止使用 carrot 的脚本开始:

#include #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 (1) { len = 6; memset(buffer, 0, 6); ret = ckb_load_cell_by_field(buffer, &len, 0, index, CKB_SOURCE_OUTPUT, CKB_CELL_FIELD_DATA); /* (2) */ if (ret == CKB_INDEX_OUT_OF_BOUND) { /* (3) */ break; }
if (memcmp(buffer, "carrot
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值