
王者荣耀点券修改器下载地址: https://ghb2023zs.bj.bcebos.com/gg/ggxgq
各位游戏大佬大家好,今天小编为大家分享关于gg修改器脚本要root吗_gg修改器免root的内容,轻松修改游戏数据,赶快来一起来看看吧。

Xuejie 是 CKB-VM的核心开发者,他在自己的博客「Less is More」中,创作了一系列介绍 CKB 脚本编程的文章,用于补充白皮书中编写 CKB 脚本所需的所有缺失的细节实现。本文是该系列的第五篇,详细介绍了 CKB 的调试过程,快来一起查看吧 ~^.^~
作者:Xuejie
原文链接:https://xuejie.space/2019_10_18_introduction_to_ckb_script_programming_debugging/
译者:史迪仔
事实上,CKB 脚本工作的层级要比其他智能合约低很多,因此 CKB 的调试过程就显得相当神秘。在本文中,我们将展示如何调试 CKB 脚本。你会发现,其实调试 CKB 脚本和你日常调试程序并没有太大区别。本文建立在 ckb v0.23.0 之上。具体的,我在每个项目中使用的是如下版本的 commit:
• ckb:
7e2ad2d9ed6718360587f3762163229eccd2cf10
• ckb-sdk-ruby:
18a89d8c69e173ad59ce3e3b3bf79b5d11c5f8f8
• ckb-duktape:
347bf730c08eb0aab7e56e0357945a4d6cee109a
• ckb-standalone-debugger:
2379e89ae285e4e639b961756c22d8e4fde4d6ab
使用 GDB 调试 C 程序
CKB 脚本调试的第一种方案,通常适用于 C、Rust 等编程语言。也许你已经习惯了写 C 的程序,而 GDB 也是你的好搭档。你想知道是不是可以用 GDB 来调试 C 程序,答案当然是:Yes!你肯定可以通过 GDB 来调试用 C 编写的 CKB 脚本!让我来演示一下:
首先,我们还是用之前文章中用到的关于 carrot 的例子:
#includeint main(int argc, char* argv[]) {int ret;size_t index = 0;uint64_t len = 0;unsigned char buffer[6];while (1) {len = 6;memset(buffer, 0, 6);ret = ckb_load_cell_data(buffer, &len, 0, index, CKB_SOURCE_OUTPUT);if (ret == CKB_INDEX_OUT_OF_BOUND) {break;}int cmp = memcmp(buffer, "carrot", 6);if (cmp) {return -1;}index++;}return 0;}这里我进行了两处修改:
- 首先我更新了这个脚本,让它可以兼容 ckb v0.23.0。在这个版本中,我们可以使用
ckb_load_cell_data来获取 cell 的数据。- 我还在这段代码中加入了一个小 bug,这样我们等会儿就可以进行调试的工作流程。如果你非常熟悉 C,你可能已经注意到了,当然你没有在意到的话也完全不用担心,稍后我会解释的。
和往常一样,我们使用官方的 toolchain 来将其编译成 RISC-V 的代码:
$ lscarrot.c$ git clone https:///nervosnetwork/ckb-system-scripts$ cp ckb-system-scripts/c/ckb_*.h ./$ lscarrot.c ckb_consts.h ckb_syscalls.h ckb-system-scripts/$ sudo docker run --rm -it -v `pwd`:/code nervos/ckb-riscv-gnu-toolchain:bionic-20191012 bashroot@3efa454be9af:/# cd /coderoot@3efa454be9af:/code# riscv64-unknown-elf-gcc carrot.c -g -o carrotroot@3efa454be9af:/code# exit请注意,当我编译脚本的时候,我添加了
-g,以便生成调试信息,这在 GDB 中非常有用。对于实际使用的脚本,你总是希望尽量地完善它们来尽量节省存储在链上的空间。现在,让我们将脚本部署到 CKB 上。保持 CKB 节点处于运行状态,并启动 Ruby SDK:
pry(main)> api = CKB::API.newpry(main)> wallet = CKB::Wallet.from_hex(api, "pry(main)> wallet2 = CKB::Wallet.from_hex(api, CKB::Key.random_private_key)pry(main)> carrot_data = File.read("carrot")pry(main)> carrot_data.bytesize=> 19296pry(main)> carrot_tx_hash = wallet.send_capacity(wallet2.address, CKB::Utils.byte_to_shannon(20000), CKB::Utils.bin_to_hex(carrot_data), fee: 21000)pry(main)> carrot_data_hash = CKB::Blake2b.hexdigest(carrot_data)pry(main)> carrot_type_script = CKB::Types::Script.new(code_hash: carrot_data_hash, args: "0x")pry(main)> carrot_cell_dep = CKB::Types::CellDep.new(out_point: CKB::Types::OutPoint.new(tx_hash: carrot_tx_hash, index: 0))现在链上有了 carrot 的脚本,我们可以创建一笔交易来测试这个 carrot 脚本:
pry(main)> tx = wallet.generate_tx(wallet2.address, CKB::Utils.byte_to_shannon(100), use_dep_group: false, fee: 5000)pry(main)> tx.outputs[0].type = carrot_type_scriptpry(main)> tx.cell_depspry(main)> tx.witnesses[0] = "0x"pry(main)> tx = tx.sign(wallet.key, pute_transaction_hash(tx))pry(main)> api.send_transaction(tx)CKB::RPCError: jsonrpc error: {:code=>-3, :message=>"Script(ValidationFailure(-1))"}如果你仔细检查这笔交易,你会发现在输出的 cell 中,并没有以
carrot开头的数据。然而我们运行之后仍然是验证失败,这意味着我们的脚本一定存在 bug。先前,没什么别的办法,你可能需要返回去检查代码,希望可以找到出错的地方。但现在没有这个必要了,你可以跳过这里的交易,然后将其输入到一个独立的 CKB 调试器开始调试它!首先,让我们将这笔交易连同使用的环境,都转存到一个本地文件中:
pry(main)> CKB::MockTransactionDumper.new(api, tx).write("carrot.json")在这里你还需要跟踪 carrot 类型脚本的哈希:
pry(main)> carrot_type_pute_hash=> "0x039c2fba64f389575cdecff8173882b97be5f8d3bdb2bb0770d8a7e265b91933"请注意,你可能会得到和我这里不一样的哈希,这得看你使用的环境。现在,让我们来试试 ckb-standalone-debugger:
$ git clone https:///nervosnetwork/ckb-standalone-debugger$ cd ckb-standalone-debugger/bins$ cargo build --release$ ./target/release/ckb-debugger -l 0.0.0.0:2000 -g type -h 0x039c2fba64f389575cdecff8173882b97be5f8d3bdb2bb0770d8a7e265b91933 -t carrot.json注意,你可能需要根据你的环境,调整 carrot 类型脚本的哈希或者
carrot.json的路径。现在让我们试试在一个不同的终端内通过 GDB 连接调试器:
$ sudo docker run --rm -it -v `pwd`:/code nervos/ckb-riscv-gnu-toolchain:bionic-20191012 bashroot@66e3b39e0dfd:/# cd /coderoot@66e3b39e0dfd:/code# riscv64-unknown-elf-gdb carrotGNU gdb (GDB) 8.3.0.20190516-gitCopyright (C) 2019 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or laterThis is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.Type "show copying" and "show warranty" for details.This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv64-unknown-elf".Type "show configuration" for configuration details.For bug reporting instructions, please see:Find the GDB manual and other documentation resources online at:For help, type "help".Type "apropos word" to search mands related to "word"...Reading symbols from carrot...(gdb) target remote 192.168.1.230:2000Remote debugging using 192.168.1.230:20000x00000000000100c6 in _start(gdb)注意,这里的
192.168.1.230是我的工作站在本地网络中的 IP 地址,你可能需要调整该地址,因为你的计算机可能是不同的 IP 地址。现在我们可以试一下常见的 GDB 调试过程:
(gdb) b mainBreakpoint 1 at 0x106b0: file carrot.c, line 6.(gdb) cContinuing.Breakpoint 1, main (argc=0, argv=0x400000) at carrot.c:66 size_t index = 0;(gdb) n7 uint64_t len = 0;(gdb) n11 len = 6;(gdb) n12 memset(buffer, 0, 6);(gdb) n13 ret = ckb_load_cell_data(buffer, &len, 0, index, CKB_SOURCE_OUTPUT);(gdb) n14 if (ret == CKB_INDEX_OUT_OF_BOUND) {(gdb) n18 int cmp = memcmp(buffer, "carrot", 6);(gdb) n19 if (cmp) {(gdb) p cmp$1 = -99(gdb) p buffer[0]$2 = 0 ’ 00’(gdb) n20 return -1;这里我们可以看到哪里出问题了:
buffer中第一个字节的值是0,这和c不同,因此我们的buffer和carrot不同。条件if (cap) {没有跳转到下一个循环,而是跳到了 true 的情况,返回了-1,表明与carrot匹配。出现这样问题的原因是,当两个buffers相等的时候,memcmp将会返回 0,当它们不相等的时候,将返回非零值。但是我们没有测试memcmp的返回值是否为 0,就直接在if条件中使用了它,这样 C 会把所有的非零值都视为 true,这里返回的-99就会被判断为 true。对于初学者而言,这是在 C 中会遇到的典型的错误,我希望你不会再犯这样的错误。:)现在我们知道了错误的原因,接下来去修复 carrot 脚本中的错误就非常简单了。但是正如你看到的,我们设法从 CKB 上获取一笔错误交易在运行时的状态,然后通过 GDB(一个业界常见的工具)来对其进行调试。而且您在 GDB 上现有的工作流程和工具也可以在这里使用,是不是很棒?基于 REPL 的开发/调试
然而,GDB 仅仅是现代软件开发中的一部分。动态语言在很大程度上占据了主导地位,很多程序员都使用基于 REPL 的开发/调试工作流。这与编译语言中的 GDB 完全不同,基本上你需要的是一个运行的环境,你可以输入任何你想要与环境进行交互的代码,然后得到不同的结果。正如我们将在这里展示的,CKB 也会支持这种类型的开发/调试工作流。: p在这里,我们将使用 ckb-duktape 来展示基于 JavaScript 的 REPL。但是请注意,这只是一个 demo 用来演示一下工作流程,没有任何东西阻止您将自己喜爱的动态语言(不管是 Ruby、Rython、Lisp 等等)移植到 CKB 中去,并为该语言启动 REPL。首先,让我们尝试编译 duktape:
$ git clone https:///nervosnetwork/ckb-duktape$ cd ckb-duktape$ sudo docker run --rm -it -v `pwd`:/code nervos/ckb-riscv-gnu-toolchain:bionic-20191012 bashroot@982d1e906b76:/# cd /coderoot@982d1e906b76:/code# makeriscv64-unknown-elf-gcc -Os -DCKB_NO_MMU -D__riscv_soft_float -D__riscv_float_abi_soft -Iduktape -Ic -Wall -Werror c/entry.c -c -o build/entry.oriscv64-unknown-elf-gcc -Os -DCKB_NO_MMU -D__riscv_soft_float -D__riscv_float_abi_soft -Iduktape -Ic -Wall -Werror duktape/duktape.c -c -o build/duktape.oriscv64-unknown-elf-gcc build/entry.o build/duktape.o -o build/duktape -lm -Wl,-static -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,-sriscv64-unknown-elf-gcc -Os -DCKB_NO_MMU -D__riscv_soft_float -D__riscv_float_abi_soft -Iduktape -Ic -Wall -Werror c/repl.c -c -o build/repl.oriscv64-unknown-elf-gcc build/repl.o build/duktape.o -o build/repl -lm -Wl,-static -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,-sroot@982d1e906b76:/code# exit你需要在这里生成
build/repl二进制文件。和 carrot 的例子类似,我们先将 duktape REPL 的二进制文件部署在 CKB 上:
pry(main)> api = CKB::API.newpry(main)> wallet = CKB::Wallet.from_hex(api, "pry(main)> wallet2 = CKB::Wallet.from_hex(api, CKB::Key.random_private_key)pry(main)> duktape_repl_data = File.read("build/repl")pry(main)> duktape_repl_data.bytesize=> 283048pry(main)> duktape_repl_tx_hash = wallet.send_capacity(wallet2.address, CKB::Utils.byte_to_shannon(300000), CKB::Utils.bin_to_hex(duktape_repl_data), fee: 310000)pry(main)> duktape_repl_data_hash = CKB::Blake2b.hexdigest(duktape_repl_data)pry(main)> duktape_repl_type_script = CKB::Types::Script.new(code_hash: duktape_repl_data_hash, args: "0x")pry(main)> duktape_repl_cell_dep = CKB::Types::CellDep.new(out_point: CKB::Types::OutPoint.new(tx_hash: duktape_repl_tx_hash, index: 0))我们还需要创建一笔包含 duktape 脚本的交易,我这里使用一个非常简单的脚本,当然你可以加入更多的数据,这样你就可以在 CKB 上玩起来了
pry(main)> tx = wallet.generate_tx(wallet2.address, CKB::Utils.byte_to_shannon(100), use_dep_group: false, fee: 5000)pry(main)> tx.outputs[0].type = duktape_repl_type_scriptpry(main)> tx.cell_depspry(main)> tx.witnesses[0] = "0x"然后让我们把它转存到文件中,并检查 duktape 类型脚本的哈希:
pry(main)> CKB::MockTransactionDumper.new(api, tx).write("duktape.json")=> 2765824pry(main)> duktape_repl_type_pute_hash=> "0xa8b79392c857e29cb283e452f2cd48a8e06c51af64be175e0fe0e2902c482837"与上面不同的是,我们不需要启动 GDB,而是可以直接启动程序:
$ ./target/release/ckb-debugger -g type -h 0xa8b79392c857e29cb283e452f2cd48a8e06c51af64be175e0fe0e2902c482837 -t duktape.jsonduk>你可以看到一个
duk>提示你输入 JS 代码!同样,如果遇到错误,请检查是否需要更改类型脚本的哈希,或者使用正确的duktape.json路径。我们看到常见的 JS 代码可以在这里工作运行:
duk> print(1 + 2)3= undefinedduk> function foo(a) { return a + 1; }= undefinedduk> foo(123)= 124您还可以使用与 CKB 相关的功能:
duk> var hash = CKB.load_script_hash= undefinedduk> function buf2hex(buffer) { return Array.prototype.map.call(new Uint8Array(buffer), function(x) { return (’00’ + x.toString(16)).slice(-2); }).join(’’); }= undefinedduk> buf2hex(hash)= a8b79392c857e29cb283e452f2cd48a8e06c51af64be175e0fe0e2902c482837请注意,我们在这里得到的脚本哈希正是我们当前执行的类型脚本的哈希!这将证明 CKB 系统调试在这里是有效的,我们也可以尝试更多有趣的东西:
duk> print(CKB.SOURCE.OUTPUT)2= undefinedduk> print(CKB.CELL.CAPACITY)0= undefinedduk> capacity_field = CKB.load_cell_by_field(0, 0, CKB.SOURCE.OUTPUT, CKB.CELL.CAPACITY)= [object ArrayBuffer]duk> buf2hex(capacity_field)= 00e40b5402000000这个
00e40b5402000000可能在一开始看起来有点神秘,但是请注意 RISC-V 使用的是 little endian(低字节序),所以如果在这里我们将字节序列颠倒,我们将得到00000002540be400,在十进制中正好是10000000000。还要记住,在 CKB 中容量使用的单位是shannons,所以10000000000正好是100个字节,这正是我们生成上面的交易时,想要发送的代币的数量!现在你看到了如何在 duktape 环境中与 CKB 愉快地玩耍了 :)结论
我们已经介绍了两种不同的在 CKB 中调试的过程,你可以随意使用其中一种(或者两种)。我已经迫不及待地想看你们在 CKB 上玩出花来啦!
以上就是关于gg修改器脚本要root吗_gg修改器免root的全部内容,游戏大佬们学会了吗?

王者荣耀刷9999点卷助手 分类:点卷助手 1,096人在玩 随着《王者荣耀》的持续火爆,点卷作为游戏中重要的虚拟货币,被广泛用于购买英雄、皮肤、道具等资源。不少玩家希望以最低成本获得大量点卷,于是网络上出现了诸如“王者荣耀刷9999……
下载
王者荣耀刷5000点卷 3分钟教程 分类:点卷助手 342人在玩 网络上流传着一些号称“王者荣耀刷5000点卷3分钟教程”的信息,打着“免ROOT”“一键刷点卷”“永久不封号”等旗号,吸引大量玩家点击下载所谓的“点券生成器”“无限点卷助手”等非法软件。这……
下载
刷王者荣耀点卷的人的qq,刷王者荣耀点券的qq群 分类:点卷助手 978人在玩 近年来,随着《王者荣耀》的热度不断上升,越来越多的玩家开始寻求通过非官方渠道获取点卷和点券,其中,“刷王者荣耀点卷的人的QQ”和“刷王者荣耀点券的QQ群”成为不少玩家关注的焦……
下载
王者荣耀助手刷点券下载-王者荣耀刷点券破解版下载【2025免费安全安卓/iOS】 分类:点卷助手 6,193人在玩 一、为什么「王者荣耀助手刷点券」霸榜移动端热搜? 2025年《王者荣耀》全球用户突破12亿,随着「星穹幻境」赛季限定皮肤的推出,玩家日均点券消耗量激增47%。百度指数显示,「王者……
下载
gg修改器方舟免root,下载 gg修改器方舟免root 软件 分类:修改器 19,451人在玩 gg修改器方舟免root是一款非常实用的手机游戏辅助工具。它可以帮助玩家轻松地获取游戏中的各种资源,比如金币、钻石、装备等。该软件支持大部分主流的手机游戏,并且不需要进行Root……
下载
无root使用gg修改器,无root使用gg修改器,畅享游戏乐趣 分类:修改器 20,534人在玩 在游戏中卡顿、无法通过某些关卡或者想要获得更多的金币、钻石等资源时,我们可能会想到使用一些辅助工具来解决这些问题。而其中比较常见的就是修改器了。但是传统的修改器需要root……
下载
gg修改器怎么用无root_GG修改器无 分类:修改器 23,676人在玩 各位游戏大佬大家好,今天小编为大家分享关于gg修改器怎么用无root_GG修改器无的内容,轻松修改游戏数据,赶快来一起来看看吧。 完成这两步,就可以正式开始自定义状态栏了。状……
下载
王者荣耀2026刷点卷不封号,王者免费刷点卷不封号 分类:未分类点卷助手 646人在玩 近年来,随着《王者荣耀》的持续火爆,不少玩家出于对点卷资源的需求,开始在网络平台上搜索“王者荣耀2026刷点卷不封号”“王者免费刷点卷不封号”等关键词,试图寻找一种“安全、稳定……
下载
王者荣耀最新免费刷点卷,王者,免费刷点卷 分类:点卷助手 591人在玩 近年来,随着《王者荣耀》的持续火爆,越来越多的玩家希望通过各种方式获取游戏中的虚拟货币“点卷”。点卷不仅可以用于购买英雄、皮肤,还能参与抽奖和兑换稀有道具,因此一些玩家……
下载
在gg修改器怎么使用root,什么是GG修改器? 分类:修改器 19,921人在玩 下载GG修改器,轻松实现ROOT GG修改器是一款安卓手机平台上的修改工具,它可以帮助用户进行游戏内部数据的修改、加速、挂机等操作。使用GG修改器不需要复杂的编程知识,只需简单的……
下载